diff options
883 files changed, 22951 insertions, 14873 deletions
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 6f242d5dee9a..17910e2052ad 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl | |||
@@ -189,8 +189,7 @@ static void __iomem *baseaddr; | |||
189 | <title>Partition defines</title> | 189 | <title>Partition defines</title> |
190 | <para> | 190 | <para> |
191 | If you want to divide your device into partitions, then | 191 | If you want to divide your device into partitions, then |
192 | enable the configuration switch CONFIG_MTD_PARTITIONS and define | 192 | define a partitioning scheme suitable to your board. |
193 | a partitioning scheme suitable to your board. | ||
194 | </para> | 193 | </para> |
195 | <programlisting> | 194 | <programlisting> |
196 | #define NUM_PARTITIONS 2 | 195 | #define NUM_PARTITIONS 2 |
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt index c078ad48f7a1..8173cec473aa 100644 --- a/Documentation/RCU/trace.txt +++ b/Documentation/RCU/trace.txt | |||
@@ -99,18 +99,11 @@ o "qp" indicates that RCU still expects a quiescent state from | |||
99 | 99 | ||
100 | o "dt" is the current value of the dyntick counter that is incremented | 100 | o "dt" is the current value of the dyntick counter that is incremented |
101 | when entering or leaving dynticks idle state, either by the | 101 | when entering or leaving dynticks idle state, either by the |
102 | scheduler or by irq. The number after the "/" is the interrupt | 102 | scheduler or by irq. This number is even if the CPU is in |
103 | nesting depth when in dyntick-idle state, or one greater than | 103 | dyntick idle mode and odd otherwise. The number after the first |
104 | the interrupt-nesting depth otherwise. | 104 | "/" is the interrupt nesting depth when in dyntick-idle state, |
105 | 105 | or one greater than the interrupt-nesting depth otherwise. | |
106 | This field is displayed only for CONFIG_NO_HZ kernels. | 106 | The number after the second "/" is the NMI nesting depth. |
107 | |||
108 | o "dn" is the current value of the dyntick counter that is incremented | ||
109 | when entering or leaving dynticks idle state via NMI. If both | ||
110 | the "dt" and "dn" values are even, then this CPU is in dynticks | ||
111 | idle mode and may be ignored by RCU. If either of these two | ||
112 | counters is odd, then RCU must be alert to the possibility of | ||
113 | an RCU read-side critical section running on this CPU. | ||
114 | 107 | ||
115 | This field is displayed only for CONFIG_NO_HZ kernels. | 108 | This field is displayed only for CONFIG_NO_HZ kernels. |
116 | 109 | ||
diff --git a/Documentation/acpi/method-customizing.txt b/Documentation/acpi/method-customizing.txt index 3e1d25aee3fb..5f55373dd53b 100644 --- a/Documentation/acpi/method-customizing.txt +++ b/Documentation/acpi/method-customizing.txt | |||
@@ -66,3 +66,8 @@ Note: We can use a kernel with multiple custom ACPI method running, | |||
66 | But each individual write to debugfs can implement a SINGLE | 66 | But each individual write to debugfs can implement a SINGLE |
67 | method override. i.e. if we want to insert/override multiple | 67 | method override. i.e. if we want to insert/override multiple |
68 | ACPI methods, we need to redo step c) ~ g) for multiple times. | 68 | ACPI methods, we need to redo step c) ~ g) for multiple times. |
69 | |||
70 | Note: Be aware that root can mis-use this driver to modify arbitrary | ||
71 | memory and gain additional rights, if root's privileges got | ||
72 | restricted (for example if root is not allowed to load additional | ||
73 | modules after boot). | ||
diff --git a/Documentation/arm/Booting b/Documentation/arm/Booting index 76850295af8f..4e686a2ed91e 100644 --- a/Documentation/arm/Booting +++ b/Documentation/arm/Booting | |||
@@ -65,13 +65,19 @@ looks at the connected hardware is beyond the scope of this document. | |||
65 | The boot loader must ultimately be able to provide a MACH_TYPE_xxx | 65 | The boot loader must ultimately be able to provide a MACH_TYPE_xxx |
66 | value to the kernel. (see linux/arch/arm/tools/mach-types). | 66 | value to the kernel. (see linux/arch/arm/tools/mach-types). |
67 | 67 | ||
68 | 68 | 4. Setup boot data | |
69 | 4. Setup the kernel tagged list | 69 | ------------------ |
70 | ------------------------------- | ||
71 | 70 | ||
72 | Existing boot loaders: OPTIONAL, HIGHLY RECOMMENDED | 71 | Existing boot loaders: OPTIONAL, HIGHLY RECOMMENDED |
73 | New boot loaders: MANDATORY | 72 | New boot loaders: MANDATORY |
74 | 73 | ||
74 | The boot loader must provide either a tagged list or a dtb image for | ||
75 | passing configuration data to the kernel. The physical address of the | ||
76 | boot data is passed to the kernel in register r2. | ||
77 | |||
78 | 4a. Setup the kernel tagged list | ||
79 | -------------------------------- | ||
80 | |||
75 | The boot loader must create and initialise the kernel tagged list. | 81 | The boot loader must create and initialise the kernel tagged list. |
76 | A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE. | 82 | A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE. |
77 | The ATAG_CORE tag may or may not be empty. An empty ATAG_CORE tag | 83 | The ATAG_CORE tag may or may not be empty. An empty ATAG_CORE tag |
@@ -101,6 +107,24 @@ The tagged list must be placed in a region of memory where neither | |||
101 | the kernel decompressor nor initrd 'bootp' program will overwrite | 107 | the kernel decompressor nor initrd 'bootp' program will overwrite |
102 | it. The recommended placement is in the first 16KiB of RAM. | 108 | it. The recommended placement is in the first 16KiB of RAM. |
103 | 109 | ||
110 | 4b. Setup the device tree | ||
111 | ------------------------- | ||
112 | |||
113 | The boot loader must load a device tree image (dtb) into system ram | ||
114 | at a 64bit aligned address and initialize it with the boot data. The | ||
115 | dtb format is documented in Documentation/devicetree/booting-without-of.txt. | ||
116 | The kernel will look for the dtb magic value of 0xd00dfeed at the dtb | ||
117 | physical address to determine if a dtb has been passed instead of a | ||
118 | tagged list. | ||
119 | |||
120 | The boot loader must pass at a minimum the size and location of the | ||
121 | system memory, and the root filesystem location. The dtb must be | ||
122 | placed in a region of memory where the kernel decompressor will not | ||
123 | overwrite it. The recommended placement is in the first 16KiB of RAM | ||
124 | with the caveat that it may not be located at physical address 0 since | ||
125 | the kernel interprets a value of 0 in r2 to mean neither a tagged list | ||
126 | nor a dtb were passed. | ||
127 | |||
104 | 5. Calling the kernel image | 128 | 5. Calling the kernel image |
105 | --------------------------- | 129 | --------------------------- |
106 | 130 | ||
@@ -125,7 +149,8 @@ In either case, the following conditions must be met: | |||
125 | - CPU register settings | 149 | - CPU register settings |
126 | r0 = 0, | 150 | r0 = 0, |
127 | r1 = machine type number discovered in (3) above. | 151 | r1 = machine type number discovered in (3) above. |
128 | r2 = physical address of tagged list in system RAM. | 152 | r2 = physical address of tagged list in system RAM, or |
153 | physical address of device tree block (dtb) in system RAM | ||
129 | 154 | ||
130 | - CPU mode | 155 | - CPU mode |
131 | All forms of interrupts must be disabled (IRQs and FIQs) | 156 | All forms of interrupts must be disabled (IRQs and FIQs) |
diff --git a/Documentation/arm/Samsung/Overview.txt b/Documentation/arm/Samsung/Overview.txt index c3094ea51aa7..658abb258cef 100644 --- a/Documentation/arm/Samsung/Overview.txt +++ b/Documentation/arm/Samsung/Overview.txt | |||
@@ -14,7 +14,6 @@ Introduction | |||
14 | - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list | 14 | - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list |
15 | - S3C64XX: S3C6400 and S3C6410 | 15 | - S3C64XX: S3C6400 and S3C6410 |
16 | - S5P6440 | 16 | - S5P6440 |
17 | - S5P6442 | ||
18 | - S5PC100 | 17 | - S5PC100 |
19 | - S5PC110 / S5PV210 | 18 | - S5PC110 / S5PV210 |
20 | 19 | ||
@@ -36,7 +35,6 @@ Configuration | |||
36 | unifying all the SoCs into one kernel. | 35 | unifying all the SoCs into one kernel. |
37 | 36 | ||
38 | s5p6440_defconfig - S5P6440 specific default configuration | 37 | s5p6440_defconfig - S5P6440 specific default configuration |
39 | s5p6442_defconfig - S5P6442 specific default configuration | ||
40 | s5pc100_defconfig - S5PC100 specific default configuration | 38 | s5pc100_defconfig - S5PC100 specific default configuration |
41 | s5pc110_defconfig - S5PC110 specific default configuration | 39 | s5pc110_defconfig - S5PC110 specific default configuration |
42 | s5pv210_defconfig - S5PV210 specific default configuration | 40 | s5pv210_defconfig - S5PV210 specific default configuration |
diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index 50619a0720a8..7c1329de0596 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt | |||
@@ -12,8 +12,9 @@ Table of Contents | |||
12 | ================= | 12 | ================= |
13 | 13 | ||
14 | I - Introduction | 14 | I - Introduction |
15 | 1) Entry point for arch/powerpc | 15 | 1) Entry point for arch/arm |
16 | 2) Entry point for arch/x86 | 16 | 2) Entry point for arch/powerpc |
17 | 3) Entry point for arch/x86 | ||
17 | 18 | ||
18 | II - The DT block format | 19 | II - The DT block format |
19 | 1) Header | 20 | 1) Header |
@@ -148,7 +149,46 @@ upgrades without significantly impacting the kernel code or cluttering | |||
148 | it with special cases. | 149 | it with special cases. |
149 | 150 | ||
150 | 151 | ||
151 | 1) Entry point for arch/powerpc | 152 | 1) Entry point for arch/arm |
153 | --------------------------- | ||
154 | |||
155 | There is one single entry point to the kernel, at the start | ||
156 | of the kernel image. That entry point supports two calling | ||
157 | conventions. A summary of the interface is described here. A full | ||
158 | description of the boot requirements is documented in | ||
159 | Documentation/arm/Booting | ||
160 | |||
161 | a) ATAGS interface. Minimal information is passed from firmware | ||
162 | to the kernel with a tagged list of predefined parameters. | ||
163 | |||
164 | r0 : 0 | ||
165 | |||
166 | r1 : Machine type number | ||
167 | |||
168 | r2 : Physical address of tagged list in system RAM | ||
169 | |||
170 | b) Entry with a flattened device-tree block. Firmware loads the | ||
171 | physical address of the flattened device tree block (dtb) into r2, | ||
172 | r1 is not used, but it is considered good practise to use a valid | ||
173 | machine number as described in Documentation/arm/Booting. | ||
174 | |||
175 | r0 : 0 | ||
176 | |||
177 | r1 : Valid machine type number. When using a device tree, | ||
178 | a single machine type number will often be assigned to | ||
179 | represent a class or family of SoCs. | ||
180 | |||
181 | r2 : physical pointer to the device-tree block | ||
182 | (defined in chapter II) in RAM. Device tree can be located | ||
183 | anywhere in system RAM, but it should be aligned on a 64 bit | ||
184 | boundary. | ||
185 | |||
186 | The kernel will differentiate between ATAGS and device tree booting by | ||
187 | reading the memory pointed to by r2 and looking for either the flattened | ||
188 | device tree block magic value (0xd00dfeed) or the ATAG_CORE value at | ||
189 | offset 0x4 from r2 (0x54410001). | ||
190 | |||
191 | 2) Entry point for arch/powerpc | ||
152 | ------------------------------- | 192 | ------------------------------- |
153 | 193 | ||
154 | There is one single entry point to the kernel, at the start | 194 | There is one single entry point to the kernel, at the start |
@@ -226,7 +266,7 @@ it with special cases. | |||
226 | cannot support both configurations with Book E and configurations | 266 | cannot support both configurations with Book E and configurations |
227 | with classic Powerpc architectures. | 267 | with classic Powerpc architectures. |
228 | 268 | ||
229 | 2) Entry point for arch/x86 | 269 | 3) Entry point for arch/x86 |
230 | ------------------------------- | 270 | ------------------------------- |
231 | 271 | ||
232 | There is one single 32bit entry point to the kernel at code32_start, | 272 | There is one single 32bit entry point to the kernel at code32_start, |
diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt index 0c1c2f63c0a9..5a0cb1ef6164 100644 --- a/Documentation/dmaengine.txt +++ b/Documentation/dmaengine.txt | |||
@@ -1 +1,96 @@ | |||
1 | See Documentation/crypto/async-tx-api.txt | 1 | DMA Engine API Guide |
2 | ==================== | ||
3 | |||
4 | Vinod Koul <vinod dot koul at intel.com> | ||
5 | |||
6 | NOTE: For DMA Engine usage in async_tx please see: | ||
7 | Documentation/crypto/async-tx-api.txt | ||
8 | |||
9 | |||
10 | Below is a guide to device driver writers on how to use the Slave-DMA API of the | ||
11 | DMA Engine. This is applicable only for slave DMA usage only. | ||
12 | |||
13 | The slave DMA usage consists of following steps | ||
14 | 1. Allocate a DMA slave channel | ||
15 | 2. Set slave and controller specific parameters | ||
16 | 3. Get a descriptor for transaction | ||
17 | 4. Submit the transaction and wait for callback notification | ||
18 | |||
19 | 1. Allocate a DMA slave channel | ||
20 | Channel allocation is slightly different in the slave DMA context, client | ||
21 | drivers typically need a channel from a particular DMA controller only and even | ||
22 | in some cases a specific channel is desired. To request a channel | ||
23 | dma_request_channel() API is used. | ||
24 | |||
25 | Interface: | ||
26 | struct dma_chan *dma_request_channel(dma_cap_mask_t mask, | ||
27 | dma_filter_fn filter_fn, | ||
28 | void *filter_param); | ||
29 | where dma_filter_fn is defined as: | ||
30 | typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); | ||
31 | |||
32 | When the optional 'filter_fn' parameter is set to NULL dma_request_channel | ||
33 | simply returns the first channel that satisfies the capability mask. Otherwise, | ||
34 | when the mask parameter is insufficient for specifying the necessary channel, | ||
35 | the filter_fn routine can be used to disposition the available channels in the | ||
36 | system. The filter_fn routine is called once for each free channel in the | ||
37 | system. Upon seeing a suitable channel filter_fn returns DMA_ACK which flags | ||
38 | that channel to be the return value from dma_request_channel. A channel | ||
39 | allocated via this interface is exclusive to the caller, until | ||
40 | dma_release_channel() is called. | ||
41 | |||
42 | 2. Set slave and controller specific parameters | ||
43 | Next step is always to pass some specific information to the DMA driver. Most of | ||
44 | the generic information which a slave DMA can use is in struct dma_slave_config. | ||
45 | It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA | ||
46 | burst lengths etc. If some DMA controllers have more parameters to be sent then | ||
47 | they should try to embed struct dma_slave_config in their controller specific | ||
48 | structure. That gives flexibility to client to pass more parameters, if | ||
49 | required. | ||
50 | |||
51 | Interface: | ||
52 | int dmaengine_slave_config(struct dma_chan *chan, | ||
53 | struct dma_slave_config *config) | ||
54 | |||
55 | 3. Get a descriptor for transaction | ||
56 | For slave usage the various modes of slave transfers supported by the | ||
57 | DMA-engine are: | ||
58 | slave_sg - DMA a list of scatter gather buffers from/to a peripheral | ||
59 | dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the | ||
60 | operation is explicitly stopped. | ||
61 | The non NULL return of this transfer API represents a "descriptor" for the given | ||
62 | transaction. | ||
63 | |||
64 | Interface: | ||
65 | struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)( | ||
66 | struct dma_chan *chan, | ||
67 | struct scatterlist *dst_sg, unsigned int dst_nents, | ||
68 | struct scatterlist *src_sg, unsigned int src_nents, | ||
69 | unsigned long flags); | ||
70 | struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)( | ||
71 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | ||
72 | size_t period_len, enum dma_data_direction direction); | ||
73 | |||
74 | 4. Submit the transaction and wait for callback notification | ||
75 | To schedule the transaction to be scheduled by dma device, the "descriptor" | ||
76 | returned in above (3) needs to be submitted. | ||
77 | To tell the dma driver that a transaction is ready to be serviced, the | ||
78 | descriptor->submit() callback needs to be invoked. This chains the descriptor to | ||
79 | the pending queue. | ||
80 | The transactions in the pending queue can be activated by calling the | ||
81 | issue_pending API. If channel is idle then the first transaction in queue is | ||
82 | started and subsequent ones queued up. | ||
83 | On completion of the DMA operation the next in queue is submitted and a tasklet | ||
84 | triggered. The tasklet would then call the client driver completion callback | ||
85 | routine for notification, if set. | ||
86 | Interface: | ||
87 | void dma_async_issue_pending(struct dma_chan *chan); | ||
88 | |||
89 | ============================================================================== | ||
90 | |||
91 | Additional usage notes for dma driver writers | ||
92 | 1/ Although DMA engine specifies that completion callback routines cannot submit | ||
93 | any new operations, but typically for slave DMA subsequent transaction may not | ||
94 | be available for submit prior to callback routine being called. This requirement | ||
95 | is not a requirement for DMA-slave devices. But they should take care to drop | ||
96 | the spin-lock they might be holding before calling the callback routine | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index ff31b1cc50aa..1a9446b59153 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -6,6 +6,42 @@ be removed from this file. | |||
6 | 6 | ||
7 | --------------------------- | 7 | --------------------------- |
8 | 8 | ||
9 | What: x86 floppy disable_hlt | ||
10 | When: 2012 | ||
11 | Why: ancient workaround of dubious utility clutters the | ||
12 | code used by everybody else. | ||
13 | Who: Len Brown <len.brown@intel.com> | ||
14 | |||
15 | --------------------------- | ||
16 | |||
17 | What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle | ||
18 | When: 2012 | ||
19 | Why: This optional sub-feature of APM is of dubious reliability, | ||
20 | and ancient APM laptops are likely better served by calling HLT. | ||
21 | Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting | ||
22 | the pm_idle function pointer to modules. | ||
23 | Who: Len Brown <len.brown@intel.com> | ||
24 | |||
25 | ---------------------------- | ||
26 | |||
27 | What: x86_32 "no-hlt" cmdline param | ||
28 | When: 2012 | ||
29 | Why: remove a branch from idle path, simplify code used by everybody. | ||
30 | This option disabled the use of HLT in idle and machine_halt() | ||
31 | for hardware that was flakey 15-years ago. Today we have | ||
32 | "idle=poll" that removed HLT from idle, and so if such a machine | ||
33 | is still running the upstream kernel, "idle=poll" is likely sufficient. | ||
34 | Who: Len Brown <len.brown@intel.com> | ||
35 | |||
36 | ---------------------------- | ||
37 | |||
38 | What: x86 "idle=mwait" cmdline param | ||
39 | When: 2012 | ||
40 | Why: simplify x86 idle code | ||
41 | Who: Len Brown <len.brown@intel.com> | ||
42 | |||
43 | ---------------------------- | ||
44 | |||
9 | What: PRISM54 | 45 | What: PRISM54 |
10 | When: 2.6.34 | 46 | When: 2.6.34 |
11 | 47 | ||
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 61b31acb9176..57d827d6071d 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -104,7 +104,7 @@ of the locking scheme for directory operations. | |||
104 | prototypes: | 104 | prototypes: |
105 | struct inode *(*alloc_inode)(struct super_block *sb); | 105 | struct inode *(*alloc_inode)(struct super_block *sb); |
106 | void (*destroy_inode)(struct inode *); | 106 | void (*destroy_inode)(struct inode *); |
107 | void (*dirty_inode) (struct inode *); | 107 | void (*dirty_inode) (struct inode *, int flags); |
108 | int (*write_inode) (struct inode *, struct writeback_control *wbc); | 108 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
109 | int (*drop_inode) (struct inode *); | 109 | int (*drop_inode) (struct inode *); |
110 | void (*evict_inode) (struct inode *); | 110 | void (*evict_inode) (struct inode *); |
@@ -126,7 +126,7 @@ locking rules: | |||
126 | s_umount | 126 | s_umount |
127 | alloc_inode: | 127 | alloc_inode: |
128 | destroy_inode: | 128 | destroy_inode: |
129 | dirty_inode: (must not sleep) | 129 | dirty_inode: |
130 | write_inode: | 130 | write_inode: |
131 | drop_inode: !!!inode->i_lock!!! | 131 | drop_inode: !!!inode->i_lock!!! |
132 | evict_inode: | 132 | evict_inode: |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 21a7dc467bba..88b9f5519af9 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -211,7 +211,7 @@ struct super_operations { | |||
211 | struct inode *(*alloc_inode)(struct super_block *sb); | 211 | struct inode *(*alloc_inode)(struct super_block *sb); |
212 | void (*destroy_inode)(struct inode *); | 212 | void (*destroy_inode)(struct inode *); |
213 | 213 | ||
214 | void (*dirty_inode) (struct inode *); | 214 | void (*dirty_inode) (struct inode *, int flags); |
215 | int (*write_inode) (struct inode *, int); | 215 | int (*write_inode) (struct inode *, int); |
216 | void (*drop_inode) (struct inode *); | 216 | void (*drop_inode) (struct inode *); |
217 | void (*delete_inode) (struct inode *); | 217 | void (*delete_inode) (struct inode *); |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5438a2d7907f..d9a203b058f1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -999,7 +999,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
999 | With this option on every unmap_single operation will | 999 | With this option on every unmap_single operation will |
1000 | result in a hardware IOTLB flush operation as opposed | 1000 | result in a hardware IOTLB flush operation as opposed |
1001 | to batching them for performance. | 1001 | to batching them for performance. |
1002 | 1002 | sp_off [Default Off] | |
1003 | By default, super page will be supported if Intel IOMMU | ||
1004 | has the capability. With this option, super page will | ||
1005 | not be supported. | ||
1003 | intremap= [X86-64, Intel-IOMMU] | 1006 | intremap= [X86-64, Intel-IOMMU] |
1004 | Format: { on (default) | off | nosid } | 1007 | Format: { on (default) | off | nosid } |
1005 | on enable Interrupt Remapping (default) | 1008 | on enable Interrupt Remapping (default) |
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt deleted file mode 100644 index 4beafa663dd6..000000000000 --- a/Documentation/laptops/acer-wmi.txt +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | Acer Laptop WMI Extras Driver | ||
2 | http://code.google.com/p/aceracpi | ||
3 | Version 0.3 | ||
4 | 4th April 2009 | ||
5 | |||
6 | Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
7 | |||
8 | acer-wmi is a driver to allow you to control various parts of your Acer laptop | ||
9 | hardware under Linux which are exposed via ACPI-WMI. | ||
10 | |||
11 | This driver completely replaces the old out-of-tree acer_acpi, which I am | ||
12 | currently maintaining for bug fixes only on pre-2.6.25 kernels. All development | ||
13 | work is now focused solely on acer-wmi. | ||
14 | |||
15 | Disclaimer | ||
16 | ********** | ||
17 | |||
18 | Acer and Wistron have provided nothing towards the development acer_acpi or | ||
19 | acer-wmi. All information we have has been through the efforts of the developers | ||
20 | and the users to discover as much as possible about the hardware. | ||
21 | |||
22 | As such, I do warn that this could break your hardware - this is extremely | ||
23 | unlikely of course, but please bear this in mind. | ||
24 | |||
25 | Background | ||
26 | ********** | ||
27 | |||
28 | acer-wmi is derived from acer_acpi, originally developed by Mark | ||
29 | Smith in 2005, then taken over by Carlos Corbacho in 2007, in order to activate | ||
30 | the wireless LAN card under a 64-bit version of Linux, as acerhk[1] (the | ||
31 | previous solution to the problem) relied on making 32 bit BIOS calls which are | ||
32 | not possible in kernel space from a 64 bit OS. | ||
33 | |||
34 | [1] acerhk: http://www.cakey.de/acerhk/ | ||
35 | |||
36 | Supported Hardware | ||
37 | ****************** | ||
38 | |||
39 | NOTE: The Acer Aspire One is not supported hardware. It cannot work with | ||
40 | acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been | ||
41 | blacklisted until that happens. | ||
42 | |||
43 | Please see the website for the current list of known working hardware: | ||
44 | |||
45 | http://code.google.com/p/aceracpi/wiki/SupportedHardware | ||
46 | |||
47 | If your laptop is not listed, or listed as unknown, and works with acer-wmi, | ||
48 | please contact me with a copy of the DSDT. | ||
49 | |||
50 | If your Acer laptop doesn't work with acer-wmi, I would also like to see the | ||
51 | DSDT. | ||
52 | |||
53 | To send me the DSDT, as root/sudo: | ||
54 | |||
55 | cat /sys/firmware/acpi/tables/DSDT > dsdt | ||
56 | |||
57 | And send me the resulting 'dsdt' file. | ||
58 | |||
59 | Usage | ||
60 | ***** | ||
61 | |||
62 | On Acer laptops, acer-wmi should already be autoloaded based on DMI matching. | ||
63 | For non-Acer laptops, until WMI based autoloading support is added, you will | ||
64 | need to manually load acer-wmi. | ||
65 | |||
66 | acer-wmi creates /sys/devices/platform/acer-wmi, and fills it with various | ||
67 | files whose usage is detailed below, which enables you to control some of the | ||
68 | following (varies between models): | ||
69 | |||
70 | * the wireless LAN card radio | ||
71 | * inbuilt Bluetooth adapter | ||
72 | * inbuilt 3G card | ||
73 | * mail LED of your laptop | ||
74 | * brightness of the LCD panel | ||
75 | |||
76 | Wireless | ||
77 | ******** | ||
78 | |||
79 | With regards to wireless, all acer-wmi does is enable the radio on the card. It | ||
80 | is not responsible for the wireless LED - once the radio is enabled, this is | ||
81 | down to the wireless driver for your card. So the behaviour of the wireless LED, | ||
82 | once you enable the radio, will depend on your hardware and driver combination. | ||
83 | |||
84 | e.g. With the BCM4318 on the Acer Aspire 5020 series: | ||
85 | |||
86 | ndiswrapper: Light blinks on when transmitting | ||
87 | b43: Solid light, blinks off when transmitting | ||
88 | |||
89 | Wireless radio control is unconditionally enabled - all Acer laptops that support | ||
90 | acer-wmi come with built-in wireless. However, should you feel so inclined to | ||
91 | ever wish to remove the card, or swap it out at some point, please get in touch | ||
92 | with me, as we may well be able to gain some data on wireless card detection. | ||
93 | |||
94 | The wireless radio is exposed through rfkill. | ||
95 | |||
96 | Bluetooth | ||
97 | ********* | ||
98 | |||
99 | For bluetooth, this is an internal USB dongle, so once enabled, you will get | ||
100 | a USB device connection event, and a new USB device appears. When you disable | ||
101 | bluetooth, you get the reverse - a USB device disconnect event, followed by the | ||
102 | device disappearing again. | ||
103 | |||
104 | Bluetooth is autodetected by acer-wmi, so if you do not have a bluetooth module | ||
105 | installed in your laptop, this file won't exist (please be aware that it is | ||
106 | quite common for Acer not to fit bluetooth to their laptops - so just because | ||
107 | you have a bluetooth button on the laptop, doesn't mean that bluetooth is | ||
108 | installed). | ||
109 | |||
110 | For the adventurously minded - if you want to buy an internal bluetooth | ||
111 | module off the internet that is compatible with your laptop and fit it, then | ||
112 | it will work just fine with acer-wmi. | ||
113 | |||
114 | Bluetooth is exposed through rfkill. | ||
115 | |||
116 | 3G | ||
117 | ** | ||
118 | |||
119 | 3G is currently not autodetected, so the 'threeg' file is always created under | ||
120 | sysfs. So far, no-one in possession of an Acer laptop with 3G built-in appears to | ||
121 | have tried Linux, or reported back, so we don't have any information on this. | ||
122 | |||
123 | If you have an Acer laptop that does have a 3G card in, please contact me so we | ||
124 | can properly detect these, and find out a bit more about them. | ||
125 | |||
126 | To read the status of the 3G card (0=off, 1=on): | ||
127 | cat /sys/devices/platform/acer-wmi/threeg | ||
128 | |||
129 | To enable the 3G card: | ||
130 | echo 1 > /sys/devices/platform/acer-wmi/threeg | ||
131 | |||
132 | To disable the 3G card: | ||
133 | echo 0 > /sys/devices/platform/acer-wmi/threeg | ||
134 | |||
135 | To set the state of the 3G card when loading acer-wmi, pass: | ||
136 | threeg=X (where X is 0 or 1) | ||
137 | |||
138 | Mail LED | ||
139 | ******** | ||
140 | |||
141 | This can be found in most older Acer laptops supported by acer-wmi, and many | ||
142 | newer ones - it is built into the 'mail' button, and blinks when active. | ||
143 | |||
144 | On newer (WMID) laptops though, we have no way of detecting the mail LED. If | ||
145 | your laptop identifies itself in dmesg as a WMID model, then please try loading | ||
146 | acer_acpi with: | ||
147 | |||
148 | force_series=2490 | ||
149 | |||
150 | This will use a known alternative method of reading/ writing the mail LED. If | ||
151 | it works, please report back to me with the DMI data from your laptop so this | ||
152 | can be added to acer-wmi. | ||
153 | |||
154 | The LED is exposed through the LED subsystem, and can be found in: | ||
155 | |||
156 | /sys/devices/platform/acer-wmi/leds/acer-wmi::mail/ | ||
157 | |||
158 | The mail LED is autodetected, so if you don't have one, the LED device won't | ||
159 | be registered. | ||
160 | |||
161 | Backlight | ||
162 | ********* | ||
163 | |||
164 | The backlight brightness control is available on all acer-wmi supported | ||
165 | hardware. The maximum brightness level is usually 15, but on some newer laptops | ||
166 | it's 10 (this is again autodetected). | ||
167 | |||
168 | The backlight is exposed through the backlight subsystem, and can be found in: | ||
169 | |||
170 | /sys/devices/platform/acer-wmi/backlight/acer-wmi/ | ||
171 | |||
172 | Credits | ||
173 | ******* | ||
174 | |||
175 | Olaf Tauber, who did the real hard work when he developed acerhk | ||
176 | http://www.cakey.de/acerhk/ | ||
177 | All the authors of laptop ACPI modules in the kernel, whose work | ||
178 | was an inspiration in the early days of acer_acpi | ||
179 | Mathieu Segaud, who solved the problem with having to modprobe the driver | ||
180 | twice in acer_acpi 0.2. | ||
181 | Jim Ramsay, who added support for the WMID interface | ||
182 | Mark Smith, who started the original acer_acpi | ||
183 | |||
184 | And the many people who have used both acer_acpi and acer-wmi. | ||
diff --git a/Documentation/lockstat.txt b/Documentation/lockstat.txt index 9c0a80d17a23..cef00d42ed5b 100644 --- a/Documentation/lockstat.txt +++ b/Documentation/lockstat.txt | |||
@@ -12,8 +12,9 @@ Because things like lock contention can severely impact performance. | |||
12 | - HOW | 12 | - HOW |
13 | 13 | ||
14 | Lockdep already has hooks in the lock functions and maps lock instances to | 14 | Lockdep already has hooks in the lock functions and maps lock instances to |
15 | lock classes. We build on that. The graph below shows the relation between | 15 | lock classes. We build on that (see Documentation/lockdep-design.txt). |
16 | the lock functions and the various hooks therein. | 16 | The graph below shows the relation between the lock functions and the various |
17 | hooks therein. | ||
17 | 18 | ||
18 | __acquire | 19 | __acquire |
19 | | | 20 | | |
@@ -128,6 +129,37 @@ points are the points we're contending with. | |||
128 | 129 | ||
129 | The integer part of the time values is in us. | 130 | The integer part of the time values is in us. |
130 | 131 | ||
132 | Dealing with nested locks, subclasses may appear: | ||
133 | |||
134 | 32............................................................................................................................................................................................... | ||
135 | 33 | ||
136 | 34 &rq->lock: 13128 13128 0.43 190.53 103881.26 97454 3453404 0.00 401.11 13224683.11 | ||
137 | 35 --------- | ||
138 | 36 &rq->lock 645 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75 | ||
139 | 37 &rq->lock 297 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a | ||
140 | 38 &rq->lock 360 [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a | ||
141 | 39 &rq->lock 428 [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb | ||
142 | 40 --------- | ||
143 | 41 &rq->lock 77 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75 | ||
144 | 42 &rq->lock 174 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a | ||
145 | 43 &rq->lock 4715 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54 | ||
146 | 44 &rq->lock 893 [<ffffffff81340524>] schedule+0x157/0x7b8 | ||
147 | 45 | ||
148 | 46............................................................................................................................................................................................... | ||
149 | 47 | ||
150 | 48 &rq->lock/1: 11526 11488 0.33 388.73 136294.31 21461 38404 0.00 37.93 109388.53 | ||
151 | 49 ----------- | ||
152 | 50 &rq->lock/1 11526 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54 | ||
153 | 51 ----------- | ||
154 | 52 &rq->lock/1 5645 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54 | ||
155 | 53 &rq->lock/1 1224 [<ffffffff81340524>] schedule+0x157/0x7b8 | ||
156 | 54 &rq->lock/1 4336 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54 | ||
157 | 55 &rq->lock/1 181 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a | ||
158 | |||
159 | Line 48 shows statistics for the second subclass (/1) of &rq->lock class | ||
160 | (subclass starts from 0), since in this case, as line 50 suggests, | ||
161 | double_rq_lock actually acquires a nested lock of two spinlocks. | ||
162 | |||
131 | View the top contending locks: | 163 | View the top contending locks: |
132 | 164 | ||
133 | # grep : /proc/lock_stat | head | 165 | # grep : /proc/lock_stat | head |
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index 4d9ce73ff730..9ed1d9d96783 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas | |||
@@ -1,3 +1,17 @@ | |||
1 | Release Date : Wed. May 11, 2011 17:00:00 PST 2010 - | ||
2 | (emaild-id:megaraidlinux@lsi.com) | ||
3 | Adam Radford | ||
4 | Current Version : 00.00.05.38-rc1 | ||
5 | Old Version : 00.00.05.34-rc1 | ||
6 | 1. Remove MSI-X black list, use MFI_REG_STATE.ready.msiEnable. | ||
7 | 2. Remove un-used function megasas_return_cmd_for_smid(). | ||
8 | 3. Check MFI_REG_STATE.fault.resetAdapter in megasas_reset_fusion(). | ||
9 | 4. Disable interrupts/free_irq() in megasas_shutdown(). | ||
10 | 5. Fix bug where AENs could be lost in probe() and resume(). | ||
11 | 6. Convert 6,10,12 byte CDB's to 16 byte CDB for large LBA's for FastPath | ||
12 | IO. | ||
13 | 7. Add 1078 OCR support. | ||
14 | ------------------------------------------------------------------------------- | ||
1 | Release Date : Thu. Feb 24, 2011 17:00:00 PST 2010 - | 15 | Release Date : Thu. Feb 24, 2011 17:00:00 PST 2010 - |
2 | (emaild-id:megaraidlinux@lsi.com) | 16 | (emaild-id:megaraidlinux@lsi.com) |
3 | Adam Radford | 17 | Adam Radford |
diff --git a/Documentation/virtual/lguest/Makefile b/Documentation/virtual/lguest/Makefile index bebac6b4f332..0ac34206f7a7 100644 --- a/Documentation/virtual/lguest/Makefile +++ b/Documentation/virtual/lguest/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # This creates the demonstration utility "lguest" which runs a Linux guest. | 1 | # This creates the demonstration utility "lguest" which runs a Linux guest. |
2 | # Missing headers? Add "-I../../include -I../../arch/x86/include" | 2 | # Missing headers? Add "-I../../../include -I../../../arch/x86/include" |
3 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE | 3 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE |
4 | 4 | ||
5 | all: lguest | 5 | all: lguest |
diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c index d9da7e148538..cd9d6af61d07 100644 --- a/Documentation/virtual/lguest/lguest.c +++ b/Documentation/virtual/lguest/lguest.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <linux/virtio_rng.h> | 49 | #include <linux/virtio_rng.h> |
50 | #include <linux/virtio_ring.h> | 50 | #include <linux/virtio_ring.h> |
51 | #include <asm/bootparam.h> | 51 | #include <asm/bootparam.h> |
52 | #include "../../include/linux/lguest_launcher.h" | 52 | #include "../../../include/linux/lguest_launcher.h" |
53 | /*L:110 | 53 | /*L:110 |
54 | * We can ignore the 42 include files we need for this program, but I do want | 54 | * We can ignore the 42 include files we need for this program, but I do want |
55 | * to draw attention to the use of kernel-style types. | 55 | * to draw attention to the use of kernel-style types. |
@@ -135,9 +135,6 @@ struct device { | |||
135 | /* Is it operational */ | 135 | /* Is it operational */ |
136 | bool running; | 136 | bool running; |
137 | 137 | ||
138 | /* Does Guest want an intrrupt on empty? */ | ||
139 | bool irq_on_empty; | ||
140 | |||
141 | /* Device-specific data. */ | 138 | /* Device-specific data. */ |
142 | void *priv; | 139 | void *priv; |
143 | }; | 140 | }; |
@@ -637,10 +634,7 @@ static void trigger_irq(struct virtqueue *vq) | |||
637 | 634 | ||
638 | /* If they don't want an interrupt, don't send one... */ | 635 | /* If they don't want an interrupt, don't send one... */ |
639 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { | 636 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { |
640 | /* ... unless they've asked us to force one on empty. */ | 637 | return; |
641 | if (!vq->dev->irq_on_empty | ||
642 | || lg_last_avail(vq) != vq->vring.avail->idx) | ||
643 | return; | ||
644 | } | 638 | } |
645 | 639 | ||
646 | /* Send the Guest an interrupt tell them we used something up. */ | 640 | /* Send the Guest an interrupt tell them we used something up. */ |
@@ -1057,15 +1051,6 @@ static void create_thread(struct virtqueue *vq) | |||
1057 | close(vq->eventfd); | 1051 | close(vq->eventfd); |
1058 | } | 1052 | } |
1059 | 1053 | ||
1060 | static bool accepted_feature(struct device *dev, unsigned int bit) | ||
1061 | { | ||
1062 | const u8 *features = get_feature_bits(dev) + dev->feature_len; | ||
1063 | |||
1064 | if (dev->feature_len < bit / CHAR_BIT) | ||
1065 | return false; | ||
1066 | return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT)); | ||
1067 | } | ||
1068 | |||
1069 | static void start_device(struct device *dev) | 1054 | static void start_device(struct device *dev) |
1070 | { | 1055 | { |
1071 | unsigned int i; | 1056 | unsigned int i; |
@@ -1079,8 +1064,6 @@ static void start_device(struct device *dev) | |||
1079 | verbose(" %02x", get_feature_bits(dev) | 1064 | verbose(" %02x", get_feature_bits(dev) |
1080 | [dev->feature_len+i]); | 1065 | [dev->feature_len+i]); |
1081 | 1066 | ||
1082 | dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); | ||
1083 | |||
1084 | for (vq = dev->vq; vq; vq = vq->next) { | 1067 | for (vq = dev->vq; vq; vq = vq->next) { |
1085 | if (vq->service) | 1068 | if (vq->service) |
1086 | create_thread(vq); | 1069 | create_thread(vq); |
@@ -1564,7 +1547,6 @@ static void setup_tun_net(char *arg) | |||
1564 | /* Set up the tun device. */ | 1547 | /* Set up the tun device. */ |
1565 | configure_device(ipfd, tapif, ip); | 1548 | configure_device(ipfd, tapif, ip); |
1566 | 1549 | ||
1567 | add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); | ||
1568 | /* Expect Guest to handle everything except UFO */ | 1550 | /* Expect Guest to handle everything except UFO */ |
1569 | add_feature(dev, VIRTIO_NET_F_CSUM); | 1551 | add_feature(dev, VIRTIO_NET_F_CSUM); |
1570 | add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); | 1552 | add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); |
diff --git a/MAINTAINERS b/MAINTAINERS index a33b11560d3f..29801f760b6f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -223,10 +223,8 @@ S: Maintained | |||
223 | F: drivers/platform/x86/acerhdf.c | 223 | F: drivers/platform/x86/acerhdf.c |
224 | 224 | ||
225 | ACER WMI LAPTOP EXTRAS | 225 | ACER WMI LAPTOP EXTRAS |
226 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 226 | M: Joey Lee <jlee@novell.com> |
227 | L: aceracpi@googlegroups.com (subscribers-only) | ||
228 | L: platform-driver-x86@vger.kernel.org | 227 | L: platform-driver-x86@vger.kernel.org |
229 | W: http://code.google.com/p/aceracpi | ||
230 | S: Maintained | 228 | S: Maintained |
231 | F: drivers/platform/x86/acer-wmi.c | 229 | F: drivers/platform/x86/acer-wmi.c |
232 | 230 | ||
@@ -271,10 +269,8 @@ S: Supported | |||
271 | F: drivers/acpi/video.c | 269 | F: drivers/acpi/video.c |
272 | 270 | ||
273 | ACPI WMI DRIVER | 271 | ACPI WMI DRIVER |
274 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
275 | L: platform-driver-x86@vger.kernel.org | 272 | L: platform-driver-x86@vger.kernel.org |
276 | W: http://www.lesswatts.org/projects/acpi/ | 273 | S: Orphan |
277 | S: Maintained | ||
278 | F: drivers/platform/x86/wmi.c | 274 | F: drivers/platform/x86/wmi.c |
279 | 275 | ||
280 | AD1889 ALSA SOUND DRIVER | 276 | AD1889 ALSA SOUND DRIVER |
@@ -2178,6 +2174,8 @@ M: Dan Williams <dan.j.williams@intel.com> | |||
2178 | S: Supported | 2174 | S: Supported |
2179 | F: drivers/dma/ | 2175 | F: drivers/dma/ |
2180 | F: include/linux/dma* | 2176 | F: include/linux/dma* |
2177 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx.git | ||
2178 | T: git git://git.infradead.org/users/vkoul/slave-dma.git (slave-dma) | ||
2181 | 2179 | ||
2182 | DME1737 HARDWARE MONITOR DRIVER | 2180 | DME1737 HARDWARE MONITOR DRIVER |
2183 | M: Juerg Haefliger <juergh@gmail.com> | 2181 | M: Juerg Haefliger <juergh@gmail.com> |
@@ -3031,9 +3029,8 @@ S: Maintained | |||
3031 | F: drivers/net/wireless/hostap/ | 3029 | F: drivers/net/wireless/hostap/ |
3032 | 3030 | ||
3033 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER | 3031 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER |
3034 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
3035 | L: platform-driver-x86@vger.kernel.org | 3032 | L: platform-driver-x86@vger.kernel.org |
3036 | S: Odd Fixes | 3033 | S: Orphan |
3037 | F: drivers/platform/x86/tc1100-wmi.c | 3034 | F: drivers/platform/x86/tc1100-wmi.c |
3038 | 3035 | ||
3039 | HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series | 3036 | HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series |
@@ -5451,6 +5448,13 @@ L: linux-serial@vger.kernel.org | |||
5451 | S: Maintained | 5448 | S: Maintained |
5452 | F: drivers/tty/serial | 5449 | F: drivers/tty/serial |
5453 | 5450 | ||
5451 | SYNOPSYS DESIGNWARE DMAC DRIVER | ||
5452 | M: Viresh Kumar <viresh.kumar@st.com> | ||
5453 | S: Maintained | ||
5454 | F: include/linux/dw_dmac.h | ||
5455 | F: drivers/dma/dw_dmac_regs.h | ||
5456 | F: drivers/dma/dw_dmac.c | ||
5457 | |||
5454 | TIMEKEEPING, NTP | 5458 | TIMEKEEPING, NTP |
5455 | M: John Stultz <johnstul@us.ibm.com> | 5459 | M: John Stultz <johnstul@us.ibm.com> |
5456 | M: Thomas Gleixner <tglx@linutronix.de> | 5460 | M: Thomas Gleixner <tglx@linutronix.de> |
@@ -5515,7 +5519,7 @@ F: drivers/scsi/sg.c | |||
5515 | F: include/scsi/sg.h | 5519 | F: include/scsi/sg.h |
5516 | 5520 | ||
5517 | SCSI SUBSYSTEM | 5521 | SCSI SUBSYSTEM |
5518 | M: "James E.J. Bottomley" <James.Bottomley@suse.de> | 5522 | M: "James E.J. Bottomley" <JBottomley@parallels.com> |
5519 | L: linux-scsi@vger.kernel.org | 5523 | L: linux-scsi@vger.kernel.org |
5520 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git | 5524 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git |
5521 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git | 5525 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git |
@@ -6084,6 +6088,17 @@ F: Documentation/filesystems/sysv-fs.txt | |||
6084 | F: fs/sysv/ | 6088 | F: fs/sysv/ |
6085 | F: include/linux/sysv_fs.h | 6089 | F: include/linux/sysv_fs.h |
6086 | 6090 | ||
6091 | TARGET SUBSYSTEM | ||
6092 | M: Nicholas A. Bellinger <nab@linux-iscsi.org> | ||
6093 | L: linux-scsi@vger.kernel.org | ||
6094 | L: http://groups.google.com/group/linux-iscsi-target-dev | ||
6095 | W: http://www.linux-iscsi.org | ||
6096 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core-2.6.git master | ||
6097 | S: Supported | ||
6098 | F: drivers/target/ | ||
6099 | F: include/target/ | ||
6100 | F: Documentation/target/ | ||
6101 | |||
6087 | TASKSTATS STATISTICS INTERFACE | 6102 | TASKSTATS STATISTICS INTERFACE |
6088 | M: Balbir Singh <balbir@linux.vnet.ibm.com> | 6103 | M: Balbir Singh <balbir@linux.vnet.ibm.com> |
6089 | S: Maintained | 6104 | S: Maintained |
@@ -1,8 +1,8 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 0 |
3 | SUBLEVEL = 39 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION = -rc1 |
5 | NAME = Flesh-Eating Bats with Fangs | 5 | NAME = Sneaky Weasel |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
8 | # To see a list of typical targets execute "make help" | 8 | # To see a list of typical targets execute "make help" |
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index b1834166922d..4ac48a095f3a 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
@@ -456,10 +456,11 @@ | |||
456 | #define __NR_open_by_handle_at 498 | 456 | #define __NR_open_by_handle_at 498 |
457 | #define __NR_clock_adjtime 499 | 457 | #define __NR_clock_adjtime 499 |
458 | #define __NR_syncfs 500 | 458 | #define __NR_syncfs 500 |
459 | #define __NR_setns 501 | ||
459 | 460 | ||
460 | #ifdef __KERNEL__ | 461 | #ifdef __KERNEL__ |
461 | 462 | ||
462 | #define NR_SYSCALLS 501 | 463 | #define NR_SYSCALLS 502 |
463 | 464 | ||
464 | #define __ARCH_WANT_IPC_PARSE_VERSION | 465 | #define __ARCH_WANT_IPC_PARSE_VERSION |
465 | #define __ARCH_WANT_OLD_READDIR | 466 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 15f999d41c75..b9c28f3f1956 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -519,6 +519,7 @@ sys_call_table: | |||
519 | .quad sys_open_by_handle_at | 519 | .quad sys_open_by_handle_at |
520 | .quad sys_clock_adjtime | 520 | .quad sys_clock_adjtime |
521 | .quad sys_syncfs /* 500 */ | 521 | .quad sys_syncfs /* 500 */ |
522 | .quad sys_setns | ||
522 | 523 | ||
523 | .size sys_call_table, . - sys_call_table | 524 | .size sys_call_table, . - sys_call_table |
524 | .type sys_call_table, @object | 525 | .type sys_call_table, @object |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7275009686e6..9adc278a22ab 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -294,6 +294,8 @@ config ARCH_AT91 | |||
294 | bool "Atmel AT91" | 294 | bool "Atmel AT91" |
295 | select ARCH_REQUIRE_GPIOLIB | 295 | select ARCH_REQUIRE_GPIOLIB |
296 | select HAVE_CLK | 296 | select HAVE_CLK |
297 | select CLKDEV_LOOKUP | ||
298 | select ARM_PATCH_PHYS_VIRT if MMU | ||
297 | help | 299 | help |
298 | This enables support for systems based on the Atmel AT91RM9200, | 300 | This enables support for systems based on the Atmel AT91RM9200, |
299 | AT91SAM9 and AT91CAP9 processors. | 301 | AT91SAM9 and AT91CAP9 processors. |
@@ -730,16 +732,6 @@ config ARCH_S5P64X0 | |||
730 | Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, | 732 | Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, |
731 | SMDK6450. | 733 | SMDK6450. |
732 | 734 | ||
733 | config ARCH_S5P6442 | ||
734 | bool "Samsung S5P6442" | ||
735 | select CPU_V6 | ||
736 | select GENERIC_GPIO | ||
737 | select HAVE_CLK | ||
738 | select ARCH_USES_GETTIMEOFFSET | ||
739 | select HAVE_S3C2410_WATCHDOG if WATCHDOG | ||
740 | help | ||
741 | Samsung S5P6442 CPU based systems | ||
742 | |||
743 | config ARCH_S5PC100 | 735 | config ARCH_S5PC100 |
744 | bool "Samsung S5PC100" | 736 | bool "Samsung S5PC100" |
745 | select GENERIC_GPIO | 737 | select GENERIC_GPIO |
@@ -991,8 +983,6 @@ endif | |||
991 | 983 | ||
992 | source "arch/arm/mach-s5p64x0/Kconfig" | 984 | source "arch/arm/mach-s5p64x0/Kconfig" |
993 | 985 | ||
994 | source "arch/arm/mach-s5p6442/Kconfig" | ||
995 | |||
996 | source "arch/arm/mach-s5pc100/Kconfig" | 986 | source "arch/arm/mach-s5pc100/Kconfig" |
997 | 987 | ||
998 | source "arch/arm/mach-s5pv210/Kconfig" | 988 | source "arch/arm/mach-s5pv210/Kconfig" |
@@ -1399,7 +1389,6 @@ config NR_CPUS | |||
1399 | config HOTPLUG_CPU | 1389 | config HOTPLUG_CPU |
1400 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | 1390 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" |
1401 | depends on SMP && HOTPLUG && EXPERIMENTAL | 1391 | depends on SMP && HOTPLUG && EXPERIMENTAL |
1402 | depends on !ARCH_MSM | ||
1403 | help | 1392 | help |
1404 | Say Y here to experiment with turning CPUs off and on. CPUs | 1393 | Say Y here to experiment with turning CPUs off and on. CPUs |
1405 | can be controlled through /sys/devices/system/cpu. | 1394 | can be controlled through /sys/devices/system/cpu. |
@@ -1420,7 +1409,7 @@ source kernel/Kconfig.preempt | |||
1420 | config HZ | 1409 | config HZ |
1421 | int | 1410 | int |
1422 | default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \ | 1411 | default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \ |
1423 | ARCH_S5P6442 || ARCH_S5PV210 || ARCH_EXYNOS4 | 1412 | ARCH_S5PV210 || ARCH_EXYNOS4 |
1424 | default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER | 1413 | default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER |
1425 | default AT91_TIMER_HZ if ARCH_AT91 | 1414 | default AT91_TIMER_HZ if ARCH_AT91 |
1426 | default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE | 1415 | default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE |
@@ -1516,6 +1505,9 @@ config ARCH_SPARSEMEM_DEFAULT | |||
1516 | config ARCH_SELECT_MEMORY_MODEL | 1505 | config ARCH_SELECT_MEMORY_MODEL |
1517 | def_bool ARCH_SPARSEMEM_ENABLE | 1506 | def_bool ARCH_SPARSEMEM_ENABLE |
1518 | 1507 | ||
1508 | config HAVE_ARCH_PFN_VALID | ||
1509 | def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM | ||
1510 | |||
1519 | config HIGHMEM | 1511 | config HIGHMEM |
1520 | bool "High Memory Support" | 1512 | bool "High Memory Support" |
1521 | depends on MMU | 1513 | depends on MMU |
@@ -1683,6 +1675,13 @@ endmenu | |||
1683 | 1675 | ||
1684 | menu "Boot options" | 1676 | menu "Boot options" |
1685 | 1677 | ||
1678 | config USE_OF | ||
1679 | bool "Flattened Device Tree support" | ||
1680 | select OF | ||
1681 | select OF_EARLY_FLATTREE | ||
1682 | help | ||
1683 | Include support for flattened device tree machine descriptions. | ||
1684 | |||
1686 | # Compressed boot loader in ROM. Yes, we really want to ask about | 1685 | # Compressed boot loader in ROM. Yes, we really want to ask about |
1687 | # TEXT and BSS so we preserve their values in the config files. | 1686 | # TEXT and BSS so we preserve their values in the config files. |
1688 | config ZBOOT_ROM_TEXT | 1687 | config ZBOOT_ROM_TEXT |
@@ -2021,7 +2020,7 @@ menu "Power management options" | |||
2021 | source "kernel/power/Kconfig" | 2020 | source "kernel/power/Kconfig" |
2022 | 2021 | ||
2023 | config ARCH_SUSPEND_POSSIBLE | 2022 | config ARCH_SUSPEND_POSSIBLE |
2024 | depends on !ARCH_S5P64X0 && !ARCH_S5P6442 && !ARCH_S5PC100 | 2023 | depends on !ARCH_S5P64X0 && !ARCH_S5PC100 |
2025 | depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \ | 2024 | depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \ |
2026 | CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE | 2025 | CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE |
2027 | def_bool y | 2026 | def_bool y |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 25750bcb3397..f5b2b390c8f2 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -176,7 +176,6 @@ machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c24 | |||
176 | machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 | 176 | machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 |
177 | machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx | 177 | machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx |
178 | machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0 | 178 | machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0 |
179 | machine-$(CONFIG_ARCH_S5P6442) := s5p6442 | ||
180 | machine-$(CONFIG_ARCH_S5PC100) := s5pc100 | 179 | machine-$(CONFIG_ARCH_S5PC100) := s5pc100 |
181 | machine-$(CONFIG_ARCH_S5PV210) := s5pv210 | 180 | machine-$(CONFIG_ARCH_S5PV210) := s5pv210 |
182 | machine-$(CONFIG_ARCH_EXYNOS4) := exynos4 | 181 | machine-$(CONFIG_ARCH_EXYNOS4) := exynos4 |
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index ea5ee4d067f3..4b71766fb21d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig | |||
@@ -7,7 +7,7 @@ config ARM_VIC | |||
7 | config ARM_VIC_NR | 7 | config ARM_VIC_NR |
8 | int | 8 | int |
9 | default 4 if ARCH_S5PV210 | 9 | default 4 if ARCH_S5PV210 |
10 | default 3 if ARCH_S5P6442 || ARCH_S5PC100 | 10 | default 3 if ARCH_S5PC100 |
11 | default 2 | 11 | default 2 |
12 | depends on ARM_VIC | 12 | depends on ARM_VIC |
13 | help | 13 | help |
diff --git a/arch/arm/configs/at572d940hfek_defconfig b/arch/arm/configs/at572d940hfek_defconfig deleted file mode 100644 index 1b1158ae8f82..000000000000 --- a/arch/arm/configs/at572d940hfek_defconfig +++ /dev/null | |||
@@ -1,358 +0,0 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_LOCALVERSION="-AT572D940HF" | ||
3 | # CONFIG_LOCALVERSION_AUTO is not set | ||
4 | CONFIG_SYSVIPC=y | ||
5 | CONFIG_POSIX_MQUEUE=y | ||
6 | CONFIG_BSD_PROCESS_ACCT=y | ||
7 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
8 | CONFIG_TASKSTATS=y | ||
9 | CONFIG_TASK_XACCT=y | ||
10 | CONFIG_TASK_IO_ACCOUNTING=y | ||
11 | CONFIG_AUDIT=y | ||
12 | CONFIG_CGROUPS=y | ||
13 | CONFIG_CGROUP_CPUACCT=y | ||
14 | CONFIG_CGROUP_SCHED=y | ||
15 | CONFIG_RT_GROUP_SCHED=y | ||
16 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
17 | CONFIG_RELAY=y | ||
18 | CONFIG_BLK_DEV_INITRD=y | ||
19 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
20 | CONFIG_EXPERT=y | ||
21 | CONFIG_SLAB=y | ||
22 | CONFIG_PROFILING=y | ||
23 | CONFIG_OPROFILE=m | ||
24 | CONFIG_KPROBES=y | ||
25 | CONFIG_MODULES=y | ||
26 | CONFIG_MODULE_UNLOAD=y | ||
27 | CONFIG_MODVERSIONS=y | ||
28 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
29 | # CONFIG_BLK_DEV_BSG is not set | ||
30 | CONFIG_ARCH_AT91=y | ||
31 | CONFIG_ARCH_AT572D940HF=y | ||
32 | CONFIG_MACH_AT572D940HFEB=y | ||
33 | CONFIG_AT91_PROGRAMMABLE_CLOCKS=y | ||
34 | CONFIG_NO_HZ=y | ||
35 | CONFIG_HIGH_RES_TIMERS=y | ||
36 | CONFIG_PREEMPT=y | ||
37 | CONFIG_CMDLINE="mem=48M console=ttyS0 initrd=0x21100000,3145728 root=/dev/ram0 rw ip=172.16.1.181" | ||
38 | CONFIG_KEXEC=y | ||
39 | CONFIG_FPE_NWFPE=y | ||
40 | CONFIG_FPE_NWFPE_XP=y | ||
41 | CONFIG_NET=y | ||
42 | CONFIG_PACKET=m | ||
43 | CONFIG_UNIX=y | ||
44 | CONFIG_INET=y | ||
45 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
46 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
47 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
48 | # CONFIG_INET_LRO is not set | ||
49 | # CONFIG_INET_DIAG is not set | ||
50 | # CONFIG_IPV6 is not set | ||
51 | CONFIG_NET_PKTGEN=m | ||
52 | CONFIG_NET_TCPPROBE=m | ||
53 | CONFIG_CAN=m | ||
54 | CONFIG_CAN_RAW=m | ||
55 | CONFIG_CAN_BCM=m | ||
56 | CONFIG_CAN_VCAN=m | ||
57 | CONFIG_CAN_DEBUG_DEVICES=y | ||
58 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
59 | CONFIG_CONNECTOR=m | ||
60 | CONFIG_MTD=m | ||
61 | CONFIG_MTD_DEBUG=y | ||
62 | CONFIG_MTD_DEBUG_VERBOSE=1 | ||
63 | CONFIG_MTD_CONCAT=m | ||
64 | CONFIG_MTD_PARTITIONS=y | ||
65 | CONFIG_MTD_CHAR=m | ||
66 | CONFIG_MTD_BLOCK=m | ||
67 | CONFIG_MTD_BLOCK_RO=m | ||
68 | CONFIG_FTL=m | ||
69 | CONFIG_NFTL=m | ||
70 | CONFIG_NFTL_RW=y | ||
71 | CONFIG_INFTL=m | ||
72 | CONFIG_RFD_FTL=m | ||
73 | CONFIG_SSFDC=m | ||
74 | CONFIG_MTD_OOPS=m | ||
75 | CONFIG_MTD_CFI=m | ||
76 | CONFIG_MTD_JEDECPROBE=m | ||
77 | CONFIG_MTD_CFI_INTELEXT=m | ||
78 | CONFIG_MTD_CFI_AMDSTD=m | ||
79 | CONFIG_MTD_CFI_STAA=m | ||
80 | CONFIG_MTD_ROM=m | ||
81 | CONFIG_MTD_ABSENT=m | ||
82 | CONFIG_MTD_COMPLEX_MAPPINGS=y | ||
83 | CONFIG_MTD_PHYSMAP=m | ||
84 | CONFIG_MTD_PLATRAM=m | ||
85 | CONFIG_MTD_DATAFLASH=m | ||
86 | CONFIG_MTD_M25P80=m | ||
87 | CONFIG_MTD_SLRAM=m | ||
88 | CONFIG_MTD_PHRAM=m | ||
89 | CONFIG_MTD_MTDRAM=m | ||
90 | CONFIG_MTD_BLOCK2MTD=m | ||
91 | CONFIG_MTD_NAND=m | ||
92 | CONFIG_MTD_NAND_VERIFY_WRITE=y | ||
93 | CONFIG_MTD_NAND_DISKONCHIP=m | ||
94 | CONFIG_MTD_NAND_NANDSIM=m | ||
95 | CONFIG_MTD_NAND_PLATFORM=m | ||
96 | CONFIG_MTD_ALAUDA=m | ||
97 | CONFIG_MTD_UBI=m | ||
98 | CONFIG_MTD_UBI_GLUEBI=m | ||
99 | CONFIG_BLK_DEV_LOOP=y | ||
100 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
101 | CONFIG_BLK_DEV_NBD=m | ||
102 | CONFIG_BLK_DEV_RAM=y | ||
103 | CONFIG_BLK_DEV_RAM_SIZE=65536 | ||
104 | CONFIG_ATMEL_TCLIB=y | ||
105 | CONFIG_ATMEL_SSC=m | ||
106 | CONFIG_SENSORS_TSL2550=m | ||
107 | CONFIG_DS1682=m | ||
108 | CONFIG_RAID_ATTRS=m | ||
109 | CONFIG_SCSI=m | ||
110 | CONFIG_SCSI_TGT=m | ||
111 | # CONFIG_SCSI_PROC_FS is not set | ||
112 | CONFIG_BLK_DEV_SD=m | ||
113 | CONFIG_BLK_DEV_SR=m | ||
114 | CONFIG_CHR_DEV_SG=m | ||
115 | CONFIG_CHR_DEV_SCH=m | ||
116 | CONFIG_SCSI_MULTI_LUN=y | ||
117 | CONFIG_SCSI_CONSTANTS=y | ||
118 | CONFIG_SCSI_LOGGING=y | ||
119 | CONFIG_SCSI_SCAN_ASYNC=y | ||
120 | CONFIG_SCSI_ISCSI_ATTRS=m | ||
121 | CONFIG_NETDEVICES=y | ||
122 | CONFIG_DUMMY=m | ||
123 | CONFIG_BONDING=m | ||
124 | CONFIG_MACVLAN=m | ||
125 | CONFIG_EQUALIZER=m | ||
126 | CONFIG_TUN=m | ||
127 | CONFIG_VETH=m | ||
128 | CONFIG_PHYLIB=y | ||
129 | CONFIG_MARVELL_PHY=m | ||
130 | CONFIG_DAVICOM_PHY=m | ||
131 | CONFIG_QSEMI_PHY=m | ||
132 | CONFIG_LXT_PHY=m | ||
133 | CONFIG_CICADA_PHY=m | ||
134 | CONFIG_VITESSE_PHY=m | ||
135 | CONFIG_SMSC_PHY=m | ||
136 | CONFIG_BROADCOM_PHY=m | ||
137 | CONFIG_ICPLUS_PHY=m | ||
138 | CONFIG_MDIO_BITBANG=m | ||
139 | CONFIG_NET_ETHERNET=y | ||
140 | # CONFIG_NETDEV_1000 is not set | ||
141 | # CONFIG_NETDEV_10000 is not set | ||
142 | CONFIG_USB_ZD1201=m | ||
143 | CONFIG_HOSTAP=m | ||
144 | CONFIG_HOSTAP_FIRMWARE=y | ||
145 | CONFIG_HOSTAP_FIRMWARE_NVRAM=y | ||
146 | CONFIG_USB_CATC=m | ||
147 | CONFIG_USB_KAWETH=m | ||
148 | CONFIG_USB_PEGASUS=m | ||
149 | CONFIG_USB_RTL8150=m | ||
150 | CONFIG_USB_USBNET=m | ||
151 | CONFIG_USB_NET_DM9601=m | ||
152 | CONFIG_USB_NET_GL620A=m | ||
153 | CONFIG_USB_NET_PLUSB=m | ||
154 | CONFIG_USB_NET_MCS7830=m | ||
155 | CONFIG_USB_NET_RNDIS_HOST=m | ||
156 | CONFIG_USB_ALI_M5632=y | ||
157 | CONFIG_USB_AN2720=y | ||
158 | CONFIG_USB_EPSON2888=y | ||
159 | CONFIG_USB_KC2190=y | ||
160 | # CONFIG_USB_NET_ZAURUS is not set | ||
161 | CONFIG_INPUT_MOUSEDEV=m | ||
162 | CONFIG_INPUT_EVDEV=m | ||
163 | CONFIG_INPUT_EVBUG=m | ||
164 | CONFIG_KEYBOARD_LKKBD=m | ||
165 | CONFIG_KEYBOARD_GPIO=m | ||
166 | CONFIG_KEYBOARD_NEWTON=m | ||
167 | CONFIG_KEYBOARD_STOWAWAY=m | ||
168 | CONFIG_KEYBOARD_SUNKBD=m | ||
169 | CONFIG_KEYBOARD_XTKBD=m | ||
170 | CONFIG_MOUSE_PS2=m | ||
171 | CONFIG_MOUSE_SERIAL=m | ||
172 | CONFIG_MOUSE_APPLETOUCH=m | ||
173 | CONFIG_MOUSE_VSXXXAA=m | ||
174 | CONFIG_MOUSE_GPIO=m | ||
175 | CONFIG_INPUT_MISC=y | ||
176 | CONFIG_INPUT_UINPUT=m | ||
177 | CONFIG_SERIO_SERPORT=m | ||
178 | CONFIG_SERIO_RAW=m | ||
179 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
180 | CONFIG_SERIAL_NONSTANDARD=y | ||
181 | CONFIG_N_HDLC=m | ||
182 | CONFIG_SPECIALIX=m | ||
183 | CONFIG_STALDRV=y | ||
184 | CONFIG_SERIAL_ATMEL=y | ||
185 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
186 | CONFIG_IPMI_HANDLER=m | ||
187 | CONFIG_IPMI_DEVICE_INTERFACE=m | ||
188 | CONFIG_IPMI_SI=m | ||
189 | CONFIG_IPMI_WATCHDOG=m | ||
190 | CONFIG_IPMI_POWEROFF=m | ||
191 | CONFIG_HW_RANDOM=y | ||
192 | CONFIG_R3964=m | ||
193 | CONFIG_RAW_DRIVER=m | ||
194 | CONFIG_TCG_TPM=m | ||
195 | CONFIG_TCG_NSC=m | ||
196 | CONFIG_TCG_ATMEL=m | ||
197 | CONFIG_I2C=m | ||
198 | CONFIG_I2C_CHARDEV=m | ||
199 | CONFIG_SPI=y | ||
200 | CONFIG_SPI_ATMEL=y | ||
201 | CONFIG_SPI_BITBANG=m | ||
202 | CONFIG_SPI_SPIDEV=m | ||
203 | # CONFIG_HWMON is not set | ||
204 | # CONFIG_VGA_CONSOLE is not set | ||
205 | CONFIG_SOUND=m | ||
206 | CONFIG_SND=m | ||
207 | CONFIG_SND_SEQUENCER=m | ||
208 | CONFIG_SND_SEQ_DUMMY=m | ||
209 | CONFIG_SND_MIXER_OSS=m | ||
210 | CONFIG_SND_PCM_OSS=m | ||
211 | # CONFIG_SND_PCM_OSS_PLUGINS is not set | ||
212 | CONFIG_SND_SEQUENCER_OSS=y | ||
213 | CONFIG_SND_DYNAMIC_MINORS=y | ||
214 | # CONFIG_SND_VERBOSE_PROCFS is not set | ||
215 | CONFIG_SND_DUMMY=m | ||
216 | CONFIG_SND_VIRMIDI=m | ||
217 | CONFIG_SND_USB_AUDIO=m | ||
218 | CONFIG_SND_USB_CAIAQ=m | ||
219 | CONFIG_SND_USB_CAIAQ_INPUT=y | ||
220 | CONFIG_HID=m | ||
221 | CONFIG_HIDRAW=y | ||
222 | CONFIG_USB_HID=m | ||
223 | CONFIG_USB_HIDDEV=y | ||
224 | CONFIG_USB_KBD=m | ||
225 | CONFIG_USB_MOUSE=m | ||
226 | CONFIG_HID_A4TECH=m | ||
227 | CONFIG_HID_APPLE=m | ||
228 | CONFIG_HID_BELKIN=m | ||
229 | CONFIG_HID_CHERRY=m | ||
230 | CONFIG_HID_CHICONY=m | ||
231 | CONFIG_HID_CYPRESS=m | ||
232 | CONFIG_HID_EZKEY=m | ||
233 | CONFIG_HID_GYRATION=m | ||
234 | CONFIG_HID_LOGITECH=m | ||
235 | CONFIG_HID_MICROSOFT=m | ||
236 | CONFIG_HID_MONTEREY=m | ||
237 | CONFIG_HID_PANTHERLORD=m | ||
238 | CONFIG_HID_PETALYNX=m | ||
239 | CONFIG_HID_SAMSUNG=m | ||
240 | CONFIG_HID_SONY=m | ||
241 | CONFIG_HID_SUNPLUS=m | ||
242 | CONFIG_USB=y | ||
243 | CONFIG_USB_DEVICEFS=y | ||
244 | # CONFIG_USB_DEVICE_CLASS is not set | ||
245 | CONFIG_USB_DYNAMIC_MINORS=y | ||
246 | CONFIG_USB_MON=y | ||
247 | CONFIG_USB_OHCI_HCD=y | ||
248 | CONFIG_USB_STORAGE=m | ||
249 | CONFIG_USB_STORAGE_DATAFAB=m | ||
250 | CONFIG_USB_STORAGE_FREECOM=m | ||
251 | CONFIG_USB_STORAGE_ISD200=m | ||
252 | CONFIG_USB_STORAGE_USBAT=m | ||
253 | CONFIG_USB_STORAGE_SDDR09=m | ||
254 | CONFIG_USB_STORAGE_SDDR55=m | ||
255 | CONFIG_USB_STORAGE_JUMPSHOT=m | ||
256 | CONFIG_USB_STORAGE_ALAUDA=m | ||
257 | CONFIG_USB_STORAGE_KARMA=m | ||
258 | CONFIG_USB_LIBUSUAL=y | ||
259 | CONFIG_USB_SERIAL=m | ||
260 | CONFIG_USB_EZUSB=y | ||
261 | CONFIG_USB_SERIAL_GENERIC=y | ||
262 | CONFIG_USB_SERIAL_PL2303=m | ||
263 | CONFIG_USB_SERIAL_SPCP8X5=m | ||
264 | CONFIG_USB_SERIAL_DEBUG=m | ||
265 | CONFIG_USB_EMI62=m | ||
266 | CONFIG_USB_EMI26=m | ||
267 | CONFIG_USB_ADUTUX=m | ||
268 | CONFIG_USB_TEST=m | ||
269 | CONFIG_USB_GADGET=m | ||
270 | CONFIG_USB_GADGET_DEBUG_FILES=y | ||
271 | CONFIG_USB_GADGET_DEBUG_FS=y | ||
272 | CONFIG_USB_ZERO=m | ||
273 | CONFIG_USB_ETH=m | ||
274 | CONFIG_USB_GADGETFS=m | ||
275 | CONFIG_USB_FILE_STORAGE=m | ||
276 | CONFIG_USB_G_SERIAL=m | ||
277 | CONFIG_USB_MIDI_GADGET=m | ||
278 | CONFIG_MMC=y | ||
279 | CONFIG_SDIO_UART=m | ||
280 | CONFIG_MMC_AT91=m | ||
281 | CONFIG_MMC_SPI=m | ||
282 | CONFIG_NEW_LEDS=y | ||
283 | CONFIG_LEDS_CLASS=m | ||
284 | CONFIG_LEDS_GPIO=m | ||
285 | CONFIG_LEDS_TRIGGERS=y | ||
286 | CONFIG_LEDS_TRIGGER_TIMER=m | ||
287 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m | ||
288 | CONFIG_RTC_CLASS=y | ||
289 | CONFIG_RTC_INTF_DEV_UIE_EMUL=y | ||
290 | CONFIG_RTC_DRV_DS1307=m | ||
291 | CONFIG_RTC_DRV_DS1305=y | ||
292 | CONFIG_EXT2_FS=y | ||
293 | CONFIG_EXT2_FS_XATTR=y | ||
294 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
295 | CONFIG_EXT2_FS_SECURITY=y | ||
296 | CONFIG_EXT3_FS=y | ||
297 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
298 | CONFIG_EXT3_FS_SECURITY=y | ||
299 | CONFIG_JBD_DEBUG=y | ||
300 | CONFIG_REISERFS_FS=m | ||
301 | CONFIG_REISERFS_CHECK=y | ||
302 | CONFIG_REISERFS_PROC_INFO=y | ||
303 | CONFIG_REISERFS_FS_XATTR=y | ||
304 | CONFIG_REISERFS_FS_POSIX_ACL=y | ||
305 | CONFIG_REISERFS_FS_SECURITY=y | ||
306 | CONFIG_INOTIFY=y | ||
307 | CONFIG_FUSE_FS=m | ||
308 | CONFIG_MSDOS_FS=m | ||
309 | CONFIG_VFAT_FS=y | ||
310 | CONFIG_NTFS_FS=m | ||
311 | CONFIG_NTFS_RW=y | ||
312 | CONFIG_TMPFS=y | ||
313 | CONFIG_TMPFS_POSIX_ACL=y | ||
314 | CONFIG_JFFS2_FS=m | ||
315 | CONFIG_JFFS2_COMPRESSION_OPTIONS=y | ||
316 | CONFIG_JFFS2_LZO=y | ||
317 | CONFIG_JFFS2_CMODE_FAVOURLZO=y | ||
318 | CONFIG_CRAMFS=m | ||
319 | CONFIG_NFS_FS=m | ||
320 | CONFIG_NFS_V3=y | ||
321 | CONFIG_NFS_V3_ACL=y | ||
322 | CONFIG_NFS_V4=y | ||
323 | CONFIG_NFSD=m | ||
324 | CONFIG_NFSD_V3_ACL=y | ||
325 | CONFIG_NFSD_V4=y | ||
326 | CONFIG_CIFS=m | ||
327 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
328 | CONFIG_PARTITION_ADVANCED=y | ||
329 | CONFIG_MAC_PARTITION=y | ||
330 | CONFIG_BSD_DISKLABEL=y | ||
331 | CONFIG_MINIX_SUBPARTITION=y | ||
332 | CONFIG_SOLARIS_X86_PARTITION=y | ||
333 | CONFIG_UNIXWARE_DISKLABEL=y | ||
334 | CONFIG_LDM_PARTITION=y | ||
335 | CONFIG_LDM_DEBUG=y | ||
336 | CONFIG_SGI_PARTITION=y | ||
337 | CONFIG_SUN_PARTITION=y | ||
338 | CONFIG_NLS_DEFAULT="cp437" | ||
339 | CONFIG_NLS_CODEPAGE_437=y | ||
340 | CONFIG_NLS_CODEPAGE_850=m | ||
341 | CONFIG_NLS_ASCII=y | ||
342 | CONFIG_NLS_ISO8859_1=y | ||
343 | CONFIG_NLS_UTF8=m | ||
344 | CONFIG_DLM=m | ||
345 | CONFIG_PRINTK_TIME=y | ||
346 | CONFIG_MAGIC_SYSRQ=y | ||
347 | CONFIG_UNUSED_SYMBOLS=y | ||
348 | CONFIG_DEBUG_FS=y | ||
349 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
350 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
351 | CONFIG_CRYPTO=y | ||
352 | CONFIG_CRYPTO_GF128MUL=m | ||
353 | CONFIG_CRYPTO_HMAC=y | ||
354 | CONFIG_CRYPTO_MD5=y | ||
355 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
356 | # CONFIG_CRYPTO_HW is not set | ||
357 | CONFIG_CRC_CCITT=m | ||
358 | CONFIG_CRC16=m | ||
diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261_defconfig index b46025b66b64..ade6b2f23116 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261_defconfig | |||
@@ -1,9 +1,13 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_KERNEL_LZMA=y | ||
3 | # CONFIG_SWAP is not set | 4 | # CONFIG_SWAP is not set |
4 | CONFIG_SYSVIPC=y | 5 | CONFIG_SYSVIPC=y |
6 | CONFIG_IKCONFIG=y | ||
7 | CONFIG_IKCONFIG_PROC=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | 8 | CONFIG_LOG_BUF_SHIFT=14 |
6 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_NAMESPACES=y |
10 | CONFIG_EMBEDDED=y | ||
7 | CONFIG_SLAB=y | 11 | CONFIG_SLAB=y |
8 | CONFIG_MODULES=y | 12 | CONFIG_MODULES=y |
9 | CONFIG_MODULE_UNLOAD=y | 13 | CONFIG_MODULE_UNLOAD=y |
@@ -15,18 +19,27 @@ CONFIG_ARCH_AT91SAM9261=y | |||
15 | CONFIG_MACH_AT91SAM9261EK=y | 19 | CONFIG_MACH_AT91SAM9261EK=y |
16 | CONFIG_AT91_PROGRAMMABLE_CLOCKS=y | 20 | CONFIG_AT91_PROGRAMMABLE_CLOCKS=y |
17 | # CONFIG_ARM_THUMB is not set | 21 | # CONFIG_ARM_THUMB is not set |
22 | CONFIG_AEABI=y | ||
23 | # CONFIG_OABI_COMPAT is not set | ||
18 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 24 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
19 | CONFIG_ZBOOT_ROM_BSS=0x0 | 25 | CONFIG_ZBOOT_ROM_BSS=0x0 |
20 | CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" | 26 | CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" |
21 | CONFIG_FPE_NWFPE=y | 27 | CONFIG_AUTO_ZRELADDR=y |
28 | CONFIG_VFP=y | ||
29 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
22 | CONFIG_NET=y | 30 | CONFIG_NET=y |
23 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
24 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
25 | CONFIG_INET=y | 33 | CONFIG_INET=y |
34 | CONFIG_IP_MULTICAST=y | ||
26 | CONFIG_IP_PNP=y | 35 | CONFIG_IP_PNP=y |
36 | CONFIG_IP_PNP_DHCP=y | ||
27 | CONFIG_IP_PNP_BOOTP=y | 37 | CONFIG_IP_PNP_BOOTP=y |
28 | # CONFIG_INET_LRO is not set | 38 | # CONFIG_INET_LRO is not set |
29 | # CONFIG_IPV6 is not set | 39 | # CONFIG_IPV6 is not set |
40 | CONFIG_CFG80211=y | ||
41 | CONFIG_LIB80211=y | ||
42 | CONFIG_MAC80211=y | ||
30 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
31 | CONFIG_MTD=y | 44 | CONFIG_MTD=y |
32 | CONFIG_MTD_PARTITIONS=y | 45 | CONFIG_MTD_PARTITIONS=y |
@@ -34,8 +47,12 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
34 | CONFIG_MTD_BLOCK=y | 47 | CONFIG_MTD_BLOCK=y |
35 | CONFIG_MTD_NAND=y | 48 | CONFIG_MTD_NAND=y |
36 | CONFIG_MTD_NAND_ATMEL=y | 49 | CONFIG_MTD_NAND_ATMEL=y |
50 | CONFIG_MTD_UBI=y | ||
51 | CONFIG_MTD_UBI_GLUEBI=y | ||
37 | CONFIG_BLK_DEV_RAM=y | 52 | CONFIG_BLK_DEV_RAM=y |
38 | CONFIG_BLK_DEV_RAM_SIZE=8192 | 53 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
54 | CONFIG_MISC_DEVICES=y | ||
55 | CONFIG_ATMEL_TCLIB=y | ||
39 | CONFIG_ATMEL_SSC=y | 56 | CONFIG_ATMEL_SSC=y |
40 | CONFIG_SCSI=y | 57 | CONFIG_SCSI=y |
41 | CONFIG_BLK_DEV_SD=y | 58 | CONFIG_BLK_DEV_SD=y |
@@ -45,12 +62,27 @@ CONFIG_NET_ETHERNET=y | |||
45 | CONFIG_DM9000=y | 62 | CONFIG_DM9000=y |
46 | # CONFIG_NETDEV_1000 is not set | 63 | # CONFIG_NETDEV_1000 is not set |
47 | # CONFIG_NETDEV_10000 is not set | 64 | # CONFIG_NETDEV_10000 is not set |
65 | CONFIG_USB_ZD1201=m | ||
66 | CONFIG_RTL8187=m | ||
67 | CONFIG_LIBERTAS=m | ||
68 | CONFIG_LIBERTAS_USB=m | ||
69 | CONFIG_LIBERTAS_SDIO=m | ||
70 | CONFIG_LIBERTAS_SPI=m | ||
71 | CONFIG_RT2X00=m | ||
72 | CONFIG_RT2500USB=m | ||
73 | CONFIG_RT73USB=m | ||
74 | CONFIG_ZD1211RW=m | ||
75 | CONFIG_INPUT_POLLDEV=m | ||
48 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 76 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
77 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 | ||
78 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 | ||
79 | CONFIG_INPUT_EVDEV=y | ||
49 | # CONFIG_KEYBOARD_ATKBD is not set | 80 | # CONFIG_KEYBOARD_ATKBD is not set |
50 | CONFIG_KEYBOARD_GPIO=y | 81 | CONFIG_KEYBOARD_GPIO=y |
51 | # CONFIG_INPUT_MOUSE is not set | 82 | # CONFIG_INPUT_MOUSE is not set |
52 | CONFIG_INPUT_TOUCHSCREEN=y | 83 | CONFIG_INPUT_TOUCHSCREEN=y |
53 | CONFIG_TOUCHSCREEN_ADS7846=y | 84 | CONFIG_TOUCHSCREEN_ADS7846=y |
85 | CONFIG_DEVPTS_MULTIPLE_INSTANCES=y | ||
54 | CONFIG_SERIAL_ATMEL=y | 86 | CONFIG_SERIAL_ATMEL=y |
55 | CONFIG_SERIAL_ATMEL_CONSOLE=y | 87 | CONFIG_SERIAL_ATMEL_CONSOLE=y |
56 | CONFIG_HW_RANDOM=y | 88 | CONFIG_HW_RANDOM=y |
@@ -65,31 +97,62 @@ CONFIG_WATCHDOG_NOWAYOUT=y | |||
65 | CONFIG_AT91SAM9X_WATCHDOG=y | 97 | CONFIG_AT91SAM9X_WATCHDOG=y |
66 | CONFIG_FB=y | 98 | CONFIG_FB=y |
67 | CONFIG_FB_ATMEL=y | 99 | CONFIG_FB_ATMEL=y |
68 | # CONFIG_VGA_CONSOLE is not set | 100 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
101 | # CONFIG_LCD_CLASS_DEVICE is not set | ||
102 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
103 | CONFIG_BACKLIGHT_ATMEL_LCDC=y | ||
104 | # CONFIG_BACKLIGHT_GENERIC is not set | ||
105 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
106 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | ||
107 | CONFIG_LOGO=y | ||
108 | CONFIG_SOUND=y | ||
109 | CONFIG_SND=y | ||
110 | CONFIG_SND_SEQUENCER=y | ||
111 | CONFIG_SND_MIXER_OSS=y | ||
112 | CONFIG_SND_PCM_OSS=y | ||
113 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
114 | # CONFIG_SND_VERBOSE_PROCFS is not set | ||
115 | # CONFIG_SND_DRIVERS is not set | ||
116 | # CONFIG_SND_ARM is not set | ||
117 | CONFIG_SND_AT73C213=y | ||
118 | CONFIG_SND_USB_AUDIO=m | ||
69 | # CONFIG_USB_HID is not set | 119 | # CONFIG_USB_HID is not set |
70 | CONFIG_USB=y | 120 | CONFIG_USB=y |
71 | CONFIG_USB_DEVICEFS=y | 121 | CONFIG_USB_DEVICEFS=y |
72 | CONFIG_USB_MON=y | ||
73 | CONFIG_USB_OHCI_HCD=y | 122 | CONFIG_USB_OHCI_HCD=y |
74 | CONFIG_USB_STORAGE=y | 123 | CONFIG_USB_STORAGE=y |
75 | CONFIG_USB_STORAGE_DEBUG=y | ||
76 | CONFIG_USB_GADGET=y | 124 | CONFIG_USB_GADGET=y |
77 | CONFIG_USB_ZERO=m | 125 | CONFIG_USB_ZERO=m |
126 | CONFIG_USB_ETH=m | ||
78 | CONFIG_USB_GADGETFS=m | 127 | CONFIG_USB_GADGETFS=m |
79 | CONFIG_USB_FILE_STORAGE=m | 128 | CONFIG_USB_FILE_STORAGE=m |
80 | CONFIG_USB_G_SERIAL=m | 129 | CONFIG_USB_G_SERIAL=m |
81 | CONFIG_MMC=y | 130 | CONFIG_MMC=y |
82 | CONFIG_MMC_AT91=m | 131 | CONFIG_MMC_AT91=m |
132 | CONFIG_NEW_LEDS=y | ||
133 | CONFIG_LEDS_CLASS=y | ||
134 | CONFIG_LEDS_GPIO=y | ||
135 | CONFIG_LEDS_TRIGGERS=y | ||
136 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
137 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
138 | CONFIG_LEDS_TRIGGER_GPIO=y | ||
83 | CONFIG_RTC_CLASS=y | 139 | CONFIG_RTC_CLASS=y |
84 | CONFIG_RTC_DRV_AT91SAM9=y | 140 | CONFIG_RTC_DRV_AT91SAM9=y |
85 | CONFIG_EXT2_FS=y | 141 | CONFIG_MSDOS_FS=y |
86 | CONFIG_INOTIFY=y | ||
87 | CONFIG_VFAT_FS=y | 142 | CONFIG_VFAT_FS=y |
88 | CONFIG_TMPFS=y | 143 | CONFIG_TMPFS=y |
89 | CONFIG_CRAMFS=y | 144 | CONFIG_UBIFS_FS=y |
145 | CONFIG_UBIFS_FS_ADVANCED_COMPR=y | ||
146 | CONFIG_SQUASHFS=y | ||
147 | CONFIG_SQUASHFS_LZO=y | ||
148 | CONFIG_SQUASHFS_XZ=y | ||
149 | CONFIG_NFS_FS=y | ||
150 | CONFIG_NFS_V3=y | ||
151 | CONFIG_ROOT_NFS=y | ||
90 | CONFIG_NLS_CODEPAGE_437=y | 152 | CONFIG_NLS_CODEPAGE_437=y |
91 | CONFIG_NLS_CODEPAGE_850=y | 153 | CONFIG_NLS_CODEPAGE_850=y |
92 | CONFIG_NLS_ISO8859_1=y | 154 | CONFIG_NLS_ISO8859_1=y |
93 | CONFIG_DEBUG_KERNEL=y | 155 | CONFIG_NLS_ISO8859_15=y |
94 | CONFIG_DEBUG_USER=y | 156 | CONFIG_NLS_UTF8=y |
95 | CONFIG_DEBUG_LL=y | 157 | CONFIG_FTRACE=y |
158 | CONFIG_CRC_CCITT=m | ||
diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263_defconfig index 8a04d6f4e065..1cf96264cba1 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263_defconfig | |||
@@ -1,9 +1,13 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_KERNEL_LZMA=y | ||
3 | # CONFIG_SWAP is not set | 4 | # CONFIG_SWAP is not set |
4 | CONFIG_SYSVIPC=y | 5 | CONFIG_SYSVIPC=y |
6 | CONFIG_IKCONFIG=y | ||
7 | CONFIG_IKCONFIG_PROC=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | 8 | CONFIG_LOG_BUF_SHIFT=14 |
6 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_NAMESPACES=y |
10 | CONFIG_EMBEDDED=y | ||
7 | CONFIG_SLAB=y | 11 | CONFIG_SLAB=y |
8 | CONFIG_MODULES=y | 12 | CONFIG_MODULES=y |
9 | CONFIG_MODULE_UNLOAD=y | 13 | CONFIG_MODULE_UNLOAD=y |
@@ -13,53 +17,81 @@ CONFIG_MODULE_UNLOAD=y | |||
13 | CONFIG_ARCH_AT91=y | 17 | CONFIG_ARCH_AT91=y |
14 | CONFIG_ARCH_AT91SAM9263=y | 18 | CONFIG_ARCH_AT91SAM9263=y |
15 | CONFIG_MACH_AT91SAM9263EK=y | 19 | CONFIG_MACH_AT91SAM9263EK=y |
20 | CONFIG_MACH_USB_A9263=y | ||
21 | CONFIG_MACH_NEOCORE926=y | ||
16 | CONFIG_MTD_AT91_DATAFLASH_CARD=y | 22 | CONFIG_MTD_AT91_DATAFLASH_CARD=y |
17 | # CONFIG_ARM_THUMB is not set | 23 | # CONFIG_ARM_THUMB is not set |
24 | CONFIG_AEABI=y | ||
25 | # CONFIG_OABI_COMPAT is not set | ||
18 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 26 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
19 | CONFIG_ZBOOT_ROM_BSS=0x0 | 27 | CONFIG_ZBOOT_ROM_BSS=0x0 |
20 | CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" | 28 | CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" |
21 | CONFIG_FPE_NWFPE=y | 29 | CONFIG_AUTO_ZRELADDR=y |
22 | CONFIG_NET=y | 30 | CONFIG_NET=y |
23 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
24 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
33 | CONFIG_NET_KEY=y | ||
25 | CONFIG_INET=y | 34 | CONFIG_INET=y |
35 | CONFIG_IP_MULTICAST=y | ||
36 | CONFIG_IP_ADVANCED_ROUTER=y | ||
37 | CONFIG_IP_ROUTE_VERBOSE=y | ||
26 | CONFIG_IP_PNP=y | 38 | CONFIG_IP_PNP=y |
39 | CONFIG_IP_PNP_DHCP=y | ||
27 | CONFIG_IP_PNP_BOOTP=y | 40 | CONFIG_IP_PNP_BOOTP=y |
28 | CONFIG_IP_PNP_RARP=y | 41 | CONFIG_IP_PNP_RARP=y |
42 | CONFIG_NET_IPIP=y | ||
43 | CONFIG_IP_MROUTE=y | ||
44 | CONFIG_IP_PIMSM_V1=y | ||
45 | CONFIG_IP_PIMSM_V2=y | ||
29 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | 46 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set |
30 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | 47 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set |
31 | # CONFIG_INET_XFRM_MODE_BEET is not set | 48 | # CONFIG_INET_XFRM_MODE_BEET is not set |
32 | # CONFIG_INET_LRO is not set | 49 | # CONFIG_INET_LRO is not set |
33 | # CONFIG_INET_DIAG is not set | 50 | # CONFIG_INET_DIAG is not set |
34 | # CONFIG_IPV6 is not set | 51 | CONFIG_IPV6=y |
35 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 52 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
36 | CONFIG_MTD=y | 53 | CONFIG_MTD=y |
37 | CONFIG_MTD_PARTITIONS=y | 54 | CONFIG_MTD_PARTITIONS=y |
38 | CONFIG_MTD_CMDLINE_PARTS=y | 55 | CONFIG_MTD_CMDLINE_PARTS=y |
39 | CONFIG_MTD_CHAR=y | 56 | CONFIG_MTD_CHAR=y |
40 | CONFIG_MTD_BLOCK=y | 57 | CONFIG_MTD_BLOCK=y |
58 | CONFIG_NFTL=y | ||
59 | CONFIG_NFTL_RW=y | ||
41 | CONFIG_MTD_DATAFLASH=y | 60 | CONFIG_MTD_DATAFLASH=y |
61 | CONFIG_MTD_BLOCK2MTD=y | ||
42 | CONFIG_MTD_NAND=y | 62 | CONFIG_MTD_NAND=y |
43 | CONFIG_MTD_NAND_ATMEL=y | 63 | CONFIG_MTD_NAND_ATMEL=y |
64 | CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y | ||
65 | CONFIG_MTD_UBI=y | ||
66 | CONFIG_MTD_UBI_GLUEBI=y | ||
44 | CONFIG_BLK_DEV_LOOP=y | 67 | CONFIG_BLK_DEV_LOOP=y |
45 | CONFIG_BLK_DEV_RAM=y | 68 | CONFIG_BLK_DEV_RAM=y |
46 | CONFIG_BLK_DEV_RAM_SIZE=8192 | 69 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
47 | CONFIG_ATMEL_SSC=y | 70 | CONFIG_MISC_DEVICES=y |
71 | CONFIG_ATMEL_PWM=y | ||
72 | CONFIG_ATMEL_TCLIB=y | ||
48 | CONFIG_SCSI=y | 73 | CONFIG_SCSI=y |
49 | CONFIG_BLK_DEV_SD=y | 74 | CONFIG_BLK_DEV_SD=y |
50 | CONFIG_SCSI_MULTI_LUN=y | 75 | CONFIG_SCSI_MULTI_LUN=y |
51 | CONFIG_NETDEVICES=y | 76 | CONFIG_NETDEVICES=y |
52 | CONFIG_NET_ETHERNET=y | ||
53 | CONFIG_MII=y | 77 | CONFIG_MII=y |
78 | CONFIG_SMSC_PHY=y | ||
79 | CONFIG_NET_ETHERNET=y | ||
54 | CONFIG_MACB=y | 80 | CONFIG_MACB=y |
81 | # CONFIG_NETDEV_1000 is not set | ||
82 | # CONFIG_NETDEV_10000 is not set | ||
83 | CONFIG_USB_ZD1201=m | ||
84 | CONFIG_INPUT_POLLDEV=m | ||
55 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 85 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
86 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 | ||
87 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 | ||
56 | CONFIG_INPUT_EVDEV=y | 88 | CONFIG_INPUT_EVDEV=y |
57 | # CONFIG_KEYBOARD_ATKBD is not set | 89 | # CONFIG_KEYBOARD_ATKBD is not set |
58 | CONFIG_KEYBOARD_GPIO=y | 90 | CONFIG_KEYBOARD_GPIO=y |
59 | # CONFIG_INPUT_MOUSE is not set | 91 | # CONFIG_INPUT_MOUSE is not set |
60 | CONFIG_INPUT_TOUCHSCREEN=y | 92 | CONFIG_INPUT_TOUCHSCREEN=y |
61 | CONFIG_TOUCHSCREEN_ADS7846=y | 93 | CONFIG_TOUCHSCREEN_ADS7846=y |
62 | # CONFIG_SERIO is not set | 94 | CONFIG_LEGACY_PTY_COUNT=4 |
63 | CONFIG_SERIAL_ATMEL=y | 95 | CONFIG_SERIAL_ATMEL=y |
64 | CONFIG_SERIAL_ATMEL_CONSOLE=y | 96 | CONFIG_SERIAL_ATMEL_CONSOLE=y |
65 | CONFIG_HW_RANDOM=y | 97 | CONFIG_HW_RANDOM=y |
@@ -74,8 +106,25 @@ CONFIG_WATCHDOG_NOWAYOUT=y | |||
74 | CONFIG_AT91SAM9X_WATCHDOG=y | 106 | CONFIG_AT91SAM9X_WATCHDOG=y |
75 | CONFIG_FB=y | 107 | CONFIG_FB=y |
76 | CONFIG_FB_ATMEL=y | 108 | CONFIG_FB_ATMEL=y |
77 | # CONFIG_VGA_CONSOLE is not set | 109 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
78 | # CONFIG_USB_HID is not set | 110 | CONFIG_LCD_CLASS_DEVICE=y |
111 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
112 | CONFIG_BACKLIGHT_ATMEL_LCDC=y | ||
113 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
114 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | ||
115 | CONFIG_LOGO=y | ||
116 | CONFIG_SOUND=y | ||
117 | CONFIG_SND=y | ||
118 | CONFIG_SND_SEQUENCER=y | ||
119 | CONFIG_SND_MIXER_OSS=y | ||
120 | CONFIG_SND_PCM_OSS=y | ||
121 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
122 | # CONFIG_SND_VERBOSE_PROCFS is not set | ||
123 | # CONFIG_SND_DRIVERS is not set | ||
124 | # CONFIG_SND_ARM is not set | ||
125 | CONFIG_SND_ATMEL_AC97C=y | ||
126 | # CONFIG_SND_SPI is not set | ||
127 | CONFIG_SND_USB_AUDIO=m | ||
79 | CONFIG_USB=y | 128 | CONFIG_USB=y |
80 | CONFIG_USB_DEVICEFS=y | 129 | CONFIG_USB_DEVICEFS=y |
81 | CONFIG_USB_MON=y | 130 | CONFIG_USB_MON=y |
@@ -83,24 +132,37 @@ CONFIG_USB_OHCI_HCD=y | |||
83 | CONFIG_USB_STORAGE=y | 132 | CONFIG_USB_STORAGE=y |
84 | CONFIG_USB_GADGET=y | 133 | CONFIG_USB_GADGET=y |
85 | CONFIG_USB_ZERO=m | 134 | CONFIG_USB_ZERO=m |
135 | CONFIG_USB_ETH=m | ||
86 | CONFIG_USB_GADGETFS=m | 136 | CONFIG_USB_GADGETFS=m |
87 | CONFIG_USB_FILE_STORAGE=m | 137 | CONFIG_USB_FILE_STORAGE=m |
88 | CONFIG_USB_G_SERIAL=m | 138 | CONFIG_USB_G_SERIAL=m |
89 | CONFIG_MMC=y | 139 | CONFIG_MMC=y |
140 | CONFIG_SDIO_UART=m | ||
90 | CONFIG_MMC_AT91=m | 141 | CONFIG_MMC_AT91=m |
142 | CONFIG_NEW_LEDS=y | ||
143 | CONFIG_LEDS_CLASS=y | ||
144 | CONFIG_LEDS_ATMEL_PWM=y | ||
145 | CONFIG_LEDS_GPIO=y | ||
146 | CONFIG_LEDS_TRIGGERS=y | ||
147 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
91 | CONFIG_RTC_CLASS=y | 148 | CONFIG_RTC_CLASS=y |
92 | CONFIG_RTC_DRV_AT91SAM9=y | 149 | CONFIG_RTC_DRV_AT91SAM9=y |
93 | CONFIG_EXT2_FS=y | 150 | CONFIG_EXT2_FS=y |
94 | CONFIG_INOTIFY=y | 151 | CONFIG_FUSE_FS=m |
95 | CONFIG_VFAT_FS=y | 152 | CONFIG_VFAT_FS=y |
96 | CONFIG_TMPFS=y | 153 | CONFIG_TMPFS=y |
97 | CONFIG_JFFS2_FS=y | 154 | CONFIG_JFFS2_FS=y |
155 | CONFIG_UBIFS_FS=y | ||
156 | CONFIG_UBIFS_FS_ADVANCED_COMPR=y | ||
98 | CONFIG_CRAMFS=y | 157 | CONFIG_CRAMFS=y |
99 | CONFIG_NFS_FS=y | 158 | CONFIG_NFS_FS=y |
159 | CONFIG_NFS_V3=y | ||
160 | CONFIG_NFS_V3_ACL=y | ||
161 | CONFIG_NFS_V4=y | ||
100 | CONFIG_ROOT_NFS=y | 162 | CONFIG_ROOT_NFS=y |
101 | CONFIG_NLS_CODEPAGE_437=y | 163 | CONFIG_NLS_CODEPAGE_437=y |
102 | CONFIG_NLS_CODEPAGE_850=y | 164 | CONFIG_NLS_CODEPAGE_850=y |
103 | CONFIG_NLS_ISO8859_1=y | 165 | CONFIG_NLS_ISO8859_1=y |
104 | CONFIG_DEBUG_KERNEL=y | 166 | CONFIG_FTRACE=y |
105 | CONFIG_DEBUG_USER=y | 167 | CONFIG_DEBUG_USER=y |
106 | CONFIG_DEBUG_LL=y | 168 | CONFIG_XZ_DEC=y |
diff --git a/arch/arm/configs/exynos4_defconfig b/arch/arm/configs/exynos4_defconfig index 2ffba24d2e2a..da53ff3b4d70 100644 --- a/arch/arm/configs/exynos4_defconfig +++ b/arch/arm/configs/exynos4_defconfig | |||
@@ -8,7 +8,9 @@ CONFIG_ARCH_EXYNOS4=y | |||
8 | CONFIG_S3C_LOWLEVEL_UART_PORT=1 | 8 | CONFIG_S3C_LOWLEVEL_UART_PORT=1 |
9 | CONFIG_MACH_SMDKC210=y | 9 | CONFIG_MACH_SMDKC210=y |
10 | CONFIG_MACH_SMDKV310=y | 10 | CONFIG_MACH_SMDKV310=y |
11 | CONFIG_MACH_ARMLEX4210=y | ||
11 | CONFIG_MACH_UNIVERSAL_C210=y | 12 | CONFIG_MACH_UNIVERSAL_C210=y |
13 | CONFIG_MACH_NURI=y | ||
12 | CONFIG_NO_HZ=y | 14 | CONFIG_NO_HZ=y |
13 | CONFIG_HIGH_RES_TIMERS=y | 15 | CONFIG_HIGH_RES_TIMERS=y |
14 | CONFIG_SMP=y | 16 | CONFIG_SMP=y |
diff --git a/arch/arm/configs/neocore926_defconfig b/arch/arm/configs/neocore926_defconfig deleted file mode 100644 index 462dd1850d15..000000000000 --- a/arch/arm/configs/neocore926_defconfig +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | # CONFIG_LOCALVERSION_AUTO is not set | ||
3 | # CONFIG_SWAP is not set | ||
4 | CONFIG_SYSVIPC=y | ||
5 | CONFIG_BLK_DEV_INITRD=y | ||
6 | # CONFIG_COMPAT_BRK is not set | ||
7 | CONFIG_MODULES=y | ||
8 | CONFIG_MODULE_UNLOAD=y | ||
9 | # CONFIG_BLK_DEV_BSG is not set | ||
10 | # CONFIG_IOSCHED_DEADLINE is not set | ||
11 | # CONFIG_IOSCHED_CFQ is not set | ||
12 | CONFIG_ARCH_AT91=y | ||
13 | CONFIG_ARCH_AT91SAM9263=y | ||
14 | CONFIG_MACH_NEOCORE926=y | ||
15 | CONFIG_MTD_AT91_DATAFLASH_CARD=y | ||
16 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
17 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
18 | CONFIG_FPE_NWFPE=y | ||
19 | CONFIG_NET=y | ||
20 | CONFIG_PACKET=y | ||
21 | CONFIG_UNIX=y | ||
22 | CONFIG_NET_KEY=y | ||
23 | CONFIG_INET=y | ||
24 | CONFIG_IP_PNP=y | ||
25 | CONFIG_IP_PNP_DHCP=y | ||
26 | CONFIG_IP_PNP_BOOTP=y | ||
27 | CONFIG_IP_PNP_RARP=y | ||
28 | CONFIG_NET_IPIP=y | ||
29 | # CONFIG_INET_LRO is not set | ||
30 | CONFIG_IPV6=y | ||
31 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
32 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||
33 | CONFIG_MTD=y | ||
34 | CONFIG_MTD_PARTITIONS=y | ||
35 | CONFIG_MTD_CHAR=y | ||
36 | CONFIG_MTD_BLOCK=y | ||
37 | CONFIG_NFTL=y | ||
38 | CONFIG_NFTL_RW=y | ||
39 | CONFIG_MTD_BLOCK2MTD=y | ||
40 | CONFIG_MTD_NAND=y | ||
41 | CONFIG_MTD_NAND_ECC_SMC=y | ||
42 | CONFIG_MTD_NAND_VERIFY_WRITE=y | ||
43 | CONFIG_MTD_NAND_ATMEL=y | ||
44 | CONFIG_MTD_NAND_PLATFORM=y | ||
45 | CONFIG_BLK_DEV_LOOP=y | ||
46 | CONFIG_BLK_DEV_NBD=y | ||
47 | CONFIG_ATMEL_PWM=y | ||
48 | CONFIG_ATMEL_TCLIB=y | ||
49 | CONFIG_SCSI=y | ||
50 | CONFIG_CHR_DEV_SG=y | ||
51 | CONFIG_NETDEVICES=y | ||
52 | CONFIG_SMSC_PHY=y | ||
53 | CONFIG_NET_ETHERNET=y | ||
54 | CONFIG_MACB=y | ||
55 | # CONFIG_NETDEV_1000 is not set | ||
56 | # CONFIG_NETDEV_10000 is not set | ||
57 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
58 | CONFIG_INPUT_EVDEV=y | ||
59 | CONFIG_INPUT_TOUCHSCREEN=y | ||
60 | CONFIG_TOUCHSCREEN_ADS7846=y | ||
61 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
62 | # CONFIG_DEVKMEM is not set | ||
63 | CONFIG_SERIAL_NONSTANDARD=y | ||
64 | CONFIG_SERIAL_ATMEL=y | ||
65 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
66 | # CONFIG_SERIAL_ATMEL_PDC is not set | ||
67 | # CONFIG_HW_RANDOM is not set | ||
68 | CONFIG_I2C=y | ||
69 | CONFIG_I2C_CHARDEV=y | ||
70 | CONFIG_SPI=y | ||
71 | CONFIG_SPI_ATMEL=y | ||
72 | # CONFIG_HWMON is not set | ||
73 | CONFIG_VIDEO_OUTPUT_CONTROL=y | ||
74 | CONFIG_FB=y | ||
75 | CONFIG_FB_ATMEL=y | ||
76 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | ||
77 | CONFIG_LCD_CLASS_DEVICE=y | ||
78 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
79 | CONFIG_BACKLIGHT_ATMEL_LCDC=y | ||
80 | # CONFIG_VGA_CONSOLE is not set | ||
81 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
82 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | ||
83 | CONFIG_LOGO=y | ||
84 | CONFIG_USB=y | ||
85 | CONFIG_USB_DEVICEFS=y | ||
86 | CONFIG_USB_MON=y | ||
87 | CONFIG_USB_OHCI_HCD=y | ||
88 | CONFIG_USB_STORAGE=y | ||
89 | CONFIG_MMC=y | ||
90 | CONFIG_SDIO_UART=y | ||
91 | CONFIG_MMC_AT91=m | ||
92 | CONFIG_EXT2_FS=y | ||
93 | # CONFIG_DNOTIFY is not set | ||
94 | CONFIG_AUTOFS_FS=y | ||
95 | CONFIG_VFAT_FS=y | ||
96 | CONFIG_TMPFS=y | ||
97 | CONFIG_JFFS2_FS=y | ||
98 | CONFIG_JFFS2_FS_WBUF_VERIFY=y | ||
99 | CONFIG_NFS_FS=y | ||
100 | CONFIG_ROOT_NFS=y | ||
101 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
102 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
103 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
104 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/arm/configs/s5p6442_defconfig b/arch/arm/configs/s5p6442_defconfig deleted file mode 100644 index 0e92a784af66..000000000000 --- a/arch/arm/configs/s5p6442_defconfig +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
3 | CONFIG_BLK_DEV_INITRD=y | ||
4 | CONFIG_KALLSYMS_ALL=y | ||
5 | CONFIG_MODULES=y | ||
6 | CONFIG_MODULE_UNLOAD=y | ||
7 | # CONFIG_BLK_DEV_BSG is not set | ||
8 | CONFIG_ARCH_S5P6442=y | ||
9 | CONFIG_S3C_LOWLEVEL_UART_PORT=1 | ||
10 | CONFIG_MACH_SMDK6442=y | ||
11 | CONFIG_CPU_32v6K=y | ||
12 | CONFIG_AEABI=y | ||
13 | CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc" | ||
14 | CONFIG_FPE_NWFPE=y | ||
15 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
16 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||
17 | CONFIG_BLK_DEV_LOOP=y | ||
18 | CONFIG_BLK_DEV_RAM=y | ||
19 | CONFIG_BLK_DEV_RAM_SIZE=8192 | ||
20 | # CONFIG_MISC_DEVICES is not set | ||
21 | CONFIG_SCSI=y | ||
22 | CONFIG_BLK_DEV_SD=y | ||
23 | CONFIG_CHR_DEV_SG=y | ||
24 | CONFIG_INPUT_EVDEV=y | ||
25 | # CONFIG_INPUT_KEYBOARD is not set | ||
26 | # CONFIG_INPUT_MOUSE is not set | ||
27 | CONFIG_INPUT_TOUCHSCREEN=y | ||
28 | CONFIG_SERIAL_8250=y | ||
29 | CONFIG_SERIAL_8250_NR_UARTS=3 | ||
30 | CONFIG_SERIAL_SAMSUNG=y | ||
31 | CONFIG_SERIAL_SAMSUNG_CONSOLE=y | ||
32 | CONFIG_HW_RANDOM=y | ||
33 | # CONFIG_HWMON is not set | ||
34 | # CONFIG_VGA_CONSOLE is not set | ||
35 | # CONFIG_HID_SUPPORT is not set | ||
36 | # CONFIG_USB_SUPPORT is not set | ||
37 | CONFIG_EXT2_FS=y | ||
38 | CONFIG_INOTIFY=y | ||
39 | CONFIG_MSDOS_FS=y | ||
40 | CONFIG_VFAT_FS=y | ||
41 | CONFIG_TMPFS=y | ||
42 | CONFIG_TMPFS_POSIX_ACL=y | ||
43 | CONFIG_CRAMFS=y | ||
44 | CONFIG_ROMFS_FS=y | ||
45 | CONFIG_PARTITION_ADVANCED=y | ||
46 | CONFIG_BSD_DISKLABEL=y | ||
47 | CONFIG_SOLARIS_X86_PARTITION=y | ||
48 | CONFIG_NLS_CODEPAGE_437=y | ||
49 | CONFIG_NLS_ASCII=y | ||
50 | CONFIG_NLS_ISO8859_1=y | ||
51 | CONFIG_MAGIC_SYSRQ=y | ||
52 | CONFIG_DEBUG_KERNEL=y | ||
53 | CONFIG_DEBUG_RT_MUTEXES=y | ||
54 | CONFIG_DEBUG_SPINLOCK=y | ||
55 | CONFIG_DEBUG_MUTEXES=y | ||
56 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | ||
57 | CONFIG_DEBUG_INFO=y | ||
58 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
59 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
60 | # CONFIG_ARM_UNWIND is not set | ||
61 | CONFIG_DEBUG_USER=y | ||
62 | CONFIG_DEBUG_ERRORS=y | ||
63 | CONFIG_DEBUG_LL=y | ||
64 | CONFIG_DEBUG_S3C_UART=1 | ||
65 | CONFIG_CRC_CCITT=y | ||
diff --git a/arch/arm/configs/usb-a9263_defconfig b/arch/arm/configs/usb-a9263_defconfig deleted file mode 100644 index ee82d09249c6..000000000000 --- a/arch/arm/configs/usb-a9263_defconfig +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | # CONFIG_LOCALVERSION_AUTO is not set | ||
3 | # CONFIG_SWAP is not set | ||
4 | CONFIG_SYSVIPC=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | ||
6 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
7 | CONFIG_SLAB=y | ||
8 | CONFIG_MODULES=y | ||
9 | CONFIG_MODULE_UNLOAD=y | ||
10 | # CONFIG_BLK_DEV_BSG is not set | ||
11 | # CONFIG_IOSCHED_DEADLINE is not set | ||
12 | # CONFIG_IOSCHED_CFQ is not set | ||
13 | CONFIG_ARCH_AT91=y | ||
14 | CONFIG_ARCH_AT91SAM9263=y | ||
15 | CONFIG_MACH_USB_A9263=y | ||
16 | CONFIG_AT91_SLOW_CLOCK=y | ||
17 | # CONFIG_ARM_THUMB is not set | ||
18 | CONFIG_AEABI=y | ||
19 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
20 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
21 | CONFIG_CMDLINE="mem=64M console=ttyS0,115200" | ||
22 | CONFIG_FPE_NWFPE=y | ||
23 | CONFIG_PM=y | ||
24 | CONFIG_NET=y | ||
25 | CONFIG_PACKET=y | ||
26 | CONFIG_UNIX=y | ||
27 | CONFIG_INET=y | ||
28 | CONFIG_IP_MULTICAST=y | ||
29 | CONFIG_IP_ADVANCED_ROUTER=y | ||
30 | CONFIG_IP_ROUTE_VERBOSE=y | ||
31 | CONFIG_IP_PNP=y | ||
32 | CONFIG_IP_PNP_BOOTP=y | ||
33 | CONFIG_IP_PNP_RARP=y | ||
34 | CONFIG_IP_MROUTE=y | ||
35 | CONFIG_IP_PIMSM_V1=y | ||
36 | CONFIG_IP_PIMSM_V2=y | ||
37 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
38 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
39 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
40 | # CONFIG_INET_LRO is not set | ||
41 | # CONFIG_INET_DIAG is not set | ||
42 | # CONFIG_IPV6 is not set | ||
43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
44 | CONFIG_MTD=y | ||
45 | CONFIG_MTD_PARTITIONS=y | ||
46 | CONFIG_MTD_CMDLINE_PARTS=y | ||
47 | CONFIG_MTD_CHAR=y | ||
48 | CONFIG_MTD_BLOCK=y | ||
49 | CONFIG_MTD_DATAFLASH=y | ||
50 | CONFIG_MTD_NAND=y | ||
51 | CONFIG_MTD_NAND_ATMEL=y | ||
52 | CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y | ||
53 | CONFIG_BLK_DEV_LOOP=y | ||
54 | # CONFIG_MISC_DEVICES is not set | ||
55 | CONFIG_SCSI=y | ||
56 | CONFIG_BLK_DEV_SD=y | ||
57 | CONFIG_SCSI_MULTI_LUN=y | ||
58 | CONFIG_NETDEVICES=y | ||
59 | CONFIG_NET_ETHERNET=y | ||
60 | CONFIG_MII=y | ||
61 | CONFIG_MACB=y | ||
62 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
63 | CONFIG_INPUT_EVDEV=y | ||
64 | CONFIG_INPUT_EVBUG=y | ||
65 | # CONFIG_KEYBOARD_ATKBD is not set | ||
66 | CONFIG_KEYBOARD_GPIO=y | ||
67 | # CONFIG_INPUT_MOUSE is not set | ||
68 | # CONFIG_SERIO is not set | ||
69 | CONFIG_SERIAL_ATMEL=y | ||
70 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
71 | CONFIG_HW_RANDOM=y | ||
72 | CONFIG_SPI=y | ||
73 | CONFIG_SPI_ATMEL=y | ||
74 | # CONFIG_HWMON is not set | ||
75 | # CONFIG_VGA_CONSOLE is not set | ||
76 | # CONFIG_USB_HID is not set | ||
77 | CONFIG_USB=y | ||
78 | CONFIG_USB_DEVICEFS=y | ||
79 | CONFIG_USB_MON=y | ||
80 | CONFIG_USB_OHCI_HCD=y | ||
81 | CONFIG_USB_STORAGE=y | ||
82 | CONFIG_USB_GADGET=y | ||
83 | CONFIG_USB_ETH=m | ||
84 | CONFIG_NEW_LEDS=y | ||
85 | CONFIG_LEDS_CLASS=y | ||
86 | CONFIG_LEDS_GPIO=y | ||
87 | CONFIG_LEDS_TRIGGERS=y | ||
88 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
89 | CONFIG_EXT2_FS=y | ||
90 | CONFIG_INOTIFY=y | ||
91 | CONFIG_FUSE_FS=m | ||
92 | CONFIG_VFAT_FS=y | ||
93 | CONFIG_TMPFS=y | ||
94 | CONFIG_JFFS2_FS=y | ||
95 | CONFIG_NFS_FS=y | ||
96 | CONFIG_NFS_V3=y | ||
97 | CONFIG_NFS_V3_ACL=y | ||
98 | CONFIG_NFS_V4=y | ||
99 | CONFIG_ROOT_NFS=y | ||
100 | CONFIG_NLS_CODEPAGE_437=y | ||
101 | CONFIG_NLS_CODEPAGE_850=y | ||
102 | CONFIG_NLS_ISO8859_1=y | ||
103 | CONFIG_DEBUG_KERNEL=y | ||
104 | CONFIG_DEBUG_USER=y | ||
105 | CONFIG_DEBUG_LL=y | ||
106 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h index 2242ce22ec6c..d493d0b742a1 100644 --- a/arch/arm/include/asm/fiq.h +++ b/arch/arm/include/asm/fiq.h | |||
@@ -4,6 +4,13 @@ | |||
4 | * Support for FIQ on ARM architectures. | 4 | * Support for FIQ on ARM architectures. |
5 | * Written by Philip Blundell <philb@gnu.org>, 1998 | 5 | * Written by Philip Blundell <philb@gnu.org>, 1998 |
6 | * Re-written by Russell King | 6 | * Re-written by Russell King |
7 | * | ||
8 | * NOTE: The FIQ mode registers are not magically preserved across | ||
9 | * suspend/resume. | ||
10 | * | ||
11 | * Drivers which require these registers to be preserved across power | ||
12 | * management operations must implement appropriate suspend/resume handlers to | ||
13 | * save and restore them. | ||
7 | */ | 14 | */ |
8 | 15 | ||
9 | #ifndef __ASM_FIQ_H | 16 | #ifndef __ASM_FIQ_H |
@@ -29,9 +36,21 @@ struct fiq_handler { | |||
29 | extern int claim_fiq(struct fiq_handler *f); | 36 | extern int claim_fiq(struct fiq_handler *f); |
30 | extern void release_fiq(struct fiq_handler *f); | 37 | extern void release_fiq(struct fiq_handler *f); |
31 | extern void set_fiq_handler(void *start, unsigned int length); | 38 | extern void set_fiq_handler(void *start, unsigned int length); |
32 | extern void set_fiq_regs(struct pt_regs *regs); | ||
33 | extern void get_fiq_regs(struct pt_regs *regs); | ||
34 | extern void enable_fiq(int fiq); | 39 | extern void enable_fiq(int fiq); |
35 | extern void disable_fiq(int fiq); | 40 | extern void disable_fiq(int fiq); |
36 | 41 | ||
42 | /* helpers defined in fiqasm.S: */ | ||
43 | extern void __set_fiq_regs(unsigned long const *regs); | ||
44 | extern void __get_fiq_regs(unsigned long *regs); | ||
45 | |||
46 | static inline void set_fiq_regs(struct pt_regs const *regs) | ||
47 | { | ||
48 | __set_fiq_regs(®s->ARM_r8); | ||
49 | } | ||
50 | |||
51 | static inline void get_fiq_regs(struct pt_regs *regs) | ||
52 | { | ||
53 | __get_fiq_regs(®s->ARM_r8); | ||
54 | } | ||
55 | |||
37 | #endif | 56 | #endif |
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index bf13b814c1b8..946f4d778f71 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h | |||
@@ -18,6 +18,8 @@ struct machine_desc { | |||
18 | unsigned int nr; /* architecture number */ | 18 | unsigned int nr; /* architecture number */ |
19 | const char *name; /* architecture name */ | 19 | const char *name; /* architecture name */ |
20 | unsigned long boot_params; /* tagged list */ | 20 | unsigned long boot_params; /* tagged list */ |
21 | const char **dt_compat; /* array of device tree | ||
22 | * 'compatible' strings */ | ||
21 | 23 | ||
22 | unsigned int nr_irqs; /* number of IRQs */ | 24 | unsigned int nr_irqs; /* number of IRQs */ |
23 | 25 | ||
@@ -48,6 +50,13 @@ struct machine_desc { | |||
48 | extern struct machine_desc *machine_desc; | 50 | extern struct machine_desc *machine_desc; |
49 | 51 | ||
50 | /* | 52 | /* |
53 | * Machine type table - also only accessible during boot | ||
54 | */ | ||
55 | extern struct machine_desc __arch_info_begin[], __arch_info_end[]; | ||
56 | #define for_each_machine_desc(p) \ | ||
57 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
58 | |||
59 | /* | ||
51 | * Set of macros to define architecture features. This is built into | 60 | * Set of macros to define architecture features. This is built into |
52 | * a table by the linker. | 61 | * a table by the linker. |
53 | */ | 62 | */ |
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index f51a69595f6e..ac75d0848889 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h | |||
@@ -197,7 +197,7 @@ typedef unsigned long pgprot_t; | |||
197 | 197 | ||
198 | typedef struct page *pgtable_t; | 198 | typedef struct page *pgtable_t; |
199 | 199 | ||
200 | #ifndef CONFIG_SPARSEMEM | 200 | #ifdef CONFIG_HAVE_ARCH_PFN_VALID |
201 | extern int pfn_valid(unsigned long); | 201 | extern int pfn_valid(unsigned long); |
202 | #endif | 202 | #endif |
203 | 203 | ||
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h new file mode 100644 index 000000000000..11b8708fc4db --- /dev/null +++ b/arch/arm/include/asm/prom.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/prom.h | ||
3 | * | ||
4 | * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | #ifndef __ASMARM_PROM_H | ||
12 | #define __ASMARM_PROM_H | ||
13 | |||
14 | #ifdef CONFIG_OF | ||
15 | |||
16 | #include <asm/setup.h> | ||
17 | #include <asm/irq.h> | ||
18 | |||
19 | static inline void irq_dispose_mapping(unsigned int virq) | ||
20 | { | ||
21 | return; | ||
22 | } | ||
23 | |||
24 | extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); | ||
25 | extern void arm_dt_memblock_reserve(void); | ||
26 | |||
27 | #else /* CONFIG_OF */ | ||
28 | |||
29 | static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys) | ||
30 | { | ||
31 | return NULL; | ||
32 | } | ||
33 | |||
34 | static inline void arm_dt_memblock_reserve(void) { } | ||
35 | |||
36 | #endif /* CONFIG_OF */ | ||
37 | #endif /* ASMARM_PROM_H */ | ||
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 95176af3df8c..ee2ad8ae07af 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h | |||
@@ -217,6 +217,10 @@ extern struct meminfo meminfo; | |||
217 | #define bank_phys_end(bank) ((bank)->start + (bank)->size) | 217 | #define bank_phys_end(bank) ((bank)->start + (bank)->size) |
218 | #define bank_phys_size(bank) (bank)->size | 218 | #define bank_phys_size(bank) (bank)->size |
219 | 219 | ||
220 | extern int arm_add_memory(phys_addr_t start, unsigned long size); | ||
221 | extern void early_print(const char *str, ...); | ||
222 | extern void dump_machine_table(void); | ||
223 | |||
220 | #endif /* __KERNEL__ */ | 224 | #endif /* __KERNEL__ */ |
221 | 225 | ||
222 | #endif | 226 | #endif |
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index d2b514fd76f4..e42d96a45d3e 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h | |||
@@ -70,6 +70,7 @@ extern void platform_smp_prepare_cpus(unsigned int); | |||
70 | */ | 70 | */ |
71 | struct secondary_data { | 71 | struct secondary_data { |
72 | unsigned long pgdir; | 72 | unsigned long pgdir; |
73 | unsigned long swapper_pg_dir; | ||
73 | void *stack; | 74 | void *stack; |
74 | }; | 75 | }; |
75 | extern struct secondary_data secondary_data; | 76 | extern struct secondary_data secondary_data; |
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 87dbe3e21970..2c04ed5efeb5 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
@@ -400,6 +400,8 @@ | |||
400 | #define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371) | 400 | #define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371) |
401 | #define __NR_clock_adjtime (__NR_SYSCALL_BASE+372) | 401 | #define __NR_clock_adjtime (__NR_SYSCALL_BASE+372) |
402 | #define __NR_syncfs (__NR_SYSCALL_BASE+373) | 402 | #define __NR_syncfs (__NR_SYSCALL_BASE+373) |
403 | #define __NR_sendmmsg (__NR_SYSCALL_BASE+374) | ||
404 | #define __NR_setns (__NR_SYSCALL_BASE+375) | ||
403 | 405 | ||
404 | /* | 406 | /* |
405 | * The following SWIs are ARM private. | 407 | * The following SWIs are ARM private. |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 8d95446150a3..a5b31af5c2b8 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -24,7 +24,7 @@ obj-$(CONFIG_OC_ETM) += etm.o | |||
24 | 24 | ||
25 | obj-$(CONFIG_ISA_DMA_API) += dma.o | 25 | obj-$(CONFIG_ISA_DMA_API) += dma.o |
26 | obj-$(CONFIG_ARCH_ACORN) += ecard.o | 26 | obj-$(CONFIG_ARCH_ACORN) += ecard.o |
27 | obj-$(CONFIG_FIQ) += fiq.o | 27 | obj-$(CONFIG_FIQ) += fiq.o fiqasm.o |
28 | obj-$(CONFIG_MODULES) += armksyms.o module.o | 28 | obj-$(CONFIG_MODULES) += armksyms.o module.o |
29 | obj-$(CONFIG_ARTHUR) += arthur.o | 29 | obj-$(CONFIG_ARTHUR) += arthur.o |
30 | obj-$(CONFIG_ISA_DMA) += dma-isa.o | 30 | obj-$(CONFIG_ISA_DMA) += dma-isa.o |
@@ -44,6 +44,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o | |||
44 | obj-$(CONFIG_KGDB) += kgdb.o | 44 | obj-$(CONFIG_KGDB) += kgdb.o |
45 | obj-$(CONFIG_ARM_UNWIND) += unwind.o | 45 | obj-$(CONFIG_ARM_UNWIND) += unwind.o |
46 | obj-$(CONFIG_HAVE_TCM) += tcm.o | 46 | obj-$(CONFIG_HAVE_TCM) += tcm.o |
47 | obj-$(CONFIG_OF) += devtree.o | ||
47 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 48 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
48 | obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o | 49 | obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o |
49 | CFLAGS_swp_emulate.o := -Wa,-march=armv7-a | 50 | CFLAGS_swp_emulate.o := -Wa,-march=armv7-a |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 7fbf28c35bb2..80f7896cc016 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -383,6 +383,8 @@ | |||
383 | CALL(sys_open_by_handle_at) | 383 | CALL(sys_open_by_handle_at) |
384 | CALL(sys_clock_adjtime) | 384 | CALL(sys_clock_adjtime) |
385 | CALL(sys_syncfs) | 385 | CALL(sys_syncfs) |
386 | CALL(sys_sendmmsg) | ||
387 | /* 375 */ CALL(sys_setns) | ||
386 | #ifndef syscalls_counted | 388 | #ifndef syscalls_counted |
387 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 389 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
388 | #define syscalls_counted | 390 | #define syscalls_counted |
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c new file mode 100644 index 000000000000..a701e4226a6c --- /dev/null +++ b/arch/arm/kernel/devtree.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/devtree.c | ||
3 | * | ||
4 | * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/bootmem.h> | ||
16 | #include <linux/memblock.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_fdt.h> | ||
19 | #include <linux/of_irq.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | |||
22 | #include <asm/setup.h> | ||
23 | #include <asm/page.h> | ||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/mach-types.h> | ||
26 | |||
27 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | ||
28 | { | ||
29 | arm_add_memory(base, size); | ||
30 | } | ||
31 | |||
32 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | ||
33 | { | ||
34 | return alloc_bootmem_align(size, align); | ||
35 | } | ||
36 | |||
37 | void __init arm_dt_memblock_reserve(void) | ||
38 | { | ||
39 | u64 *reserve_map, base, size; | ||
40 | |||
41 | if (!initial_boot_params) | ||
42 | return; | ||
43 | |||
44 | /* Reserve the dtb region */ | ||
45 | memblock_reserve(virt_to_phys(initial_boot_params), | ||
46 | be32_to_cpu(initial_boot_params->totalsize)); | ||
47 | |||
48 | /* | ||
49 | * Process the reserve map. This will probably overlap the initrd | ||
50 | * and dtb locations which are already reserved, but overlaping | ||
51 | * doesn't hurt anything | ||
52 | */ | ||
53 | reserve_map = ((void*)initial_boot_params) + | ||
54 | be32_to_cpu(initial_boot_params->off_mem_rsvmap); | ||
55 | while (1) { | ||
56 | base = be64_to_cpup(reserve_map++); | ||
57 | size = be64_to_cpup(reserve_map++); | ||
58 | if (!size) | ||
59 | break; | ||
60 | memblock_reserve(base, size); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel | ||
66 | * @dt_phys: physical address of dt blob | ||
67 | * | ||
68 | * If a dtb was passed to the kernel in r2, then use it to choose the | ||
69 | * correct machine_desc and to setup the system. | ||
70 | */ | ||
71 | struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) | ||
72 | { | ||
73 | struct boot_param_header *devtree; | ||
74 | struct machine_desc *mdesc, *mdesc_best = NULL; | ||
75 | unsigned int score, mdesc_score = ~1; | ||
76 | unsigned long dt_root; | ||
77 | const char *model; | ||
78 | |||
79 | devtree = phys_to_virt(dt_phys); | ||
80 | |||
81 | /* check device tree validity */ | ||
82 | if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) | ||
83 | return NULL; | ||
84 | |||
85 | /* Search the mdescs for the 'best' compatible value match */ | ||
86 | initial_boot_params = devtree; | ||
87 | dt_root = of_get_flat_dt_root(); | ||
88 | for_each_machine_desc(mdesc) { | ||
89 | score = of_flat_dt_match(dt_root, mdesc->dt_compat); | ||
90 | if (score > 0 && score < mdesc_score) { | ||
91 | mdesc_best = mdesc; | ||
92 | mdesc_score = score; | ||
93 | } | ||
94 | } | ||
95 | if (!mdesc_best) { | ||
96 | const char *prop; | ||
97 | long size; | ||
98 | |||
99 | early_print("\nError: unrecognized/unsupported " | ||
100 | "device tree compatible list:\n[ "); | ||
101 | |||
102 | prop = of_get_flat_dt_prop(dt_root, "compatible", &size); | ||
103 | while (size > 0) { | ||
104 | early_print("'%s' ", prop); | ||
105 | size -= strlen(prop) + 1; | ||
106 | prop += strlen(prop) + 1; | ||
107 | } | ||
108 | early_print("]\n\n"); | ||
109 | |||
110 | dump_machine_table(); /* does not return */ | ||
111 | } | ||
112 | |||
113 | model = of_get_flat_dt_prop(dt_root, "model", NULL); | ||
114 | if (!model) | ||
115 | model = of_get_flat_dt_prop(dt_root, "compatible", NULL); | ||
116 | if (!model) | ||
117 | model = "<unknown>"; | ||
118 | pr_info("Machine: %s, model: %s\n", mdesc_best->name, model); | ||
119 | |||
120 | /* Retrieve various information from the /chosen node */ | ||
121 | of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); | ||
122 | /* Initialize {size,address}-cells info */ | ||
123 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
124 | /* Setup memory, calling early_init_dt_add_memory_arch */ | ||
125 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
126 | |||
127 | /* Change machine number to match the mdesc we're using */ | ||
128 | __machine_arch_type = mdesc_best->nr; | ||
129 | |||
130 | return mdesc_best; | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# | ||
135 | * | ||
136 | * Currently the mapping mechanism is trivial; simple flat hwirq numbers are | ||
137 | * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not | ||
138 | * supported. | ||
139 | */ | ||
140 | unsigned int irq_create_of_mapping(struct device_node *controller, | ||
141 | const u32 *intspec, unsigned int intsize) | ||
142 | { | ||
143 | return intspec[0]; | ||
144 | } | ||
145 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | ||
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index e72dc34eea1c..4c164ece5891 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c | |||
@@ -89,47 +89,6 @@ void set_fiq_handler(void *start, unsigned int length) | |||
89 | flush_icache_range(0x1c, 0x1c + length); | 89 | flush_icache_range(0x1c, 0x1c + length); |
90 | } | 90 | } |
91 | 91 | ||
92 | /* | ||
93 | * Taking an interrupt in FIQ mode is death, so both these functions | ||
94 | * disable irqs for the duration. Note - these functions are almost | ||
95 | * entirely coded in assembly. | ||
96 | */ | ||
97 | void __naked set_fiq_regs(struct pt_regs *regs) | ||
98 | { | ||
99 | register unsigned long tmp; | ||
100 | asm volatile ( | ||
101 | "mov ip, sp\n\ | ||
102 | stmfd sp!, {fp, ip, lr, pc}\n\ | ||
103 | sub fp, ip, #4\n\ | ||
104 | mrs %0, cpsr\n\ | ||
105 | msr cpsr_c, %2 @ select FIQ mode\n\ | ||
106 | mov r0, r0\n\ | ||
107 | ldmia %1, {r8 - r14}\n\ | ||
108 | msr cpsr_c, %0 @ return to SVC mode\n\ | ||
109 | mov r0, r0\n\ | ||
110 | ldmfd sp, {fp, sp, pc}" | ||
111 | : "=&r" (tmp) | ||
112 | : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); | ||
113 | } | ||
114 | |||
115 | void __naked get_fiq_regs(struct pt_regs *regs) | ||
116 | { | ||
117 | register unsigned long tmp; | ||
118 | asm volatile ( | ||
119 | "mov ip, sp\n\ | ||
120 | stmfd sp!, {fp, ip, lr, pc}\n\ | ||
121 | sub fp, ip, #4\n\ | ||
122 | mrs %0, cpsr\n\ | ||
123 | msr cpsr_c, %2 @ select FIQ mode\n\ | ||
124 | mov r0, r0\n\ | ||
125 | stmia %1, {r8 - r14}\n\ | ||
126 | msr cpsr_c, %0 @ return to SVC mode\n\ | ||
127 | mov r0, r0\n\ | ||
128 | ldmfd sp, {fp, sp, pc}" | ||
129 | : "=&r" (tmp) | ||
130 | : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); | ||
131 | } | ||
132 | |||
133 | int claim_fiq(struct fiq_handler *f) | 92 | int claim_fiq(struct fiq_handler *f) |
134 | { | 93 | { |
135 | int ret = 0; | 94 | int ret = 0; |
@@ -174,8 +133,8 @@ void disable_fiq(int fiq) | |||
174 | } | 133 | } |
175 | 134 | ||
176 | EXPORT_SYMBOL(set_fiq_handler); | 135 | EXPORT_SYMBOL(set_fiq_handler); |
177 | EXPORT_SYMBOL(set_fiq_regs); | 136 | EXPORT_SYMBOL(__set_fiq_regs); /* defined in fiqasm.S */ |
178 | EXPORT_SYMBOL(get_fiq_regs); | 137 | EXPORT_SYMBOL(__get_fiq_regs); /* defined in fiqasm.S */ |
179 | EXPORT_SYMBOL(claim_fiq); | 138 | EXPORT_SYMBOL(claim_fiq); |
180 | EXPORT_SYMBOL(release_fiq); | 139 | EXPORT_SYMBOL(release_fiq); |
181 | EXPORT_SYMBOL(enable_fiq); | 140 | EXPORT_SYMBOL(enable_fiq); |
diff --git a/arch/arm/kernel/fiqasm.S b/arch/arm/kernel/fiqasm.S new file mode 100644 index 000000000000..207f9d652010 --- /dev/null +++ b/arch/arm/kernel/fiqasm.S | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/fiqasm.S | ||
3 | * | ||
4 | * Derived from code originally in linux/arch/arm/kernel/fiq.c: | ||
5 | * | ||
6 | * Copyright (C) 1998 Russell King | ||
7 | * Copyright (C) 1998, 1999 Phil Blundell | ||
8 | * Copyright (C) 2011, Linaro Limited | ||
9 | * | ||
10 | * FIQ support written by Philip Blundell <philb@gnu.org>, 1998. | ||
11 | * | ||
12 | * FIQ support re-written by Russell King to be more generic | ||
13 | * | ||
14 | * v7/Thumb-2 compatibility modifications by Linaro Limited, 2011. | ||
15 | */ | ||
16 | |||
17 | #include <linux/linkage.h> | ||
18 | #include <asm/assembler.h> | ||
19 | |||
20 | /* | ||
21 | * Taking an interrupt in FIQ mode is death, so both these functions | ||
22 | * disable irqs for the duration. | ||
23 | */ | ||
24 | |||
25 | ENTRY(__set_fiq_regs) | ||
26 | mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE | ||
27 | mrs r1, cpsr | ||
28 | msr cpsr_c, r2 @ select FIQ mode | ||
29 | mov r0, r0 @ avoid hazard prior to ARMv4 | ||
30 | ldmia r0!, {r8 - r12} | ||
31 | ldr sp, [r0], #4 | ||
32 | ldr lr, [r0] | ||
33 | msr cpsr_c, r1 @ return to SVC mode | ||
34 | mov r0, r0 @ avoid hazard prior to ARMv4 | ||
35 | mov pc, lr | ||
36 | ENDPROC(__set_fiq_regs) | ||
37 | |||
38 | ENTRY(__get_fiq_regs) | ||
39 | mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE | ||
40 | mrs r1, cpsr | ||
41 | msr cpsr_c, r2 @ select FIQ mode | ||
42 | mov r0, r0 @ avoid hazard prior to ARMv4 | ||
43 | stmia r0!, {r8 - r12} | ||
44 | str sp, [r0], #4 | ||
45 | str lr, [r0] | ||
46 | msr cpsr_c, r1 @ return to SVC mode | ||
47 | mov r0, r0 @ avoid hazard prior to ARMv4 | ||
48 | mov pc, lr | ||
49 | ENDPROC(__get_fiq_regs) | ||
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index c84b57d27d07..854bd22380d3 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -15,6 +15,12 @@ | |||
15 | #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) | 15 | #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) |
16 | #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) | 16 | #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) |
17 | 17 | ||
18 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
19 | #define OF_DT_MAGIC 0xd00dfeed | ||
20 | #else | ||
21 | #define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */ | ||
22 | #endif | ||
23 | |||
18 | /* | 24 | /* |
19 | * Exception handling. Something went wrong and we can't proceed. We | 25 | * Exception handling. Something went wrong and we can't proceed. We |
20 | * ought to tell the user, but since we don't have any guarantee that | 26 | * ought to tell the user, but since we don't have any guarantee that |
@@ -28,20 +34,26 @@ | |||
28 | 34 | ||
29 | /* Determine validity of the r2 atags pointer. The heuristic requires | 35 | /* Determine validity of the r2 atags pointer. The heuristic requires |
30 | * that the pointer be aligned, in the first 16k of physical RAM and | 36 | * that the pointer be aligned, in the first 16k of physical RAM and |
31 | * that the ATAG_CORE marker is first and present. Future revisions | 37 | * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE |
38 | * is selected, then it will also accept a dtb pointer. Future revisions | ||
32 | * of this function may be more lenient with the physical address and | 39 | * of this function may be more lenient with the physical address and |
33 | * may also be able to move the ATAGS block if necessary. | 40 | * may also be able to move the ATAGS block if necessary. |
34 | * | 41 | * |
35 | * Returns: | 42 | * Returns: |
36 | * r2 either valid atags pointer, or zero | 43 | * r2 either valid atags pointer, valid dtb pointer, or zero |
37 | * r5, r6 corrupted | 44 | * r5, r6 corrupted |
38 | */ | 45 | */ |
39 | __vet_atags: | 46 | __vet_atags: |
40 | tst r2, #0x3 @ aligned? | 47 | tst r2, #0x3 @ aligned? |
41 | bne 1f | 48 | bne 1f |
42 | 49 | ||
43 | ldr r5, [r2, #0] @ is first tag ATAG_CORE? | 50 | ldr r5, [r2, #0] |
44 | cmp r5, #ATAG_CORE_SIZE | 51 | #ifdef CONFIG_OF_FLATTREE |
52 | ldr r6, =OF_DT_MAGIC @ is it a DTB? | ||
53 | cmp r5, r6 | ||
54 | beq 2f | ||
55 | #endif | ||
56 | cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE? | ||
45 | cmpne r5, #ATAG_CORE_SIZE_EMPTY | 57 | cmpne r5, #ATAG_CORE_SIZE_EMPTY |
46 | bne 1f | 58 | bne 1f |
47 | ldr r5, [r2, #4] | 59 | ldr r5, [r2, #4] |
@@ -49,7 +61,7 @@ __vet_atags: | |||
49 | cmp r5, r6 | 61 | cmp r5, r6 |
50 | bne 1f | 62 | bne 1f |
51 | 63 | ||
52 | mov pc, lr @ atag pointer is ok | 64 | 2: mov pc, lr @ atag/dtb pointer is ok |
53 | 65 | ||
54 | 1: mov r2, #0 | 66 | 1: mov r2, #0 |
55 | mov pc, lr | 67 | mov pc, lr |
@@ -61,7 +73,7 @@ ENDPROC(__vet_atags) | |||
61 | * | 73 | * |
62 | * r0 = cp#15 control register | 74 | * r0 = cp#15 control register |
63 | * r1 = machine ID | 75 | * r1 = machine ID |
64 | * r2 = atags pointer | 76 | * r2 = atags/dtb pointer |
65 | * r9 = processor ID | 77 | * r9 = processor ID |
66 | */ | 78 | */ |
67 | __INIT | 79 | __INIT |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index c9173cfbbc74..278c1b0ebb2e 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -59,7 +59,7 @@ | |||
59 | * | 59 | * |
60 | * This is normally called from the decompressor code. The requirements | 60 | * This is normally called from the decompressor code. The requirements |
61 | * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, | 61 | * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, |
62 | * r1 = machine nr, r2 = atags pointer. | 62 | * r1 = machine nr, r2 = atags or dtb pointer. |
63 | * | 63 | * |
64 | * This code is mostly position independent, so if you link the kernel at | 64 | * This code is mostly position independent, so if you link the kernel at |
65 | * 0xc0008000, you call this at __pa(0xc0008000). | 65 | * 0xc0008000, you call this at __pa(0xc0008000). |
@@ -91,7 +91,7 @@ ENTRY(stext) | |||
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * r1 = machine no, r2 = atags, | 94 | * r1 = machine no, r2 = atags or dtb, |
95 | * r8 = phys_offset, r9 = cpuid, r10 = procinfo | 95 | * r8 = phys_offset, r9 = cpuid, r10 = procinfo |
96 | */ | 96 | */ |
97 | bl __vet_atags | 97 | bl __vet_atags |
@@ -113,6 +113,7 @@ ENTRY(stext) | |||
113 | ldr r13, =__mmap_switched @ address to jump to after | 113 | ldr r13, =__mmap_switched @ address to jump to after |
114 | @ mmu has been enabled | 114 | @ mmu has been enabled |
115 | adr lr, BSYM(1f) @ return (PIC) address | 115 | adr lr, BSYM(1f) @ return (PIC) address |
116 | mov r8, r4 @ set TTBR1 to swapper_pg_dir | ||
116 | ARM( add pc, r10, #PROCINFO_INITFUNC ) | 117 | ARM( add pc, r10, #PROCINFO_INITFUNC ) |
117 | THUMB( add r12, r10, #PROCINFO_INITFUNC ) | 118 | THUMB( add r12, r10, #PROCINFO_INITFUNC ) |
118 | THUMB( mov pc, r12 ) | 119 | THUMB( mov pc, r12 ) |
@@ -302,8 +303,10 @@ ENTRY(secondary_startup) | |||
302 | */ | 303 | */ |
303 | adr r4, __secondary_data | 304 | adr r4, __secondary_data |
304 | ldmia r4, {r5, r7, r12} @ address to jump to after | 305 | ldmia r4, {r5, r7, r12} @ address to jump to after |
305 | sub r4, r4, r5 @ mmu has been enabled | 306 | sub lr, r4, r5 @ mmu has been enabled |
306 | ldr r4, [r7, r4] @ get secondary_data.pgdir | 307 | ldr r4, [r7, lr] @ get secondary_data.pgdir |
308 | add r7, r7, #4 | ||
309 | ldr r8, [r7, lr] @ get secondary_data.swapper_pg_dir | ||
307 | adr lr, BSYM(__enable_mmu) @ return address | 310 | adr lr, BSYM(__enable_mmu) @ return address |
308 | mov r13, r12 @ __secondary_switched address | 311 | mov r13, r12 @ __secondary_switched address |
309 | ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor | 312 | ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor |
@@ -339,7 +342,7 @@ __secondary_data: | |||
339 | * | 342 | * |
340 | * r0 = cp#15 control register | 343 | * r0 = cp#15 control register |
341 | * r1 = machine ID | 344 | * r1 = machine ID |
342 | * r2 = atags pointer | 345 | * r2 = atags or dtb pointer |
343 | * r4 = page table pointer | 346 | * r4 = page table pointer |
344 | * r9 = processor ID | 347 | * r9 = processor ID |
345 | * r13 = *virtual* address to jump to upon completion | 348 | * r13 = *virtual* address to jump to upon completion |
@@ -376,7 +379,7 @@ ENDPROC(__enable_mmu) | |||
376 | * | 379 | * |
377 | * r0 = cp#15 control register | 380 | * r0 = cp#15 control register |
378 | * r1 = machine ID | 381 | * r1 = machine ID |
379 | * r2 = atags pointer | 382 | * r2 = atags or dtb pointer |
380 | * r9 = processor ID | 383 | * r9 = processor ID |
381 | * r13 = *virtual* address to jump to upon completion | 384 | * r13 = *virtual* address to jump to upon completion |
382 | * | 385 | * |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 6dce209a623b..ed11fb08b05a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/screen_info.h> | 20 | #include <linux/screen_info.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/kexec.h> | 22 | #include <linux/kexec.h> |
23 | #include <linux/of_fdt.h> | ||
23 | #include <linux/crash_dump.h> | 24 | #include <linux/crash_dump.h> |
24 | #include <linux/root_dev.h> | 25 | #include <linux/root_dev.h> |
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
@@ -42,6 +43,7 @@ | |||
42 | #include <asm/cachetype.h> | 43 | #include <asm/cachetype.h> |
43 | #include <asm/tlbflush.h> | 44 | #include <asm/tlbflush.h> |
44 | 45 | ||
46 | #include <asm/prom.h> | ||
45 | #include <asm/mach/arch.h> | 47 | #include <asm/mach/arch.h> |
46 | #include <asm/mach/irq.h> | 48 | #include <asm/mach/irq.h> |
47 | #include <asm/mach/time.h> | 49 | #include <asm/mach/time.h> |
@@ -309,7 +311,7 @@ static void __init cacheid_init(void) | |||
309 | */ | 311 | */ |
310 | extern struct proc_info_list *lookup_processor_type(unsigned int); | 312 | extern struct proc_info_list *lookup_processor_type(unsigned int); |
311 | 313 | ||
312 | static void __init early_print(const char *str, ...) | 314 | void __init early_print(const char *str, ...) |
313 | { | 315 | { |
314 | extern void printascii(const char *); | 316 | extern void printascii(const char *); |
315 | char buf[256]; | 317 | char buf[256]; |
@@ -439,25 +441,12 @@ void cpu_init(void) | |||
439 | : "r14"); | 441 | : "r14"); |
440 | } | 442 | } |
441 | 443 | ||
442 | static struct machine_desc * __init setup_machine(unsigned int nr) | 444 | void __init dump_machine_table(void) |
443 | { | 445 | { |
444 | extern struct machine_desc __arch_info_begin[], __arch_info_end[]; | ||
445 | struct machine_desc *p; | 446 | struct machine_desc *p; |
446 | 447 | ||
447 | /* | 448 | early_print("Available machine support:\n\nID (hex)\tNAME\n"); |
448 | * locate machine in the list of supported machines. | 449 | for_each_machine_desc(p) |
449 | */ | ||
450 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
451 | if (nr == p->nr) { | ||
452 | printk("Machine: %s\n", p->name); | ||
453 | return p; | ||
454 | } | ||
455 | |||
456 | early_print("\n" | ||
457 | "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n" | ||
458 | "Available machine support:\n\nID (hex)\tNAME\n", nr); | ||
459 | |||
460 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
461 | early_print("%08x\t%s\n", p->nr, p->name); | 450 | early_print("%08x\t%s\n", p->nr, p->name); |
462 | 451 | ||
463 | early_print("\nPlease check your kernel config and/or bootloader.\n"); | 452 | early_print("\nPlease check your kernel config and/or bootloader.\n"); |
@@ -466,7 +455,7 @@ static struct machine_desc * __init setup_machine(unsigned int nr) | |||
466 | /* can't use cpu_relax() here as it may require MMU setup */; | 455 | /* can't use cpu_relax() here as it may require MMU setup */; |
467 | } | 456 | } |
468 | 457 | ||
469 | static int __init arm_add_memory(phys_addr_t start, unsigned long size) | 458 | int __init arm_add_memory(phys_addr_t start, unsigned long size) |
470 | { | 459 | { |
471 | struct membank *bank = &meminfo.bank[meminfo.nr_banks]; | 460 | struct membank *bank = &meminfo.bank[meminfo.nr_banks]; |
472 | 461 | ||
@@ -801,23 +790,29 @@ static void __init squash_mem_tags(struct tag *tag) | |||
801 | tag->hdr.tag = ATAG_NONE; | 790 | tag->hdr.tag = ATAG_NONE; |
802 | } | 791 | } |
803 | 792 | ||
804 | void __init setup_arch(char **cmdline_p) | 793 | static struct machine_desc * __init setup_machine_tags(unsigned int nr) |
805 | { | 794 | { |
806 | struct tag *tags = (struct tag *)&init_tags; | 795 | struct tag *tags = (struct tag *)&init_tags; |
807 | struct machine_desc *mdesc; | 796 | struct machine_desc *mdesc = NULL, *p; |
808 | char *from = default_command_line; | 797 | char *from = default_command_line; |
809 | 798 | ||
810 | init_tags.mem.start = PHYS_OFFSET; | 799 | init_tags.mem.start = PHYS_OFFSET; |
811 | 800 | ||
812 | unwind_init(); | 801 | /* |
813 | 802 | * locate machine in the list of supported machines. | |
814 | setup_processor(); | 803 | */ |
815 | mdesc = setup_machine(machine_arch_type); | 804 | for_each_machine_desc(p) |
816 | machine_desc = mdesc; | 805 | if (nr == p->nr) { |
817 | machine_name = mdesc->name; | 806 | printk("Machine: %s\n", p->name); |
807 | mdesc = p; | ||
808 | break; | ||
809 | } | ||
818 | 810 | ||
819 | if (mdesc->soft_reboot) | 811 | if (!mdesc) { |
820 | reboot_setup("s"); | 812 | early_print("\nError: unrecognized/unsupported machine ID" |
813 | " (r1 = 0x%08x).\n\n", nr); | ||
814 | dump_machine_table(); /* does not return */ | ||
815 | } | ||
821 | 816 | ||
822 | if (__atags_pointer) | 817 | if (__atags_pointer) |
823 | tags = phys_to_virt(__atags_pointer); | 818 | tags = phys_to_virt(__atags_pointer); |
@@ -849,8 +844,17 @@ void __init setup_arch(char **cmdline_p) | |||
849 | if (tags->hdr.tag != ATAG_CORE) | 844 | if (tags->hdr.tag != ATAG_CORE) |
850 | convert_to_tag_list(tags); | 845 | convert_to_tag_list(tags); |
851 | #endif | 846 | #endif |
852 | if (tags->hdr.tag != ATAG_CORE) | 847 | |
848 | if (tags->hdr.tag != ATAG_CORE) { | ||
849 | #if defined(CONFIG_OF) | ||
850 | /* | ||
851 | * If CONFIG_OF is set, then assume this is a reasonably | ||
852 | * modern system that should pass boot parameters | ||
853 | */ | ||
854 | early_print("Warning: Neither atags nor dtb found\n"); | ||
855 | #endif | ||
853 | tags = (struct tag *)&init_tags; | 856 | tags = (struct tag *)&init_tags; |
857 | } | ||
854 | 858 | ||
855 | if (mdesc->fixup) | 859 | if (mdesc->fixup) |
856 | mdesc->fixup(mdesc, tags, &from, &meminfo); | 860 | mdesc->fixup(mdesc, tags, &from, &meminfo); |
@@ -862,14 +866,34 @@ void __init setup_arch(char **cmdline_p) | |||
862 | parse_tags(tags); | 866 | parse_tags(tags); |
863 | } | 867 | } |
864 | 868 | ||
869 | /* parse_early_param needs a boot_command_line */ | ||
870 | strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); | ||
871 | |||
872 | return mdesc; | ||
873 | } | ||
874 | |||
875 | |||
876 | void __init setup_arch(char **cmdline_p) | ||
877 | { | ||
878 | struct machine_desc *mdesc; | ||
879 | |||
880 | unwind_init(); | ||
881 | |||
882 | setup_processor(); | ||
883 | mdesc = setup_machine_fdt(__atags_pointer); | ||
884 | if (!mdesc) | ||
885 | mdesc = setup_machine_tags(machine_arch_type); | ||
886 | machine_desc = mdesc; | ||
887 | machine_name = mdesc->name; | ||
888 | |||
889 | if (mdesc->soft_reboot) | ||
890 | reboot_setup("s"); | ||
891 | |||
865 | init_mm.start_code = (unsigned long) _text; | 892 | init_mm.start_code = (unsigned long) _text; |
866 | init_mm.end_code = (unsigned long) _etext; | 893 | init_mm.end_code = (unsigned long) _etext; |
867 | init_mm.end_data = (unsigned long) _edata; | 894 | init_mm.end_data = (unsigned long) _edata; |
868 | init_mm.brk = (unsigned long) _end; | 895 | init_mm.brk = (unsigned long) _end; |
869 | 896 | ||
870 | /* parse_early_param needs a boot_command_line */ | ||
871 | strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); | ||
872 | |||
873 | /* populate cmd_line too for later use, preserving boot_command_line */ | 897 | /* populate cmd_line too for later use, preserving boot_command_line */ |
874 | strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); | 898 | strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); |
875 | *cmdline_p = cmd_line; | 899 | *cmdline_p = cmd_line; |
@@ -881,6 +905,8 @@ void __init setup_arch(char **cmdline_p) | |||
881 | paging_init(mdesc); | 905 | paging_init(mdesc); |
882 | request_standard_resources(mdesc); | 906 | request_standard_resources(mdesc); |
883 | 907 | ||
908 | unflatten_device_tree(); | ||
909 | |||
884 | #ifdef CONFIG_SMP | 910 | #ifdef CONFIG_SMP |
885 | if (is_smp()) | 911 | if (is_smp()) |
886 | smp_init_cpus(); | 912 | smp_init_cpus(); |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d439a8f4c078..344e52b16c8c 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -105,6 +105,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
105 | */ | 105 | */ |
106 | secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; | 106 | secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; |
107 | secondary_data.pgdir = virt_to_phys(pgd); | 107 | secondary_data.pgdir = virt_to_phys(pgd); |
108 | secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); | ||
108 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); | 109 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); |
109 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); | 110 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); |
110 | 111 | ||
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S index 6dc06487f3c3..c562f649734c 100644 --- a/arch/arm/lib/lib1funcs.S +++ b/arch/arm/lib/lib1funcs.S | |||
@@ -35,7 +35,7 @@ Boston, MA 02111-1307, USA. */ | |||
35 | 35 | ||
36 | #include <linux/linkage.h> | 36 | #include <linux/linkage.h> |
37 | #include <asm/assembler.h> | 37 | #include <asm/assembler.h> |
38 | 38 | #include <asm/unwind.h> | |
39 | 39 | ||
40 | .macro ARM_DIV_BODY dividend, divisor, result, curbit | 40 | .macro ARM_DIV_BODY dividend, divisor, result, curbit |
41 | 41 | ||
@@ -207,6 +207,7 @@ Boston, MA 02111-1307, USA. */ | |||
207 | 207 | ||
208 | ENTRY(__udivsi3) | 208 | ENTRY(__udivsi3) |
209 | ENTRY(__aeabi_uidiv) | 209 | ENTRY(__aeabi_uidiv) |
210 | UNWIND(.fnstart) | ||
210 | 211 | ||
211 | subs r2, r1, #1 | 212 | subs r2, r1, #1 |
212 | moveq pc, lr | 213 | moveq pc, lr |
@@ -230,10 +231,12 @@ ENTRY(__aeabi_uidiv) | |||
230 | mov r0, r0, lsr r2 | 231 | mov r0, r0, lsr r2 |
231 | mov pc, lr | 232 | mov pc, lr |
232 | 233 | ||
234 | UNWIND(.fnend) | ||
233 | ENDPROC(__udivsi3) | 235 | ENDPROC(__udivsi3) |
234 | ENDPROC(__aeabi_uidiv) | 236 | ENDPROC(__aeabi_uidiv) |
235 | 237 | ||
236 | ENTRY(__umodsi3) | 238 | ENTRY(__umodsi3) |
239 | UNWIND(.fnstart) | ||
237 | 240 | ||
238 | subs r2, r1, #1 @ compare divisor with 1 | 241 | subs r2, r1, #1 @ compare divisor with 1 |
239 | bcc Ldiv0 | 242 | bcc Ldiv0 |
@@ -247,10 +250,12 @@ ENTRY(__umodsi3) | |||
247 | 250 | ||
248 | mov pc, lr | 251 | mov pc, lr |
249 | 252 | ||
253 | UNWIND(.fnend) | ||
250 | ENDPROC(__umodsi3) | 254 | ENDPROC(__umodsi3) |
251 | 255 | ||
252 | ENTRY(__divsi3) | 256 | ENTRY(__divsi3) |
253 | ENTRY(__aeabi_idiv) | 257 | ENTRY(__aeabi_idiv) |
258 | UNWIND(.fnstart) | ||
254 | 259 | ||
255 | cmp r1, #0 | 260 | cmp r1, #0 |
256 | eor ip, r0, r1 @ save the sign of the result. | 261 | eor ip, r0, r1 @ save the sign of the result. |
@@ -287,10 +292,12 @@ ENTRY(__aeabi_idiv) | |||
287 | rsbmi r0, r0, #0 | 292 | rsbmi r0, r0, #0 |
288 | mov pc, lr | 293 | mov pc, lr |
289 | 294 | ||
295 | UNWIND(.fnend) | ||
290 | ENDPROC(__divsi3) | 296 | ENDPROC(__divsi3) |
291 | ENDPROC(__aeabi_idiv) | 297 | ENDPROC(__aeabi_idiv) |
292 | 298 | ||
293 | ENTRY(__modsi3) | 299 | ENTRY(__modsi3) |
300 | UNWIND(.fnstart) | ||
294 | 301 | ||
295 | cmp r1, #0 | 302 | cmp r1, #0 |
296 | beq Ldiv0 | 303 | beq Ldiv0 |
@@ -310,11 +317,14 @@ ENTRY(__modsi3) | |||
310 | rsbmi r0, r0, #0 | 317 | rsbmi r0, r0, #0 |
311 | mov pc, lr | 318 | mov pc, lr |
312 | 319 | ||
320 | UNWIND(.fnend) | ||
313 | ENDPROC(__modsi3) | 321 | ENDPROC(__modsi3) |
314 | 322 | ||
315 | #ifdef CONFIG_AEABI | 323 | #ifdef CONFIG_AEABI |
316 | 324 | ||
317 | ENTRY(__aeabi_uidivmod) | 325 | ENTRY(__aeabi_uidivmod) |
326 | UNWIND(.fnstart) | ||
327 | UNWIND(.save {r0, r1, ip, lr} ) | ||
318 | 328 | ||
319 | stmfd sp!, {r0, r1, ip, lr} | 329 | stmfd sp!, {r0, r1, ip, lr} |
320 | bl __aeabi_uidiv | 330 | bl __aeabi_uidiv |
@@ -323,10 +333,12 @@ ENTRY(__aeabi_uidivmod) | |||
323 | sub r1, r1, r3 | 333 | sub r1, r1, r3 |
324 | mov pc, lr | 334 | mov pc, lr |
325 | 335 | ||
336 | UNWIND(.fnend) | ||
326 | ENDPROC(__aeabi_uidivmod) | 337 | ENDPROC(__aeabi_uidivmod) |
327 | 338 | ||
328 | ENTRY(__aeabi_idivmod) | 339 | ENTRY(__aeabi_idivmod) |
329 | 340 | UNWIND(.fnstart) | |
341 | UNWIND(.save {r0, r1, ip, lr} ) | ||
330 | stmfd sp!, {r0, r1, ip, lr} | 342 | stmfd sp!, {r0, r1, ip, lr} |
331 | bl __aeabi_idiv | 343 | bl __aeabi_idiv |
332 | ldmfd sp!, {r1, r2, ip, lr} | 344 | ldmfd sp!, {r1, r2, ip, lr} |
@@ -334,15 +346,18 @@ ENTRY(__aeabi_idivmod) | |||
334 | sub r1, r1, r3 | 346 | sub r1, r1, r3 |
335 | mov pc, lr | 347 | mov pc, lr |
336 | 348 | ||
349 | UNWIND(.fnend) | ||
337 | ENDPROC(__aeabi_idivmod) | 350 | ENDPROC(__aeabi_idivmod) |
338 | 351 | ||
339 | #endif | 352 | #endif |
340 | 353 | ||
341 | Ldiv0: | 354 | Ldiv0: |
342 | 355 | UNWIND(.fnstart) | |
356 | UNWIND(.pad #4) | ||
357 | UNWIND(.save {lr}) | ||
343 | str lr, [sp, #-8]! | 358 | str lr, [sp, #-8]! |
344 | bl __div0 | 359 | bl __div0 |
345 | mov r0, #0 @ About as wrong as it could be. | 360 | mov r0, #0 @ About as wrong as it could be. |
346 | ldr pc, [sp], #8 | 361 | ldr pc, [sp], #8 |
347 | 362 | UNWIND(.fnend) | |
348 | 363 | ENDPROC(Ldiv0) | |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 2d299bf5d72f..22484670e7ba 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -3,9 +3,6 @@ if ARCH_AT91 | |||
3 | config HAVE_AT91_DATAFLASH_CARD | 3 | config HAVE_AT91_DATAFLASH_CARD |
4 | bool | 4 | bool |
5 | 5 | ||
6 | config HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
7 | bool | ||
8 | |||
9 | config HAVE_AT91_USART3 | 6 | config HAVE_AT91_USART3 |
10 | bool | 7 | bool |
11 | 8 | ||
@@ -85,11 +82,6 @@ config ARCH_AT91CAP9 | |||
85 | select HAVE_FB_ATMEL | 82 | select HAVE_FB_ATMEL |
86 | select HAVE_NET_MACB | 83 | select HAVE_NET_MACB |
87 | 84 | ||
88 | config ARCH_AT572D940HF | ||
89 | bool "AT572D940HF" | ||
90 | select CPU_ARM926T | ||
91 | select GENERIC_CLOCKEVENTS | ||
92 | |||
93 | config ARCH_AT91X40 | 85 | config ARCH_AT91X40 |
94 | bool "AT91x40" | 86 | bool "AT91x40" |
95 | select ARCH_USES_GETTIMEOFFSET | 87 | select ARCH_USES_GETTIMEOFFSET |
@@ -209,7 +201,6 @@ comment "AT91SAM9260 / AT91SAM9XE Board Type" | |||
209 | config MACH_AT91SAM9260EK | 201 | config MACH_AT91SAM9260EK |
210 | bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit" | 202 | bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit" |
211 | select HAVE_AT91_DATAFLASH_CARD | 203 | select HAVE_AT91_DATAFLASH_CARD |
212 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
213 | help | 204 | help |
214 | Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit | 205 | Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit |
215 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> | 206 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> |
@@ -270,7 +261,6 @@ comment "AT91SAM9261 Board Type" | |||
270 | config MACH_AT91SAM9261EK | 261 | config MACH_AT91SAM9261EK |
271 | bool "Atmel AT91SAM9261-EK Evaluation Kit" | 262 | bool "Atmel AT91SAM9261-EK Evaluation Kit" |
272 | select HAVE_AT91_DATAFLASH_CARD | 263 | select HAVE_AT91_DATAFLASH_CARD |
273 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
274 | help | 264 | help |
275 | Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. | 265 | Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. |
276 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820> | 266 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820> |
@@ -286,7 +276,6 @@ comment "AT91SAM9G10 Board Type" | |||
286 | config MACH_AT91SAM9G10EK | 276 | config MACH_AT91SAM9G10EK |
287 | bool "Atmel AT91SAM9G10-EK Evaluation Kit" | 277 | bool "Atmel AT91SAM9G10-EK Evaluation Kit" |
288 | select HAVE_AT91_DATAFLASH_CARD | 278 | select HAVE_AT91_DATAFLASH_CARD |
289 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
290 | help | 279 | help |
291 | Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit. | 280 | Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit. |
292 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588> | 281 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588> |
@@ -302,7 +291,6 @@ comment "AT91SAM9263 Board Type" | |||
302 | config MACH_AT91SAM9263EK | 291 | config MACH_AT91SAM9263EK |
303 | bool "Atmel AT91SAM9263-EK Evaluation Kit" | 292 | bool "Atmel AT91SAM9263-EK Evaluation Kit" |
304 | select HAVE_AT91_DATAFLASH_CARD | 293 | select HAVE_AT91_DATAFLASH_CARD |
305 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
306 | help | 294 | help |
307 | Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit. | 295 | Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit. |
308 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057> | 296 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057> |
@@ -343,7 +331,6 @@ comment "AT91SAM9G20 Board Type" | |||
343 | config MACH_AT91SAM9G20EK | 331 | config MACH_AT91SAM9G20EK |
344 | bool "Atmel AT91SAM9G20-EK Evaluation Kit" | 332 | bool "Atmel AT91SAM9G20-EK Evaluation Kit" |
345 | select HAVE_AT91_DATAFLASH_CARD | 333 | select HAVE_AT91_DATAFLASH_CARD |
346 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
347 | help | 334 | help |
348 | Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit | 335 | Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit |
349 | that embeds only one SD/MMC slot. | 336 | that embeds only one SD/MMC slot. |
@@ -351,7 +338,6 @@ config MACH_AT91SAM9G20EK | |||
351 | config MACH_AT91SAM9G20EK_2MMC | 338 | config MACH_AT91SAM9G20EK_2MMC |
352 | depends on MACH_AT91SAM9G20EK | 339 | depends on MACH_AT91SAM9G20EK |
353 | bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots" | 340 | bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots" |
354 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
355 | help | 341 | help |
356 | Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit | 342 | Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit |
357 | with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and | 343 | with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and |
@@ -416,7 +402,6 @@ comment "AT91SAM9G45 Board Type" | |||
416 | 402 | ||
417 | config MACH_AT91SAM9M10G45EK | 403 | config MACH_AT91SAM9M10G45EK |
418 | bool "Atmel AT91SAM9M10G45-EK Evaluation Kits" | 404 | bool "Atmel AT91SAM9M10G45-EK Evaluation Kits" |
419 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
420 | help | 405 | help |
421 | Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit. | 406 | Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit. |
422 | "ES" at the end of the name means that this board is an | 407 | "ES" at the end of the name means that this board is an |
@@ -433,7 +418,6 @@ comment "AT91CAP9 Board Type" | |||
433 | config MACH_AT91CAP9ADK | 418 | config MACH_AT91CAP9ADK |
434 | bool "Atmel AT91CAP9A-DK Evaluation Kit" | 419 | bool "Atmel AT91CAP9A-DK Evaluation Kit" |
435 | select HAVE_AT91_DATAFLASH_CARD | 420 | select HAVE_AT91_DATAFLASH_CARD |
436 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
437 | help | 421 | help |
438 | Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. | 422 | Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. |
439 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138> | 423 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138> |
@@ -442,23 +426,6 @@ endif | |||
442 | 426 | ||
443 | # ---------------------------------------------------------- | 427 | # ---------------------------------------------------------- |
444 | 428 | ||
445 | if ARCH_AT572D940HF | ||
446 | |||
447 | comment "AT572D940HF Board Type" | ||
448 | |||
449 | config MACH_AT572D940HFEB | ||
450 | bool "AT572D940HF-EK" | ||
451 | depends on ARCH_AT572D940HF | ||
452 | select HAVE_AT91_DATAFLASH_CARD | ||
453 | select HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
454 | help | ||
455 | Select this if you are using Atmel's AT572D940HF-EK evaluation kit. | ||
456 | <http://www.atmel.com/products/diopsis/default.asp> | ||
457 | |||
458 | endif | ||
459 | |||
460 | # ---------------------------------------------------------- | ||
461 | |||
462 | if ARCH_AT91X40 | 429 | if ARCH_AT91X40 |
463 | 430 | ||
464 | comment "AT91X40 Board Type" | 431 | comment "AT91X40 Board Type" |
@@ -483,13 +450,6 @@ config MTD_AT91_DATAFLASH_CARD | |||
483 | help | 450 | help |
484 | Enable support for the DataFlash card. | 451 | Enable support for the DataFlash card. |
485 | 452 | ||
486 | config MTD_NAND_ATMEL_BUSWIDTH_16 | ||
487 | bool "Enable 16-bit data bus interface to NAND flash" | ||
488 | depends on HAVE_NAND_ATMEL_BUSWIDTH_16 | ||
489 | help | ||
490 | On AT91SAM926x boards both types of NAND flash can be present | ||
491 | (8 and 16 bit data bus width). | ||
492 | |||
493 | # ---------------------------------------------------------- | 453 | # ---------------------------------------------------------- |
494 | 454 | ||
495 | comment "AT91 Feature Selections" | 455 | comment "AT91 Feature Selections" |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index a83835e0c185..96966231920c 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -19,7 +19,6 @@ obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devi | |||
19 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o | 19 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o |
20 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o | 20 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o |
21 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o | 21 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o |
22 | obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o | ||
23 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o | 22 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o |
24 | 23 | ||
25 | # AT91RM9200 board-specific support | 24 | # AT91RM9200 board-specific support |
@@ -78,9 +77,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o | |||
78 | # AT91CAP9 board-specific support | 77 | # AT91CAP9 board-specific support |
79 | obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o | 78 | obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o |
80 | 79 | ||
81 | # AT572D940HF board-specific support | ||
82 | obj-$(CONFIG_MACH_AT572D940HFEB) += board-at572d940hf_ek.o | ||
83 | |||
84 | # AT91X40 board-specific support | 80 | # AT91X40 board-specific support |
85 | obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o | 81 | obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o |
86 | 82 | ||
diff --git a/arch/arm/mach-at91/at572d940hf.c b/arch/arm/mach-at91/at572d940hf.c deleted file mode 100644 index a6b9c68c003a..000000000000 --- a/arch/arm/mach-at91/at572d940hf.c +++ /dev/null | |||
@@ -1,377 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at572d940hf.c | ||
3 | * | ||
4 | * Antonio R. Costa <costa.antonior@gmail.com> | ||
5 | * Copyright (C) 2008 Atmel | ||
6 | * | ||
7 | * Copyright (C) 2005 SAN People | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | |||
27 | #include <asm/mach/irq.h> | ||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | #include <mach/at572d940hf.h> | ||
31 | #include <mach/at91_pmc.h> | ||
32 | #include <mach/at91_rstc.h> | ||
33 | |||
34 | #include "generic.h" | ||
35 | #include "clock.h" | ||
36 | |||
37 | static struct map_desc at572d940hf_io_desc[] __initdata = { | ||
38 | { | ||
39 | .virtual = AT91_VA_BASE_SYS, | ||
40 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
41 | .length = SZ_16K, | ||
42 | .type = MT_DEVICE, | ||
43 | }, { | ||
44 | .virtual = AT91_IO_VIRT_BASE - AT572D940HF_SRAM_SIZE, | ||
45 | .pfn = __phys_to_pfn(AT572D940HF_SRAM_BASE), | ||
46 | .length = AT572D940HF_SRAM_SIZE, | ||
47 | .type = MT_DEVICE, | ||
48 | }, | ||
49 | }; | ||
50 | |||
51 | /* -------------------------------------------------------------------- | ||
52 | * Clocks | ||
53 | * -------------------------------------------------------------------- */ | ||
54 | |||
55 | /* | ||
56 | * The peripheral clocks. | ||
57 | */ | ||
58 | static struct clk pioA_clk = { | ||
59 | .name = "pioA_clk", | ||
60 | .pmc_mask = 1 << AT572D940HF_ID_PIOA, | ||
61 | .type = CLK_TYPE_PERIPHERAL, | ||
62 | }; | ||
63 | static struct clk pioB_clk = { | ||
64 | .name = "pioB_clk", | ||
65 | .pmc_mask = 1 << AT572D940HF_ID_PIOB, | ||
66 | .type = CLK_TYPE_PERIPHERAL, | ||
67 | }; | ||
68 | static struct clk pioC_clk = { | ||
69 | .name = "pioC_clk", | ||
70 | .pmc_mask = 1 << AT572D940HF_ID_PIOC, | ||
71 | .type = CLK_TYPE_PERIPHERAL, | ||
72 | }; | ||
73 | static struct clk macb_clk = { | ||
74 | .name = "macb_clk", | ||
75 | .pmc_mask = 1 << AT572D940HF_ID_EMAC, | ||
76 | .type = CLK_TYPE_PERIPHERAL, | ||
77 | }; | ||
78 | static struct clk usart0_clk = { | ||
79 | .name = "usart0_clk", | ||
80 | .pmc_mask = 1 << AT572D940HF_ID_US0, | ||
81 | .type = CLK_TYPE_PERIPHERAL, | ||
82 | }; | ||
83 | static struct clk usart1_clk = { | ||
84 | .name = "usart1_clk", | ||
85 | .pmc_mask = 1 << AT572D940HF_ID_US1, | ||
86 | .type = CLK_TYPE_PERIPHERAL, | ||
87 | }; | ||
88 | static struct clk usart2_clk = { | ||
89 | .name = "usart2_clk", | ||
90 | .pmc_mask = 1 << AT572D940HF_ID_US2, | ||
91 | .type = CLK_TYPE_PERIPHERAL, | ||
92 | }; | ||
93 | static struct clk mmc_clk = { | ||
94 | .name = "mci_clk", | ||
95 | .pmc_mask = 1 << AT572D940HF_ID_MCI, | ||
96 | .type = CLK_TYPE_PERIPHERAL, | ||
97 | }; | ||
98 | static struct clk udc_clk = { | ||
99 | .name = "udc_clk", | ||
100 | .pmc_mask = 1 << AT572D940HF_ID_UDP, | ||
101 | .type = CLK_TYPE_PERIPHERAL, | ||
102 | }; | ||
103 | static struct clk twi0_clk = { | ||
104 | .name = "twi0_clk", | ||
105 | .pmc_mask = 1 << AT572D940HF_ID_TWI0, | ||
106 | .type = CLK_TYPE_PERIPHERAL, | ||
107 | }; | ||
108 | static struct clk spi0_clk = { | ||
109 | .name = "spi0_clk", | ||
110 | .pmc_mask = 1 << AT572D940HF_ID_SPI0, | ||
111 | .type = CLK_TYPE_PERIPHERAL, | ||
112 | }; | ||
113 | static struct clk spi1_clk = { | ||
114 | .name = "spi1_clk", | ||
115 | .pmc_mask = 1 << AT572D940HF_ID_SPI1, | ||
116 | .type = CLK_TYPE_PERIPHERAL, | ||
117 | }; | ||
118 | static struct clk ssc0_clk = { | ||
119 | .name = "ssc0_clk", | ||
120 | .pmc_mask = 1 << AT572D940HF_ID_SSC0, | ||
121 | .type = CLK_TYPE_PERIPHERAL, | ||
122 | }; | ||
123 | static struct clk ssc1_clk = { | ||
124 | .name = "ssc1_clk", | ||
125 | .pmc_mask = 1 << AT572D940HF_ID_SSC1, | ||
126 | .type = CLK_TYPE_PERIPHERAL, | ||
127 | }; | ||
128 | static struct clk ssc2_clk = { | ||
129 | .name = "ssc2_clk", | ||
130 | .pmc_mask = 1 << AT572D940HF_ID_SSC2, | ||
131 | .type = CLK_TYPE_PERIPHERAL, | ||
132 | }; | ||
133 | static struct clk tc0_clk = { | ||
134 | .name = "tc0_clk", | ||
135 | .pmc_mask = 1 << AT572D940HF_ID_TC0, | ||
136 | .type = CLK_TYPE_PERIPHERAL, | ||
137 | }; | ||
138 | static struct clk tc1_clk = { | ||
139 | .name = "tc1_clk", | ||
140 | .pmc_mask = 1 << AT572D940HF_ID_TC1, | ||
141 | .type = CLK_TYPE_PERIPHERAL, | ||
142 | }; | ||
143 | static struct clk tc2_clk = { | ||
144 | .name = "tc2_clk", | ||
145 | .pmc_mask = 1 << AT572D940HF_ID_TC2, | ||
146 | .type = CLK_TYPE_PERIPHERAL, | ||
147 | }; | ||
148 | static struct clk ohci_clk = { | ||
149 | .name = "ohci_clk", | ||
150 | .pmc_mask = 1 << AT572D940HF_ID_UHP, | ||
151 | .type = CLK_TYPE_PERIPHERAL, | ||
152 | }; | ||
153 | static struct clk ssc3_clk = { | ||
154 | .name = "ssc3_clk", | ||
155 | .pmc_mask = 1 << AT572D940HF_ID_SSC3, | ||
156 | .type = CLK_TYPE_PERIPHERAL, | ||
157 | }; | ||
158 | static struct clk twi1_clk = { | ||
159 | .name = "twi1_clk", | ||
160 | .pmc_mask = 1 << AT572D940HF_ID_TWI1, | ||
161 | .type = CLK_TYPE_PERIPHERAL, | ||
162 | }; | ||
163 | static struct clk can0_clk = { | ||
164 | .name = "can0_clk", | ||
165 | .pmc_mask = 1 << AT572D940HF_ID_CAN0, | ||
166 | .type = CLK_TYPE_PERIPHERAL, | ||
167 | }; | ||
168 | static struct clk can1_clk = { | ||
169 | .name = "can1_clk", | ||
170 | .pmc_mask = 1 << AT572D940HF_ID_CAN1, | ||
171 | .type = CLK_TYPE_PERIPHERAL, | ||
172 | }; | ||
173 | static struct clk mAgicV_clk = { | ||
174 | .name = "mAgicV_clk", | ||
175 | .pmc_mask = 1 << AT572D940HF_ID_MSIRQ0, | ||
176 | .type = CLK_TYPE_PERIPHERAL, | ||
177 | }; | ||
178 | |||
179 | |||
180 | static struct clk *periph_clocks[] __initdata = { | ||
181 | &pioA_clk, | ||
182 | &pioB_clk, | ||
183 | &pioC_clk, | ||
184 | &macb_clk, | ||
185 | &usart0_clk, | ||
186 | &usart1_clk, | ||
187 | &usart2_clk, | ||
188 | &mmc_clk, | ||
189 | &udc_clk, | ||
190 | &twi0_clk, | ||
191 | &spi0_clk, | ||
192 | &spi1_clk, | ||
193 | &ssc0_clk, | ||
194 | &ssc1_clk, | ||
195 | &ssc2_clk, | ||
196 | &tc0_clk, | ||
197 | &tc1_clk, | ||
198 | &tc2_clk, | ||
199 | &ohci_clk, | ||
200 | &ssc3_clk, | ||
201 | &twi1_clk, | ||
202 | &can0_clk, | ||
203 | &can1_clk, | ||
204 | &mAgicV_clk, | ||
205 | /* irq0 .. irq2 */ | ||
206 | }; | ||
207 | |||
208 | /* | ||
209 | * The five programmable clocks. | ||
210 | * You must configure pin multiplexing to bring these signals out. | ||
211 | */ | ||
212 | static struct clk pck0 = { | ||
213 | .name = "pck0", | ||
214 | .pmc_mask = AT91_PMC_PCK0, | ||
215 | .type = CLK_TYPE_PROGRAMMABLE, | ||
216 | .id = 0, | ||
217 | }; | ||
218 | static struct clk pck1 = { | ||
219 | .name = "pck1", | ||
220 | .pmc_mask = AT91_PMC_PCK1, | ||
221 | .type = CLK_TYPE_PROGRAMMABLE, | ||
222 | .id = 1, | ||
223 | }; | ||
224 | static struct clk pck2 = { | ||
225 | .name = "pck2", | ||
226 | .pmc_mask = AT91_PMC_PCK2, | ||
227 | .type = CLK_TYPE_PROGRAMMABLE, | ||
228 | .id = 2, | ||
229 | }; | ||
230 | static struct clk pck3 = { | ||
231 | .name = "pck3", | ||
232 | .pmc_mask = AT91_PMC_PCK3, | ||
233 | .type = CLK_TYPE_PROGRAMMABLE, | ||
234 | .id = 3, | ||
235 | }; | ||
236 | |||
237 | static struct clk mAgicV_mem_clk = { | ||
238 | .name = "mAgicV_mem_clk", | ||
239 | .pmc_mask = AT91_PMC_PCK4, | ||
240 | .type = CLK_TYPE_PROGRAMMABLE, | ||
241 | .id = 4, | ||
242 | }; | ||
243 | |||
244 | /* HClocks */ | ||
245 | static struct clk hck0 = { | ||
246 | .name = "hck0", | ||
247 | .pmc_mask = AT91_PMC_HCK0, | ||
248 | .type = CLK_TYPE_SYSTEM, | ||
249 | .id = 0, | ||
250 | }; | ||
251 | static struct clk hck1 = { | ||
252 | .name = "hck1", | ||
253 | .pmc_mask = AT91_PMC_HCK1, | ||
254 | .type = CLK_TYPE_SYSTEM, | ||
255 | .id = 1, | ||
256 | }; | ||
257 | |||
258 | static void __init at572d940hf_register_clocks(void) | ||
259 | { | ||
260 | int i; | ||
261 | |||
262 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
263 | clk_register(periph_clocks[i]); | ||
264 | |||
265 | clk_register(&pck0); | ||
266 | clk_register(&pck1); | ||
267 | clk_register(&pck2); | ||
268 | clk_register(&pck3); | ||
269 | clk_register(&mAgicV_mem_clk); | ||
270 | |||
271 | clk_register(&hck0); | ||
272 | clk_register(&hck1); | ||
273 | } | ||
274 | |||
275 | /* -------------------------------------------------------------------- | ||
276 | * GPIO | ||
277 | * -------------------------------------------------------------------- */ | ||
278 | |||
279 | static struct at91_gpio_bank at572d940hf_gpio[] = { | ||
280 | { | ||
281 | .id = AT572D940HF_ID_PIOA, | ||
282 | .offset = AT91_PIOA, | ||
283 | .clock = &pioA_clk, | ||
284 | }, { | ||
285 | .id = AT572D940HF_ID_PIOB, | ||
286 | .offset = AT91_PIOB, | ||
287 | .clock = &pioB_clk, | ||
288 | }, { | ||
289 | .id = AT572D940HF_ID_PIOC, | ||
290 | .offset = AT91_PIOC, | ||
291 | .clock = &pioC_clk, | ||
292 | } | ||
293 | }; | ||
294 | |||
295 | static void at572d940hf_reset(void) | ||
296 | { | ||
297 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
298 | } | ||
299 | |||
300 | |||
301 | /* -------------------------------------------------------------------- | ||
302 | * AT572D940HF processor initialization | ||
303 | * -------------------------------------------------------------------- */ | ||
304 | |||
305 | void __init at572d940hf_initialize(unsigned long main_clock) | ||
306 | { | ||
307 | /* Map peripherals */ | ||
308 | iotable_init(at572d940hf_io_desc, ARRAY_SIZE(at572d940hf_io_desc)); | ||
309 | |||
310 | at91_arch_reset = at572d940hf_reset; | ||
311 | at91_extern_irq = (1 << AT572D940HF_ID_IRQ0) | (1 << AT572D940HF_ID_IRQ1) | ||
312 | | (1 << AT572D940HF_ID_IRQ2); | ||
313 | |||
314 | /* Init clock subsystem */ | ||
315 | at91_clock_init(main_clock); | ||
316 | |||
317 | /* Register the processor-specific clocks */ | ||
318 | at572d940hf_register_clocks(); | ||
319 | |||
320 | /* Register GPIO subsystem */ | ||
321 | at91_gpio_init(at572d940hf_gpio, 3); | ||
322 | } | ||
323 | |||
324 | /* -------------------------------------------------------------------- | ||
325 | * Interrupt initialization | ||
326 | * -------------------------------------------------------------------- */ | ||
327 | |||
328 | /* | ||
329 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
330 | */ | ||
331 | static unsigned int at572d940hf_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
332 | 7, /* Advanced Interrupt Controller */ | ||
333 | 7, /* System Peripherals */ | ||
334 | 0, /* Parallel IO Controller A */ | ||
335 | 0, /* Parallel IO Controller B */ | ||
336 | 0, /* Parallel IO Controller C */ | ||
337 | 3, /* Ethernet */ | ||
338 | 6, /* USART 0 */ | ||
339 | 6, /* USART 1 */ | ||
340 | 6, /* USART 2 */ | ||
341 | 0, /* Multimedia Card Interface */ | ||
342 | 4, /* USB Device Port */ | ||
343 | 0, /* Two-Wire Interface 0 */ | ||
344 | 6, /* Serial Peripheral Interface 0 */ | ||
345 | 6, /* Serial Peripheral Interface 1 */ | ||
346 | 5, /* Serial Synchronous Controller 0 */ | ||
347 | 5, /* Serial Synchronous Controller 1 */ | ||
348 | 5, /* Serial Synchronous Controller 2 */ | ||
349 | 0, /* Timer Counter 0 */ | ||
350 | 0, /* Timer Counter 1 */ | ||
351 | 0, /* Timer Counter 2 */ | ||
352 | 3, /* USB Host port */ | ||
353 | 3, /* Serial Synchronous Controller 3 */ | ||
354 | 0, /* Two-Wire Interface 1 */ | ||
355 | 0, /* CAN Controller 0 */ | ||
356 | 0, /* CAN Controller 1 */ | ||
357 | 0, /* mAgicV HALT line */ | ||
358 | 0, /* mAgicV SIRQ0 line */ | ||
359 | 0, /* mAgicV exception line */ | ||
360 | 0, /* mAgicV end of DMA line */ | ||
361 | 0, /* Advanced Interrupt Controller */ | ||
362 | 0, /* Advanced Interrupt Controller */ | ||
363 | 0, /* Advanced Interrupt Controller */ | ||
364 | }; | ||
365 | |||
366 | void __init at572d940hf_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
367 | { | ||
368 | if (!priority) | ||
369 | priority = at572d940hf_default_irq_priority; | ||
370 | |||
371 | /* Initialize the AIC interrupt controller */ | ||
372 | at91_aic_init(priority); | ||
373 | |||
374 | /* Enable GPIO interrupts */ | ||
375 | at91_gpio_irq_setup(); | ||
376 | } | ||
377 | |||
diff --git a/arch/arm/mach-at91/at572d940hf_devices.c b/arch/arm/mach-at91/at572d940hf_devices.c deleted file mode 100644 index 0fc20a240782..000000000000 --- a/arch/arm/mach-at91/at572d940hf_devices.c +++ /dev/null | |||
@@ -1,970 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at572d940hf_devices.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com> | ||
5 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | ||
6 | * Copyright (C) 2005 David Brownell | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/mach/map.h> | ||
26 | |||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | |||
30 | #include <mach/board.h> | ||
31 | #include <mach/gpio.h> | ||
32 | #include <mach/at572d940hf.h> | ||
33 | #include <mach/at572d940hf_matrix.h> | ||
34 | #include <mach/at91sam9_smc.h> | ||
35 | |||
36 | #include "generic.h" | ||
37 | #include "sam9_smc.h" | ||
38 | |||
39 | |||
40 | /* -------------------------------------------------------------------- | ||
41 | * USB Host | ||
42 | * -------------------------------------------------------------------- */ | ||
43 | |||
44 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
45 | static u64 ohci_dmamask = DMA_BIT_MASK(32); | ||
46 | static struct at91_usbh_data usbh_data; | ||
47 | |||
48 | static struct resource usbh_resources[] = { | ||
49 | [0] = { | ||
50 | .start = AT572D940HF_UHP_BASE, | ||
51 | .end = AT572D940HF_UHP_BASE + SZ_1M - 1, | ||
52 | .flags = IORESOURCE_MEM, | ||
53 | }, | ||
54 | [1] = { | ||
55 | .start = AT572D940HF_ID_UHP, | ||
56 | .end = AT572D940HF_ID_UHP, | ||
57 | .flags = IORESOURCE_IRQ, | ||
58 | }, | ||
59 | }; | ||
60 | |||
61 | static struct platform_device at572d940hf_usbh_device = { | ||
62 | .name = "at91_ohci", | ||
63 | .id = -1, | ||
64 | .dev = { | ||
65 | .dma_mask = &ohci_dmamask, | ||
66 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
67 | .platform_data = &usbh_data, | ||
68 | }, | ||
69 | .resource = usbh_resources, | ||
70 | .num_resources = ARRAY_SIZE(usbh_resources), | ||
71 | }; | ||
72 | |||
73 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | ||
74 | { | ||
75 | if (!data) | ||
76 | return; | ||
77 | |||
78 | usbh_data = *data; | ||
79 | platform_device_register(&at572d940hf_usbh_device); | ||
80 | |||
81 | } | ||
82 | #else | ||
83 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | ||
84 | #endif | ||
85 | |||
86 | |||
87 | /* -------------------------------------------------------------------- | ||
88 | * USB Device (Gadget) | ||
89 | * -------------------------------------------------------------------- */ | ||
90 | |||
91 | #ifdef CONFIG_USB_GADGET_AT91 | ||
92 | static struct at91_udc_data udc_data; | ||
93 | |||
94 | static struct resource udc_resources[] = { | ||
95 | [0] = { | ||
96 | .start = AT572D940HF_BASE_UDP, | ||
97 | .end = AT572D940HF_BASE_UDP + SZ_16K - 1, | ||
98 | .flags = IORESOURCE_MEM, | ||
99 | }, | ||
100 | [1] = { | ||
101 | .start = AT572D940HF_ID_UDP, | ||
102 | .end = AT572D940HF_ID_UDP, | ||
103 | .flags = IORESOURCE_IRQ, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | static struct platform_device at572d940hf_udc_device = { | ||
108 | .name = "at91_udc", | ||
109 | .id = -1, | ||
110 | .dev = { | ||
111 | .platform_data = &udc_data, | ||
112 | }, | ||
113 | .resource = udc_resources, | ||
114 | .num_resources = ARRAY_SIZE(udc_resources), | ||
115 | }; | ||
116 | |||
117 | void __init at91_add_device_udc(struct at91_udc_data *data) | ||
118 | { | ||
119 | if (!data) | ||
120 | return; | ||
121 | |||
122 | if (data->vbus_pin) { | ||
123 | at91_set_gpio_input(data->vbus_pin, 0); | ||
124 | at91_set_deglitch(data->vbus_pin, 1); | ||
125 | } | ||
126 | |||
127 | /* Pullup pin is handled internally */ | ||
128 | |||
129 | udc_data = *data; | ||
130 | platform_device_register(&at572d940hf_udc_device); | ||
131 | } | ||
132 | #else | ||
133 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | ||
134 | #endif | ||
135 | |||
136 | |||
137 | /* -------------------------------------------------------------------- | ||
138 | * Ethernet | ||
139 | * -------------------------------------------------------------------- */ | ||
140 | |||
141 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | ||
142 | static u64 eth_dmamask = DMA_BIT_MASK(32); | ||
143 | static struct at91_eth_data eth_data; | ||
144 | |||
145 | static struct resource eth_resources[] = { | ||
146 | [0] = { | ||
147 | .start = AT572D940HF_BASE_EMAC, | ||
148 | .end = AT572D940HF_BASE_EMAC + SZ_16K - 1, | ||
149 | .flags = IORESOURCE_MEM, | ||
150 | }, | ||
151 | [1] = { | ||
152 | .start = AT572D940HF_ID_EMAC, | ||
153 | .end = AT572D940HF_ID_EMAC, | ||
154 | .flags = IORESOURCE_IRQ, | ||
155 | }, | ||
156 | }; | ||
157 | |||
158 | static struct platform_device at572d940hf_eth_device = { | ||
159 | .name = "macb", | ||
160 | .id = -1, | ||
161 | .dev = { | ||
162 | .dma_mask = ð_dmamask, | ||
163 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
164 | .platform_data = ð_data, | ||
165 | }, | ||
166 | .resource = eth_resources, | ||
167 | .num_resources = ARRAY_SIZE(eth_resources), | ||
168 | }; | ||
169 | |||
170 | void __init at91_add_device_eth(struct at91_eth_data *data) | ||
171 | { | ||
172 | if (!data) | ||
173 | return; | ||
174 | |||
175 | if (data->phy_irq_pin) { | ||
176 | at91_set_gpio_input(data->phy_irq_pin, 0); | ||
177 | at91_set_deglitch(data->phy_irq_pin, 1); | ||
178 | } | ||
179 | |||
180 | /* Only RMII is supported */ | ||
181 | data->is_rmii = 1; | ||
182 | |||
183 | /* Pins used for RMII */ | ||
184 | at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXCK_EREFCK */ | ||
185 | at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */ | ||
186 | at91_set_A_periph(AT91_PIN_PA18, 0); /* ERX0 */ | ||
187 | at91_set_A_periph(AT91_PIN_PA19, 0); /* ERX1 */ | ||
188 | at91_set_A_periph(AT91_PIN_PA20, 0); /* ERXER */ | ||
189 | at91_set_A_periph(AT91_PIN_PA23, 0); /* ETXEN */ | ||
190 | at91_set_A_periph(AT91_PIN_PA21, 0); /* ETX0 */ | ||
191 | at91_set_A_periph(AT91_PIN_PA22, 0); /* ETX1 */ | ||
192 | at91_set_A_periph(AT91_PIN_PA13, 0); /* EMDIO */ | ||
193 | at91_set_A_periph(AT91_PIN_PA14, 0); /* EMDC */ | ||
194 | |||
195 | eth_data = *data; | ||
196 | platform_device_register(&at572d940hf_eth_device); | ||
197 | } | ||
198 | #else | ||
199 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | ||
200 | #endif | ||
201 | |||
202 | |||
203 | /* -------------------------------------------------------------------- | ||
204 | * MMC / SD | ||
205 | * -------------------------------------------------------------------- */ | ||
206 | |||
207 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | ||
208 | static u64 mmc_dmamask = DMA_BIT_MASK(32); | ||
209 | static struct at91_mmc_data mmc_data; | ||
210 | |||
211 | static struct resource mmc_resources[] = { | ||
212 | [0] = { | ||
213 | .start = AT572D940HF_BASE_MCI, | ||
214 | .end = AT572D940HF_BASE_MCI + SZ_16K - 1, | ||
215 | .flags = IORESOURCE_MEM, | ||
216 | }, | ||
217 | [1] = { | ||
218 | .start = AT572D940HF_ID_MCI, | ||
219 | .end = AT572D940HF_ID_MCI, | ||
220 | .flags = IORESOURCE_IRQ, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | static struct platform_device at572d940hf_mmc_device = { | ||
225 | .name = "at91_mci", | ||
226 | .id = -1, | ||
227 | .dev = { | ||
228 | .dma_mask = &mmc_dmamask, | ||
229 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
230 | .platform_data = &mmc_data, | ||
231 | }, | ||
232 | .resource = mmc_resources, | ||
233 | .num_resources = ARRAY_SIZE(mmc_resources), | ||
234 | }; | ||
235 | |||
236 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | ||
237 | { | ||
238 | if (!data) | ||
239 | return; | ||
240 | |||
241 | /* input/irq */ | ||
242 | if (data->det_pin) { | ||
243 | at91_set_gpio_input(data->det_pin, 1); | ||
244 | at91_set_deglitch(data->det_pin, 1); | ||
245 | } | ||
246 | if (data->wp_pin) | ||
247 | at91_set_gpio_input(data->wp_pin, 1); | ||
248 | if (data->vcc_pin) | ||
249 | at91_set_gpio_output(data->vcc_pin, 0); | ||
250 | |||
251 | /* CLK */ | ||
252 | at91_set_A_periph(AT91_PIN_PC22, 0); | ||
253 | |||
254 | /* CMD */ | ||
255 | at91_set_A_periph(AT91_PIN_PC23, 1); | ||
256 | |||
257 | /* DAT0, maybe DAT1..DAT3 */ | ||
258 | at91_set_A_periph(AT91_PIN_PC24, 1); | ||
259 | if (data->wire4) { | ||
260 | at91_set_A_periph(AT91_PIN_PC25, 1); | ||
261 | at91_set_A_periph(AT91_PIN_PC26, 1); | ||
262 | at91_set_A_periph(AT91_PIN_PC27, 1); | ||
263 | } | ||
264 | |||
265 | mmc_data = *data; | ||
266 | platform_device_register(&at572d940hf_mmc_device); | ||
267 | } | ||
268 | #else | ||
269 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} | ||
270 | #endif | ||
271 | |||
272 | |||
273 | /* -------------------------------------------------------------------- | ||
274 | * NAND / SmartMedia | ||
275 | * -------------------------------------------------------------------- */ | ||
276 | |||
277 | #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) | ||
278 | static struct atmel_nand_data nand_data; | ||
279 | |||
280 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
281 | |||
282 | static struct resource nand_resources[] = { | ||
283 | { | ||
284 | .start = NAND_BASE, | ||
285 | .end = NAND_BASE + SZ_256M - 1, | ||
286 | .flags = IORESOURCE_MEM, | ||
287 | } | ||
288 | }; | ||
289 | |||
290 | static struct platform_device at572d940hf_nand_device = { | ||
291 | .name = "atmel_nand", | ||
292 | .id = -1, | ||
293 | .dev = { | ||
294 | .platform_data = &nand_data, | ||
295 | }, | ||
296 | .resource = nand_resources, | ||
297 | .num_resources = ARRAY_SIZE(nand_resources), | ||
298 | }; | ||
299 | |||
300 | void __init at91_add_device_nand(struct atmel_nand_data *data) | ||
301 | { | ||
302 | unsigned long csa; | ||
303 | |||
304 | if (!data) | ||
305 | return; | ||
306 | |||
307 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
308 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); | ||
309 | |||
310 | /* enable pin */ | ||
311 | if (data->enable_pin) | ||
312 | at91_set_gpio_output(data->enable_pin, 1); | ||
313 | |||
314 | /* ready/busy pin */ | ||
315 | if (data->rdy_pin) | ||
316 | at91_set_gpio_input(data->rdy_pin, 1); | ||
317 | |||
318 | /* card detect pin */ | ||
319 | if (data->det_pin) | ||
320 | at91_set_gpio_input(data->det_pin, 1); | ||
321 | |||
322 | at91_set_A_periph(AT91_PIN_PB28, 0); /* A[22] */ | ||
323 | at91_set_B_periph(AT91_PIN_PA28, 0); /* NANDOE */ | ||
324 | at91_set_B_periph(AT91_PIN_PA29, 0); /* NANDWE */ | ||
325 | |||
326 | nand_data = *data; | ||
327 | platform_device_register(&at572d940hf_nand_device); | ||
328 | } | ||
329 | |||
330 | #else | ||
331 | void __init at91_add_device_nand(struct atmel_nand_data *data) {} | ||
332 | #endif | ||
333 | |||
334 | |||
335 | /* -------------------------------------------------------------------- | ||
336 | * TWI (i2c) | ||
337 | * -------------------------------------------------------------------- */ | ||
338 | |||
339 | /* | ||
340 | * Prefer the GPIO code since the TWI controller isn't robust | ||
341 | * (gets overruns and underruns under load) and can only issue | ||
342 | * repeated STARTs in one scenario (the driver doesn't yet handle them). | ||
343 | */ | ||
344 | |||
345 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
346 | |||
347 | static struct i2c_gpio_platform_data pdata = { | ||
348 | .sda_pin = AT91_PIN_PC7, | ||
349 | .sda_is_open_drain = 1, | ||
350 | .scl_pin = AT91_PIN_PC8, | ||
351 | .scl_is_open_drain = 1, | ||
352 | .udelay = 2, /* ~100 kHz */ | ||
353 | }; | ||
354 | |||
355 | static struct platform_device at572d940hf_twi_device { | ||
356 | .name = "i2c-gpio", | ||
357 | .id = -1, | ||
358 | .dev.platform_data = &pdata, | ||
359 | }; | ||
360 | |||
361 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | ||
362 | { | ||
363 | at91_set_GPIO_periph(AT91_PIN_PC7, 1); /* TWD (SDA) */ | ||
364 | at91_set_multi_drive(AT91_PIN_PC7, 1); | ||
365 | |||
366 | at91_set_GPIO_periph(AT91_PIN_PA8, 1); /* TWCK (SCL) */ | ||
367 | at91_set_multi_drive(AT91_PIN_PC8, 1); | ||
368 | |||
369 | i2c_register_board_info(0, devices, nr_devices); | ||
370 | platform_device_register(&at572d940hf_twi_device); | ||
371 | } | ||
372 | |||
373 | #elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
374 | |||
375 | static struct resource twi0_resources[] = { | ||
376 | [0] = { | ||
377 | .start = AT572D940HF_BASE_TWI0, | ||
378 | .end = AT572D940HF_BASE_TWI0 + SZ_16K - 1, | ||
379 | .flags = IORESOURCE_MEM, | ||
380 | }, | ||
381 | [1] = { | ||
382 | .start = AT572D940HF_ID_TWI0, | ||
383 | .end = AT572D940HF_ID_TWI0, | ||
384 | .flags = IORESOURCE_IRQ, | ||
385 | }, | ||
386 | }; | ||
387 | |||
388 | static struct platform_device at572d940hf_twi0_device = { | ||
389 | .name = "at91_i2c", | ||
390 | .id = 0, | ||
391 | .resource = twi0_resources, | ||
392 | .num_resources = ARRAY_SIZE(twi0_resources), | ||
393 | }; | ||
394 | |||
395 | static struct resource twi1_resources[] = { | ||
396 | [0] = { | ||
397 | .start = AT572D940HF_BASE_TWI1, | ||
398 | .end = AT572D940HF_BASE_TWI1 + SZ_16K - 1, | ||
399 | .flags = IORESOURCE_MEM, | ||
400 | }, | ||
401 | [1] = { | ||
402 | .start = AT572D940HF_ID_TWI1, | ||
403 | .end = AT572D940HF_ID_TWI1, | ||
404 | .flags = IORESOURCE_IRQ, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | static struct platform_device at572d940hf_twi1_device = { | ||
409 | .name = "at91_i2c", | ||
410 | .id = 1, | ||
411 | .resource = twi1_resources, | ||
412 | .num_resources = ARRAY_SIZE(twi1_resources), | ||
413 | }; | ||
414 | |||
415 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | ||
416 | { | ||
417 | /* pins used for TWI0 interface */ | ||
418 | at91_set_A_periph(AT91_PIN_PC7, 0); /* TWD */ | ||
419 | at91_set_multi_drive(AT91_PIN_PC7, 1); | ||
420 | |||
421 | at91_set_A_periph(AT91_PIN_PC8, 0); /* TWCK */ | ||
422 | at91_set_multi_drive(AT91_PIN_PC8, 1); | ||
423 | |||
424 | /* pins used for TWI1 interface */ | ||
425 | at91_set_A_periph(AT91_PIN_PC20, 0); /* TWD */ | ||
426 | at91_set_multi_drive(AT91_PIN_PC20, 1); | ||
427 | |||
428 | at91_set_A_periph(AT91_PIN_PC21, 0); /* TWCK */ | ||
429 | at91_set_multi_drive(AT91_PIN_PC21, 1); | ||
430 | |||
431 | i2c_register_board_info(0, devices, nr_devices); | ||
432 | platform_device_register(&at572d940hf_twi0_device); | ||
433 | platform_device_register(&at572d940hf_twi1_device); | ||
434 | } | ||
435 | #else | ||
436 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} | ||
437 | #endif | ||
438 | |||
439 | |||
440 | /* -------------------------------------------------------------------- | ||
441 | * SPI | ||
442 | * -------------------------------------------------------------------- */ | ||
443 | |||
444 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
445 | static u64 spi_dmamask = DMA_BIT_MASK(32); | ||
446 | |||
447 | static struct resource spi0_resources[] = { | ||
448 | [0] = { | ||
449 | .start = AT572D940HF_BASE_SPI0, | ||
450 | .end = AT572D940HF_BASE_SPI0 + SZ_16K - 1, | ||
451 | .flags = IORESOURCE_MEM, | ||
452 | }, | ||
453 | [1] = { | ||
454 | .start = AT572D940HF_ID_SPI0, | ||
455 | .end = AT572D940HF_ID_SPI0, | ||
456 | .flags = IORESOURCE_IRQ, | ||
457 | }, | ||
458 | }; | ||
459 | |||
460 | static struct platform_device at572d940hf_spi0_device = { | ||
461 | .name = "atmel_spi", | ||
462 | .id = 0, | ||
463 | .dev = { | ||
464 | .dma_mask = &spi_dmamask, | ||
465 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
466 | }, | ||
467 | .resource = spi0_resources, | ||
468 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
469 | }; | ||
470 | |||
471 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; | ||
472 | |||
473 | static struct resource spi1_resources[] = { | ||
474 | [0] = { | ||
475 | .start = AT572D940HF_BASE_SPI1, | ||
476 | .end = AT572D940HF_BASE_SPI1 + SZ_16K - 1, | ||
477 | .flags = IORESOURCE_MEM, | ||
478 | }, | ||
479 | [1] = { | ||
480 | .start = AT572D940HF_ID_SPI1, | ||
481 | .end = AT572D940HF_ID_SPI1, | ||
482 | .flags = IORESOURCE_IRQ, | ||
483 | }, | ||
484 | }; | ||
485 | |||
486 | static struct platform_device at572d940hf_spi1_device = { | ||
487 | .name = "atmel_spi", | ||
488 | .id = 1, | ||
489 | .dev = { | ||
490 | .dma_mask = &spi_dmamask, | ||
491 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
492 | }, | ||
493 | .resource = spi1_resources, | ||
494 | .num_resources = ARRAY_SIZE(spi1_resources), | ||
495 | }; | ||
496 | |||
497 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PC3, AT91_PIN_PC4, AT91_PIN_PC5, AT91_PIN_PC6 }; | ||
498 | |||
499 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
500 | { | ||
501 | int i; | ||
502 | unsigned long cs_pin; | ||
503 | short enable_spi0 = 0; | ||
504 | short enable_spi1 = 0; | ||
505 | |||
506 | /* Choose SPI chip-selects */ | ||
507 | for (i = 0; i < nr_devices; i++) { | ||
508 | if (devices[i].controller_data) | ||
509 | cs_pin = (unsigned long) devices[i].controller_data; | ||
510 | else if (devices[i].bus_num == 0) | ||
511 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | ||
512 | else | ||
513 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | ||
514 | |||
515 | if (devices[i].bus_num == 0) | ||
516 | enable_spi0 = 1; | ||
517 | else | ||
518 | enable_spi1 = 1; | ||
519 | |||
520 | /* enable chip-select pin */ | ||
521 | at91_set_gpio_output(cs_pin, 1); | ||
522 | |||
523 | /* pass chip-select pin to driver */ | ||
524 | devices[i].controller_data = (void *) cs_pin; | ||
525 | } | ||
526 | |||
527 | spi_register_board_info(devices, nr_devices); | ||
528 | |||
529 | /* Configure SPI bus(es) */ | ||
530 | if (enable_spi0) { | ||
531 | at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ | ||
532 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | ||
533 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ | ||
534 | |||
535 | at91_clock_associate("spi0_clk", &at572d940hf_spi0_device.dev, "spi_clk"); | ||
536 | platform_device_register(&at572d940hf_spi0_device); | ||
537 | } | ||
538 | if (enable_spi1) { | ||
539 | at91_set_A_periph(AT91_PIN_PC0, 0); /* SPI1_MISO */ | ||
540 | at91_set_A_periph(AT91_PIN_PC1, 0); /* SPI1_MOSI */ | ||
541 | at91_set_A_periph(AT91_PIN_PC2, 0); /* SPI1_SPCK */ | ||
542 | |||
543 | at91_clock_associate("spi1_clk", &at572d940hf_spi1_device.dev, "spi_clk"); | ||
544 | platform_device_register(&at572d940hf_spi1_device); | ||
545 | } | ||
546 | } | ||
547 | #else | ||
548 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
549 | #endif | ||
550 | |||
551 | |||
552 | /* -------------------------------------------------------------------- | ||
553 | * Timer/Counter blocks | ||
554 | * -------------------------------------------------------------------- */ | ||
555 | |||
556 | #ifdef CONFIG_ATMEL_TCLIB | ||
557 | |||
558 | static struct resource tcb_resources[] = { | ||
559 | [0] = { | ||
560 | .start = AT572D940HF_BASE_TCB, | ||
561 | .end = AT572D940HF_BASE_TCB + SZ_16K - 1, | ||
562 | .flags = IORESOURCE_MEM, | ||
563 | }, | ||
564 | [1] = { | ||
565 | .start = AT572D940HF_ID_TC0, | ||
566 | .end = AT572D940HF_ID_TC0, | ||
567 | .flags = IORESOURCE_IRQ, | ||
568 | }, | ||
569 | [2] = { | ||
570 | .start = AT572D940HF_ID_TC1, | ||
571 | .end = AT572D940HF_ID_TC1, | ||
572 | .flags = IORESOURCE_IRQ, | ||
573 | }, | ||
574 | [3] = { | ||
575 | .start = AT572D940HF_ID_TC2, | ||
576 | .end = AT572D940HF_ID_TC2, | ||
577 | .flags = IORESOURCE_IRQ, | ||
578 | }, | ||
579 | }; | ||
580 | |||
581 | static struct platform_device at572d940hf_tcb_device = { | ||
582 | .name = "atmel_tcb", | ||
583 | .id = 0, | ||
584 | .resource = tcb_resources, | ||
585 | .num_resources = ARRAY_SIZE(tcb_resources), | ||
586 | }; | ||
587 | |||
588 | static void __init at91_add_device_tc(void) | ||
589 | { | ||
590 | /* this chip has a separate clock and irq for each TC channel */ | ||
591 | at91_clock_associate("tc0_clk", &at572d940hf_tcb_device.dev, "t0_clk"); | ||
592 | at91_clock_associate("tc1_clk", &at572d940hf_tcb_device.dev, "t1_clk"); | ||
593 | at91_clock_associate("tc2_clk", &at572d940hf_tcb_device.dev, "t2_clk"); | ||
594 | platform_device_register(&at572d940hf_tcb_device); | ||
595 | } | ||
596 | #else | ||
597 | static void __init at91_add_device_tc(void) { } | ||
598 | #endif | ||
599 | |||
600 | |||
601 | /* -------------------------------------------------------------------- | ||
602 | * RTT | ||
603 | * -------------------------------------------------------------------- */ | ||
604 | |||
605 | static struct resource rtt_resources[] = { | ||
606 | { | ||
607 | .start = AT91_BASE_SYS + AT91_RTT, | ||
608 | .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, | ||
609 | .flags = IORESOURCE_MEM, | ||
610 | } | ||
611 | }; | ||
612 | |||
613 | static struct platform_device at572d940hf_rtt_device = { | ||
614 | .name = "at91_rtt", | ||
615 | .id = 0, | ||
616 | .resource = rtt_resources, | ||
617 | .num_resources = ARRAY_SIZE(rtt_resources), | ||
618 | }; | ||
619 | |||
620 | static void __init at91_add_device_rtt(void) | ||
621 | { | ||
622 | platform_device_register(&at572d940hf_rtt_device); | ||
623 | } | ||
624 | |||
625 | |||
626 | /* -------------------------------------------------------------------- | ||
627 | * Watchdog | ||
628 | * -------------------------------------------------------------------- */ | ||
629 | |||
630 | #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) | ||
631 | static struct platform_device at572d940hf_wdt_device = { | ||
632 | .name = "at91_wdt", | ||
633 | .id = -1, | ||
634 | .num_resources = 0, | ||
635 | }; | ||
636 | |||
637 | static void __init at91_add_device_watchdog(void) | ||
638 | { | ||
639 | platform_device_register(&at572d940hf_wdt_device); | ||
640 | } | ||
641 | #else | ||
642 | static void __init at91_add_device_watchdog(void) {} | ||
643 | #endif | ||
644 | |||
645 | |||
646 | /* -------------------------------------------------------------------- | ||
647 | * UART | ||
648 | * -------------------------------------------------------------------- */ | ||
649 | |||
650 | #if defined(CONFIG_SERIAL_ATMEL) | ||
651 | static struct resource dbgu_resources[] = { | ||
652 | [0] = { | ||
653 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
654 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
655 | .flags = IORESOURCE_MEM, | ||
656 | }, | ||
657 | [1] = { | ||
658 | .start = AT91_ID_SYS, | ||
659 | .end = AT91_ID_SYS, | ||
660 | .flags = IORESOURCE_IRQ, | ||
661 | }, | ||
662 | }; | ||
663 | |||
664 | static struct atmel_uart_data dbgu_data = { | ||
665 | .use_dma_tx = 0, | ||
666 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
667 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
668 | }; | ||
669 | |||
670 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
671 | |||
672 | static struct platform_device at572d940hf_dbgu_device = { | ||
673 | .name = "atmel_usart", | ||
674 | .id = 0, | ||
675 | .dev = { | ||
676 | .dma_mask = &dbgu_dmamask, | ||
677 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
678 | .platform_data = &dbgu_data, | ||
679 | }, | ||
680 | .resource = dbgu_resources, | ||
681 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
682 | }; | ||
683 | |||
684 | static inline void configure_dbgu_pins(void) | ||
685 | { | ||
686 | at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ | ||
687 | at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ | ||
688 | } | ||
689 | |||
690 | static struct resource uart0_resources[] = { | ||
691 | [0] = { | ||
692 | .start = AT572D940HF_BASE_US0, | ||
693 | .end = AT572D940HF_BASE_US0 + SZ_16K - 1, | ||
694 | .flags = IORESOURCE_MEM, | ||
695 | }, | ||
696 | [1] = { | ||
697 | .start = AT572D940HF_ID_US0, | ||
698 | .end = AT572D940HF_ID_US0, | ||
699 | .flags = IORESOURCE_IRQ, | ||
700 | }, | ||
701 | }; | ||
702 | |||
703 | static struct atmel_uart_data uart0_data = { | ||
704 | .use_dma_tx = 1, | ||
705 | .use_dma_rx = 1, | ||
706 | }; | ||
707 | |||
708 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
709 | |||
710 | static struct platform_device at572d940hf_uart0_device = { | ||
711 | .name = "atmel_usart", | ||
712 | .id = 1, | ||
713 | .dev = { | ||
714 | .dma_mask = &uart0_dmamask, | ||
715 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
716 | .platform_data = &uart0_data, | ||
717 | }, | ||
718 | .resource = uart0_resources, | ||
719 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
720 | }; | ||
721 | |||
722 | static inline void configure_usart0_pins(unsigned pins) | ||
723 | { | ||
724 | at91_set_A_periph(AT91_PIN_PA8, 1); /* TXD0 */ | ||
725 | at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */ | ||
726 | |||
727 | if (pins & ATMEL_UART_RTS) | ||
728 | at91_set_A_periph(AT91_PIN_PA10, 0); /* RTS0 */ | ||
729 | if (pins & ATMEL_UART_CTS) | ||
730 | at91_set_A_periph(AT91_PIN_PA9, 0); /* CTS0 */ | ||
731 | } | ||
732 | |||
733 | static struct resource uart1_resources[] = { | ||
734 | [0] = { | ||
735 | .start = AT572D940HF_BASE_US1, | ||
736 | .end = AT572D940HF_BASE_US1 + SZ_16K - 1, | ||
737 | .flags = IORESOURCE_MEM, | ||
738 | }, | ||
739 | [1] = { | ||
740 | .start = AT572D940HF_ID_US1, | ||
741 | .end = AT572D940HF_ID_US1, | ||
742 | .flags = IORESOURCE_IRQ, | ||
743 | }, | ||
744 | }; | ||
745 | |||
746 | static struct atmel_uart_data uart1_data = { | ||
747 | .use_dma_tx = 1, | ||
748 | .use_dma_rx = 1, | ||
749 | }; | ||
750 | |||
751 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
752 | |||
753 | static struct platform_device at572d940hf_uart1_device = { | ||
754 | .name = "atmel_usart", | ||
755 | .id = 2, | ||
756 | .dev = { | ||
757 | .dma_mask = &uart1_dmamask, | ||
758 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
759 | .platform_data = &uart1_data, | ||
760 | }, | ||
761 | .resource = uart1_resources, | ||
762 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
763 | }; | ||
764 | |||
765 | static inline void configure_usart1_pins(unsigned pins) | ||
766 | { | ||
767 | at91_set_A_periph(AT91_PIN_PC10, 1); /* TXD1 */ | ||
768 | at91_set_A_periph(AT91_PIN_PC9 , 0); /* RXD1 */ | ||
769 | |||
770 | if (pins & ATMEL_UART_RTS) | ||
771 | at91_set_A_periph(AT91_PIN_PC12, 0); /* RTS1 */ | ||
772 | if (pins & ATMEL_UART_CTS) | ||
773 | at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS1 */ | ||
774 | } | ||
775 | |||
776 | static struct resource uart2_resources[] = { | ||
777 | [0] = { | ||
778 | .start = AT572D940HF_BASE_US2, | ||
779 | .end = AT572D940HF_BASE_US2 + SZ_16K - 1, | ||
780 | .flags = IORESOURCE_MEM, | ||
781 | }, | ||
782 | [1] = { | ||
783 | .start = AT572D940HF_ID_US2, | ||
784 | .end = AT572D940HF_ID_US2, | ||
785 | .flags = IORESOURCE_IRQ, | ||
786 | }, | ||
787 | }; | ||
788 | |||
789 | static struct atmel_uart_data uart2_data = { | ||
790 | .use_dma_tx = 1, | ||
791 | .use_dma_rx = 1, | ||
792 | }; | ||
793 | |||
794 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
795 | |||
796 | static struct platform_device at572d940hf_uart2_device = { | ||
797 | .name = "atmel_usart", | ||
798 | .id = 3, | ||
799 | .dev = { | ||
800 | .dma_mask = &uart2_dmamask, | ||
801 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
802 | .platform_data = &uart2_data, | ||
803 | }, | ||
804 | .resource = uart2_resources, | ||
805 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
806 | }; | ||
807 | |||
808 | static inline void configure_usart2_pins(unsigned pins) | ||
809 | { | ||
810 | at91_set_A_periph(AT91_PIN_PC15, 1); /* TXD2 */ | ||
811 | at91_set_A_periph(AT91_PIN_PC14, 0); /* RXD2 */ | ||
812 | |||
813 | if (pins & ATMEL_UART_RTS) | ||
814 | at91_set_A_periph(AT91_PIN_PC17, 0); /* RTS2 */ | ||
815 | if (pins & ATMEL_UART_CTS) | ||
816 | at91_set_A_periph(AT91_PIN_PC16, 0); /* CTS2 */ | ||
817 | } | ||
818 | |||
819 | static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
820 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
821 | |||
822 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
823 | { | ||
824 | struct platform_device *pdev; | ||
825 | |||
826 | switch (id) { | ||
827 | case 0: /* DBGU */ | ||
828 | pdev = &at572d940hf_dbgu_device; | ||
829 | configure_dbgu_pins(); | ||
830 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
831 | break; | ||
832 | case AT572D940HF_ID_US0: | ||
833 | pdev = &at572d940hf_uart0_device; | ||
834 | configure_usart0_pins(pins); | ||
835 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
836 | break; | ||
837 | case AT572D940HF_ID_US1: | ||
838 | pdev = &at572d940hf_uart1_device; | ||
839 | configure_usart1_pins(pins); | ||
840 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
841 | break; | ||
842 | case AT572D940HF_ID_US2: | ||
843 | pdev = &at572d940hf_uart2_device; | ||
844 | configure_usart2_pins(pins); | ||
845 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
846 | break; | ||
847 | default: | ||
848 | return; | ||
849 | } | ||
850 | pdev->id = portnr; /* update to mapped ID */ | ||
851 | |||
852 | if (portnr < ATMEL_MAX_UART) | ||
853 | at91_uarts[portnr] = pdev; | ||
854 | } | ||
855 | |||
856 | void __init at91_set_serial_console(unsigned portnr) | ||
857 | { | ||
858 | if (portnr < ATMEL_MAX_UART) | ||
859 | atmel_default_console_device = at91_uarts[portnr]; | ||
860 | } | ||
861 | |||
862 | void __init at91_add_device_serial(void) | ||
863 | { | ||
864 | int i; | ||
865 | |||
866 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
867 | if (at91_uarts[i]) | ||
868 | platform_device_register(at91_uarts[i]); | ||
869 | } | ||
870 | |||
871 | if (!atmel_default_console_device) | ||
872 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
873 | } | ||
874 | |||
875 | #else | ||
876 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
877 | void __init at91_set_serial_console(unsigned portnr) {} | ||
878 | void __init at91_add_device_serial(void) {} | ||
879 | #endif | ||
880 | |||
881 | |||
882 | /* -------------------------------------------------------------------- | ||
883 | * mAgic | ||
884 | * -------------------------------------------------------------------- */ | ||
885 | |||
886 | #ifdef CONFIG_MAGICV | ||
887 | static struct resource mAgic_resources[] = { | ||
888 | { | ||
889 | .start = AT91_MAGIC_PM_BASE, | ||
890 | .end = AT91_MAGIC_PM_BASE + AT91_MAGIC_PM_SIZE - 1, | ||
891 | .flags = IORESOURCE_MEM, | ||
892 | }, | ||
893 | { | ||
894 | .start = AT91_MAGIC_DM_I_BASE, | ||
895 | .end = AT91_MAGIC_DM_I_BASE + AT91_MAGIC_DM_I_SIZE - 1, | ||
896 | .flags = IORESOURCE_MEM, | ||
897 | }, | ||
898 | { | ||
899 | .start = AT91_MAGIC_DM_F_BASE, | ||
900 | .end = AT91_MAGIC_DM_F_BASE + AT91_MAGIC_DM_F_SIZE - 1, | ||
901 | .flags = IORESOURCE_MEM, | ||
902 | }, | ||
903 | { | ||
904 | .start = AT91_MAGIC_DM_DB_BASE, | ||
905 | .end = AT91_MAGIC_DM_DB_BASE + AT91_MAGIC_DM_DB_SIZE - 1, | ||
906 | .flags = IORESOURCE_MEM, | ||
907 | }, | ||
908 | { | ||
909 | .start = AT91_MAGIC_REGS_BASE, | ||
910 | .end = AT91_MAGIC_REGS_BASE + AT91_MAGIC_REGS_SIZE - 1, | ||
911 | .flags = IORESOURCE_MEM, | ||
912 | }, | ||
913 | { | ||
914 | .start = AT91_MAGIC_EXTPAGE_BASE, | ||
915 | .end = AT91_MAGIC_EXTPAGE_BASE + AT91_MAGIC_EXTPAGE_SIZE - 1, | ||
916 | .flags = IORESOURCE_MEM, | ||
917 | }, | ||
918 | { | ||
919 | .start = AT572D940HF_ID_MSIRQ0, | ||
920 | .end = AT572D940HF_ID_MSIRQ0, | ||
921 | .flags = IORESOURCE_IRQ, | ||
922 | }, | ||
923 | { | ||
924 | .start = AT572D940HF_ID_MHALT, | ||
925 | .end = AT572D940HF_ID_MHALT, | ||
926 | .flags = IORESOURCE_IRQ, | ||
927 | }, | ||
928 | { | ||
929 | .start = AT572D940HF_ID_MEXC, | ||
930 | .end = AT572D940HF_ID_MEXC, | ||
931 | .flags = IORESOURCE_IRQ, | ||
932 | }, | ||
933 | { | ||
934 | .start = AT572D940HF_ID_MEDMA, | ||
935 | .end = AT572D940HF_ID_MEDMA, | ||
936 | .flags = IORESOURCE_IRQ, | ||
937 | }, | ||
938 | }; | ||
939 | |||
940 | static struct platform_device mAgic_device = { | ||
941 | .name = "mAgic", | ||
942 | .id = -1, | ||
943 | .num_resources = ARRAY_SIZE(mAgic_resources), | ||
944 | .resource = mAgic_resources, | ||
945 | }; | ||
946 | |||
947 | void __init at91_add_device_mAgic(void) | ||
948 | { | ||
949 | platform_device_register(&mAgic_device); | ||
950 | } | ||
951 | #else | ||
952 | void __init at91_add_device_mAgic(void) {} | ||
953 | #endif | ||
954 | |||
955 | |||
956 | /* -------------------------------------------------------------------- */ | ||
957 | |||
958 | /* | ||
959 | * These devices are always present and don't need any board-specific | ||
960 | * setup. | ||
961 | */ | ||
962 | static int __init at91_add_standard_devices(void) | ||
963 | { | ||
964 | at91_add_device_rtt(); | ||
965 | at91_add_device_watchdog(); | ||
966 | at91_add_device_tc(); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 73376170fb91..17fae4a42ab5 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c | |||
@@ -222,6 +222,25 @@ static struct clk *periph_clocks[] __initdata = { | |||
222 | // irq0 .. irq1 | 222 | // irq0 .. irq1 |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static struct clk_lookup periph_clocks_lookups[] = { | ||
226 | CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc.0", &utmi_clk), | ||
227 | CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc.0", &udphs_clk), | ||
228 | CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), | ||
229 | CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), | ||
230 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | ||
231 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | ||
232 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), | ||
233 | CLKDEV_CON_DEV_ID("ssc", "ssc.0", &ssc0_clk), | ||
234 | CLKDEV_CON_DEV_ID("ssc", "ssc.1", &ssc1_clk), | ||
235 | }; | ||
236 | |||
237 | static struct clk_lookup usart_clocks_lookups[] = { | ||
238 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
239 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
240 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
241 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
242 | }; | ||
243 | |||
225 | /* | 244 | /* |
226 | * The four programmable clocks. | 245 | * The four programmable clocks. |
227 | * You must configure pin multiplexing to bring these signals out. | 246 | * You must configure pin multiplexing to bring these signals out. |
@@ -258,12 +277,29 @@ static void __init at91cap9_register_clocks(void) | |||
258 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 277 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
259 | clk_register(periph_clocks[i]); | 278 | clk_register(periph_clocks[i]); |
260 | 279 | ||
280 | clkdev_add_table(periph_clocks_lookups, | ||
281 | ARRAY_SIZE(periph_clocks_lookups)); | ||
282 | clkdev_add_table(usart_clocks_lookups, | ||
283 | ARRAY_SIZE(usart_clocks_lookups)); | ||
284 | |||
261 | clk_register(&pck0); | 285 | clk_register(&pck0); |
262 | clk_register(&pck1); | 286 | clk_register(&pck1); |
263 | clk_register(&pck2); | 287 | clk_register(&pck2); |
264 | clk_register(&pck3); | 288 | clk_register(&pck3); |
265 | } | 289 | } |
266 | 290 | ||
291 | static struct clk_lookup console_clock_lookup; | ||
292 | |||
293 | void __init at91cap9_set_console_clock(int id) | ||
294 | { | ||
295 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
296 | return; | ||
297 | |||
298 | console_clock_lookup.con_id = "usart"; | ||
299 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
300 | clkdev_add(&console_clock_lookup); | ||
301 | } | ||
302 | |||
267 | /* -------------------------------------------------------------------- | 303 | /* -------------------------------------------------------------------- |
268 | * GPIO | 304 | * GPIO |
269 | * -------------------------------------------------------------------- */ | 305 | * -------------------------------------------------------------------- */ |
@@ -303,11 +339,14 @@ static void at91cap9_poweroff(void) | |||
303 | * AT91CAP9 processor initialization | 339 | * AT91CAP9 processor initialization |
304 | * -------------------------------------------------------------------- */ | 340 | * -------------------------------------------------------------------- */ |
305 | 341 | ||
306 | void __init at91cap9_initialize(unsigned long main_clock) | 342 | void __init at91cap9_map_io(void) |
307 | { | 343 | { |
308 | /* Map peripherals */ | 344 | /* Map peripherals */ |
309 | iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc)); | 345 | iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc)); |
346 | } | ||
310 | 347 | ||
348 | void __init at91cap9_initialize(unsigned long main_clock) | ||
349 | { | ||
311 | at91_arch_reset = at91cap9_reset; | 350 | at91_arch_reset = at91cap9_reset; |
312 | pm_power_off = at91cap9_poweroff; | 351 | pm_power_off = at91cap9_poweroff; |
313 | at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); | 352 | at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); |
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 21020ceb2f3a..cd850ed6f335 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c | |||
@@ -181,10 +181,6 @@ void __init at91_add_device_usba(struct usba_platform_data *data) | |||
181 | 181 | ||
182 | /* Pullup pin is handled internally by USB device peripheral */ | 182 | /* Pullup pin is handled internally by USB device peripheral */ |
183 | 183 | ||
184 | /* Clocks */ | ||
185 | at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); | ||
186 | at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); | ||
187 | |||
188 | platform_device_register(&at91_usba_udc_device); | 184 | platform_device_register(&at91_usba_udc_device); |
189 | } | 185 | } |
190 | #else | 186 | #else |
@@ -355,7 +351,6 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | |||
355 | } | 351 | } |
356 | 352 | ||
357 | mmc0_data = *data; | 353 | mmc0_data = *data; |
358 | at91_clock_associate("mci0_clk", &at91cap9_mmc0_device.dev, "mci_clk"); | ||
359 | platform_device_register(&at91cap9_mmc0_device); | 354 | platform_device_register(&at91cap9_mmc0_device); |
360 | } else { /* MCI1 */ | 355 | } else { /* MCI1 */ |
361 | /* CLK */ | 356 | /* CLK */ |
@@ -373,7 +368,6 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | |||
373 | } | 368 | } |
374 | 369 | ||
375 | mmc1_data = *data; | 370 | mmc1_data = *data; |
376 | at91_clock_associate("mci1_clk", &at91cap9_mmc1_device.dev, "mci_clk"); | ||
377 | platform_device_register(&at91cap9_mmc1_device); | 371 | platform_device_register(&at91cap9_mmc1_device); |
378 | } | 372 | } |
379 | } | 373 | } |
@@ -614,7 +608,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
614 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | 608 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ |
615 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ | 609 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ |
616 | 610 | ||
617 | at91_clock_associate("spi0_clk", &at91cap9_spi0_device.dev, "spi_clk"); | ||
618 | platform_device_register(&at91cap9_spi0_device); | 611 | platform_device_register(&at91cap9_spi0_device); |
619 | } | 612 | } |
620 | if (enable_spi1) { | 613 | if (enable_spi1) { |
@@ -622,7 +615,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
622 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ | 615 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ |
623 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ | 616 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ |
624 | 617 | ||
625 | at91_clock_associate("spi1_clk", &at91cap9_spi1_device.dev, "spi_clk"); | ||
626 | platform_device_register(&at91cap9_spi1_device); | 618 | platform_device_register(&at91cap9_spi1_device); |
627 | } | 619 | } |
628 | } | 620 | } |
@@ -659,8 +651,6 @@ static struct platform_device at91cap9_tcb_device = { | |||
659 | 651 | ||
660 | static void __init at91_add_device_tc(void) | 652 | static void __init at91_add_device_tc(void) |
661 | { | 653 | { |
662 | /* this chip has one clock and irq for all three TC channels */ | ||
663 | at91_clock_associate("tcb_clk", &at91cap9_tcb_device.dev, "t0_clk"); | ||
664 | platform_device_register(&at91cap9_tcb_device); | 654 | platform_device_register(&at91cap9_tcb_device); |
665 | } | 655 | } |
666 | #else | 656 | #else |
@@ -1001,12 +991,10 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
1001 | case AT91CAP9_ID_SSC0: | 991 | case AT91CAP9_ID_SSC0: |
1002 | pdev = &at91cap9_ssc0_device; | 992 | pdev = &at91cap9_ssc0_device; |
1003 | configure_ssc0_pins(pins); | 993 | configure_ssc0_pins(pins); |
1004 | at91_clock_associate("ssc0_clk", &pdev->dev, "ssc"); | ||
1005 | break; | 994 | break; |
1006 | case AT91CAP9_ID_SSC1: | 995 | case AT91CAP9_ID_SSC1: |
1007 | pdev = &at91cap9_ssc1_device; | 996 | pdev = &at91cap9_ssc1_device; |
1008 | configure_ssc1_pins(pins); | 997 | configure_ssc1_pins(pins); |
1009 | at91_clock_associate("ssc1_clk", &pdev->dev, "ssc"); | ||
1010 | break; | 998 | break; |
1011 | default: | 999 | default: |
1012 | return; | 1000 | return; |
@@ -1199,32 +1187,30 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
1199 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 1187 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1200 | { | 1188 | { |
1201 | struct platform_device *pdev; | 1189 | struct platform_device *pdev; |
1190 | struct atmel_uart_data *pdata; | ||
1202 | 1191 | ||
1203 | switch (id) { | 1192 | switch (id) { |
1204 | case 0: /* DBGU */ | 1193 | case 0: /* DBGU */ |
1205 | pdev = &at91cap9_dbgu_device; | 1194 | pdev = &at91cap9_dbgu_device; |
1206 | configure_dbgu_pins(); | 1195 | configure_dbgu_pins(); |
1207 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1208 | break; | 1196 | break; |
1209 | case AT91CAP9_ID_US0: | 1197 | case AT91CAP9_ID_US0: |
1210 | pdev = &at91cap9_uart0_device; | 1198 | pdev = &at91cap9_uart0_device; |
1211 | configure_usart0_pins(pins); | 1199 | configure_usart0_pins(pins); |
1212 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1213 | break; | 1200 | break; |
1214 | case AT91CAP9_ID_US1: | 1201 | case AT91CAP9_ID_US1: |
1215 | pdev = &at91cap9_uart1_device; | 1202 | pdev = &at91cap9_uart1_device; |
1216 | configure_usart1_pins(pins); | 1203 | configure_usart1_pins(pins); |
1217 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1218 | break; | 1204 | break; |
1219 | case AT91CAP9_ID_US2: | 1205 | case AT91CAP9_ID_US2: |
1220 | pdev = &at91cap9_uart2_device; | 1206 | pdev = &at91cap9_uart2_device; |
1221 | configure_usart2_pins(pins); | 1207 | configure_usart2_pins(pins); |
1222 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1223 | break; | 1208 | break; |
1224 | default: | 1209 | default: |
1225 | return; | 1210 | return; |
1226 | } | 1211 | } |
1227 | pdev->id = portnr; /* update to mapped ID */ | 1212 | pdata = pdev->dev.platform_data; |
1213 | pdata->num = portnr; /* update to mapped ID */ | ||
1228 | 1214 | ||
1229 | if (portnr < ATMEL_MAX_UART) | 1215 | if (portnr < ATMEL_MAX_UART) |
1230 | at91_uarts[portnr] = pdev; | 1216 | at91_uarts[portnr] = pdev; |
@@ -1232,8 +1218,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1232 | 1218 | ||
1233 | void __init at91_set_serial_console(unsigned portnr) | 1219 | void __init at91_set_serial_console(unsigned portnr) |
1234 | { | 1220 | { |
1235 | if (portnr < ATMEL_MAX_UART) | 1221 | if (portnr < ATMEL_MAX_UART) { |
1236 | atmel_default_console_device = at91_uarts[portnr]; | 1222 | atmel_default_console_device = at91_uarts[portnr]; |
1223 | at91cap9_set_console_clock(portnr); | ||
1224 | } | ||
1237 | } | 1225 | } |
1238 | 1226 | ||
1239 | void __init at91_add_device_serial(void) | 1227 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 2e9ecad97f3d..b228ce9e21a1 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <mach/at91rm9200.h> | 18 | #include <mach/at91rm9200.h> |
19 | #include <mach/at91_pmc.h> | 19 | #include <mach/at91_pmc.h> |
20 | #include <mach/at91_st.h> | 20 | #include <mach/at91_st.h> |
21 | #include <mach/cpu.h> | ||
21 | 22 | ||
22 | #include "generic.h" | 23 | #include "generic.h" |
23 | #include "clock.h" | 24 | #include "clock.h" |
@@ -191,6 +192,26 @@ static struct clk *periph_clocks[] __initdata = { | |||
191 | // irq0 .. irq6 | 192 | // irq0 .. irq6 |
192 | }; | 193 | }; |
193 | 194 | ||
195 | static struct clk_lookup periph_clocks_lookups[] = { | ||
196 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | ||
197 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | ||
198 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | ||
199 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), | ||
200 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), | ||
201 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), | ||
202 | CLKDEV_CON_DEV_ID("ssc", "ssc.0", &ssc0_clk), | ||
203 | CLKDEV_CON_DEV_ID("ssc", "ssc.1", &ssc1_clk), | ||
204 | CLKDEV_CON_DEV_ID("ssc", "ssc.2", &ssc2_clk), | ||
205 | }; | ||
206 | |||
207 | static struct clk_lookup usart_clocks_lookups[] = { | ||
208 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
209 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
210 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
211 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
212 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), | ||
213 | }; | ||
214 | |||
194 | /* | 215 | /* |
195 | * The four programmable clocks. | 216 | * The four programmable clocks. |
196 | * You must configure pin multiplexing to bring these signals out. | 217 | * You must configure pin multiplexing to bring these signals out. |
@@ -227,12 +248,29 @@ static void __init at91rm9200_register_clocks(void) | |||
227 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 248 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
228 | clk_register(periph_clocks[i]); | 249 | clk_register(periph_clocks[i]); |
229 | 250 | ||
251 | clkdev_add_table(periph_clocks_lookups, | ||
252 | ARRAY_SIZE(periph_clocks_lookups)); | ||
253 | clkdev_add_table(usart_clocks_lookups, | ||
254 | ARRAY_SIZE(usart_clocks_lookups)); | ||
255 | |||
230 | clk_register(&pck0); | 256 | clk_register(&pck0); |
231 | clk_register(&pck1); | 257 | clk_register(&pck1); |
232 | clk_register(&pck2); | 258 | clk_register(&pck2); |
233 | clk_register(&pck3); | 259 | clk_register(&pck3); |
234 | } | 260 | } |
235 | 261 | ||
262 | static struct clk_lookup console_clock_lookup; | ||
263 | |||
264 | void __init at91rm9200_set_console_clock(int id) | ||
265 | { | ||
266 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
267 | return; | ||
268 | |||
269 | console_clock_lookup.con_id = "usart"; | ||
270 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
271 | clkdev_add(&console_clock_lookup); | ||
272 | } | ||
273 | |||
236 | /* -------------------------------------------------------------------- | 274 | /* -------------------------------------------------------------------- |
237 | * GPIO | 275 | * GPIO |
238 | * -------------------------------------------------------------------- */ | 276 | * -------------------------------------------------------------------- */ |
@@ -266,15 +304,25 @@ static void at91rm9200_reset(void) | |||
266 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | 304 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); |
267 | } | 305 | } |
268 | 306 | ||
307 | int rm9200_type; | ||
308 | EXPORT_SYMBOL(rm9200_type); | ||
309 | |||
310 | void __init at91rm9200_set_type(int type) | ||
311 | { | ||
312 | rm9200_type = type; | ||
313 | } | ||
269 | 314 | ||
270 | /* -------------------------------------------------------------------- | 315 | /* -------------------------------------------------------------------- |
271 | * AT91RM9200 processor initialization | 316 | * AT91RM9200 processor initialization |
272 | * -------------------------------------------------------------------- */ | 317 | * -------------------------------------------------------------------- */ |
273 | void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) | 318 | void __init at91rm9200_map_io(void) |
274 | { | 319 | { |
275 | /* Map peripherals */ | 320 | /* Map peripherals */ |
276 | iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); | 321 | iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); |
322 | } | ||
277 | 323 | ||
324 | void __init at91rm9200_initialize(unsigned long main_clock) | ||
325 | { | ||
278 | at91_arch_reset = at91rm9200_reset; | 326 | at91_arch_reset = at91rm9200_reset; |
279 | at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) | 327 | at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) |
280 | | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) | 328 | | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) |
@@ -288,7 +336,8 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks | |||
288 | at91rm9200_register_clocks(); | 336 | at91rm9200_register_clocks(); |
289 | 337 | ||
290 | /* Initialize GPIO subsystem */ | 338 | /* Initialize GPIO subsystem */ |
291 | at91_gpio_init(at91rm9200_gpio, banks); | 339 | at91_gpio_init(at91rm9200_gpio, |
340 | cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP); | ||
292 | } | 341 | } |
293 | 342 | ||
294 | 343 | ||
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 7b539228e0ef..a0ba475be04c 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -644,15 +644,7 @@ static struct platform_device at91rm9200_tcb1_device = { | |||
644 | 644 | ||
645 | static void __init at91_add_device_tc(void) | 645 | static void __init at91_add_device_tc(void) |
646 | { | 646 | { |
647 | /* this chip has a separate clock and irq for each TC channel */ | ||
648 | at91_clock_associate("tc0_clk", &at91rm9200_tcb0_device.dev, "t0_clk"); | ||
649 | at91_clock_associate("tc1_clk", &at91rm9200_tcb0_device.dev, "t1_clk"); | ||
650 | at91_clock_associate("tc2_clk", &at91rm9200_tcb0_device.dev, "t2_clk"); | ||
651 | platform_device_register(&at91rm9200_tcb0_device); | 647 | platform_device_register(&at91rm9200_tcb0_device); |
652 | |||
653 | at91_clock_associate("tc3_clk", &at91rm9200_tcb1_device.dev, "t0_clk"); | ||
654 | at91_clock_associate("tc4_clk", &at91rm9200_tcb1_device.dev, "t1_clk"); | ||
655 | at91_clock_associate("tc5_clk", &at91rm9200_tcb1_device.dev, "t2_clk"); | ||
656 | platform_device_register(&at91rm9200_tcb1_device); | 648 | platform_device_register(&at91rm9200_tcb1_device); |
657 | } | 649 | } |
658 | #else | 650 | #else |
@@ -849,17 +841,14 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
849 | case AT91RM9200_ID_SSC0: | 841 | case AT91RM9200_ID_SSC0: |
850 | pdev = &at91rm9200_ssc0_device; | 842 | pdev = &at91rm9200_ssc0_device; |
851 | configure_ssc0_pins(pins); | 843 | configure_ssc0_pins(pins); |
852 | at91_clock_associate("ssc0_clk", &pdev->dev, "ssc"); | ||
853 | break; | 844 | break; |
854 | case AT91RM9200_ID_SSC1: | 845 | case AT91RM9200_ID_SSC1: |
855 | pdev = &at91rm9200_ssc1_device; | 846 | pdev = &at91rm9200_ssc1_device; |
856 | configure_ssc1_pins(pins); | 847 | configure_ssc1_pins(pins); |
857 | at91_clock_associate("ssc1_clk", &pdev->dev, "ssc"); | ||
858 | break; | 848 | break; |
859 | case AT91RM9200_ID_SSC2: | 849 | case AT91RM9200_ID_SSC2: |
860 | pdev = &at91rm9200_ssc2_device; | 850 | pdev = &at91rm9200_ssc2_device; |
861 | configure_ssc2_pins(pins); | 851 | configure_ssc2_pins(pins); |
862 | at91_clock_associate("ssc2_clk", &pdev->dev, "ssc"); | ||
863 | break; | 852 | break; |
864 | default: | 853 | default: |
865 | return; | 854 | return; |
@@ -1109,37 +1098,34 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
1109 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 1098 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1110 | { | 1099 | { |
1111 | struct platform_device *pdev; | 1100 | struct platform_device *pdev; |
1101 | struct atmel_uart_data *pdata; | ||
1112 | 1102 | ||
1113 | switch (id) { | 1103 | switch (id) { |
1114 | case 0: /* DBGU */ | 1104 | case 0: /* DBGU */ |
1115 | pdev = &at91rm9200_dbgu_device; | 1105 | pdev = &at91rm9200_dbgu_device; |
1116 | configure_dbgu_pins(); | 1106 | configure_dbgu_pins(); |
1117 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1118 | break; | 1107 | break; |
1119 | case AT91RM9200_ID_US0: | 1108 | case AT91RM9200_ID_US0: |
1120 | pdev = &at91rm9200_uart0_device; | 1109 | pdev = &at91rm9200_uart0_device; |
1121 | configure_usart0_pins(pins); | 1110 | configure_usart0_pins(pins); |
1122 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1123 | break; | 1111 | break; |
1124 | case AT91RM9200_ID_US1: | 1112 | case AT91RM9200_ID_US1: |
1125 | pdev = &at91rm9200_uart1_device; | 1113 | pdev = &at91rm9200_uart1_device; |
1126 | configure_usart1_pins(pins); | 1114 | configure_usart1_pins(pins); |
1127 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1128 | break; | 1115 | break; |
1129 | case AT91RM9200_ID_US2: | 1116 | case AT91RM9200_ID_US2: |
1130 | pdev = &at91rm9200_uart2_device; | 1117 | pdev = &at91rm9200_uart2_device; |
1131 | configure_usart2_pins(pins); | 1118 | configure_usart2_pins(pins); |
1132 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1133 | break; | 1119 | break; |
1134 | case AT91RM9200_ID_US3: | 1120 | case AT91RM9200_ID_US3: |
1135 | pdev = &at91rm9200_uart3_device; | 1121 | pdev = &at91rm9200_uart3_device; |
1136 | configure_usart3_pins(pins); | 1122 | configure_usart3_pins(pins); |
1137 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
1138 | break; | 1123 | break; |
1139 | default: | 1124 | default: |
1140 | return; | 1125 | return; |
1141 | } | 1126 | } |
1142 | pdev->id = portnr; /* update to mapped ID */ | 1127 | pdata = pdev->dev.platform_data; |
1128 | pdata->num = portnr; /* update to mapped ID */ | ||
1143 | 1129 | ||
1144 | if (portnr < ATMEL_MAX_UART) | 1130 | if (portnr < ATMEL_MAX_UART) |
1145 | at91_uarts[portnr] = pdev; | 1131 | at91_uarts[portnr] = pdev; |
@@ -1147,8 +1133,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1147 | 1133 | ||
1148 | void __init at91_set_serial_console(unsigned portnr) | 1134 | void __init at91_set_serial_console(unsigned portnr) |
1149 | { | 1135 | { |
1150 | if (portnr < ATMEL_MAX_UART) | 1136 | if (portnr < ATMEL_MAX_UART) { |
1151 | atmel_default_console_device = at91_uarts[portnr]; | 1137 | atmel_default_console_device = at91_uarts[portnr]; |
1138 | at91rm9200_set_console_clock(portnr); | ||
1139 | } | ||
1152 | } | 1140 | } |
1153 | 1141 | ||
1154 | void __init at91_add_device_serial(void) | 1142 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 195208b30024..7d606b04d313 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -231,6 +231,28 @@ static struct clk *periph_clocks[] __initdata = { | |||
231 | // irq0 .. irq2 | 231 | // irq0 .. irq2 |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static struct clk_lookup periph_clocks_lookups[] = { | ||
235 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | ||
236 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | ||
237 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | ||
238 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | ||
239 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | ||
240 | CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk), | ||
241 | CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk), | ||
242 | CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk), | ||
243 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), | ||
244 | }; | ||
245 | |||
246 | static struct clk_lookup usart_clocks_lookups[] = { | ||
247 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
248 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
249 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
250 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
251 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), | ||
252 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.5", &usart4_clk), | ||
253 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.6", &usart5_clk), | ||
254 | }; | ||
255 | |||
234 | /* | 256 | /* |
235 | * The two programmable clocks. | 257 | * The two programmable clocks. |
236 | * You must configure pin multiplexing to bring these signals out. | 258 | * You must configure pin multiplexing to bring these signals out. |
@@ -255,10 +277,27 @@ static void __init at91sam9260_register_clocks(void) | |||
255 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 277 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
256 | clk_register(periph_clocks[i]); | 278 | clk_register(periph_clocks[i]); |
257 | 279 | ||
280 | clkdev_add_table(periph_clocks_lookups, | ||
281 | ARRAY_SIZE(periph_clocks_lookups)); | ||
282 | clkdev_add_table(usart_clocks_lookups, | ||
283 | ARRAY_SIZE(usart_clocks_lookups)); | ||
284 | |||
258 | clk_register(&pck0); | 285 | clk_register(&pck0); |
259 | clk_register(&pck1); | 286 | clk_register(&pck1); |
260 | } | 287 | } |
261 | 288 | ||
289 | static struct clk_lookup console_clock_lookup; | ||
290 | |||
291 | void __init at91sam9260_set_console_clock(int id) | ||
292 | { | ||
293 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
294 | return; | ||
295 | |||
296 | console_clock_lookup.con_id = "usart"; | ||
297 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
298 | clkdev_add(&console_clock_lookup); | ||
299 | } | ||
300 | |||
262 | /* -------------------------------------------------------------------- | 301 | /* -------------------------------------------------------------------- |
263 | * GPIO | 302 | * GPIO |
264 | * -------------------------------------------------------------------- */ | 303 | * -------------------------------------------------------------------- */ |
@@ -289,7 +328,7 @@ static void at91sam9260_poweroff(void) | |||
289 | * AT91SAM9260 processor initialization | 328 | * AT91SAM9260 processor initialization |
290 | * -------------------------------------------------------------------- */ | 329 | * -------------------------------------------------------------------- */ |
291 | 330 | ||
292 | static void __init at91sam9xe_initialize(void) | 331 | static void __init at91sam9xe_map_io(void) |
293 | { | 332 | { |
294 | unsigned long cidr, sram_size; | 333 | unsigned long cidr, sram_size; |
295 | 334 | ||
@@ -310,18 +349,21 @@ static void __init at91sam9xe_initialize(void) | |||
310 | iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); | 349 | iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); |
311 | } | 350 | } |
312 | 351 | ||
313 | void __init at91sam9260_initialize(unsigned long main_clock) | 352 | void __init at91sam9260_map_io(void) |
314 | { | 353 | { |
315 | /* Map peripherals */ | 354 | /* Map peripherals */ |
316 | iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); | 355 | iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); |
317 | 356 | ||
318 | if (cpu_is_at91sam9xe()) | 357 | if (cpu_is_at91sam9xe()) |
319 | at91sam9xe_initialize(); | 358 | at91sam9xe_map_io(); |
320 | else if (cpu_is_at91sam9g20()) | 359 | else if (cpu_is_at91sam9g20()) |
321 | iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); | 360 | iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); |
322 | else | 361 | else |
323 | iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); | 362 | iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); |
363 | } | ||
324 | 364 | ||
365 | void __init at91sam9260_initialize(unsigned long main_clock) | ||
366 | { | ||
325 | at91_arch_reset = at91sam9_alt_reset; | 367 | at91_arch_reset = at91sam9_alt_reset; |
326 | pm_power_off = at91sam9260_poweroff; | 368 | pm_power_off = at91sam9260_poweroff; |
327 | at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | 369 | at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 07eb7b07e442..1fdeb9058a76 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -609,7 +609,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
609 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | 609 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ |
610 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ | 610 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ |
611 | 611 | ||
612 | at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk"); | ||
613 | platform_device_register(&at91sam9260_spi0_device); | 612 | platform_device_register(&at91sam9260_spi0_device); |
614 | } | 613 | } |
615 | if (enable_spi1) { | 614 | if (enable_spi1) { |
@@ -617,7 +616,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
617 | at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ | 616 | at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ |
618 | at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ | 617 | at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ |
619 | 618 | ||
620 | at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk"); | ||
621 | platform_device_register(&at91sam9260_spi1_device); | 619 | platform_device_register(&at91sam9260_spi1_device); |
622 | } | 620 | } |
623 | } | 621 | } |
@@ -694,15 +692,7 @@ static struct platform_device at91sam9260_tcb1_device = { | |||
694 | 692 | ||
695 | static void __init at91_add_device_tc(void) | 693 | static void __init at91_add_device_tc(void) |
696 | { | 694 | { |
697 | /* this chip has a separate clock and irq for each TC channel */ | ||
698 | at91_clock_associate("tc0_clk", &at91sam9260_tcb0_device.dev, "t0_clk"); | ||
699 | at91_clock_associate("tc1_clk", &at91sam9260_tcb0_device.dev, "t1_clk"); | ||
700 | at91_clock_associate("tc2_clk", &at91sam9260_tcb0_device.dev, "t2_clk"); | ||
701 | platform_device_register(&at91sam9260_tcb0_device); | 695 | platform_device_register(&at91sam9260_tcb0_device); |
702 | |||
703 | at91_clock_associate("tc3_clk", &at91sam9260_tcb1_device.dev, "t0_clk"); | ||
704 | at91_clock_associate("tc4_clk", &at91sam9260_tcb1_device.dev, "t1_clk"); | ||
705 | at91_clock_associate("tc5_clk", &at91sam9260_tcb1_device.dev, "t2_clk"); | ||
706 | platform_device_register(&at91sam9260_tcb1_device); | 696 | platform_device_register(&at91sam9260_tcb1_device); |
707 | } | 697 | } |
708 | #else | 698 | #else |
@@ -820,7 +810,6 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
820 | case AT91SAM9260_ID_SSC: | 810 | case AT91SAM9260_ID_SSC: |
821 | pdev = &at91sam9260_ssc_device; | 811 | pdev = &at91sam9260_ssc_device; |
822 | configure_ssc_pins(pins); | 812 | configure_ssc_pins(pins); |
823 | at91_clock_associate("ssc_clk", &pdev->dev, "pclk"); | ||
824 | break; | 813 | break; |
825 | default: | 814 | default: |
826 | return; | 815 | return; |
@@ -1139,47 +1128,42 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
1139 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 1128 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1140 | { | 1129 | { |
1141 | struct platform_device *pdev; | 1130 | struct platform_device *pdev; |
1131 | struct atmel_uart_data *pdata; | ||
1142 | 1132 | ||
1143 | switch (id) { | 1133 | switch (id) { |
1144 | case 0: /* DBGU */ | 1134 | case 0: /* DBGU */ |
1145 | pdev = &at91sam9260_dbgu_device; | 1135 | pdev = &at91sam9260_dbgu_device; |
1146 | configure_dbgu_pins(); | 1136 | configure_dbgu_pins(); |
1147 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1148 | break; | 1137 | break; |
1149 | case AT91SAM9260_ID_US0: | 1138 | case AT91SAM9260_ID_US0: |
1150 | pdev = &at91sam9260_uart0_device; | 1139 | pdev = &at91sam9260_uart0_device; |
1151 | configure_usart0_pins(pins); | 1140 | configure_usart0_pins(pins); |
1152 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1153 | break; | 1141 | break; |
1154 | case AT91SAM9260_ID_US1: | 1142 | case AT91SAM9260_ID_US1: |
1155 | pdev = &at91sam9260_uart1_device; | 1143 | pdev = &at91sam9260_uart1_device; |
1156 | configure_usart1_pins(pins); | 1144 | configure_usart1_pins(pins); |
1157 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1158 | break; | 1145 | break; |
1159 | case AT91SAM9260_ID_US2: | 1146 | case AT91SAM9260_ID_US2: |
1160 | pdev = &at91sam9260_uart2_device; | 1147 | pdev = &at91sam9260_uart2_device; |
1161 | configure_usart2_pins(pins); | 1148 | configure_usart2_pins(pins); |
1162 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1163 | break; | 1149 | break; |
1164 | case AT91SAM9260_ID_US3: | 1150 | case AT91SAM9260_ID_US3: |
1165 | pdev = &at91sam9260_uart3_device; | 1151 | pdev = &at91sam9260_uart3_device; |
1166 | configure_usart3_pins(pins); | 1152 | configure_usart3_pins(pins); |
1167 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
1168 | break; | 1153 | break; |
1169 | case AT91SAM9260_ID_US4: | 1154 | case AT91SAM9260_ID_US4: |
1170 | pdev = &at91sam9260_uart4_device; | 1155 | pdev = &at91sam9260_uart4_device; |
1171 | configure_usart4_pins(); | 1156 | configure_usart4_pins(); |
1172 | at91_clock_associate("usart4_clk", &pdev->dev, "usart"); | ||
1173 | break; | 1157 | break; |
1174 | case AT91SAM9260_ID_US5: | 1158 | case AT91SAM9260_ID_US5: |
1175 | pdev = &at91sam9260_uart5_device; | 1159 | pdev = &at91sam9260_uart5_device; |
1176 | configure_usart5_pins(); | 1160 | configure_usart5_pins(); |
1177 | at91_clock_associate("usart5_clk", &pdev->dev, "usart"); | ||
1178 | break; | 1161 | break; |
1179 | default: | 1162 | default: |
1180 | return; | 1163 | return; |
1181 | } | 1164 | } |
1182 | pdev->id = portnr; /* update to mapped ID */ | 1165 | pdata = pdev->dev.platform_data; |
1166 | pdata->num = portnr; /* update to mapped ID */ | ||
1183 | 1167 | ||
1184 | if (portnr < ATMEL_MAX_UART) | 1168 | if (portnr < ATMEL_MAX_UART) |
1185 | at91_uarts[portnr] = pdev; | 1169 | at91_uarts[portnr] = pdev; |
@@ -1187,8 +1171,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1187 | 1171 | ||
1188 | void __init at91_set_serial_console(unsigned portnr) | 1172 | void __init at91_set_serial_console(unsigned portnr) |
1189 | { | 1173 | { |
1190 | if (portnr < ATMEL_MAX_UART) | 1174 | if (portnr < ATMEL_MAX_UART) { |
1191 | atmel_default_console_device = at91_uarts[portnr]; | 1175 | atmel_default_console_device = at91_uarts[portnr]; |
1176 | at91sam9260_set_console_clock(portnr); | ||
1177 | } | ||
1192 | } | 1178 | } |
1193 | 1179 | ||
1194 | void __init at91_add_device_serial(void) | 1180 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index fcad88668504..c1483168c97a 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -178,6 +178,24 @@ static struct clk *periph_clocks[] __initdata = { | |||
178 | // irq0 .. irq2 | 178 | // irq0 .. irq2 |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static struct clk_lookup periph_clocks_lookups[] = { | ||
182 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | ||
183 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | ||
184 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | ||
185 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | ||
186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk), | ||
187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | ||
188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | ||
189 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), | ||
190 | }; | ||
191 | |||
192 | static struct clk_lookup usart_clocks_lookups[] = { | ||
193 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
194 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
195 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
196 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
197 | }; | ||
198 | |||
181 | /* | 199 | /* |
182 | * The four programmable clocks. | 200 | * The four programmable clocks. |
183 | * You must configure pin multiplexing to bring these signals out. | 201 | * You must configure pin multiplexing to bring these signals out. |
@@ -228,6 +246,11 @@ static void __init at91sam9261_register_clocks(void) | |||
228 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 246 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
229 | clk_register(periph_clocks[i]); | 247 | clk_register(periph_clocks[i]); |
230 | 248 | ||
249 | clkdev_add_table(periph_clocks_lookups, | ||
250 | ARRAY_SIZE(periph_clocks_lookups)); | ||
251 | clkdev_add_table(usart_clocks_lookups, | ||
252 | ARRAY_SIZE(usart_clocks_lookups)); | ||
253 | |||
231 | clk_register(&pck0); | 254 | clk_register(&pck0); |
232 | clk_register(&pck1); | 255 | clk_register(&pck1); |
233 | clk_register(&pck2); | 256 | clk_register(&pck2); |
@@ -237,6 +260,18 @@ static void __init at91sam9261_register_clocks(void) | |||
237 | clk_register(&hck1); | 260 | clk_register(&hck1); |
238 | } | 261 | } |
239 | 262 | ||
263 | static struct clk_lookup console_clock_lookup; | ||
264 | |||
265 | void __init at91sam9261_set_console_clock(int id) | ||
266 | { | ||
267 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
268 | return; | ||
269 | |||
270 | console_clock_lookup.con_id = "usart"; | ||
271 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
272 | clkdev_add(&console_clock_lookup); | ||
273 | } | ||
274 | |||
240 | /* -------------------------------------------------------------------- | 275 | /* -------------------------------------------------------------------- |
241 | * GPIO | 276 | * GPIO |
242 | * -------------------------------------------------------------------- */ | 277 | * -------------------------------------------------------------------- */ |
@@ -267,7 +302,7 @@ static void at91sam9261_poweroff(void) | |||
267 | * AT91SAM9261 processor initialization | 302 | * AT91SAM9261 processor initialization |
268 | * -------------------------------------------------------------------- */ | 303 | * -------------------------------------------------------------------- */ |
269 | 304 | ||
270 | void __init at91sam9261_initialize(unsigned long main_clock) | 305 | void __init at91sam9261_map_io(void) |
271 | { | 306 | { |
272 | /* Map peripherals */ | 307 | /* Map peripherals */ |
273 | iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); | 308 | iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); |
@@ -276,8 +311,10 @@ void __init at91sam9261_initialize(unsigned long main_clock) | |||
276 | iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc)); | 311 | iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc)); |
277 | else | 312 | else |
278 | iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc)); | 313 | iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc)); |
314 | } | ||
279 | 315 | ||
280 | 316 | void __init at91sam9261_initialize(unsigned long main_clock) | |
317 | { | ||
281 | at91_arch_reset = at91sam9_alt_reset; | 318 | at91_arch_reset = at91sam9_alt_reset; |
282 | pm_power_off = at91sam9261_poweroff; | 319 | pm_power_off = at91sam9261_poweroff; |
283 | at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | 320 | at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) |
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 59fc48311fb0..3eb4538fceeb 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -426,7 +426,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
426 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | 426 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ |
427 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ | 427 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ |
428 | 428 | ||
429 | at91_clock_associate("spi0_clk", &at91sam9261_spi0_device.dev, "spi_clk"); | ||
430 | platform_device_register(&at91sam9261_spi0_device); | 429 | platform_device_register(&at91sam9261_spi0_device); |
431 | } | 430 | } |
432 | if (enable_spi1) { | 431 | if (enable_spi1) { |
@@ -434,7 +433,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
434 | at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ | 433 | at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ |
435 | at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ | 434 | at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ |
436 | 435 | ||
437 | at91_clock_associate("spi1_clk", &at91sam9261_spi1_device.dev, "spi_clk"); | ||
438 | platform_device_register(&at91sam9261_spi1_device); | 436 | platform_device_register(&at91sam9261_spi1_device); |
439 | } | 437 | } |
440 | } | 438 | } |
@@ -581,10 +579,6 @@ static struct platform_device at91sam9261_tcb_device = { | |||
581 | 579 | ||
582 | static void __init at91_add_device_tc(void) | 580 | static void __init at91_add_device_tc(void) |
583 | { | 581 | { |
584 | /* this chip has a separate clock and irq for each TC channel */ | ||
585 | at91_clock_associate("tc0_clk", &at91sam9261_tcb_device.dev, "t0_clk"); | ||
586 | at91_clock_associate("tc1_clk", &at91sam9261_tcb_device.dev, "t1_clk"); | ||
587 | at91_clock_associate("tc2_clk", &at91sam9261_tcb_device.dev, "t2_clk"); | ||
588 | platform_device_register(&at91sam9261_tcb_device); | 582 | platform_device_register(&at91sam9261_tcb_device); |
589 | } | 583 | } |
590 | #else | 584 | #else |
@@ -786,17 +780,14 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
786 | case AT91SAM9261_ID_SSC0: | 780 | case AT91SAM9261_ID_SSC0: |
787 | pdev = &at91sam9261_ssc0_device; | 781 | pdev = &at91sam9261_ssc0_device; |
788 | configure_ssc0_pins(pins); | 782 | configure_ssc0_pins(pins); |
789 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
790 | break; | 783 | break; |
791 | case AT91SAM9261_ID_SSC1: | 784 | case AT91SAM9261_ID_SSC1: |
792 | pdev = &at91sam9261_ssc1_device; | 785 | pdev = &at91sam9261_ssc1_device; |
793 | configure_ssc1_pins(pins); | 786 | configure_ssc1_pins(pins); |
794 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
795 | break; | 787 | break; |
796 | case AT91SAM9261_ID_SSC2: | 788 | case AT91SAM9261_ID_SSC2: |
797 | pdev = &at91sam9261_ssc2_device; | 789 | pdev = &at91sam9261_ssc2_device; |
798 | configure_ssc2_pins(pins); | 790 | configure_ssc2_pins(pins); |
799 | at91_clock_associate("ssc2_clk", &pdev->dev, "pclk"); | ||
800 | break; | 791 | break; |
801 | default: | 792 | default: |
802 | return; | 793 | return; |
@@ -989,32 +980,30 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
989 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 980 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
990 | { | 981 | { |
991 | struct platform_device *pdev; | 982 | struct platform_device *pdev; |
983 | struct atmel_uart_data *pdata; | ||
992 | 984 | ||
993 | switch (id) { | 985 | switch (id) { |
994 | case 0: /* DBGU */ | 986 | case 0: /* DBGU */ |
995 | pdev = &at91sam9261_dbgu_device; | 987 | pdev = &at91sam9261_dbgu_device; |
996 | configure_dbgu_pins(); | 988 | configure_dbgu_pins(); |
997 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
998 | break; | 989 | break; |
999 | case AT91SAM9261_ID_US0: | 990 | case AT91SAM9261_ID_US0: |
1000 | pdev = &at91sam9261_uart0_device; | 991 | pdev = &at91sam9261_uart0_device; |
1001 | configure_usart0_pins(pins); | 992 | configure_usart0_pins(pins); |
1002 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1003 | break; | 993 | break; |
1004 | case AT91SAM9261_ID_US1: | 994 | case AT91SAM9261_ID_US1: |
1005 | pdev = &at91sam9261_uart1_device; | 995 | pdev = &at91sam9261_uart1_device; |
1006 | configure_usart1_pins(pins); | 996 | configure_usart1_pins(pins); |
1007 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1008 | break; | 997 | break; |
1009 | case AT91SAM9261_ID_US2: | 998 | case AT91SAM9261_ID_US2: |
1010 | pdev = &at91sam9261_uart2_device; | 999 | pdev = &at91sam9261_uart2_device; |
1011 | configure_usart2_pins(pins); | 1000 | configure_usart2_pins(pins); |
1012 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1013 | break; | 1001 | break; |
1014 | default: | 1002 | default: |
1015 | return; | 1003 | return; |
1016 | } | 1004 | } |
1017 | pdev->id = portnr; /* update to mapped ID */ | 1005 | pdata = pdev->dev.platform_data; |
1006 | pdata->num = portnr; /* update to mapped ID */ | ||
1018 | 1007 | ||
1019 | if (portnr < ATMEL_MAX_UART) | 1008 | if (portnr < ATMEL_MAX_UART) |
1020 | at91_uarts[portnr] = pdev; | 1009 | at91_uarts[portnr] = pdev; |
@@ -1022,8 +1011,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1022 | 1011 | ||
1023 | void __init at91_set_serial_console(unsigned portnr) | 1012 | void __init at91_set_serial_console(unsigned portnr) |
1024 | { | 1013 | { |
1025 | if (portnr < ATMEL_MAX_UART) | 1014 | if (portnr < ATMEL_MAX_UART) { |
1026 | atmel_default_console_device = at91_uarts[portnr]; | 1015 | atmel_default_console_device = at91_uarts[portnr]; |
1016 | at91sam9261_set_console_clock(portnr); | ||
1017 | } | ||
1027 | } | 1018 | } |
1028 | 1019 | ||
1029 | void __init at91_add_device_serial(void) | 1020 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 249f900954d8..dc28477d14ff 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c | |||
@@ -199,6 +199,23 @@ static struct clk *periph_clocks[] __initdata = { | |||
199 | // irq0 .. irq1 | 199 | // irq0 .. irq1 |
200 | }; | 200 | }; |
201 | 201 | ||
202 | static struct clk_lookup periph_clocks_lookups[] = { | ||
203 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | ||
204 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | ||
205 | CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), | ||
206 | CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), | ||
207 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | ||
208 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | ||
209 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), | ||
210 | }; | ||
211 | |||
212 | static struct clk_lookup usart_clocks_lookups[] = { | ||
213 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
214 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
215 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
216 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
217 | }; | ||
218 | |||
202 | /* | 219 | /* |
203 | * The four programmable clocks. | 220 | * The four programmable clocks. |
204 | * You must configure pin multiplexing to bring these signals out. | 221 | * You must configure pin multiplexing to bring these signals out. |
@@ -235,12 +252,29 @@ static void __init at91sam9263_register_clocks(void) | |||
235 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 252 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
236 | clk_register(periph_clocks[i]); | 253 | clk_register(periph_clocks[i]); |
237 | 254 | ||
255 | clkdev_add_table(periph_clocks_lookups, | ||
256 | ARRAY_SIZE(periph_clocks_lookups)); | ||
257 | clkdev_add_table(usart_clocks_lookups, | ||
258 | ARRAY_SIZE(usart_clocks_lookups)); | ||
259 | |||
238 | clk_register(&pck0); | 260 | clk_register(&pck0); |
239 | clk_register(&pck1); | 261 | clk_register(&pck1); |
240 | clk_register(&pck2); | 262 | clk_register(&pck2); |
241 | clk_register(&pck3); | 263 | clk_register(&pck3); |
242 | } | 264 | } |
243 | 265 | ||
266 | static struct clk_lookup console_clock_lookup; | ||
267 | |||
268 | void __init at91sam9263_set_console_clock(int id) | ||
269 | { | ||
270 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
271 | return; | ||
272 | |||
273 | console_clock_lookup.con_id = "usart"; | ||
274 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
275 | clkdev_add(&console_clock_lookup); | ||
276 | } | ||
277 | |||
244 | /* -------------------------------------------------------------------- | 278 | /* -------------------------------------------------------------------- |
245 | * GPIO | 279 | * GPIO |
246 | * -------------------------------------------------------------------- */ | 280 | * -------------------------------------------------------------------- */ |
@@ -279,11 +313,14 @@ static void at91sam9263_poweroff(void) | |||
279 | * AT91SAM9263 processor initialization | 313 | * AT91SAM9263 processor initialization |
280 | * -------------------------------------------------------------------- */ | 314 | * -------------------------------------------------------------------- */ |
281 | 315 | ||
282 | void __init at91sam9263_initialize(unsigned long main_clock) | 316 | void __init at91sam9263_map_io(void) |
283 | { | 317 | { |
284 | /* Map peripherals */ | 318 | /* Map peripherals */ |
285 | iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc)); | 319 | iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc)); |
320 | } | ||
286 | 321 | ||
322 | void __init at91sam9263_initialize(unsigned long main_clock) | ||
323 | { | ||
287 | at91_arch_reset = at91sam9_alt_reset; | 324 | at91_arch_reset = at91sam9_alt_reset; |
288 | pm_power_off = at91sam9263_poweroff; | 325 | pm_power_off = at91sam9263_poweroff; |
289 | at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); | 326 | at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index fb5c23af1017..ffe081b77ed0 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -308,7 +308,6 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | |||
308 | } | 308 | } |
309 | 309 | ||
310 | mmc0_data = *data; | 310 | mmc0_data = *data; |
311 | at91_clock_associate("mci0_clk", &at91sam9263_mmc0_device.dev, "mci_clk"); | ||
312 | platform_device_register(&at91sam9263_mmc0_device); | 311 | platform_device_register(&at91sam9263_mmc0_device); |
313 | } else { /* MCI1 */ | 312 | } else { /* MCI1 */ |
314 | /* CLK */ | 313 | /* CLK */ |
@@ -339,7 +338,6 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | |||
339 | } | 338 | } |
340 | 339 | ||
341 | mmc1_data = *data; | 340 | mmc1_data = *data; |
342 | at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk"); | ||
343 | platform_device_register(&at91sam9263_mmc1_device); | 341 | platform_device_register(&at91sam9263_mmc1_device); |
344 | } | 342 | } |
345 | } | 343 | } |
@@ -686,7 +684,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
686 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | 684 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ |
687 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ | 685 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ |
688 | 686 | ||
689 | at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk"); | ||
690 | platform_device_register(&at91sam9263_spi0_device); | 687 | platform_device_register(&at91sam9263_spi0_device); |
691 | } | 688 | } |
692 | if (enable_spi1) { | 689 | if (enable_spi1) { |
@@ -694,7 +691,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
694 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ | 691 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ |
695 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ | 692 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ |
696 | 693 | ||
697 | at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk"); | ||
698 | platform_device_register(&at91sam9263_spi1_device); | 694 | platform_device_register(&at91sam9263_spi1_device); |
699 | } | 695 | } |
700 | } | 696 | } |
@@ -941,8 +937,6 @@ static struct platform_device at91sam9263_tcb_device = { | |||
941 | 937 | ||
942 | static void __init at91_add_device_tc(void) | 938 | static void __init at91_add_device_tc(void) |
943 | { | 939 | { |
944 | /* this chip has one clock and irq for all three TC channels */ | ||
945 | at91_clock_associate("tcb_clk", &at91sam9263_tcb_device.dev, "t0_clk"); | ||
946 | platform_device_register(&at91sam9263_tcb_device); | 940 | platform_device_register(&at91sam9263_tcb_device); |
947 | } | 941 | } |
948 | #else | 942 | #else |
@@ -1171,12 +1165,10 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
1171 | case AT91SAM9263_ID_SSC0: | 1165 | case AT91SAM9263_ID_SSC0: |
1172 | pdev = &at91sam9263_ssc0_device; | 1166 | pdev = &at91sam9263_ssc0_device; |
1173 | configure_ssc0_pins(pins); | 1167 | configure_ssc0_pins(pins); |
1174 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
1175 | break; | 1168 | break; |
1176 | case AT91SAM9263_ID_SSC1: | 1169 | case AT91SAM9263_ID_SSC1: |
1177 | pdev = &at91sam9263_ssc1_device; | 1170 | pdev = &at91sam9263_ssc1_device; |
1178 | configure_ssc1_pins(pins); | 1171 | configure_ssc1_pins(pins); |
1179 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
1180 | break; | 1172 | break; |
1181 | default: | 1173 | default: |
1182 | return; | 1174 | return; |
@@ -1370,32 +1362,30 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
1370 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 1362 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1371 | { | 1363 | { |
1372 | struct platform_device *pdev; | 1364 | struct platform_device *pdev; |
1365 | struct atmel_uart_data *pdata; | ||
1373 | 1366 | ||
1374 | switch (id) { | 1367 | switch (id) { |
1375 | case 0: /* DBGU */ | 1368 | case 0: /* DBGU */ |
1376 | pdev = &at91sam9263_dbgu_device; | 1369 | pdev = &at91sam9263_dbgu_device; |
1377 | configure_dbgu_pins(); | 1370 | configure_dbgu_pins(); |
1378 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1379 | break; | 1371 | break; |
1380 | case AT91SAM9263_ID_US0: | 1372 | case AT91SAM9263_ID_US0: |
1381 | pdev = &at91sam9263_uart0_device; | 1373 | pdev = &at91sam9263_uart0_device; |
1382 | configure_usart0_pins(pins); | 1374 | configure_usart0_pins(pins); |
1383 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1384 | break; | 1375 | break; |
1385 | case AT91SAM9263_ID_US1: | 1376 | case AT91SAM9263_ID_US1: |
1386 | pdev = &at91sam9263_uart1_device; | 1377 | pdev = &at91sam9263_uart1_device; |
1387 | configure_usart1_pins(pins); | 1378 | configure_usart1_pins(pins); |
1388 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1389 | break; | 1379 | break; |
1390 | case AT91SAM9263_ID_US2: | 1380 | case AT91SAM9263_ID_US2: |
1391 | pdev = &at91sam9263_uart2_device; | 1381 | pdev = &at91sam9263_uart2_device; |
1392 | configure_usart2_pins(pins); | 1382 | configure_usart2_pins(pins); |
1393 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1394 | break; | 1383 | break; |
1395 | default: | 1384 | default: |
1396 | return; | 1385 | return; |
1397 | } | 1386 | } |
1398 | pdev->id = portnr; /* update to mapped ID */ | 1387 | pdata = pdev->dev.platform_data; |
1388 | pdata->num = portnr; /* update to mapped ID */ | ||
1399 | 1389 | ||
1400 | if (portnr < ATMEL_MAX_UART) | 1390 | if (portnr < ATMEL_MAX_UART) |
1401 | at91_uarts[portnr] = pdev; | 1391 | at91_uarts[portnr] = pdev; |
@@ -1403,8 +1393,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1403 | 1393 | ||
1404 | void __init at91_set_serial_console(unsigned portnr) | 1394 | void __init at91_set_serial_console(unsigned portnr) |
1405 | { | 1395 | { |
1406 | if (portnr < ATMEL_MAX_UART) | 1396 | if (portnr < ATMEL_MAX_UART) { |
1407 | atmel_default_console_device = at91_uarts[portnr]; | 1397 | atmel_default_console_device = at91_uarts[portnr]; |
1398 | at91sam9263_set_console_clock(portnr); | ||
1399 | } | ||
1408 | } | 1400 | } |
1409 | 1401 | ||
1410 | void __init at91_add_device_serial(void) | 1402 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index c67b47f1c0fd..2bb6ff9af1c7 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
@@ -184,22 +184,6 @@ static struct clk vdec_clk = { | |||
184 | .type = CLK_TYPE_PERIPHERAL, | 184 | .type = CLK_TYPE_PERIPHERAL, |
185 | }; | 185 | }; |
186 | 186 | ||
187 | /* One additional fake clock for ohci */ | ||
188 | static struct clk ohci_clk = { | ||
189 | .name = "ohci_clk", | ||
190 | .pmc_mask = 0, | ||
191 | .type = CLK_TYPE_PERIPHERAL, | ||
192 | .parent = &uhphs_clk, | ||
193 | }; | ||
194 | |||
195 | /* One additional fake clock for second TC block */ | ||
196 | static struct clk tcb1_clk = { | ||
197 | .name = "tcb1_clk", | ||
198 | .pmc_mask = 0, | ||
199 | .type = CLK_TYPE_PERIPHERAL, | ||
200 | .parent = &tcb0_clk, | ||
201 | }; | ||
202 | |||
203 | static struct clk *periph_clocks[] __initdata = { | 187 | static struct clk *periph_clocks[] __initdata = { |
204 | &pioA_clk, | 188 | &pioA_clk, |
205 | &pioB_clk, | 189 | &pioB_clk, |
@@ -228,8 +212,30 @@ static struct clk *periph_clocks[] __initdata = { | |||
228 | &udphs_clk, | 212 | &udphs_clk, |
229 | &mmc1_clk, | 213 | &mmc1_clk, |
230 | // irq0 | 214 | // irq0 |
231 | &ohci_clk, | 215 | }; |
232 | &tcb1_clk, | 216 | |
217 | static struct clk_lookup periph_clocks_lookups[] = { | ||
218 | /* One additional fake clock for ohci */ | ||
219 | CLKDEV_CON_ID("ohci_clk", &uhphs_clk), | ||
220 | CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci.0", &uhphs_clk), | ||
221 | CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc.0", &utmi_clk), | ||
222 | CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc.0", &udphs_clk), | ||
223 | CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), | ||
224 | CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), | ||
225 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | ||
226 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | ||
227 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk), | ||
228 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), | ||
229 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | ||
230 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | ||
231 | }; | ||
232 | |||
233 | static struct clk_lookup usart_clocks_lookups[] = { | ||
234 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
235 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
236 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
237 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
238 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), | ||
233 | }; | 239 | }; |
234 | 240 | ||
235 | /* | 241 | /* |
@@ -256,6 +262,11 @@ static void __init at91sam9g45_register_clocks(void) | |||
256 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 262 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
257 | clk_register(periph_clocks[i]); | 263 | clk_register(periph_clocks[i]); |
258 | 264 | ||
265 | clkdev_add_table(periph_clocks_lookups, | ||
266 | ARRAY_SIZE(periph_clocks_lookups)); | ||
267 | clkdev_add_table(usart_clocks_lookups, | ||
268 | ARRAY_SIZE(usart_clocks_lookups)); | ||
269 | |||
259 | if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11()) | 270 | if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11()) |
260 | clk_register(&vdec_clk); | 271 | clk_register(&vdec_clk); |
261 | 272 | ||
@@ -263,6 +274,18 @@ static void __init at91sam9g45_register_clocks(void) | |||
263 | clk_register(&pck1); | 274 | clk_register(&pck1); |
264 | } | 275 | } |
265 | 276 | ||
277 | static struct clk_lookup console_clock_lookup; | ||
278 | |||
279 | void __init at91sam9g45_set_console_clock(int id) | ||
280 | { | ||
281 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
282 | return; | ||
283 | |||
284 | console_clock_lookup.con_id = "usart"; | ||
285 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
286 | clkdev_add(&console_clock_lookup); | ||
287 | } | ||
288 | |||
266 | /* -------------------------------------------------------------------- | 289 | /* -------------------------------------------------------------------- |
267 | * GPIO | 290 | * GPIO |
268 | * -------------------------------------------------------------------- */ | 291 | * -------------------------------------------------------------------- */ |
@@ -306,11 +329,14 @@ static void at91sam9g45_poweroff(void) | |||
306 | * AT91SAM9G45 processor initialization | 329 | * AT91SAM9G45 processor initialization |
307 | * -------------------------------------------------------------------- */ | 330 | * -------------------------------------------------------------------- */ |
308 | 331 | ||
309 | void __init at91sam9g45_initialize(unsigned long main_clock) | 332 | void __init at91sam9g45_map_io(void) |
310 | { | 333 | { |
311 | /* Map peripherals */ | 334 | /* Map peripherals */ |
312 | iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc)); | 335 | iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc)); |
336 | } | ||
313 | 337 | ||
338 | void __init at91sam9g45_initialize(unsigned long main_clock) | ||
339 | { | ||
314 | at91_arch_reset = at91sam9g45_reset; | 340 | at91_arch_reset = at91sam9g45_reset; |
315 | pm_power_off = at91sam9g45_poweroff; | 341 | pm_power_off = at91sam9g45_poweroff; |
316 | at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); | 342 | at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 5e9f8a4c38df..05674865bc21 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -180,7 +180,6 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) | |||
180 | } | 180 | } |
181 | 181 | ||
182 | usbh_ehci_data = *data; | 182 | usbh_ehci_data = *data; |
183 | at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk"); | ||
184 | platform_device_register(&at91_usbh_ehci_device); | 183 | platform_device_register(&at91_usbh_ehci_device); |
185 | } | 184 | } |
186 | #else | 185 | #else |
@@ -266,10 +265,6 @@ void __init at91_add_device_usba(struct usba_platform_data *data) | |||
266 | 265 | ||
267 | /* Pullup pin is handled internally by USB device peripheral */ | 266 | /* Pullup pin is handled internally by USB device peripheral */ |
268 | 267 | ||
269 | /* Clocks */ | ||
270 | at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); | ||
271 | at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); | ||
272 | |||
273 | platform_device_register(&at91_usba_udc_device); | 268 | platform_device_register(&at91_usba_udc_device); |
274 | } | 269 | } |
275 | #else | 270 | #else |
@@ -478,7 +473,6 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) | |||
478 | } | 473 | } |
479 | 474 | ||
480 | mmc0_data = *data; | 475 | mmc0_data = *data; |
481 | at91_clock_associate("mci0_clk", &at91sam9g45_mmc0_device.dev, "mci_clk"); | ||
482 | platform_device_register(&at91sam9g45_mmc0_device); | 476 | platform_device_register(&at91sam9g45_mmc0_device); |
483 | 477 | ||
484 | } else { /* MCI1 */ | 478 | } else { /* MCI1 */ |
@@ -504,7 +498,6 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) | |||
504 | } | 498 | } |
505 | 499 | ||
506 | mmc1_data = *data; | 500 | mmc1_data = *data; |
507 | at91_clock_associate("mci1_clk", &at91sam9g45_mmc1_device.dev, "mci_clk"); | ||
508 | platform_device_register(&at91sam9g45_mmc1_device); | 501 | platform_device_register(&at91sam9g45_mmc1_device); |
509 | 502 | ||
510 | } | 503 | } |
@@ -801,7 +794,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
801 | at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */ | 794 | at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */ |
802 | at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */ | 795 | at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */ |
803 | 796 | ||
804 | at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk"); | ||
805 | platform_device_register(&at91sam9g45_spi0_device); | 797 | platform_device_register(&at91sam9g45_spi0_device); |
806 | } | 798 | } |
807 | if (enable_spi1) { | 799 | if (enable_spi1) { |
@@ -809,7 +801,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
809 | at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */ | 801 | at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */ |
810 | at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */ | 802 | at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */ |
811 | 803 | ||
812 | at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk"); | ||
813 | platform_device_register(&at91sam9g45_spi1_device); | 804 | platform_device_register(&at91sam9g45_spi1_device); |
814 | } | 805 | } |
815 | } | 806 | } |
@@ -999,10 +990,7 @@ static struct platform_device at91sam9g45_tcb1_device = { | |||
999 | 990 | ||
1000 | static void __init at91_add_device_tc(void) | 991 | static void __init at91_add_device_tc(void) |
1001 | { | 992 | { |
1002 | /* this chip has one clock and irq for all six TC channels */ | ||
1003 | at91_clock_associate("tcb0_clk", &at91sam9g45_tcb0_device.dev, "t0_clk"); | ||
1004 | platform_device_register(&at91sam9g45_tcb0_device); | 993 | platform_device_register(&at91sam9g45_tcb0_device); |
1005 | at91_clock_associate("tcb1_clk", &at91sam9g45_tcb1_device.dev, "t0_clk"); | ||
1006 | platform_device_register(&at91sam9g45_tcb1_device); | 994 | platform_device_register(&at91sam9g45_tcb1_device); |
1007 | } | 995 | } |
1008 | #else | 996 | #else |
@@ -1286,12 +1274,10 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
1286 | case AT91SAM9G45_ID_SSC0: | 1274 | case AT91SAM9G45_ID_SSC0: |
1287 | pdev = &at91sam9g45_ssc0_device; | 1275 | pdev = &at91sam9g45_ssc0_device; |
1288 | configure_ssc0_pins(pins); | 1276 | configure_ssc0_pins(pins); |
1289 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
1290 | break; | 1277 | break; |
1291 | case AT91SAM9G45_ID_SSC1: | 1278 | case AT91SAM9G45_ID_SSC1: |
1292 | pdev = &at91sam9g45_ssc1_device; | 1279 | pdev = &at91sam9g45_ssc1_device; |
1293 | configure_ssc1_pins(pins); | 1280 | configure_ssc1_pins(pins); |
1294 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
1295 | break; | 1281 | break; |
1296 | default: | 1282 | default: |
1297 | return; | 1283 | return; |
@@ -1527,37 +1513,34 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
1527 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 1513 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1528 | { | 1514 | { |
1529 | struct platform_device *pdev; | 1515 | struct platform_device *pdev; |
1516 | struct atmel_uart_data *pdata; | ||
1530 | 1517 | ||
1531 | switch (id) { | 1518 | switch (id) { |
1532 | case 0: /* DBGU */ | 1519 | case 0: /* DBGU */ |
1533 | pdev = &at91sam9g45_dbgu_device; | 1520 | pdev = &at91sam9g45_dbgu_device; |
1534 | configure_dbgu_pins(); | 1521 | configure_dbgu_pins(); |
1535 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1536 | break; | 1522 | break; |
1537 | case AT91SAM9G45_ID_US0: | 1523 | case AT91SAM9G45_ID_US0: |
1538 | pdev = &at91sam9g45_uart0_device; | 1524 | pdev = &at91sam9g45_uart0_device; |
1539 | configure_usart0_pins(pins); | 1525 | configure_usart0_pins(pins); |
1540 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1541 | break; | 1526 | break; |
1542 | case AT91SAM9G45_ID_US1: | 1527 | case AT91SAM9G45_ID_US1: |
1543 | pdev = &at91sam9g45_uart1_device; | 1528 | pdev = &at91sam9g45_uart1_device; |
1544 | configure_usart1_pins(pins); | 1529 | configure_usart1_pins(pins); |
1545 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1546 | break; | 1530 | break; |
1547 | case AT91SAM9G45_ID_US2: | 1531 | case AT91SAM9G45_ID_US2: |
1548 | pdev = &at91sam9g45_uart2_device; | 1532 | pdev = &at91sam9g45_uart2_device; |
1549 | configure_usart2_pins(pins); | 1533 | configure_usart2_pins(pins); |
1550 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1551 | break; | 1534 | break; |
1552 | case AT91SAM9G45_ID_US3: | 1535 | case AT91SAM9G45_ID_US3: |
1553 | pdev = &at91sam9g45_uart3_device; | 1536 | pdev = &at91sam9g45_uart3_device; |
1554 | configure_usart3_pins(pins); | 1537 | configure_usart3_pins(pins); |
1555 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
1556 | break; | 1538 | break; |
1557 | default: | 1539 | default: |
1558 | return; | 1540 | return; |
1559 | } | 1541 | } |
1560 | pdev->id = portnr; /* update to mapped ID */ | 1542 | pdata = pdev->dev.platform_data; |
1543 | pdata->num = portnr; /* update to mapped ID */ | ||
1561 | 1544 | ||
1562 | if (portnr < ATMEL_MAX_UART) | 1545 | if (portnr < ATMEL_MAX_UART) |
1563 | at91_uarts[portnr] = pdev; | 1546 | at91_uarts[portnr] = pdev; |
@@ -1565,8 +1548,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1565 | 1548 | ||
1566 | void __init at91_set_serial_console(unsigned portnr) | 1549 | void __init at91_set_serial_console(unsigned portnr) |
1567 | { | 1550 | { |
1568 | if (portnr < ATMEL_MAX_UART) | 1551 | if (portnr < ATMEL_MAX_UART) { |
1569 | atmel_default_console_device = at91_uarts[portnr]; | 1552 | atmel_default_console_device = at91_uarts[portnr]; |
1553 | at91sam9g45_set_console_clock(portnr); | ||
1554 | } | ||
1570 | } | 1555 | } |
1571 | 1556 | ||
1572 | void __init at91_add_device_serial(void) | 1557 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 6a9d24e5ed8e..1a40f16b66c8 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c | |||
@@ -190,6 +190,24 @@ static struct clk *periph_clocks[] __initdata = { | |||
190 | // irq0 | 190 | // irq0 |
191 | }; | 191 | }; |
192 | 192 | ||
193 | static struct clk_lookup periph_clocks_lookups[] = { | ||
194 | CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc.0", &utmi_clk), | ||
195 | CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc.0", &udphs_clk), | ||
196 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | ||
197 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | ||
198 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | ||
199 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | ||
200 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | ||
201 | }; | ||
202 | |||
203 | static struct clk_lookup usart_clocks_lookups[] = { | ||
204 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | ||
205 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | ||
206 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | ||
207 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | ||
208 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), | ||
209 | }; | ||
210 | |||
193 | /* | 211 | /* |
194 | * The two programmable clocks. | 212 | * The two programmable clocks. |
195 | * You must configure pin multiplexing to bring these signals out. | 213 | * You must configure pin multiplexing to bring these signals out. |
@@ -214,10 +232,27 @@ static void __init at91sam9rl_register_clocks(void) | |||
214 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | 232 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) |
215 | clk_register(periph_clocks[i]); | 233 | clk_register(periph_clocks[i]); |
216 | 234 | ||
235 | clkdev_add_table(periph_clocks_lookups, | ||
236 | ARRAY_SIZE(periph_clocks_lookups)); | ||
237 | clkdev_add_table(usart_clocks_lookups, | ||
238 | ARRAY_SIZE(usart_clocks_lookups)); | ||
239 | |||
217 | clk_register(&pck0); | 240 | clk_register(&pck0); |
218 | clk_register(&pck1); | 241 | clk_register(&pck1); |
219 | } | 242 | } |
220 | 243 | ||
244 | static struct clk_lookup console_clock_lookup; | ||
245 | |||
246 | void __init at91sam9rl_set_console_clock(int id) | ||
247 | { | ||
248 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | ||
249 | return; | ||
250 | |||
251 | console_clock_lookup.con_id = "usart"; | ||
252 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | ||
253 | clkdev_add(&console_clock_lookup); | ||
254 | } | ||
255 | |||
221 | /* -------------------------------------------------------------------- | 256 | /* -------------------------------------------------------------------- |
222 | * GPIO | 257 | * GPIO |
223 | * -------------------------------------------------------------------- */ | 258 | * -------------------------------------------------------------------- */ |
@@ -252,7 +287,7 @@ static void at91sam9rl_poweroff(void) | |||
252 | * AT91SAM9RL processor initialization | 287 | * AT91SAM9RL processor initialization |
253 | * -------------------------------------------------------------------- */ | 288 | * -------------------------------------------------------------------- */ |
254 | 289 | ||
255 | void __init at91sam9rl_initialize(unsigned long main_clock) | 290 | void __init at91sam9rl_map_io(void) |
256 | { | 291 | { |
257 | unsigned long cidr, sram_size; | 292 | unsigned long cidr, sram_size; |
258 | 293 | ||
@@ -275,7 +310,10 @@ void __init at91sam9rl_initialize(unsigned long main_clock) | |||
275 | 310 | ||
276 | /* Map SRAM */ | 311 | /* Map SRAM */ |
277 | iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc)); | 312 | iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc)); |
313 | } | ||
278 | 314 | ||
315 | void __init at91sam9rl_initialize(unsigned long main_clock) | ||
316 | { | ||
279 | at91_arch_reset = at91sam9_alt_reset; | 317 | at91_arch_reset = at91sam9_alt_reset; |
280 | pm_power_off = at91sam9rl_poweroff; | 318 | pm_power_off = at91sam9rl_poweroff; |
281 | at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); | 319 | at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); |
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index c49262bddd85..c296045f2b6a 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -155,10 +155,6 @@ void __init at91_add_device_usba(struct usba_platform_data *data) | |||
155 | 155 | ||
156 | /* Pullup pin is handled internally by USB device peripheral */ | 156 | /* Pullup pin is handled internally by USB device peripheral */ |
157 | 157 | ||
158 | /* Clocks */ | ||
159 | at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); | ||
160 | at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); | ||
161 | |||
162 | platform_device_register(&at91_usba_udc_device); | 158 | platform_device_register(&at91_usba_udc_device); |
163 | } | 159 | } |
164 | #else | 160 | #else |
@@ -605,10 +601,6 @@ static struct platform_device at91sam9rl_tcb_device = { | |||
605 | 601 | ||
606 | static void __init at91_add_device_tc(void) | 602 | static void __init at91_add_device_tc(void) |
607 | { | 603 | { |
608 | /* this chip has a separate clock and irq for each TC channel */ | ||
609 | at91_clock_associate("tc0_clk", &at91sam9rl_tcb_device.dev, "t0_clk"); | ||
610 | at91_clock_associate("tc1_clk", &at91sam9rl_tcb_device.dev, "t1_clk"); | ||
611 | at91_clock_associate("tc2_clk", &at91sam9rl_tcb_device.dev, "t2_clk"); | ||
612 | platform_device_register(&at91sam9rl_tcb_device); | 604 | platform_device_register(&at91sam9rl_tcb_device); |
613 | } | 605 | } |
614 | #else | 606 | #else |
@@ -892,12 +884,10 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) | |||
892 | case AT91SAM9RL_ID_SSC0: | 884 | case AT91SAM9RL_ID_SSC0: |
893 | pdev = &at91sam9rl_ssc0_device; | 885 | pdev = &at91sam9rl_ssc0_device; |
894 | configure_ssc0_pins(pins); | 886 | configure_ssc0_pins(pins); |
895 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
896 | break; | 887 | break; |
897 | case AT91SAM9RL_ID_SSC1: | 888 | case AT91SAM9RL_ID_SSC1: |
898 | pdev = &at91sam9rl_ssc1_device; | 889 | pdev = &at91sam9rl_ssc1_device; |
899 | configure_ssc1_pins(pins); | 890 | configure_ssc1_pins(pins); |
900 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
901 | break; | 891 | break; |
902 | default: | 892 | default: |
903 | return; | 893 | return; |
@@ -1141,37 +1131,34 @@ struct platform_device *atmel_default_console_device; /* the serial console devi | |||
1141 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | 1131 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) |
1142 | { | 1132 | { |
1143 | struct platform_device *pdev; | 1133 | struct platform_device *pdev; |
1134 | struct atmel_uart_data *pdata; | ||
1144 | 1135 | ||
1145 | switch (id) { | 1136 | switch (id) { |
1146 | case 0: /* DBGU */ | 1137 | case 0: /* DBGU */ |
1147 | pdev = &at91sam9rl_dbgu_device; | 1138 | pdev = &at91sam9rl_dbgu_device; |
1148 | configure_dbgu_pins(); | 1139 | configure_dbgu_pins(); |
1149 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1150 | break; | 1140 | break; |
1151 | case AT91SAM9RL_ID_US0: | 1141 | case AT91SAM9RL_ID_US0: |
1152 | pdev = &at91sam9rl_uart0_device; | 1142 | pdev = &at91sam9rl_uart0_device; |
1153 | configure_usart0_pins(pins); | 1143 | configure_usart0_pins(pins); |
1154 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1155 | break; | 1144 | break; |
1156 | case AT91SAM9RL_ID_US1: | 1145 | case AT91SAM9RL_ID_US1: |
1157 | pdev = &at91sam9rl_uart1_device; | 1146 | pdev = &at91sam9rl_uart1_device; |
1158 | configure_usart1_pins(pins); | 1147 | configure_usart1_pins(pins); |
1159 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1160 | break; | 1148 | break; |
1161 | case AT91SAM9RL_ID_US2: | 1149 | case AT91SAM9RL_ID_US2: |
1162 | pdev = &at91sam9rl_uart2_device; | 1150 | pdev = &at91sam9rl_uart2_device; |
1163 | configure_usart2_pins(pins); | 1151 | configure_usart2_pins(pins); |
1164 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1165 | break; | 1152 | break; |
1166 | case AT91SAM9RL_ID_US3: | 1153 | case AT91SAM9RL_ID_US3: |
1167 | pdev = &at91sam9rl_uart3_device; | 1154 | pdev = &at91sam9rl_uart3_device; |
1168 | configure_usart3_pins(pins); | 1155 | configure_usart3_pins(pins); |
1169 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
1170 | break; | 1156 | break; |
1171 | default: | 1157 | default: |
1172 | return; | 1158 | return; |
1173 | } | 1159 | } |
1174 | pdev->id = portnr; /* update to mapped ID */ | 1160 | pdata = pdev->dev.platform_data; |
1161 | pdata->num = portnr; /* update to mapped ID */ | ||
1175 | 1162 | ||
1176 | if (portnr < ATMEL_MAX_UART) | 1163 | if (portnr < ATMEL_MAX_UART) |
1177 | at91_uarts[portnr] = pdev; | 1164 | at91_uarts[portnr] = pdev; |
@@ -1179,8 +1166,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | |||
1179 | 1166 | ||
1180 | void __init at91_set_serial_console(unsigned portnr) | 1167 | void __init at91_set_serial_console(unsigned portnr) |
1181 | { | 1168 | { |
1182 | if (portnr < ATMEL_MAX_UART) | 1169 | if (portnr < ATMEL_MAX_UART) { |
1183 | atmel_default_console_device = at91_uarts[portnr]; | 1170 | atmel_default_console_device = at91_uarts[portnr]; |
1171 | at91sam9rl_set_console_clock(portnr); | ||
1172 | } | ||
1184 | } | 1173 | } |
1185 | 1174 | ||
1186 | void __init at91_add_device_serial(void) | 1175 | void __init at91_add_device_serial(void) |
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c index ad3ec85b2790..56ba3bd035ae 100644 --- a/arch/arm/mach-at91/at91x40.c +++ b/arch/arm/mach-at91/at91x40.c | |||
@@ -37,11 +37,6 @@ unsigned long clk_get_rate(struct clk *clk) | |||
37 | return AT91X40_MASTER_CLOCK; | 37 | return AT91X40_MASTER_CLOCK; |
38 | } | 38 | } |
39 | 39 | ||
40 | struct clk *clk_get(struct device *dev, const char *id) | ||
41 | { | ||
42 | return NULL; | ||
43 | } | ||
44 | |||
45 | void __init at91x40_initialize(unsigned long main_clock) | 40 | void __init at91x40_initialize(unsigned long main_clock) |
46 | { | 41 | { |
47 | at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) | 42 | at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) |
diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index 8a3fc84847c1..ab1d463aa47d 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c | |||
@@ -35,14 +35,18 @@ | |||
35 | 35 | ||
36 | #include <mach/board.h> | 36 | #include <mach/board.h> |
37 | #include <mach/gpio.h> | 37 | #include <mach/gpio.h> |
38 | #include <mach/cpu.h> | ||
38 | 39 | ||
39 | #include "generic.h" | 40 | #include "generic.h" |
40 | 41 | ||
41 | 42 | ||
42 | static void __init onearm_map_io(void) | 43 | static void __init onearm_init_early(void) |
43 | { | 44 | { |
45 | /* Set cpu type: PQFP */ | ||
46 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
47 | |||
44 | /* Initialize processor: 18.432 MHz crystal */ | 48 | /* Initialize processor: 18.432 MHz crystal */ |
45 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | 49 | at91rm9200_initialize(18432000); |
46 | 50 | ||
47 | /* DBGU on ttyS0. (Rx & Tx only) */ | 51 | /* DBGU on ttyS0. (Rx & Tx only) */ |
48 | at91_register_uart(0, 0, 0); | 52 | at91_register_uart(0, 0, 0); |
@@ -92,9 +96,9 @@ static void __init onearm_board_init(void) | |||
92 | 96 | ||
93 | MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") | 97 | MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") |
94 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ | 98 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ |
95 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
96 | .timer = &at91rm9200_timer, | 99 | .timer = &at91rm9200_timer, |
97 | .map_io = onearm_map_io, | 100 | .map_io = at91rm9200_map_io, |
101 | .init_early = onearm_init_early, | ||
98 | .init_irq = onearm_init_irq, | 102 | .init_irq = onearm_init_irq, |
99 | .init_machine = onearm_board_init, | 103 | .init_machine = onearm_board_init, |
100 | MACHINE_END | 104 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index cba7f7771fee..a4924de48c36 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include "generic.h" | 48 | #include "generic.h" |
49 | 49 | ||
50 | 50 | ||
51 | static void __init afeb9260_map_io(void) | 51 | static void __init afeb9260_init_early(void) |
52 | { | 52 | { |
53 | /* Initialize processor: 18.432 MHz crystal */ | 53 | /* Initialize processor: 18.432 MHz crystal */ |
54 | at91sam9260_initialize(18432000); | 54 | at91sam9260_initialize(18432000); |
@@ -218,9 +218,9 @@ static void __init afeb9260_board_init(void) | |||
218 | 218 | ||
219 | MACHINE_START(AFEB9260, "Custom afeb9260 board") | 219 | MACHINE_START(AFEB9260, "Custom afeb9260 board") |
220 | /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ | 220 | /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ |
221 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
222 | .timer = &at91sam926x_timer, | 221 | .timer = &at91sam926x_timer, |
223 | .map_io = afeb9260_map_io, | 222 | .map_io = at91sam9260_map_io, |
223 | .init_early = afeb9260_init_early, | ||
224 | .init_irq = afeb9260_init_irq, | 224 | .init_irq = afeb9260_init_irq, |
225 | .init_machine = afeb9260_board_init, | 225 | .init_machine = afeb9260_board_init, |
226 | MACHINE_END | 226 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-at572d940hf_ek.c b/arch/arm/mach-at91/board-at572d940hf_ek.c deleted file mode 100644 index 3929f1c9e4e5..000000000000 --- a/arch/arm/mach-at91/board-at572d940hf_ek.c +++ /dev/null | |||
@@ -1,326 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-at572d940hf_ek.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com> | ||
5 | * Copyright (C) 2005 SAN People | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/spi/ds1305.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <linux/mtd/physmap.h> | ||
31 | |||
32 | #include <mach/hardware.h> | ||
33 | #include <asm/setup.h> | ||
34 | #include <asm/mach-types.h> | ||
35 | #include <asm/irq.h> | ||
36 | |||
37 | #include <asm/mach/arch.h> | ||
38 | #include <asm/mach/map.h> | ||
39 | #include <asm/mach/irq.h> | ||
40 | |||
41 | #include <mach/board.h> | ||
42 | #include <mach/gpio.h> | ||
43 | #include <mach/at91sam9_smc.h> | ||
44 | |||
45 | #include "sam9_smc.h" | ||
46 | #include "generic.h" | ||
47 | |||
48 | |||
49 | static void __init eb_map_io(void) | ||
50 | { | ||
51 | /* Initialize processor: 12.500 MHz crystal */ | ||
52 | at572d940hf_initialize(12000000); | ||
53 | |||
54 | /* DBGU on ttyS0. (Rx & Tx only) */ | ||
55 | at91_register_uart(0, 0, 0); | ||
56 | |||
57 | /* USART0 on ttyS1. (Rx & Tx only) */ | ||
58 | at91_register_uart(AT572D940HF_ID_US0, 1, 0); | ||
59 | |||
60 | /* USART1 on ttyS2. (Rx & Tx only) */ | ||
61 | at91_register_uart(AT572D940HF_ID_US1, 2, 0); | ||
62 | |||
63 | /* USART2 on ttyS3. (Tx & Rx only */ | ||
64 | at91_register_uart(AT572D940HF_ID_US2, 3, 0); | ||
65 | |||
66 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
67 | at91_set_serial_console(0); | ||
68 | } | ||
69 | |||
70 | static void __init eb_init_irq(void) | ||
71 | { | ||
72 | at572d940hf_init_interrupts(NULL); | ||
73 | } | ||
74 | |||
75 | |||
76 | /* | ||
77 | * USB Host Port | ||
78 | */ | ||
79 | static struct at91_usbh_data __initdata eb_usbh_data = { | ||
80 | .ports = 2, | ||
81 | }; | ||
82 | |||
83 | |||
84 | /* | ||
85 | * USB Device Port | ||
86 | */ | ||
87 | static struct at91_udc_data __initdata eb_udc_data = { | ||
88 | .vbus_pin = 0, /* no VBUS detection,UDC always on */ | ||
89 | .pullup_pin = 0, /* pull-up driven by UDC */ | ||
90 | }; | ||
91 | |||
92 | |||
93 | /* | ||
94 | * MCI (SD/MMC) | ||
95 | */ | ||
96 | static struct at91_mmc_data __initdata eb_mmc_data = { | ||
97 | .wire4 = 1, | ||
98 | /* .det_pin = ... not connected */ | ||
99 | /* .wp_pin = ... not connected */ | ||
100 | /* .vcc_pin = ... not connected */ | ||
101 | }; | ||
102 | |||
103 | |||
104 | /* | ||
105 | * MACB Ethernet device | ||
106 | */ | ||
107 | static struct at91_eth_data __initdata eb_eth_data = { | ||
108 | .phy_irq_pin = AT91_PIN_PB25, | ||
109 | .is_rmii = 1, | ||
110 | }; | ||
111 | |||
112 | /* | ||
113 | * NOR flash | ||
114 | */ | ||
115 | |||
116 | static struct mtd_partition eb_nor_partitions[] = { | ||
117 | { | ||
118 | .name = "Raw Environment", | ||
119 | .offset = 0, | ||
120 | .size = SZ_4M, | ||
121 | .mask_flags = 0, | ||
122 | }, | ||
123 | { | ||
124 | .name = "OS FS", | ||
125 | .offset = MTDPART_OFS_APPEND, | ||
126 | .size = 3 * SZ_1M, | ||
127 | .mask_flags = 0, | ||
128 | }, | ||
129 | { | ||
130 | .name = "APP FS", | ||
131 | .offset = MTDPART_OFS_APPEND, | ||
132 | .size = MTDPART_SIZ_FULL, | ||
133 | .mask_flags = 0, | ||
134 | }, | ||
135 | }; | ||
136 | |||
137 | static void nor_flash_set_vpp(struct map_info* mi, int i) { | ||
138 | }; | ||
139 | |||
140 | static struct physmap_flash_data nor_flash_data = { | ||
141 | .width = 4, | ||
142 | .parts = eb_nor_partitions, | ||
143 | .nr_parts = ARRAY_SIZE(eb_nor_partitions), | ||
144 | .set_vpp = nor_flash_set_vpp, | ||
145 | }; | ||
146 | |||
147 | static struct resource nor_flash_resources[] = { | ||
148 | { | ||
149 | .start = AT91_CHIPSELECT_0, | ||
150 | .end = AT91_CHIPSELECT_0 + SZ_16M - 1, | ||
151 | .flags = IORESOURCE_MEM, | ||
152 | }, | ||
153 | }; | ||
154 | |||
155 | static struct platform_device nor_flash = { | ||
156 | .name = "physmap-flash", | ||
157 | .id = 0, | ||
158 | .dev = { | ||
159 | .platform_data = &nor_flash_data, | ||
160 | }, | ||
161 | .resource = nor_flash_resources, | ||
162 | .num_resources = ARRAY_SIZE(nor_flash_resources), | ||
163 | }; | ||
164 | |||
165 | static struct sam9_smc_config __initdata eb_nor_smc_config = { | ||
166 | .ncs_read_setup = 1, | ||
167 | .nrd_setup = 1, | ||
168 | .ncs_write_setup = 1, | ||
169 | .nwe_setup = 1, | ||
170 | |||
171 | .ncs_read_pulse = 7, | ||
172 | .nrd_pulse = 7, | ||
173 | .ncs_write_pulse = 7, | ||
174 | .nwe_pulse = 7, | ||
175 | |||
176 | .read_cycle = 9, | ||
177 | .write_cycle = 9, | ||
178 | |||
179 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_32, | ||
180 | .tdf_cycles = 1, | ||
181 | }; | ||
182 | |||
183 | static void __init eb_add_device_nor(void) | ||
184 | { | ||
185 | /* configure chip-select 0 (NOR) */ | ||
186 | sam9_smc_configure(0, &eb_nor_smc_config); | ||
187 | platform_device_register(&nor_flash); | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * NAND flash | ||
192 | */ | ||
193 | static struct mtd_partition __initdata eb_nand_partition[] = { | ||
194 | { | ||
195 | .name = "Partition 1", | ||
196 | .offset = 0, | ||
197 | .size = SZ_16M, | ||
198 | }, | ||
199 | { | ||
200 | .name = "Partition 2", | ||
201 | .offset = MTDPART_OFS_NXTBLK, | ||
202 | .size = MTDPART_SIZ_FULL, | ||
203 | } | ||
204 | }; | ||
205 | |||
206 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) | ||
207 | { | ||
208 | *num_partitions = ARRAY_SIZE(eb_nand_partition); | ||
209 | return eb_nand_partition; | ||
210 | } | ||
211 | |||
212 | static struct atmel_nand_data __initdata eb_nand_data = { | ||
213 | .ale = 22, | ||
214 | .cle = 21, | ||
215 | /* .det_pin = ... not connected */ | ||
216 | /* .rdy_pin = AT91_PIN_PC16, */ | ||
217 | .enable_pin = AT91_PIN_PA15, | ||
218 | .partition_info = nand_partitions, | ||
219 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
220 | .bus_width_16 = 1, | ||
221 | #else | ||
222 | .bus_width_16 = 0, | ||
223 | #endif | ||
224 | }; | ||
225 | |||
226 | static struct sam9_smc_config __initdata eb_nand_smc_config = { | ||
227 | .ncs_read_setup = 0, | ||
228 | .nrd_setup = 0, | ||
229 | .ncs_write_setup = 1, | ||
230 | .nwe_setup = 1, | ||
231 | |||
232 | .ncs_read_pulse = 3, | ||
233 | .nrd_pulse = 3, | ||
234 | .ncs_write_pulse = 3, | ||
235 | .nwe_pulse = 3, | ||
236 | |||
237 | .read_cycle = 5, | ||
238 | .write_cycle = 5, | ||
239 | |||
240 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, | ||
241 | .tdf_cycles = 12, | ||
242 | }; | ||
243 | |||
244 | static void __init eb_add_device_nand(void) | ||
245 | { | ||
246 | /* setup bus-width (8 or 16) */ | ||
247 | if (eb_nand_data.bus_width_16) | ||
248 | eb_nand_smc_config.mode |= AT91_SMC_DBW_16; | ||
249 | else | ||
250 | eb_nand_smc_config.mode |= AT91_SMC_DBW_8; | ||
251 | |||
252 | /* configure chip-select 3 (NAND) */ | ||
253 | sam9_smc_configure(3, &eb_nand_smc_config); | ||
254 | |||
255 | at91_add_device_nand(&eb_nand_data); | ||
256 | } | ||
257 | |||
258 | |||
259 | /* | ||
260 | * SPI devices | ||
261 | */ | ||
262 | static struct resource rtc_resources[] = { | ||
263 | [0] = { | ||
264 | .start = AT572D940HF_ID_IRQ1, | ||
265 | .end = AT572D940HF_ID_IRQ1, | ||
266 | .flags = IORESOURCE_IRQ, | ||
267 | }, | ||
268 | }; | ||
269 | |||
270 | static struct ds1305_platform_data ds1306_data = { | ||
271 | .is_ds1306 = true, | ||
272 | .en_1hz = false, | ||
273 | }; | ||
274 | |||
275 | static struct spi_board_info eb_spi_devices[] = { | ||
276 | { /* RTC Dallas DS1306 */ | ||
277 | .modalias = "rtc-ds1305", | ||
278 | .chip_select = 3, | ||
279 | .mode = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA, | ||
280 | .max_speed_hz = 500000, | ||
281 | .bus_num = 0, | ||
282 | .irq = AT572D940HF_ID_IRQ1, | ||
283 | .platform_data = (void *) &ds1306_data, | ||
284 | }, | ||
285 | #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) | ||
286 | { /* Dataflash card */ | ||
287 | .modalias = "mtd_dataflash", | ||
288 | .chip_select = 0, | ||
289 | .max_speed_hz = 15 * 1000 * 1000, | ||
290 | .bus_num = 0, | ||
291 | }, | ||
292 | #endif | ||
293 | }; | ||
294 | |||
295 | static void __init eb_board_init(void) | ||
296 | { | ||
297 | /* Serial */ | ||
298 | at91_add_device_serial(); | ||
299 | /* USB Host */ | ||
300 | at91_add_device_usbh(&eb_usbh_data); | ||
301 | /* USB Device */ | ||
302 | at91_add_device_udc(&eb_udc_data); | ||
303 | /* I2C */ | ||
304 | at91_add_device_i2c(NULL, 0); | ||
305 | /* NOR */ | ||
306 | eb_add_device_nor(); | ||
307 | /* NAND */ | ||
308 | eb_add_device_nand(); | ||
309 | /* SPI */ | ||
310 | at91_add_device_spi(eb_spi_devices, ARRAY_SIZE(eb_spi_devices)); | ||
311 | /* MMC */ | ||
312 | at91_add_device_mmc(0, &eb_mmc_data); | ||
313 | /* Ethernet */ | ||
314 | at91_add_device_eth(&eb_eth_data); | ||
315 | /* mAgic */ | ||
316 | at91_add_device_mAgic(); | ||
317 | } | ||
318 | |||
319 | MACHINE_START(AT572D940HFEB, "Atmel AT91D940HF-EB") | ||
320 | /* Maintainer: Atmel <costa.antonior@gmail.com> */ | ||
321 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
322 | .timer = &at91sam926x_timer, | ||
323 | .map_io = eb_map_io, | ||
324 | .init_irq = eb_init_irq, | ||
325 | .init_machine = eb_board_init, | ||
326 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index b54e3e6fceb6..148fccb9a25a 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "generic.h" | 45 | #include "generic.h" |
46 | 46 | ||
47 | 47 | ||
48 | static void __init cam60_map_io(void) | 48 | static void __init cam60_init_early(void) |
49 | { | 49 | { |
50 | /* Initialize processor: 10 MHz crystal */ | 50 | /* Initialize processor: 10 MHz crystal */ |
51 | at91sam9260_initialize(10000000); | 51 | at91sam9260_initialize(10000000); |
@@ -198,9 +198,9 @@ static void __init cam60_board_init(void) | |||
198 | 198 | ||
199 | MACHINE_START(CAM60, "KwikByte CAM60") | 199 | MACHINE_START(CAM60, "KwikByte CAM60") |
200 | /* Maintainer: KwikByte */ | 200 | /* Maintainer: KwikByte */ |
201 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
202 | .timer = &at91sam926x_timer, | 201 | .timer = &at91sam926x_timer, |
203 | .map_io = cam60_map_io, | 202 | .map_io = at91sam9260_map_io, |
203 | .init_early = cam60_init_early, | ||
204 | .init_irq = cam60_init_irq, | 204 | .init_irq = cam60_init_irq, |
205 | .init_machine = cam60_board_init, | 205 | .init_machine = cam60_board_init, |
206 | MACHINE_END | 206 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index e7274440ead9..1904fdf87613 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c | |||
@@ -44,12 +44,13 @@ | |||
44 | #include <mach/gpio.h> | 44 | #include <mach/gpio.h> |
45 | #include <mach/at91cap9_matrix.h> | 45 | #include <mach/at91cap9_matrix.h> |
46 | #include <mach/at91sam9_smc.h> | 46 | #include <mach/at91sam9_smc.h> |
47 | #include <mach/system_rev.h> | ||
47 | 48 | ||
48 | #include "sam9_smc.h" | 49 | #include "sam9_smc.h" |
49 | #include "generic.h" | 50 | #include "generic.h" |
50 | 51 | ||
51 | 52 | ||
52 | static void __init cap9adk_map_io(void) | 53 | static void __init cap9adk_init_early(void) |
53 | { | 54 | { |
54 | /* Initialize processor: 12 MHz crystal */ | 55 | /* Initialize processor: 12 MHz crystal */ |
55 | at91cap9_initialize(12000000); | 56 | at91cap9_initialize(12000000); |
@@ -187,11 +188,6 @@ static struct atmel_nand_data __initdata cap9adk_nand_data = { | |||
187 | // .rdy_pin = ... not connected | 188 | // .rdy_pin = ... not connected |
188 | .enable_pin = AT91_PIN_PD15, | 189 | .enable_pin = AT91_PIN_PD15, |
189 | .partition_info = nand_partitions, | 190 | .partition_info = nand_partitions, |
190 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
191 | .bus_width_16 = 1, | ||
192 | #else | ||
193 | .bus_width_16 = 0, | ||
194 | #endif | ||
195 | }; | 191 | }; |
196 | 192 | ||
197 | static struct sam9_smc_config __initdata cap9adk_nand_smc_config = { | 193 | static struct sam9_smc_config __initdata cap9adk_nand_smc_config = { |
@@ -219,6 +215,7 @@ static void __init cap9adk_add_device_nand(void) | |||
219 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | 215 | csa = at91_sys_read(AT91_MATRIX_EBICSA); |
220 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); | 216 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); |
221 | 217 | ||
218 | cap9adk_nand_data.bus_width_16 = !board_have_nand_8bit(); | ||
222 | /* setup bus-width (8 or 16) */ | 219 | /* setup bus-width (8 or 16) */ |
223 | if (cap9adk_nand_data.bus_width_16) | 220 | if (cap9adk_nand_data.bus_width_16) |
224 | cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16; | 221 | cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16; |
@@ -399,9 +396,9 @@ static void __init cap9adk_board_init(void) | |||
399 | 396 | ||
400 | MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") | 397 | MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") |
401 | /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ | 398 | /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ |
402 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
403 | .timer = &at91sam926x_timer, | 399 | .timer = &at91sam926x_timer, |
404 | .map_io = cap9adk_map_io, | 400 | .map_io = at91cap9_map_io, |
401 | .init_early = cap9adk_init_early, | ||
405 | .init_irq = cap9adk_init_irq, | 402 | .init_irq = cap9adk_init_irq, |
406 | .init_machine = cap9adk_board_init, | 403 | .init_machine = cap9adk_board_init, |
407 | MACHINE_END | 404 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index 295e1e77fa60..f36b18687494 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c | |||
@@ -40,10 +40,10 @@ | |||
40 | #include "generic.h" | 40 | #include "generic.h" |
41 | 41 | ||
42 | 42 | ||
43 | static void __init carmeva_map_io(void) | 43 | static void __init carmeva_init_early(void) |
44 | { | 44 | { |
45 | /* Initialize processor: 20.000 MHz crystal */ | 45 | /* Initialize processor: 20.000 MHz crystal */ |
46 | at91rm9200_initialize(20000000, AT91RM9200_BGA); | 46 | at91rm9200_initialize(20000000); |
47 | 47 | ||
48 | /* DBGU on ttyS0. (Rx & Tx only) */ | 48 | /* DBGU on ttyS0. (Rx & Tx only) */ |
49 | at91_register_uart(0, 0, 0); | 49 | at91_register_uart(0, 0, 0); |
@@ -162,9 +162,9 @@ static void __init carmeva_board_init(void) | |||
162 | 162 | ||
163 | MACHINE_START(CARMEVA, "Carmeva") | 163 | MACHINE_START(CARMEVA, "Carmeva") |
164 | /* Maintainer: Conitec Datasystems */ | 164 | /* Maintainer: Conitec Datasystems */ |
165 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
166 | .timer = &at91rm9200_timer, | 165 | .timer = &at91rm9200_timer, |
167 | .map_io = carmeva_map_io, | 166 | .map_io = at91rm9200_map_io, |
167 | .init_early = carmeva_init_early, | ||
168 | .init_irq = carmeva_init_irq, | 168 | .init_irq = carmeva_init_irq, |
169 | .init_machine = carmeva_board_init, | 169 | .init_machine = carmeva_board_init, |
170 | MACHINE_END | 170 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 3838594578f3..980511084fe4 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include "sam9_smc.h" | 47 | #include "sam9_smc.h" |
48 | #include "generic.h" | 48 | #include "generic.h" |
49 | 49 | ||
50 | static void __init cpu9krea_map_io(void) | 50 | static void __init cpu9krea_init_early(void) |
51 | { | 51 | { |
52 | /* Initialize processor: 18.432 MHz crystal */ | 52 | /* Initialize processor: 18.432 MHz crystal */ |
53 | at91sam9260_initialize(18432000); | 53 | at91sam9260_initialize(18432000); |
@@ -375,9 +375,9 @@ MACHINE_START(CPUAT9260, "Eukrea CPU9260") | |||
375 | MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") | 375 | MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") |
376 | #endif | 376 | #endif |
377 | /* Maintainer: Eric Benard - EUKREA Electromatique */ | 377 | /* Maintainer: Eric Benard - EUKREA Electromatique */ |
378 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
379 | .timer = &at91sam926x_timer, | 378 | .timer = &at91sam926x_timer, |
380 | .map_io = cpu9krea_map_io, | 379 | .map_io = at91sam9260_map_io, |
380 | .init_early = cpu9krea_init_early, | ||
381 | .init_irq = cpu9krea_init_irq, | 381 | .init_irq = cpu9krea_init_irq, |
382 | .init_machine = cpu9krea_board_init, | 382 | .init_machine = cpu9krea_board_init, |
383 | MACHINE_END | 383 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index 2f4dd8cdd484..6daabe3907a1 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <mach/board.h> | 38 | #include <mach/board.h> |
39 | #include <mach/gpio.h> | 39 | #include <mach/gpio.h> |
40 | #include <mach/at91rm9200_mc.h> | 40 | #include <mach/at91rm9200_mc.h> |
41 | #include <mach/cpu.h> | ||
41 | 42 | ||
42 | #include "generic.h" | 43 | #include "generic.h" |
43 | 44 | ||
@@ -50,10 +51,13 @@ static struct gpio_led cpuat91_leds[] = { | |||
50 | }, | 51 | }, |
51 | }; | 52 | }; |
52 | 53 | ||
53 | static void __init cpuat91_map_io(void) | 54 | static void __init cpuat91_init_early(void) |
54 | { | 55 | { |
56 | /* Set cpu type: PQFP */ | ||
57 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
58 | |||
55 | /* Initialize processor: 18.432 MHz crystal */ | 59 | /* Initialize processor: 18.432 MHz crystal */ |
56 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | 60 | at91rm9200_initialize(18432000); |
57 | 61 | ||
58 | /* DBGU on ttyS0. (Rx & Tx only) */ | 62 | /* DBGU on ttyS0. (Rx & Tx only) */ |
59 | at91_register_uart(0, 0, 0); | 63 | at91_register_uart(0, 0, 0); |
@@ -175,9 +179,9 @@ static void __init cpuat91_board_init(void) | |||
175 | 179 | ||
176 | MACHINE_START(CPUAT91, "Eukrea") | 180 | MACHINE_START(CPUAT91, "Eukrea") |
177 | /* Maintainer: Eric Benard - EUKREA Electromatique */ | 181 | /* Maintainer: Eric Benard - EUKREA Electromatique */ |
178 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
179 | .timer = &at91rm9200_timer, | 182 | .timer = &at91rm9200_timer, |
180 | .map_io = cpuat91_map_io, | 183 | .map_io = at91rm9200_map_io, |
184 | .init_early = cpuat91_init_early, | ||
181 | .init_irq = cpuat91_init_irq, | 185 | .init_irq = cpuat91_init_irq, |
182 | .init_machine = cpuat91_board_init, | 186 | .init_machine = cpuat91_board_init, |
183 | MACHINE_END | 187 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index 464839dc39bd..d98bcec1dfe0 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c | |||
@@ -43,10 +43,10 @@ | |||
43 | #include "generic.h" | 43 | #include "generic.h" |
44 | 44 | ||
45 | 45 | ||
46 | static void __init csb337_map_io(void) | 46 | static void __init csb337_init_early(void) |
47 | { | 47 | { |
48 | /* Initialize processor: 3.6864 MHz crystal */ | 48 | /* Initialize processor: 3.6864 MHz crystal */ |
49 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | 49 | at91rm9200_initialize(3686400); |
50 | 50 | ||
51 | /* Setup the LEDs */ | 51 | /* Setup the LEDs */ |
52 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); | 52 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); |
@@ -257,9 +257,9 @@ static void __init csb337_board_init(void) | |||
257 | 257 | ||
258 | MACHINE_START(CSB337, "Cogent CSB337") | 258 | MACHINE_START(CSB337, "Cogent CSB337") |
259 | /* Maintainer: Bill Gatliff */ | 259 | /* Maintainer: Bill Gatliff */ |
260 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
261 | .timer = &at91rm9200_timer, | 260 | .timer = &at91rm9200_timer, |
262 | .map_io = csb337_map_io, | 261 | .map_io = at91rm9200_map_io, |
262 | .init_early = csb337_init_early, | ||
263 | .init_irq = csb337_init_irq, | 263 | .init_irq = csb337_init_irq, |
264 | .init_machine = csb337_board_init, | 264 | .init_machine = csb337_board_init, |
265 | MACHINE_END | 265 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index 431688c61412..019aab4e20b0 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c | |||
@@ -40,10 +40,10 @@ | |||
40 | #include "generic.h" | 40 | #include "generic.h" |
41 | 41 | ||
42 | 42 | ||
43 | static void __init csb637_map_io(void) | 43 | static void __init csb637_init_early(void) |
44 | { | 44 | { |
45 | /* Initialize processor: 3.6864 MHz crystal */ | 45 | /* Initialize processor: 3.6864 MHz crystal */ |
46 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | 46 | at91rm9200_initialize(3686400); |
47 | 47 | ||
48 | /* DBGU on ttyS0. (Rx & Tx only) */ | 48 | /* DBGU on ttyS0. (Rx & Tx only) */ |
49 | at91_register_uart(0, 0, 0); | 49 | at91_register_uart(0, 0, 0); |
@@ -138,9 +138,9 @@ static void __init csb637_board_init(void) | |||
138 | 138 | ||
139 | MACHINE_START(CSB637, "Cogent CSB637") | 139 | MACHINE_START(CSB637, "Cogent CSB637") |
140 | /* Maintainer: Bill Gatliff */ | 140 | /* Maintainer: Bill Gatliff */ |
141 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
142 | .timer = &at91rm9200_timer, | 141 | .timer = &at91rm9200_timer, |
143 | .map_io = csb637_map_io, | 142 | .map_io = at91rm9200_map_io, |
143 | .init_early = csb637_init_early, | ||
144 | .init_irq = csb637_init_irq, | 144 | .init_irq = csb637_init_irq, |
145 | .init_machine = csb637_board_init, | 145 | .init_machine = csb637_board_init, |
146 | MACHINE_END | 146 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c index d8df59a3426d..d2023f27c652 100644 --- a/arch/arm/mach-at91/board-eb01.c +++ b/arch/arm/mach-at91/board-eb01.c | |||
@@ -35,7 +35,7 @@ static void __init at91eb01_init_irq(void) | |||
35 | at91x40_init_interrupts(NULL); | 35 | at91x40_init_interrupts(NULL); |
36 | } | 36 | } |
37 | 37 | ||
38 | static void __init at91eb01_map_io(void) | 38 | static void __init at91eb01_init_early(void) |
39 | { | 39 | { |
40 | at91x40_initialize(40000000); | 40 | at91x40_initialize(40000000); |
41 | } | 41 | } |
@@ -43,7 +43,7 @@ static void __init at91eb01_map_io(void) | |||
43 | MACHINE_START(AT91EB01, "Atmel AT91 EB01") | 43 | MACHINE_START(AT91EB01, "Atmel AT91 EB01") |
44 | /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ | 44 | /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ |
45 | .timer = &at91x40_timer, | 45 | .timer = &at91x40_timer, |
46 | .init_early = at91eb01_init_early, | ||
46 | .init_irq = at91eb01_init_irq, | 47 | .init_irq = at91eb01_init_irq, |
47 | .map_io = at91eb01_map_io, | ||
48 | MACHINE_END | 48 | MACHINE_END |
49 | 49 | ||
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c index 6cf6566ae346..e9484535cbc8 100644 --- a/arch/arm/mach-at91/board-eb9200.c +++ b/arch/arm/mach-at91/board-eb9200.c | |||
@@ -40,10 +40,10 @@ | |||
40 | #include "generic.h" | 40 | #include "generic.h" |
41 | 41 | ||
42 | 42 | ||
43 | static void __init eb9200_map_io(void) | 43 | static void __init eb9200_init_early(void) |
44 | { | 44 | { |
45 | /* Initialize processor: 18.432 MHz crystal */ | 45 | /* Initialize processor: 18.432 MHz crystal */ |
46 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | 46 | at91rm9200_initialize(18432000); |
47 | 47 | ||
48 | /* DBGU on ttyS0. (Rx & Tx only) */ | 48 | /* DBGU on ttyS0. (Rx & Tx only) */ |
49 | at91_register_uart(0, 0, 0); | 49 | at91_register_uart(0, 0, 0); |
@@ -120,9 +120,9 @@ static void __init eb9200_board_init(void) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | MACHINE_START(ATEB9200, "Embest ATEB9200") | 122 | MACHINE_START(ATEB9200, "Embest ATEB9200") |
123 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
124 | .timer = &at91rm9200_timer, | 123 | .timer = &at91rm9200_timer, |
125 | .map_io = eb9200_map_io, | 124 | .map_io = at91rm9200_map_io, |
125 | .init_early = eb9200_init_early, | ||
126 | .init_irq = eb9200_init_irq, | 126 | .init_irq = eb9200_init_irq, |
127 | .init_machine = eb9200_board_init, | 127 | .init_machine = eb9200_board_init, |
128 | MACHINE_END | 128 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index de2fd04e7c8a..a6f57faa10a7 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c | |||
@@ -38,14 +38,18 @@ | |||
38 | 38 | ||
39 | #include <mach/board.h> | 39 | #include <mach/board.h> |
40 | #include <mach/gpio.h> | 40 | #include <mach/gpio.h> |
41 | #include <mach/cpu.h> | ||
41 | 42 | ||
42 | #include "generic.h" | 43 | #include "generic.h" |
43 | 44 | ||
44 | 45 | ||
45 | static void __init ecb_at91map_io(void) | 46 | static void __init ecb_at91init_early(void) |
46 | { | 47 | { |
48 | /* Set cpu type: PQFP */ | ||
49 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
50 | |||
47 | /* Initialize processor: 18.432 MHz crystal */ | 51 | /* Initialize processor: 18.432 MHz crystal */ |
48 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | 52 | at91rm9200_initialize(18432000); |
49 | 53 | ||
50 | /* Setup the LEDs */ | 54 | /* Setup the LEDs */ |
51 | at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7); | 55 | at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7); |
@@ -168,9 +172,9 @@ static void __init ecb_at91board_init(void) | |||
168 | 172 | ||
169 | MACHINE_START(ECBAT91, "emQbit's ECB_AT91") | 173 | MACHINE_START(ECBAT91, "emQbit's ECB_AT91") |
170 | /* Maintainer: emQbit.com */ | 174 | /* Maintainer: emQbit.com */ |
171 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
172 | .timer = &at91rm9200_timer, | 175 | .timer = &at91rm9200_timer, |
173 | .map_io = ecb_at91map_io, | 176 | .map_io = at91rm9200_map_io, |
177 | .init_early = ecb_at91init_early, | ||
174 | .init_irq = ecb_at91init_irq, | 178 | .init_irq = ecb_at91init_irq, |
175 | .init_machine = ecb_at91board_init, | 179 | .init_machine = ecb_at91board_init, |
176 | MACHINE_END | 180 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index a158a0ce458f..bfc0062d1483 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c | |||
@@ -26,11 +26,16 @@ | |||
26 | 26 | ||
27 | #include <mach/board.h> | 27 | #include <mach/board.h> |
28 | #include <mach/at91rm9200_mc.h> | 28 | #include <mach/at91rm9200_mc.h> |
29 | #include <mach/cpu.h> | ||
30 | |||
29 | #include "generic.h" | 31 | #include "generic.h" |
30 | 32 | ||
31 | static void __init eco920_map_io(void) | 33 | static void __init eco920_init_early(void) |
32 | { | 34 | { |
33 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | 35 | /* Set cpu type: PQFP */ |
36 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
37 | |||
38 | at91rm9200_initialize(18432000); | ||
34 | 39 | ||
35 | /* Setup the LEDs */ | 40 | /* Setup the LEDs */ |
36 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); | 41 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); |
@@ -86,21 +91,6 @@ static struct platform_device eco920_flash = { | |||
86 | .num_resources = 1, | 91 | .num_resources = 1, |
87 | }; | 92 | }; |
88 | 93 | ||
89 | static struct resource at91_beeper_resources[] = { | ||
90 | [0] = { | ||
91 | .start = AT91RM9200_BASE_TC3, | ||
92 | .end = AT91RM9200_BASE_TC3 + 0x39, | ||
93 | .flags = IORESOURCE_MEM, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct platform_device at91_beeper = { | ||
98 | .name = "at91_beeper", | ||
99 | .id = 0, | ||
100 | .resource = at91_beeper_resources, | ||
101 | .num_resources = ARRAY_SIZE(at91_beeper_resources), | ||
102 | }; | ||
103 | |||
104 | static struct spi_board_info eco920_spi_devices[] = { | 94 | static struct spi_board_info eco920_spi_devices[] = { |
105 | { /* CAN controller */ | 95 | { /* CAN controller */ |
106 | .modalias = "tlv5638", | 96 | .modalias = "tlv5638", |
@@ -139,18 +129,14 @@ static void __init eco920_board_init(void) | |||
139 | AT91_SMC_TDF_(1) /* float time */ | 129 | AT91_SMC_TDF_(1) /* float time */ |
140 | ); | 130 | ); |
141 | 131 | ||
142 | at91_clock_associate("tc3_clk", &at91_beeper.dev, "at91_beeper"); | ||
143 | at91_set_B_periph(AT91_PIN_PB6, 0); | ||
144 | platform_device_register(&at91_beeper); | ||
145 | |||
146 | at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices)); | 132 | at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices)); |
147 | } | 133 | } |
148 | 134 | ||
149 | MACHINE_START(ECO920, "eco920") | 135 | MACHINE_START(ECO920, "eco920") |
150 | /* Maintainer: Sascha Hauer */ | 136 | /* Maintainer: Sascha Hauer */ |
151 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
152 | .timer = &at91rm9200_timer, | 137 | .timer = &at91rm9200_timer, |
153 | .map_io = eco920_map_io, | 138 | .map_io = at91rm9200_map_io, |
139 | .init_early = eco920_init_early, | ||
154 | .init_irq = eco920_init_irq, | 140 | .init_irq = eco920_init_irq, |
155 | .init_machine = eco920_board_init, | 141 | .init_machine = eco920_board_init, |
156 | MACHINE_END | 142 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index c8a62dc8fa65..466c063b8d21 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #include "generic.h" | 38 | #include "generic.h" |
39 | 39 | ||
40 | static void __init flexibity_map_io(void) | 40 | static void __init flexibity_init_early(void) |
41 | { | 41 | { |
42 | /* Initialize processor: 18.432 MHz crystal */ | 42 | /* Initialize processor: 18.432 MHz crystal */ |
43 | at91sam9260_initialize(18432000); | 43 | at91sam9260_initialize(18432000); |
@@ -154,9 +154,9 @@ static void __init flexibity_board_init(void) | |||
154 | 154 | ||
155 | MACHINE_START(FLEXIBITY, "Flexibity Connect") | 155 | MACHINE_START(FLEXIBITY, "Flexibity Connect") |
156 | /* Maintainer: Maxim Osipov */ | 156 | /* Maintainer: Maxim Osipov */ |
157 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
158 | .timer = &at91sam926x_timer, | 157 | .timer = &at91sam926x_timer, |
159 | .map_io = flexibity_map_io, | 158 | .map_io = at91sam9260_map_io, |
159 | .init_early = flexibity_init_early, | ||
160 | .init_irq = flexibity_init_irq, | 160 | .init_irq = flexibity_init_irq, |
161 | .init_machine = flexibity_board_init, | 161 | .init_machine = flexibity_board_init, |
162 | MACHINE_END | 162 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index dfc7dfe738e4..e2d1dc9eff45 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c | |||
@@ -57,7 +57,7 @@ | |||
57 | */ | 57 | */ |
58 | 58 | ||
59 | 59 | ||
60 | static void __init foxg20_map_io(void) | 60 | static void __init foxg20_init_early(void) |
61 | { | 61 | { |
62 | /* Initialize processor: 18.432 MHz crystal */ | 62 | /* Initialize processor: 18.432 MHz crystal */ |
63 | at91sam9260_initialize(18432000); | 63 | at91sam9260_initialize(18432000); |
@@ -266,9 +266,9 @@ static void __init foxg20_board_init(void) | |||
266 | 266 | ||
267 | MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20") | 267 | MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20") |
268 | /* Maintainer: Sergio Tanzilli */ | 268 | /* Maintainer: Sergio Tanzilli */ |
269 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
270 | .timer = &at91sam926x_timer, | 269 | .timer = &at91sam926x_timer, |
271 | .map_io = foxg20_map_io, | 270 | .map_io = at91sam9260_map_io, |
271 | .init_early = foxg20_init_early, | ||
272 | .init_irq = foxg20_init_irq, | 272 | .init_irq = foxg20_init_irq, |
273 | .init_machine = foxg20_board_init, | 273 | .init_machine = foxg20_board_init, |
274 | MACHINE_END | 274 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index bc28136ee249..1d4f36b3cb27 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c | |||
@@ -38,9 +38,9 @@ | |||
38 | #include "sam9_smc.h" | 38 | #include "sam9_smc.h" |
39 | #include "generic.h" | 39 | #include "generic.h" |
40 | 40 | ||
41 | static void __init gsia18s_map_io(void) | 41 | static void __init gsia18s_init_early(void) |
42 | { | 42 | { |
43 | stamp9g20_map_io(); | 43 | stamp9g20_init_early(); |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI). | 46 | * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI). |
@@ -576,9 +576,9 @@ static void __init gsia18s_board_init(void) | |||
576 | } | 576 | } |
577 | 577 | ||
578 | MACHINE_START(GSIA18S, "GS_IA18_S") | 578 | MACHINE_START(GSIA18S, "GS_IA18_S") |
579 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
580 | .timer = &at91sam926x_timer, | 579 | .timer = &at91sam926x_timer, |
581 | .map_io = gsia18s_map_io, | 580 | .map_io = at91sam9260_map_io, |
581 | .init_early = gsia18s_init_early, | ||
582 | .init_irq = init_irq, | 582 | .init_irq = init_irq, |
583 | .init_machine = gsia18s_board_init, | 583 | .init_machine = gsia18s_board_init, |
584 | MACHINE_END | 584 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c index d2e1f4ec1fcc..9b003ff744ba 100644 --- a/arch/arm/mach-at91/board-kafa.c +++ b/arch/arm/mach-at91/board-kafa.c | |||
@@ -35,14 +35,18 @@ | |||
35 | 35 | ||
36 | #include <mach/board.h> | 36 | #include <mach/board.h> |
37 | #include <mach/gpio.h> | 37 | #include <mach/gpio.h> |
38 | #include <mach/cpu.h> | ||
38 | 39 | ||
39 | #include "generic.h" | 40 | #include "generic.h" |
40 | 41 | ||
41 | 42 | ||
42 | static void __init kafa_map_io(void) | 43 | static void __init kafa_init_early(void) |
43 | { | 44 | { |
45 | /* Set cpu type: PQFP */ | ||
46 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
47 | |||
44 | /* Initialize processor: 18.432 MHz crystal */ | 48 | /* Initialize processor: 18.432 MHz crystal */ |
45 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | 49 | at91rm9200_initialize(18432000); |
46 | 50 | ||
47 | /* Set up the LEDs */ | 51 | /* Set up the LEDs */ |
48 | at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); | 52 | at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); |
@@ -94,9 +98,9 @@ static void __init kafa_board_init(void) | |||
94 | 98 | ||
95 | MACHINE_START(KAFA, "Sperry-Sun KAFA") | 99 | MACHINE_START(KAFA, "Sperry-Sun KAFA") |
96 | /* Maintainer: Sergei Sharonov */ | 100 | /* Maintainer: Sergei Sharonov */ |
97 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
98 | .timer = &at91rm9200_timer, | 101 | .timer = &at91rm9200_timer, |
99 | .map_io = kafa_map_io, | 102 | .map_io = at91rm9200_map_io, |
103 | .init_early = kafa_init_early, | ||
100 | .init_irq = kafa_init_irq, | 104 | .init_irq = kafa_init_irq, |
101 | .init_machine = kafa_board_init, | 105 | .init_machine = kafa_board_init, |
102 | MACHINE_END | 106 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index a13d2063faff..a813a74b65f9 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c | |||
@@ -36,16 +36,19 @@ | |||
36 | 36 | ||
37 | #include <mach/board.h> | 37 | #include <mach/board.h> |
38 | #include <mach/gpio.h> | 38 | #include <mach/gpio.h> |
39 | 39 | #include <mach/cpu.h> | |
40 | #include <mach/at91rm9200_mc.h> | 40 | #include <mach/at91rm9200_mc.h> |
41 | 41 | ||
42 | #include "generic.h" | 42 | #include "generic.h" |
43 | 43 | ||
44 | 44 | ||
45 | static void __init kb9202_map_io(void) | 45 | static void __init kb9202_init_early(void) |
46 | { | 46 | { |
47 | /* Set cpu type: PQFP */ | ||
48 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
49 | |||
47 | /* Initialize processor: 10 MHz crystal */ | 50 | /* Initialize processor: 10 MHz crystal */ |
48 | at91rm9200_initialize(10000000, AT91RM9200_PQFP); | 51 | at91rm9200_initialize(10000000); |
49 | 52 | ||
50 | /* Set up the LEDs */ | 53 | /* Set up the LEDs */ |
51 | at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); | 54 | at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); |
@@ -136,9 +139,9 @@ static void __init kb9202_board_init(void) | |||
136 | 139 | ||
137 | MACHINE_START(KB9200, "KB920x") | 140 | MACHINE_START(KB9200, "KB920x") |
138 | /* Maintainer: KwikByte, Inc. */ | 141 | /* Maintainer: KwikByte, Inc. */ |
139 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
140 | .timer = &at91rm9200_timer, | 142 | .timer = &at91rm9200_timer, |
141 | .map_io = kb9202_map_io, | 143 | .map_io = at91rm9200_map_io, |
144 | .init_early = kb9202_init_early, | ||
142 | .init_irq = kb9202_init_irq, | 145 | .init_irq = kb9202_init_irq, |
143 | .init_machine = kb9202_board_init, | 146 | .init_machine = kb9202_board_init, |
144 | MACHINE_END | 147 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index fe5f1d47e6e2..961e805db68c 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include "generic.h" | 51 | #include "generic.h" |
52 | 52 | ||
53 | 53 | ||
54 | static void __init neocore926_map_io(void) | 54 | static void __init neocore926_init_early(void) |
55 | { | 55 | { |
56 | /* Initialize processor: 20 MHz crystal */ | 56 | /* Initialize processor: 20 MHz crystal */ |
57 | at91sam9263_initialize(20000000); | 57 | at91sam9263_initialize(20000000); |
@@ -387,9 +387,9 @@ static void __init neocore926_board_init(void) | |||
387 | 387 | ||
388 | MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926") | 388 | MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926") |
389 | /* Maintainer: ADENEO */ | 389 | /* Maintainer: ADENEO */ |
390 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
391 | .timer = &at91sam926x_timer, | 390 | .timer = &at91sam926x_timer, |
392 | .map_io = neocore926_map_io, | 391 | .map_io = at91sam9263_map_io, |
392 | .init_early = neocore926_init_early, | ||
393 | .init_irq = neocore926_init_irq, | 393 | .init_irq = neocore926_init_irq, |
394 | .init_machine = neocore926_board_init, | 394 | .init_machine = neocore926_board_init, |
395 | MACHINE_END | 395 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index feb65787c30b..21a21af25878 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c | |||
@@ -37,9 +37,9 @@ | |||
37 | #include "generic.h" | 37 | #include "generic.h" |
38 | 38 | ||
39 | 39 | ||
40 | static void __init pcontrol_g20_map_io(void) | 40 | static void __init pcontrol_g20_init_early(void) |
41 | { | 41 | { |
42 | stamp9g20_map_io(); | 42 | stamp9g20_init_early(); |
43 | 43 | ||
44 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ | 44 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ |
45 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | 45 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
@@ -222,9 +222,9 @@ static void __init pcontrol_g20_board_init(void) | |||
222 | 222 | ||
223 | MACHINE_START(PCONTROL_G20, "PControl G20") | 223 | MACHINE_START(PCONTROL_G20, "PControl G20") |
224 | /* Maintainer: pgsellmann@portner-elektronik.at */ | 224 | /* Maintainer: pgsellmann@portner-elektronik.at */ |
225 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
226 | .timer = &at91sam926x_timer, | 225 | .timer = &at91sam926x_timer, |
227 | .map_io = pcontrol_g20_map_io, | 226 | .map_io = at91sam9260_map_io, |
227 | .init_early = pcontrol_g20_init_early, | ||
228 | .init_irq = init_irq, | 228 | .init_irq = init_irq, |
229 | .init_machine = pcontrol_g20_board_init, | 229 | .init_machine = pcontrol_g20_board_init, |
230 | MACHINE_END | 230 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index 55dad3a46547..756cc2a745dd 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c | |||
@@ -43,10 +43,10 @@ | |||
43 | #include "generic.h" | 43 | #include "generic.h" |
44 | 44 | ||
45 | 45 | ||
46 | static void __init picotux200_map_io(void) | 46 | static void __init picotux200_init_early(void) |
47 | { | 47 | { |
48 | /* Initialize processor: 18.432 MHz crystal */ | 48 | /* Initialize processor: 18.432 MHz crystal */ |
49 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | 49 | at91rm9200_initialize(18432000); |
50 | 50 | ||
51 | /* DBGU on ttyS0. (Rx & Tx only) */ | 51 | /* DBGU on ttyS0. (Rx & Tx only) */ |
52 | at91_register_uart(0, 0, 0); | 52 | at91_register_uart(0, 0, 0); |
@@ -123,9 +123,9 @@ static void __init picotux200_board_init(void) | |||
123 | 123 | ||
124 | MACHINE_START(PICOTUX2XX, "picotux 200") | 124 | MACHINE_START(PICOTUX2XX, "picotux 200") |
125 | /* Maintainer: Kleinhenz Elektronik GmbH */ | 125 | /* Maintainer: Kleinhenz Elektronik GmbH */ |
126 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
127 | .timer = &at91rm9200_timer, | 126 | .timer = &at91rm9200_timer, |
128 | .map_io = picotux200_map_io, | 127 | .map_io = at91rm9200_map_io, |
128 | .init_early = picotux200_init_early, | ||
129 | .init_irq = picotux200_init_irq, | 129 | .init_irq = picotux200_init_irq, |
130 | .init_machine = picotux200_board_init, | 130 | .init_machine = picotux200_board_init, |
131 | MACHINE_END | 131 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 69d15a875b66..d1a6001b0bd8 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include "generic.h" | 48 | #include "generic.h" |
49 | 49 | ||
50 | 50 | ||
51 | static void __init ek_map_io(void) | 51 | static void __init ek_init_early(void) |
52 | { | 52 | { |
53 | /* Initialize processor: 12.000 MHz crystal */ | 53 | /* Initialize processor: 12.000 MHz crystal */ |
54 | at91sam9260_initialize(12000000); | 54 | at91sam9260_initialize(12000000); |
@@ -268,9 +268,9 @@ static void __init ek_board_init(void) | |||
268 | 268 | ||
269 | MACHINE_START(QIL_A9260, "CALAO QIL_A9260") | 269 | MACHINE_START(QIL_A9260, "CALAO QIL_A9260") |
270 | /* Maintainer: calao-systems */ | 270 | /* Maintainer: calao-systems */ |
271 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
272 | .timer = &at91sam926x_timer, | 271 | .timer = &at91sam926x_timer, |
273 | .map_io = ek_map_io, | 272 | .map_io = at91sam9260_map_io, |
273 | .init_early = ek_init_early, | ||
274 | .init_irq = ek_init_irq, | 274 | .init_irq = ek_init_irq, |
275 | .init_machine = ek_board_init, | 275 | .init_machine = ek_board_init, |
276 | MACHINE_END | 276 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 4c1047c8200d..aef9627710b0 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c | |||
@@ -45,10 +45,10 @@ | |||
45 | #include "generic.h" | 45 | #include "generic.h" |
46 | 46 | ||
47 | 47 | ||
48 | static void __init dk_map_io(void) | 48 | static void __init dk_init_early(void) |
49 | { | 49 | { |
50 | /* Initialize processor: 18.432 MHz crystal */ | 50 | /* Initialize processor: 18.432 MHz crystal */ |
51 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | 51 | at91rm9200_initialize(18432000); |
52 | 52 | ||
53 | /* Setup the LEDs */ | 53 | /* Setup the LEDs */ |
54 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | 54 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); |
@@ -227,9 +227,9 @@ static void __init dk_board_init(void) | |||
227 | 227 | ||
228 | MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") | 228 | MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") |
229 | /* Maintainer: SAN People/Atmel */ | 229 | /* Maintainer: SAN People/Atmel */ |
230 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
231 | .timer = &at91rm9200_timer, | 230 | .timer = &at91rm9200_timer, |
232 | .map_io = dk_map_io, | 231 | .map_io = at91rm9200_map_io, |
232 | .init_early = dk_init_early, | ||
233 | .init_irq = dk_init_irq, | 233 | .init_irq = dk_init_irq, |
234 | .init_machine = dk_board_init, | 234 | .init_machine = dk_board_init, |
235 | MACHINE_END | 235 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index 9df1be8818c0..015a02183080 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c | |||
@@ -45,10 +45,10 @@ | |||
45 | #include "generic.h" | 45 | #include "generic.h" |
46 | 46 | ||
47 | 47 | ||
48 | static void __init ek_map_io(void) | 48 | static void __init ek_init_early(void) |
49 | { | 49 | { |
50 | /* Initialize processor: 18.432 MHz crystal */ | 50 | /* Initialize processor: 18.432 MHz crystal */ |
51 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | 51 | at91rm9200_initialize(18432000); |
52 | 52 | ||
53 | /* Setup the LEDs */ | 53 | /* Setup the LEDs */ |
54 | at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); | 54 | at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); |
@@ -193,9 +193,9 @@ static void __init ek_board_init(void) | |||
193 | 193 | ||
194 | MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") | 194 | MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") |
195 | /* Maintainer: SAN People/Atmel */ | 195 | /* Maintainer: SAN People/Atmel */ |
196 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
197 | .timer = &at91rm9200_timer, | 196 | .timer = &at91rm9200_timer, |
198 | .map_io = ek_map_io, | 197 | .map_io = at91rm9200_map_io, |
198 | .init_early = ek_init_early, | ||
199 | .init_irq = ek_init_irq, | 199 | .init_irq = ek_init_irq, |
200 | .init_machine = ek_board_init, | 200 | .init_machine = ek_board_init, |
201 | MACHINE_END | 201 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 25a26beaa728..aaf1bf0989b3 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include "generic.h" | 44 | #include "generic.h" |
45 | 45 | ||
46 | 46 | ||
47 | static void __init ek_map_io(void) | 47 | static void __init ek_init_early(void) |
48 | { | 48 | { |
49 | /* Initialize processor: 18.432 MHz crystal */ | 49 | /* Initialize processor: 18.432 MHz crystal */ |
50 | at91sam9260_initialize(18432000); | 50 | at91sam9260_initialize(18432000); |
@@ -212,9 +212,9 @@ static void __init ek_board_init(void) | |||
212 | 212 | ||
213 | MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") | 213 | MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") |
214 | /* Maintainer: Olimex */ | 214 | /* Maintainer: Olimex */ |
215 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
216 | .timer = &at91sam926x_timer, | 215 | .timer = &at91sam926x_timer, |
217 | .map_io = ek_map_io, | 216 | .map_io = at91sam9260_map_io, |
217 | .init_early = ek_init_early, | ||
218 | .init_irq = ek_init_irq, | 218 | .init_irq = ek_init_irq, |
219 | .init_machine = ek_board_init, | 219 | .init_machine = ek_board_init, |
220 | MACHINE_END | 220 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index de1816e0e1d9..d600dc123227 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c | |||
@@ -44,12 +44,13 @@ | |||
44 | #include <mach/gpio.h> | 44 | #include <mach/gpio.h> |
45 | #include <mach/at91sam9_smc.h> | 45 | #include <mach/at91sam9_smc.h> |
46 | #include <mach/at91_shdwc.h> | 46 | #include <mach/at91_shdwc.h> |
47 | #include <mach/system_rev.h> | ||
47 | 48 | ||
48 | #include "sam9_smc.h" | 49 | #include "sam9_smc.h" |
49 | #include "generic.h" | 50 | #include "generic.h" |
50 | 51 | ||
51 | 52 | ||
52 | static void __init ek_map_io(void) | 53 | static void __init ek_init_early(void) |
53 | { | 54 | { |
54 | /* Initialize processor: 18.432 MHz crystal */ | 55 | /* Initialize processor: 18.432 MHz crystal */ |
55 | at91sam9260_initialize(18432000); | 56 | at91sam9260_initialize(18432000); |
@@ -191,11 +192,6 @@ static struct atmel_nand_data __initdata ek_nand_data = { | |||
191 | .rdy_pin = AT91_PIN_PC13, | 192 | .rdy_pin = AT91_PIN_PC13, |
192 | .enable_pin = AT91_PIN_PC14, | 193 | .enable_pin = AT91_PIN_PC14, |
193 | .partition_info = nand_partitions, | 194 | .partition_info = nand_partitions, |
194 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
195 | .bus_width_16 = 1, | ||
196 | #else | ||
197 | .bus_width_16 = 0, | ||
198 | #endif | ||
199 | }; | 195 | }; |
200 | 196 | ||
201 | static struct sam9_smc_config __initdata ek_nand_smc_config = { | 197 | static struct sam9_smc_config __initdata ek_nand_smc_config = { |
@@ -218,6 +214,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { | |||
218 | 214 | ||
219 | static void __init ek_add_device_nand(void) | 215 | static void __init ek_add_device_nand(void) |
220 | { | 216 | { |
217 | ek_nand_data.bus_width_16 = !board_have_nand_8bit(); | ||
221 | /* setup bus-width (8 or 16) */ | 218 | /* setup bus-width (8 or 16) */ |
222 | if (ek_nand_data.bus_width_16) | 219 | if (ek_nand_data.bus_width_16) |
223 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | 220 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; |
@@ -356,9 +353,9 @@ static void __init ek_board_init(void) | |||
356 | 353 | ||
357 | MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") | 354 | MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") |
358 | /* Maintainer: Atmel */ | 355 | /* Maintainer: Atmel */ |
359 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
360 | .timer = &at91sam926x_timer, | 356 | .timer = &at91sam926x_timer, |
361 | .map_io = ek_map_io, | 357 | .map_io = at91sam9260_map_io, |
358 | .init_early = ek_init_early, | ||
362 | .init_irq = ek_init_irq, | 359 | .init_irq = ek_init_irq, |
363 | .init_machine = ek_board_init, | 360 | .init_machine = ek_board_init, |
364 | MACHINE_END | 361 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 14acc901e24c..f897f84d43dc 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -48,12 +48,13 @@ | |||
48 | #include <mach/gpio.h> | 48 | #include <mach/gpio.h> |
49 | #include <mach/at91sam9_smc.h> | 49 | #include <mach/at91sam9_smc.h> |
50 | #include <mach/at91_shdwc.h> | 50 | #include <mach/at91_shdwc.h> |
51 | #include <mach/system_rev.h> | ||
51 | 52 | ||
52 | #include "sam9_smc.h" | 53 | #include "sam9_smc.h" |
53 | #include "generic.h" | 54 | #include "generic.h" |
54 | 55 | ||
55 | 56 | ||
56 | static void __init ek_map_io(void) | 57 | static void __init ek_init_early(void) |
57 | { | 58 | { |
58 | /* Initialize processor: 18.432 MHz crystal */ | 59 | /* Initialize processor: 18.432 MHz crystal */ |
59 | at91sam9261_initialize(18432000); | 60 | at91sam9261_initialize(18432000); |
@@ -197,11 +198,6 @@ static struct atmel_nand_data __initdata ek_nand_data = { | |||
197 | .rdy_pin = AT91_PIN_PC15, | 198 | .rdy_pin = AT91_PIN_PC15, |
198 | .enable_pin = AT91_PIN_PC14, | 199 | .enable_pin = AT91_PIN_PC14, |
199 | .partition_info = nand_partitions, | 200 | .partition_info = nand_partitions, |
200 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
201 | .bus_width_16 = 1, | ||
202 | #else | ||
203 | .bus_width_16 = 0, | ||
204 | #endif | ||
205 | }; | 201 | }; |
206 | 202 | ||
207 | static struct sam9_smc_config __initdata ek_nand_smc_config = { | 203 | static struct sam9_smc_config __initdata ek_nand_smc_config = { |
@@ -224,6 +220,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { | |||
224 | 220 | ||
225 | static void __init ek_add_device_nand(void) | 221 | static void __init ek_add_device_nand(void) |
226 | { | 222 | { |
223 | ek_nand_data.bus_width_16 = !board_have_nand_8bit(); | ||
227 | /* setup bus-width (8 or 16) */ | 224 | /* setup bus-width (8 or 16) */ |
228 | if (ek_nand_data.bus_width_16) | 225 | if (ek_nand_data.bus_width_16) |
229 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | 226 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; |
@@ -623,9 +620,9 @@ MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") | |||
623 | MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") | 620 | MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") |
624 | #endif | 621 | #endif |
625 | /* Maintainer: Atmel */ | 622 | /* Maintainer: Atmel */ |
626 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
627 | .timer = &at91sam926x_timer, | 623 | .timer = &at91sam926x_timer, |
628 | .map_io = ek_map_io, | 624 | .map_io = at91sam9261_map_io, |
625 | .init_early = ek_init_early, | ||
629 | .init_irq = ek_init_irq, | 626 | .init_irq = ek_init_irq, |
630 | .init_machine = ek_board_init, | 627 | .init_machine = ek_board_init, |
631 | MACHINE_END | 628 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index bfe490df58be..605b26f40a4c 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c | |||
@@ -47,12 +47,13 @@ | |||
47 | #include <mach/gpio.h> | 47 | #include <mach/gpio.h> |
48 | #include <mach/at91sam9_smc.h> | 48 | #include <mach/at91sam9_smc.h> |
49 | #include <mach/at91_shdwc.h> | 49 | #include <mach/at91_shdwc.h> |
50 | #include <mach/system_rev.h> | ||
50 | 51 | ||
51 | #include "sam9_smc.h" | 52 | #include "sam9_smc.h" |
52 | #include "generic.h" | 53 | #include "generic.h" |
53 | 54 | ||
54 | 55 | ||
55 | static void __init ek_map_io(void) | 56 | static void __init ek_init_early(void) |
56 | { | 57 | { |
57 | /* Initialize processor: 16.367 MHz crystal */ | 58 | /* Initialize processor: 16.367 MHz crystal */ |
58 | at91sam9263_initialize(16367660); | 59 | at91sam9263_initialize(16367660); |
@@ -198,11 +199,6 @@ static struct atmel_nand_data __initdata ek_nand_data = { | |||
198 | .rdy_pin = AT91_PIN_PA22, | 199 | .rdy_pin = AT91_PIN_PA22, |
199 | .enable_pin = AT91_PIN_PD15, | 200 | .enable_pin = AT91_PIN_PD15, |
200 | .partition_info = nand_partitions, | 201 | .partition_info = nand_partitions, |
201 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
202 | .bus_width_16 = 1, | ||
203 | #else | ||
204 | .bus_width_16 = 0, | ||
205 | #endif | ||
206 | }; | 202 | }; |
207 | 203 | ||
208 | static struct sam9_smc_config __initdata ek_nand_smc_config = { | 204 | static struct sam9_smc_config __initdata ek_nand_smc_config = { |
@@ -225,6 +221,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { | |||
225 | 221 | ||
226 | static void __init ek_add_device_nand(void) | 222 | static void __init ek_add_device_nand(void) |
227 | { | 223 | { |
224 | ek_nand_data.bus_width_16 = !board_have_nand_8bit(); | ||
228 | /* setup bus-width (8 or 16) */ | 225 | /* setup bus-width (8 or 16) */ |
229 | if (ek_nand_data.bus_width_16) | 226 | if (ek_nand_data.bus_width_16) |
230 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | 227 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; |
@@ -454,9 +451,9 @@ static void __init ek_board_init(void) | |||
454 | 451 | ||
455 | MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") | 452 | MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") |
456 | /* Maintainer: Atmel */ | 453 | /* Maintainer: Atmel */ |
457 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
458 | .timer = &at91sam926x_timer, | 454 | .timer = &at91sam926x_timer, |
459 | .map_io = ek_map_io, | 455 | .map_io = at91sam9263_map_io, |
456 | .init_early = ek_init_early, | ||
460 | .init_irq = ek_init_irq, | 457 | .init_irq = ek_init_irq, |
461 | .init_machine = ek_board_init, | 458 | .init_machine = ek_board_init, |
462 | MACHINE_END | 459 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index ca8198b3c168..7624cf0d006b 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <mach/board.h> | 43 | #include <mach/board.h> |
44 | #include <mach/gpio.h> | 44 | #include <mach/gpio.h> |
45 | #include <mach/at91sam9_smc.h> | 45 | #include <mach/at91sam9_smc.h> |
46 | #include <mach/system_rev.h> | ||
46 | 47 | ||
47 | #include "sam9_smc.h" | 48 | #include "sam9_smc.h" |
48 | #include "generic.h" | 49 | #include "generic.h" |
@@ -60,7 +61,7 @@ static int inline ek_have_2mmc(void) | |||
60 | } | 61 | } |
61 | 62 | ||
62 | 63 | ||
63 | static void __init ek_map_io(void) | 64 | static void __init ek_init_early(void) |
64 | { | 65 | { |
65 | /* Initialize processor: 18.432 MHz crystal */ | 66 | /* Initialize processor: 18.432 MHz crystal */ |
66 | at91sam9260_initialize(18432000); | 67 | at91sam9260_initialize(18432000); |
@@ -175,11 +176,6 @@ static struct atmel_nand_data __initdata ek_nand_data = { | |||
175 | .rdy_pin = AT91_PIN_PC13, | 176 | .rdy_pin = AT91_PIN_PC13, |
176 | .enable_pin = AT91_PIN_PC14, | 177 | .enable_pin = AT91_PIN_PC14, |
177 | .partition_info = nand_partitions, | 178 | .partition_info = nand_partitions, |
178 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
179 | .bus_width_16 = 1, | ||
180 | #else | ||
181 | .bus_width_16 = 0, | ||
182 | #endif | ||
183 | }; | 179 | }; |
184 | 180 | ||
185 | static struct sam9_smc_config __initdata ek_nand_smc_config = { | 181 | static struct sam9_smc_config __initdata ek_nand_smc_config = { |
@@ -202,6 +198,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { | |||
202 | 198 | ||
203 | static void __init ek_add_device_nand(void) | 199 | static void __init ek_add_device_nand(void) |
204 | { | 200 | { |
201 | ek_nand_data.bus_width_16 = !board_have_nand_8bit(); | ||
205 | /* setup bus-width (8 or 16) */ | 202 | /* setup bus-width (8 or 16) */ |
206 | if (ek_nand_data.bus_width_16) | 203 | if (ek_nand_data.bus_width_16) |
207 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | 204 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; |
@@ -406,18 +403,18 @@ static void __init ek_board_init(void) | |||
406 | 403 | ||
407 | MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") | 404 | MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") |
408 | /* Maintainer: Atmel */ | 405 | /* Maintainer: Atmel */ |
409 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
410 | .timer = &at91sam926x_timer, | 406 | .timer = &at91sam926x_timer, |
411 | .map_io = ek_map_io, | 407 | .map_io = at91sam9260_map_io, |
408 | .init_early = ek_init_early, | ||
412 | .init_irq = ek_init_irq, | 409 | .init_irq = ek_init_irq, |
413 | .init_machine = ek_board_init, | 410 | .init_machine = ek_board_init, |
414 | MACHINE_END | 411 | MACHINE_END |
415 | 412 | ||
416 | MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") | 413 | MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") |
417 | /* Maintainer: Atmel */ | 414 | /* Maintainer: Atmel */ |
418 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
419 | .timer = &at91sam926x_timer, | 415 | .timer = &at91sam926x_timer, |
420 | .map_io = ek_map_io, | 416 | .map_io = at91sam9260_map_io, |
417 | .init_early = ek_init_early, | ||
421 | .init_irq = ek_init_irq, | 418 | .init_irq = ek_init_irq, |
422 | .init_machine = ek_board_init, | 419 | .init_machine = ek_board_init, |
423 | MACHINE_END | 420 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 6c999dbd2bcf..063c95d0e8f0 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c | |||
@@ -41,12 +41,13 @@ | |||
41 | #include <mach/gpio.h> | 41 | #include <mach/gpio.h> |
42 | #include <mach/at91sam9_smc.h> | 42 | #include <mach/at91sam9_smc.h> |
43 | #include <mach/at91_shdwc.h> | 43 | #include <mach/at91_shdwc.h> |
44 | #include <mach/system_rev.h> | ||
44 | 45 | ||
45 | #include "sam9_smc.h" | 46 | #include "sam9_smc.h" |
46 | #include "generic.h" | 47 | #include "generic.h" |
47 | 48 | ||
48 | 49 | ||
49 | static void __init ek_map_io(void) | 50 | static void __init ek_init_early(void) |
50 | { | 51 | { |
51 | /* Initialize processor: 12.000 MHz crystal */ | 52 | /* Initialize processor: 12.000 MHz crystal */ |
52 | at91sam9g45_initialize(12000000); | 53 | at91sam9g45_initialize(12000000); |
@@ -155,11 +156,6 @@ static struct atmel_nand_data __initdata ek_nand_data = { | |||
155 | .rdy_pin = AT91_PIN_PC8, | 156 | .rdy_pin = AT91_PIN_PC8, |
156 | .enable_pin = AT91_PIN_PC14, | 157 | .enable_pin = AT91_PIN_PC14, |
157 | .partition_info = nand_partitions, | 158 | .partition_info = nand_partitions, |
158 | #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) | ||
159 | .bus_width_16 = 1, | ||
160 | #else | ||
161 | .bus_width_16 = 0, | ||
162 | #endif | ||
163 | }; | 159 | }; |
164 | 160 | ||
165 | static struct sam9_smc_config __initdata ek_nand_smc_config = { | 161 | static struct sam9_smc_config __initdata ek_nand_smc_config = { |
@@ -182,6 +178,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { | |||
182 | 178 | ||
183 | static void __init ek_add_device_nand(void) | 179 | static void __init ek_add_device_nand(void) |
184 | { | 180 | { |
181 | ek_nand_data.bus_width_16 = !board_have_nand_8bit(); | ||
185 | /* setup bus-width (8 or 16) */ | 182 | /* setup bus-width (8 or 16) */ |
186 | if (ek_nand_data.bus_width_16) | 183 | if (ek_nand_data.bus_width_16) |
187 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | 184 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; |
@@ -424,9 +421,9 @@ static void __init ek_board_init(void) | |||
424 | 421 | ||
425 | MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") | 422 | MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") |
426 | /* Maintainer: Atmel */ | 423 | /* Maintainer: Atmel */ |
427 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
428 | .timer = &at91sam926x_timer, | 424 | .timer = &at91sam926x_timer, |
429 | .map_io = ek_map_io, | 425 | .map_io = at91sam9g45_map_io, |
426 | .init_early = ek_init_early, | ||
430 | .init_irq = ek_init_irq, | 427 | .init_irq = ek_init_irq, |
431 | .init_machine = ek_board_init, | 428 | .init_machine = ek_board_init, |
432 | MACHINE_END | 429 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index 3bf3408e94c1..effb399a80a6 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "generic.h" | 38 | #include "generic.h" |
39 | 39 | ||
40 | 40 | ||
41 | static void __init ek_map_io(void) | 41 | static void __init ek_init_early(void) |
42 | { | 42 | { |
43 | /* Initialize processor: 12.000 MHz crystal */ | 43 | /* Initialize processor: 12.000 MHz crystal */ |
44 | at91sam9rl_initialize(12000000); | 44 | at91sam9rl_initialize(12000000); |
@@ -329,9 +329,9 @@ static void __init ek_board_init(void) | |||
329 | 329 | ||
330 | MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") | 330 | MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") |
331 | /* Maintainer: Atmel */ | 331 | /* Maintainer: Atmel */ |
332 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
333 | .timer = &at91sam926x_timer, | 332 | .timer = &at91sam926x_timer, |
334 | .map_io = ek_map_io, | 333 | .map_io = at91sam9rl_map_io, |
334 | .init_early = ek_init_early, | ||
335 | .init_irq = ek_init_irq, | 335 | .init_irq = ek_init_irq, |
336 | .init_machine = ek_board_init, | 336 | .init_machine = ek_board_init, |
337 | MACHINE_END | 337 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 17f7d9b32142..3eb0a1153cc8 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | #define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x)) | 41 | #define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x)) |
42 | 42 | ||
43 | static void __init snapper9260_map_io(void) | 43 | static void __init snapper9260_init_early(void) |
44 | { | 44 | { |
45 | at91sam9260_initialize(18432000); | 45 | at91sam9260_initialize(18432000); |
46 | 46 | ||
@@ -178,9 +178,9 @@ static void __init snapper9260_board_init(void) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") | 180 | MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") |
181 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
182 | .timer = &at91sam926x_timer, | 181 | .timer = &at91sam926x_timer, |
183 | .map_io = snapper9260_map_io, | 182 | .map_io = at91sam9260_map_io, |
183 | .init_early = snapper9260_init_early, | ||
184 | .init_irq = snapper9260_init_irq, | 184 | .init_irq = snapper9260_init_irq, |
185 | .init_machine = snapper9260_board_init, | 185 | .init_machine = snapper9260_board_init, |
186 | MACHINE_END | 186 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index f8902b118960..5e5c85688f5f 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "generic.h" | 32 | #include "generic.h" |
33 | 33 | ||
34 | 34 | ||
35 | void __init stamp9g20_map_io(void) | 35 | void __init stamp9g20_init_early(void) |
36 | { | 36 | { |
37 | /* Initialize processor: 18.432 MHz crystal */ | 37 | /* Initialize processor: 18.432 MHz crystal */ |
38 | at91sam9260_initialize(18432000); | 38 | at91sam9260_initialize(18432000); |
@@ -44,9 +44,9 @@ void __init stamp9g20_map_io(void) | |||
44 | at91_set_serial_console(0); | 44 | at91_set_serial_console(0); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void __init stamp9g20evb_map_io(void) | 47 | static void __init stamp9g20evb_init_early(void) |
48 | { | 48 | { |
49 | stamp9g20_map_io(); | 49 | stamp9g20_init_early(); |
50 | 50 | ||
51 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | 51 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ |
52 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | 52 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS |
@@ -54,9 +54,9 @@ static void __init stamp9g20evb_map_io(void) | |||
54 | | ATMEL_UART_DCD | ATMEL_UART_RI); | 54 | | ATMEL_UART_DCD | ATMEL_UART_RI); |
55 | } | 55 | } |
56 | 56 | ||
57 | static void __init portuxg20_map_io(void) | 57 | static void __init portuxg20_init_early(void) |
58 | { | 58 | { |
59 | stamp9g20_map_io(); | 59 | stamp9g20_init_early(); |
60 | 60 | ||
61 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | 61 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ |
62 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | 62 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS |
@@ -298,18 +298,18 @@ static void __init stamp9g20evb_board_init(void) | |||
298 | 298 | ||
299 | MACHINE_START(PORTUXG20, "taskit PortuxG20") | 299 | MACHINE_START(PORTUXG20, "taskit PortuxG20") |
300 | /* Maintainer: taskit GmbH */ | 300 | /* Maintainer: taskit GmbH */ |
301 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
302 | .timer = &at91sam926x_timer, | 301 | .timer = &at91sam926x_timer, |
303 | .map_io = portuxg20_map_io, | 302 | .map_io = at91sam9260_map_io, |
303 | .init_early = portuxg20_init_early, | ||
304 | .init_irq = init_irq, | 304 | .init_irq = init_irq, |
305 | .init_machine = portuxg20_board_init, | 305 | .init_machine = portuxg20_board_init, |
306 | MACHINE_END | 306 | MACHINE_END |
307 | 307 | ||
308 | MACHINE_START(STAMP9G20, "taskit Stamp9G20") | 308 | MACHINE_START(STAMP9G20, "taskit Stamp9G20") |
309 | /* Maintainer: taskit GmbH */ | 309 | /* Maintainer: taskit GmbH */ |
310 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
311 | .timer = &at91sam926x_timer, | 310 | .timer = &at91sam926x_timer, |
312 | .map_io = stamp9g20evb_map_io, | 311 | .map_io = at91sam9260_map_io, |
312 | .init_early = stamp9g20evb_init_early, | ||
313 | .init_irq = init_irq, | 313 | .init_irq = init_irq, |
314 | .init_machine = stamp9g20evb_board_init, | 314 | .init_machine = stamp9g20evb_board_init, |
315 | MACHINE_END | 315 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c index 07784baeae84..0e784e6fedec 100644 --- a/arch/arm/mach-at91/board-usb-a9260.c +++ b/arch/arm/mach-at91/board-usb-a9260.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include "generic.h" | 48 | #include "generic.h" |
49 | 49 | ||
50 | 50 | ||
51 | static void __init ek_map_io(void) | 51 | static void __init ek_init_early(void) |
52 | { | 52 | { |
53 | /* Initialize processor: 12.000 MHz crystal */ | 53 | /* Initialize processor: 12.000 MHz crystal */ |
54 | at91sam9260_initialize(12000000); | 54 | at91sam9260_initialize(12000000); |
@@ -228,9 +228,9 @@ static void __init ek_board_init(void) | |||
228 | 228 | ||
229 | MACHINE_START(USB_A9260, "CALAO USB_A9260") | 229 | MACHINE_START(USB_A9260, "CALAO USB_A9260") |
230 | /* Maintainer: calao-systems */ | 230 | /* Maintainer: calao-systems */ |
231 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
232 | .timer = &at91sam926x_timer, | 231 | .timer = &at91sam926x_timer, |
233 | .map_io = ek_map_io, | 232 | .map_io = at91sam9260_map_io, |
233 | .init_early = ek_init_early, | ||
234 | .init_irq = ek_init_irq, | 234 | .init_irq = ek_init_irq, |
235 | .init_machine = ek_board_init, | 235 | .init_machine = ek_board_init, |
236 | MACHINE_END | 236 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c index b614508931fd..cf626dd14b2c 100644 --- a/arch/arm/mach-at91/board-usb-a9263.c +++ b/arch/arm/mach-at91/board-usb-a9263.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include "generic.h" | 47 | #include "generic.h" |
48 | 48 | ||
49 | 49 | ||
50 | static void __init ek_map_io(void) | 50 | static void __init ek_init_early(void) |
51 | { | 51 | { |
52 | /* Initialize processor: 12.00 MHz crystal */ | 52 | /* Initialize processor: 12.00 MHz crystal */ |
53 | at91sam9263_initialize(12000000); | 53 | at91sam9263_initialize(12000000); |
@@ -244,9 +244,9 @@ static void __init ek_board_init(void) | |||
244 | 244 | ||
245 | MACHINE_START(USB_A9263, "CALAO USB_A9263") | 245 | MACHINE_START(USB_A9263, "CALAO USB_A9263") |
246 | /* Maintainer: calao-systems */ | 246 | /* Maintainer: calao-systems */ |
247 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
248 | .timer = &at91sam926x_timer, | 247 | .timer = &at91sam926x_timer, |
249 | .map_io = ek_map_io, | 248 | .map_io = at91sam9263_map_io, |
249 | .init_early = ek_init_early, | ||
250 | .init_irq = ek_init_irq, | 250 | .init_irq = ek_init_irq, |
251 | .init_machine = ek_board_init, | 251 | .init_machine = ek_board_init, |
252 | MACHINE_END | 252 | MACHINE_END |
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index e0f0080eb639..c208cc334d7d 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c | |||
@@ -45,14 +45,18 @@ | |||
45 | #include <mach/board.h> | 45 | #include <mach/board.h> |
46 | #include <mach/gpio.h> | 46 | #include <mach/gpio.h> |
47 | #include <mach/at91rm9200_mc.h> | 47 | #include <mach/at91rm9200_mc.h> |
48 | #include <mach/cpu.h> | ||
48 | 49 | ||
49 | #include "generic.h" | 50 | #include "generic.h" |
50 | 51 | ||
51 | 52 | ||
52 | static void __init yl9200_map_io(void) | 53 | static void __init yl9200_init_early(void) |
53 | { | 54 | { |
55 | /* Set cpu type: PQFP */ | ||
56 | at91rm9200_set_type(ARCH_REVISON_9200_PQFP); | ||
57 | |||
54 | /* Initialize processor: 18.432 MHz crystal */ | 58 | /* Initialize processor: 18.432 MHz crystal */ |
55 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | 59 | at91rm9200_initialize(18432000); |
56 | 60 | ||
57 | /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ | 61 | /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ |
58 | at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); | 62 | at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); |
@@ -594,9 +598,9 @@ static void __init yl9200_board_init(void) | |||
594 | 598 | ||
595 | MACHINE_START(YL9200, "uCdragon YL-9200") | 599 | MACHINE_START(YL9200, "uCdragon YL-9200") |
596 | /* Maintainer: S.Birtles */ | 600 | /* Maintainer: S.Birtles */ |
597 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
598 | .timer = &at91rm9200_timer, | 601 | .timer = &at91rm9200_timer, |
599 | .map_io = yl9200_map_io, | 602 | .map_io = at91rm9200_map_io, |
603 | .init_early = yl9200_init_early, | ||
600 | .init_irq = yl9200_init_irq, | 604 | .init_irq = yl9200_init_irq, |
601 | .init_machine = yl9200_board_init, | 605 | .init_machine = yl9200_board_init, |
602 | MACHINE_END | 606 | MACHINE_END |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 9113da6845f1..61873f3aa92d 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -163,7 +163,7 @@ static struct clk udpck = { | |||
163 | .parent = &pllb, | 163 | .parent = &pllb, |
164 | .mode = pmc_sys_mode, | 164 | .mode = pmc_sys_mode, |
165 | }; | 165 | }; |
166 | static struct clk utmi_clk = { | 166 | struct clk utmi_clk = { |
167 | .name = "utmi_clk", | 167 | .name = "utmi_clk", |
168 | .parent = &main_clk, | 168 | .parent = &main_clk, |
169 | .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */ | 169 | .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */ |
@@ -182,7 +182,7 @@ static struct clk uhpck = { | |||
182 | * memory, interfaces to on-chip peripherals, the AIC, and sometimes more | 182 | * memory, interfaces to on-chip peripherals, the AIC, and sometimes more |
183 | * (e.g baud rate generation). It's sourced from one of the primary clocks. | 183 | * (e.g baud rate generation). It's sourced from one of the primary clocks. |
184 | */ | 184 | */ |
185 | static struct clk mck = { | 185 | struct clk mck = { |
186 | .name = "mck", | 186 | .name = "mck", |
187 | .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ | 187 | .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ |
188 | }; | 188 | }; |
@@ -215,43 +215,6 @@ static struct clk __init *at91_css_to_clk(unsigned long css) | |||
215 | return NULL; | 215 | return NULL; |
216 | } | 216 | } |
217 | 217 | ||
218 | /* | ||
219 | * Associate a particular clock with a function (eg, "uart") and device. | ||
220 | * The drivers can then request the same 'function' with several different | ||
221 | * devices and not care about which clock name to use. | ||
222 | */ | ||
223 | void __init at91_clock_associate(const char *id, struct device *dev, const char *func) | ||
224 | { | ||
225 | struct clk *clk = clk_get(NULL, id); | ||
226 | |||
227 | if (!dev || !clk || !IS_ERR(clk_get(dev, func))) | ||
228 | return; | ||
229 | |||
230 | clk->function = func; | ||
231 | clk->dev = dev; | ||
232 | } | ||
233 | |||
234 | /* clocks cannot be de-registered no refcounting necessary */ | ||
235 | struct clk *clk_get(struct device *dev, const char *id) | ||
236 | { | ||
237 | struct clk *clk; | ||
238 | |||
239 | list_for_each_entry(clk, &clocks, node) { | ||
240 | if (strcmp(id, clk->name) == 0) | ||
241 | return clk; | ||
242 | if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) | ||
243 | return clk; | ||
244 | } | ||
245 | |||
246 | return ERR_PTR(-ENOENT); | ||
247 | } | ||
248 | EXPORT_SYMBOL(clk_get); | ||
249 | |||
250 | void clk_put(struct clk *clk) | ||
251 | { | ||
252 | } | ||
253 | EXPORT_SYMBOL(clk_put); | ||
254 | |||
255 | static void __clk_enable(struct clk *clk) | 218 | static void __clk_enable(struct clk *clk) |
256 | { | 219 | { |
257 | if (clk->parent) | 220 | if (clk->parent) |
@@ -498,32 +461,38 @@ postcore_initcall(at91_clk_debugfs_init); | |||
498 | /*------------------------------------------------------------------------*/ | 461 | /*------------------------------------------------------------------------*/ |
499 | 462 | ||
500 | /* Register a new clock */ | 463 | /* Register a new clock */ |
464 | static void __init at91_clk_add(struct clk *clk) | ||
465 | { | ||
466 | list_add_tail(&clk->node, &clocks); | ||
467 | |||
468 | clk->cl.con_id = clk->name; | ||
469 | clk->cl.clk = clk; | ||
470 | clkdev_add(&clk->cl); | ||
471 | } | ||
472 | |||
501 | int __init clk_register(struct clk *clk) | 473 | int __init clk_register(struct clk *clk) |
502 | { | 474 | { |
503 | if (clk_is_peripheral(clk)) { | 475 | if (clk_is_peripheral(clk)) { |
504 | if (!clk->parent) | 476 | if (!clk->parent) |
505 | clk->parent = &mck; | 477 | clk->parent = &mck; |
506 | clk->mode = pmc_periph_mode; | 478 | clk->mode = pmc_periph_mode; |
507 | list_add_tail(&clk->node, &clocks); | ||
508 | } | 479 | } |
509 | else if (clk_is_sys(clk)) { | 480 | else if (clk_is_sys(clk)) { |
510 | clk->parent = &mck; | 481 | clk->parent = &mck; |
511 | clk->mode = pmc_sys_mode; | 482 | clk->mode = pmc_sys_mode; |
512 | |||
513 | list_add_tail(&clk->node, &clocks); | ||
514 | } | 483 | } |
515 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | 484 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS |
516 | else if (clk_is_programmable(clk)) { | 485 | else if (clk_is_programmable(clk)) { |
517 | clk->mode = pmc_sys_mode; | 486 | clk->mode = pmc_sys_mode; |
518 | init_programmable_clock(clk); | 487 | init_programmable_clock(clk); |
519 | list_add_tail(&clk->node, &clocks); | ||
520 | } | 488 | } |
521 | #endif | 489 | #endif |
522 | 490 | ||
491 | at91_clk_add(clk); | ||
492 | |||
523 | return 0; | 493 | return 0; |
524 | } | 494 | } |
525 | 495 | ||
526 | |||
527 | /*------------------------------------------------------------------------*/ | 496 | /*------------------------------------------------------------------------*/ |
528 | 497 | ||
529 | static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) | 498 | static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) |
@@ -630,7 +599,7 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) | |||
630 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); | 599 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); |
631 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || | 600 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || |
632 | cpu_is_at91sam9263() || cpu_is_at91sam9g20() || | 601 | cpu_is_at91sam9263() || cpu_is_at91sam9g20() || |
633 | cpu_is_at91sam9g10() || cpu_is_at572d940hf()) { | 602 | cpu_is_at91sam9g10()) { |
634 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | 603 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; |
635 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | 604 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; |
636 | } else if (cpu_is_at91cap9()) { | 605 | } else if (cpu_is_at91cap9()) { |
@@ -754,19 +723,19 @@ int __init at91_clock_init(unsigned long main_clock) | |||
754 | 723 | ||
755 | /* Register the PMC's standard clocks */ | 724 | /* Register the PMC's standard clocks */ |
756 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | 725 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) |
757 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); | 726 | at91_clk_add(standard_pmc_clocks[i]); |
758 | 727 | ||
759 | if (cpu_has_pllb()) | 728 | if (cpu_has_pllb()) |
760 | list_add_tail(&pllb.node, &clocks); | 729 | at91_clk_add(&pllb); |
761 | 730 | ||
762 | if (cpu_has_uhp()) | 731 | if (cpu_has_uhp()) |
763 | list_add_tail(&uhpck.node, &clocks); | 732 | at91_clk_add(&uhpck); |
764 | 733 | ||
765 | if (cpu_has_udpfs()) | 734 | if (cpu_has_udpfs()) |
766 | list_add_tail(&udpck.node, &clocks); | 735 | at91_clk_add(&udpck); |
767 | 736 | ||
768 | if (cpu_has_utmi()) | 737 | if (cpu_has_utmi()) |
769 | list_add_tail(&utmi_clk.node, &clocks); | 738 | at91_clk_add(&utmi_clk); |
770 | 739 | ||
771 | /* MCK and CPU clock are "always on" */ | 740 | /* MCK and CPU clock are "always on" */ |
772 | clk_enable(&mck); | 741 | clk_enable(&mck); |
diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h index 6cf4b78e175d..c2e63e47dcbe 100644 --- a/arch/arm/mach-at91/clock.h +++ b/arch/arm/mach-at91/clock.h | |||
@@ -6,6 +6,8 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/clkdev.h> | ||
10 | |||
9 | #define CLK_TYPE_PRIMARY 0x1 | 11 | #define CLK_TYPE_PRIMARY 0x1 |
10 | #define CLK_TYPE_PLL 0x2 | 12 | #define CLK_TYPE_PLL 0x2 |
11 | #define CLK_TYPE_PROGRAMMABLE 0x4 | 13 | #define CLK_TYPE_PROGRAMMABLE 0x4 |
@@ -16,8 +18,7 @@ | |||
16 | struct clk { | 18 | struct clk { |
17 | struct list_head node; | 19 | struct list_head node; |
18 | const char *name; /* unique clock name */ | 20 | const char *name; /* unique clock name */ |
19 | const char *function; /* function of the clock */ | 21 | struct clk_lookup cl; |
20 | struct device *dev; /* device associated with function */ | ||
21 | unsigned long rate_hz; | 22 | unsigned long rate_hz; |
22 | struct clk *parent; | 23 | struct clk *parent; |
23 | u32 pmc_mask; | 24 | u32 pmc_mask; |
@@ -29,3 +30,18 @@ struct clk { | |||
29 | 30 | ||
30 | 31 | ||
31 | extern int __init clk_register(struct clk *clk); | 32 | extern int __init clk_register(struct clk *clk); |
33 | extern struct clk mck; | ||
34 | extern struct clk utmi_clk; | ||
35 | |||
36 | #define CLKDEV_CON_ID(_id, _clk) \ | ||
37 | { \ | ||
38 | .con_id = _id, \ | ||
39 | .clk = _clk, \ | ||
40 | } | ||
41 | |||
42 | #define CLKDEV_CON_DEV_ID(_con_id, _dev_id, _clk) \ | ||
43 | { \ | ||
44 | .con_id = _con_id, \ | ||
45 | .dev_id = _dev_id, \ | ||
46 | .clk = _clk, \ | ||
47 | } | ||
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 0c66deb2db39..8ff3418f3430 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h | |||
@@ -8,8 +8,21 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/clkdev.h> | ||
12 | |||
13 | /* Map io */ | ||
14 | extern void __init at91rm9200_map_io(void); | ||
15 | extern void __init at91sam9260_map_io(void); | ||
16 | extern void __init at91sam9261_map_io(void); | ||
17 | extern void __init at91sam9263_map_io(void); | ||
18 | extern void __init at91sam9rl_map_io(void); | ||
19 | extern void __init at91sam9g45_map_io(void); | ||
20 | extern void __init at91x40_map_io(void); | ||
21 | extern void __init at91cap9_map_io(void); | ||
22 | |||
11 | /* Processors */ | 23 | /* Processors */ |
12 | extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); | 24 | extern void __init at91rm9200_set_type(int type); |
25 | extern void __init at91rm9200_initialize(unsigned long main_clock); | ||
13 | extern void __init at91sam9260_initialize(unsigned long main_clock); | 26 | extern void __init at91sam9260_initialize(unsigned long main_clock); |
14 | extern void __init at91sam9261_initialize(unsigned long main_clock); | 27 | extern void __init at91sam9261_initialize(unsigned long main_clock); |
15 | extern void __init at91sam9263_initialize(unsigned long main_clock); | 28 | extern void __init at91sam9263_initialize(unsigned long main_clock); |
@@ -17,7 +30,6 @@ extern void __init at91sam9rl_initialize(unsigned long main_clock); | |||
17 | extern void __init at91sam9g45_initialize(unsigned long main_clock); | 30 | extern void __init at91sam9g45_initialize(unsigned long main_clock); |
18 | extern void __init at91x40_initialize(unsigned long main_clock); | 31 | extern void __init at91x40_initialize(unsigned long main_clock); |
19 | extern void __init at91cap9_initialize(unsigned long main_clock); | 32 | extern void __init at91cap9_initialize(unsigned long main_clock); |
20 | extern void __init at572d940hf_initialize(unsigned long main_clock); | ||
21 | 33 | ||
22 | /* Interrupts */ | 34 | /* Interrupts */ |
23 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); | 35 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); |
@@ -28,7 +40,6 @@ extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); | |||
28 | extern void __init at91sam9g45_init_interrupts(unsigned int priority[]); | 40 | extern void __init at91sam9g45_init_interrupts(unsigned int priority[]); |
29 | extern void __init at91x40_init_interrupts(unsigned int priority[]); | 41 | extern void __init at91x40_init_interrupts(unsigned int priority[]); |
30 | extern void __init at91cap9_init_interrupts(unsigned int priority[]); | 42 | extern void __init at91cap9_init_interrupts(unsigned int priority[]); |
31 | extern void __init at572d940hf_init_interrupts(unsigned int priority[]); | ||
32 | extern void __init at91_aic_init(unsigned int priority[]); | 43 | extern void __init at91_aic_init(unsigned int priority[]); |
33 | 44 | ||
34 | /* Timer */ | 45 | /* Timer */ |
@@ -39,8 +50,19 @@ extern struct sys_timer at91x40_timer; | |||
39 | 50 | ||
40 | /* Clocks */ | 51 | /* Clocks */ |
41 | extern int __init at91_clock_init(unsigned long main_clock); | 52 | extern int __init at91_clock_init(unsigned long main_clock); |
53 | /* | ||
54 | * function to specify the clock of the default console. As we do not | ||
55 | * use the device/driver bus, the dev_name is not intialize. So we need | ||
56 | * to link the clock to a specific con_id only "usart" | ||
57 | */ | ||
58 | extern void __init at91rm9200_set_console_clock(int id); | ||
59 | extern void __init at91sam9260_set_console_clock(int id); | ||
60 | extern void __init at91sam9261_set_console_clock(int id); | ||
61 | extern void __init at91sam9263_set_console_clock(int id); | ||
62 | extern void __init at91sam9rl_set_console_clock(int id); | ||
63 | extern void __init at91sam9g45_set_console_clock(int id); | ||
64 | extern void __init at91cap9_set_console_clock(int id); | ||
42 | struct device; | 65 | struct device; |
43 | extern void __init at91_clock_associate(const char *id, struct device *dev, const char *func); | ||
44 | 66 | ||
45 | /* Power Management */ | 67 | /* Power Management */ |
46 | extern void at91_irq_suspend(void); | 68 | extern void at91_irq_suspend(void); |
diff --git a/arch/arm/mach-at91/include/mach/at572d940hf.h b/arch/arm/mach-at91/include/mach/at572d940hf.h deleted file mode 100644 index be510cfc56be..000000000000 --- a/arch/arm/mach-at91/include/mach/at572d940hf.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | * include/mach/at572d940hf.h | ||
3 | * | ||
4 | * Antonio R. Costa <costa.antonior@gmail.com> | ||
5 | * Copyright (C) 2008 Atmel | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef AT572D940HF_H | ||
24 | #define AT572D940HF_H | ||
25 | |||
26 | /* | ||
27 | * Peripheral identifiers/interrupts. | ||
28 | */ | ||
29 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
30 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
31 | #define AT572D940HF_ID_PIOA 2 /* Parallel IO Controller A */ | ||
32 | #define AT572D940HF_ID_PIOB 3 /* Parallel IO Controller B */ | ||
33 | #define AT572D940HF_ID_PIOC 4 /* Parallel IO Controller C */ | ||
34 | #define AT572D940HF_ID_EMAC 5 /* MACB ethernet controller */ | ||
35 | #define AT572D940HF_ID_US0 6 /* USART 0 */ | ||
36 | #define AT572D940HF_ID_US1 7 /* USART 1 */ | ||
37 | #define AT572D940HF_ID_US2 8 /* USART 2 */ | ||
38 | #define AT572D940HF_ID_MCI 9 /* Multimedia Card Interface */ | ||
39 | #define AT572D940HF_ID_UDP 10 /* USB Device Port */ | ||
40 | #define AT572D940HF_ID_TWI0 11 /* Two-Wire Interface 0 */ | ||
41 | #define AT572D940HF_ID_SPI0 12 /* Serial Peripheral Interface 0 */ | ||
42 | #define AT572D940HF_ID_SPI1 13 /* Serial Peripheral Interface 1 */ | ||
43 | #define AT572D940HF_ID_SSC0 14 /* Serial Synchronous Controller 0 */ | ||
44 | #define AT572D940HF_ID_SSC1 15 /* Serial Synchronous Controller 1 */ | ||
45 | #define AT572D940HF_ID_SSC2 16 /* Serial Synchronous Controller 2 */ | ||
46 | #define AT572D940HF_ID_TC0 17 /* Timer Counter 0 */ | ||
47 | #define AT572D940HF_ID_TC1 18 /* Timer Counter 1 */ | ||
48 | #define AT572D940HF_ID_TC2 19 /* Timer Counter 2 */ | ||
49 | #define AT572D940HF_ID_UHP 20 /* USB Host port */ | ||
50 | #define AT572D940HF_ID_SSC3 21 /* Serial Synchronous Controller 3 */ | ||
51 | #define AT572D940HF_ID_TWI1 22 /* Two-Wire Interface 1 */ | ||
52 | #define AT572D940HF_ID_CAN0 23 /* CAN Controller 0 */ | ||
53 | #define AT572D940HF_ID_CAN1 24 /* CAN Controller 1 */ | ||
54 | #define AT572D940HF_ID_MHALT 25 /* mAgicV HALT line */ | ||
55 | #define AT572D940HF_ID_MSIRQ0 26 /* mAgicV SIRQ0 line */ | ||
56 | #define AT572D940HF_ID_MEXC 27 /* mAgicV exception line */ | ||
57 | #define AT572D940HF_ID_MEDMA 28 /* mAgicV end of DMA line */ | ||
58 | #define AT572D940HF_ID_IRQ0 29 /* External Interrupt Source (IRQ0) */ | ||
59 | #define AT572D940HF_ID_IRQ1 30 /* External Interrupt Source (IRQ1) */ | ||
60 | #define AT572D940HF_ID_IRQ2 31 /* External Interrupt Source (IRQ2) */ | ||
61 | |||
62 | |||
63 | /* | ||
64 | * User Peripheral physical base addresses. | ||
65 | */ | ||
66 | #define AT572D940HF_BASE_TCB 0xfffa0000 | ||
67 | #define AT572D940HF_BASE_TC0 0xfffa0000 | ||
68 | #define AT572D940HF_BASE_TC1 0xfffa0040 | ||
69 | #define AT572D940HF_BASE_TC2 0xfffa0080 | ||
70 | #define AT572D940HF_BASE_UDP 0xfffa4000 | ||
71 | #define AT572D940HF_BASE_MCI 0xfffa8000 | ||
72 | #define AT572D940HF_BASE_TWI0 0xfffac000 | ||
73 | #define AT572D940HF_BASE_US0 0xfffb0000 | ||
74 | #define AT572D940HF_BASE_US1 0xfffb4000 | ||
75 | #define AT572D940HF_BASE_US2 0xfffb8000 | ||
76 | #define AT572D940HF_BASE_SSC0 0xfffbc000 | ||
77 | #define AT572D940HF_BASE_SSC1 0xfffc0000 | ||
78 | #define AT572D940HF_BASE_SSC2 0xfffc4000 | ||
79 | #define AT572D940HF_BASE_SPI0 0xfffc8000 | ||
80 | #define AT572D940HF_BASE_SPI1 0xfffcc000 | ||
81 | #define AT572D940HF_BASE_SSC3 0xfffd0000 | ||
82 | #define AT572D940HF_BASE_TWI1 0xfffd4000 | ||
83 | #define AT572D940HF_BASE_EMAC 0xfffd8000 | ||
84 | #define AT572D940HF_BASE_CAN0 0xfffdc000 | ||
85 | #define AT572D940HF_BASE_CAN1 0xfffe0000 | ||
86 | #define AT91_BASE_SYS 0xffffea00 | ||
87 | |||
88 | |||
89 | /* | ||
90 | * System Peripherals (offset from AT91_BASE_SYS) | ||
91 | */ | ||
92 | #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) | ||
93 | #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) | ||
94 | #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) | ||
95 | #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) | ||
96 | #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) | ||
97 | #define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) | ||
98 | #define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) | ||
99 | #define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) | ||
100 | #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) | ||
101 | #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) | ||
102 | #define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) | ||
103 | #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) | ||
104 | #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) | ||
105 | |||
106 | #define AT91_USART0 AT572D940HF_ID_US0 | ||
107 | #define AT91_USART1 AT572D940HF_ID_US1 | ||
108 | #define AT91_USART2 AT572D940HF_ID_US2 | ||
109 | |||
110 | |||
111 | /* | ||
112 | * Internal Memory. | ||
113 | */ | ||
114 | #define AT572D940HF_SRAM_BASE 0x00300000 /* Internal SRAM base address */ | ||
115 | #define AT572D940HF_SRAM_SIZE (48 * SZ_1K) /* Internal SRAM size (48Kb) */ | ||
116 | |||
117 | #define AT572D940HF_ROM_BASE 0x00400000 /* Internal ROM base address */ | ||
118 | #define AT572D940HF_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ | ||
119 | |||
120 | #define AT572D940HF_UHP_BASE 0x00500000 /* USB Host controller */ | ||
121 | |||
122 | |||
123 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h b/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h deleted file mode 100644 index b6751df09488..000000000000 --- a/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | * include/mach//at572d940hf_matrix.h | ||
3 | * | ||
4 | * Antonio R. Costa <costa.antonior@gmail.com> | ||
5 | * Copyright (C) 2008 Atmel | ||
6 | * | ||
7 | * Copyright (C) 2005 SAN People | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #ifndef AT572D940HF_MATRIX_H | ||
25 | #define AT572D940HF_MATRIX_H | ||
26 | |||
27 | #define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ | ||
28 | #define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ | ||
29 | #define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ | ||
30 | #define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ | ||
31 | #define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ | ||
32 | #define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ | ||
33 | |||
34 | #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ | ||
35 | #define AT91_MATRIX_ULBT_INFINITE (0 << 0) | ||
36 | #define AT91_MATRIX_ULBT_SINGLE (1 << 0) | ||
37 | #define AT91_MATRIX_ULBT_FOUR (2 << 0) | ||
38 | #define AT91_MATRIX_ULBT_EIGHT (3 << 0) | ||
39 | #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) | ||
40 | |||
41 | #define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ | ||
42 | #define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ | ||
43 | #define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ | ||
44 | #define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ | ||
45 | #define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ | ||
46 | #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ | ||
47 | #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ | ||
48 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) | ||
49 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) | ||
50 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) | ||
51 | #define AT91_MATRIX_FIXED_DEFMSTR (0x7 << 18) /* Fixed Index of Default Master */ | ||
52 | #define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ | ||
53 | #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) | ||
54 | #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) | ||
55 | |||
56 | #define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ | ||
57 | #define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ | ||
58 | #define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ | ||
59 | #define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ | ||
60 | #define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ | ||
61 | |||
62 | #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ | ||
63 | #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ | ||
64 | #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ | ||
65 | #define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ | ||
66 | #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ | ||
67 | #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ | ||
68 | #define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ | ||
69 | |||
70 | #define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ | ||
71 | #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ | ||
72 | #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ | ||
73 | |||
74 | #define AT91_MATRIX_SFR0 (AT91_MATRIX + 0x110) /* Special Function Register 0 */ | ||
75 | #define AT91_MATRIX_SFR1 (AT91_MATRIX + 0x114) /* Special Function Register 1 */ | ||
76 | #define AT91_MATRIX_SFR2 (AT91_MATRIX + 0x118) /* Special Function Register 2 */ | ||
77 | #define AT91_MATRIX_SFR3 (AT91_MATRIX + 0x11C) /* Special Function Register 3 */ | ||
78 | #define AT91_MATRIX_SFR4 (AT91_MATRIX + 0x120) /* Special Function Register 4 */ | ||
79 | #define AT91_MATRIX_SFR5 (AT91_MATRIX + 0x124) /* Special Function Register 5 */ | ||
80 | #define AT91_MATRIX_SFR6 (AT91_MATRIX + 0x128) /* Special Function Register 6 */ | ||
81 | #define AT91_MATRIX_SFR7 (AT91_MATRIX + 0x12C) /* Special Function Register 7 */ | ||
82 | #define AT91_MATRIX_SFR8 (AT91_MATRIX + 0x130) /* Special Function Register 8 */ | ||
83 | #define AT91_MATRIX_SFR9 (AT91_MATRIX + 0x134) /* Special Function Register 9 */ | ||
84 | #define AT91_MATRIX_SFR10 (AT91_MATRIX + 0x138) /* Special Function Register 10 */ | ||
85 | #define AT91_MATRIX_SFR11 (AT91_MATRIX + 0x13C) /* Special Function Register 11 */ | ||
86 | #define AT91_MATRIX_SFR12 (AT91_MATRIX + 0x140) /* Special Function Register 12 */ | ||
87 | #define AT91_MATRIX_SFR13 (AT91_MATRIX + 0x144) /* Special Function Register 13 */ | ||
88 | #define AT91_MATRIX_SFR14 (AT91_MATRIX + 0x148) /* Special Function Register 14 */ | ||
89 | #define AT91_MATRIX_SFR15 (AT91_MATRIX + 0x14C) /* Special Function Register 15 */ | ||
90 | |||
91 | |||
92 | /* | ||
93 | * The following registers / bits are not defined in the Datasheet (Revision A) | ||
94 | */ | ||
95 | |||
96 | #define AT91_MATRIX_TCR (AT91_MATRIX + 0x100) /* TCM Configuration Register */ | ||
97 | #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ | ||
98 | #define AT91_MATRIX_ITCM_0 (0 << 0) | ||
99 | #define AT91_MATRIX_ITCM_16 (5 << 0) | ||
100 | #define AT91_MATRIX_ITCM_32 (6 << 0) | ||
101 | #define AT91_MATRIX_ITCM_64 (7 << 0) | ||
102 | #define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ | ||
103 | #define AT91_MATRIX_DTCM_0 (0 << 4) | ||
104 | #define AT91_MATRIX_DTCM_16 (5 << 4) | ||
105 | #define AT91_MATRIX_DTCM_32 (6 << 4) | ||
106 | #define AT91_MATRIX_DTCM_64 (7 << 4) | ||
107 | |||
108 | #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */ | ||
109 | #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ | ||
110 | #define AT91_MATRIX_CS1A_SMC (0 << 1) | ||
111 | #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) | ||
112 | #define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ | ||
113 | #define AT91_MATRIX_CS3A_SMC (0 << 3) | ||
114 | #define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) | ||
115 | #define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ | ||
116 | #define AT91_MATRIX_CS4A_SMC (0 << 4) | ||
117 | #define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) | ||
118 | #define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */ | ||
119 | #define AT91_MATRIX_CS5A_SMC (0 << 5) | ||
120 | #define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) | ||
121 | #define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ | ||
122 | |||
123 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 9c6af9737485..665993849a7b 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h | |||
@@ -20,8 +20,6 @@ | |||
20 | /* | 20 | /* |
21 | * Peripheral identifiers/interrupts. | 21 | * Peripheral identifiers/interrupts. |
22 | */ | 22 | */ |
23 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
24 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
25 | #define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ | 23 | #define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ |
26 | #define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ | 24 | #define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ |
27 | #define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ | 25 | #define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ |
@@ -123,6 +121,4 @@ | |||
123 | #define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */ | 121 | #define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */ |
124 | #define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ | 122 | #define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ |
125 | 123 | ||
126 | #define CONFIG_DRAM_BASE AT91_CHIPSELECT_6 | ||
127 | |||
128 | #endif | 124 | #endif |
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 78983155a074..99e0f8d02d7b 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h | |||
@@ -19,8 +19,6 @@ | |||
19 | /* | 19 | /* |
20 | * Peripheral identifiers/interrupts. | 20 | * Peripheral identifiers/interrupts. |
21 | */ | 21 | */ |
22 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
23 | #define AT91_ID_SYS 1 /* System Peripheral */ | ||
24 | #define AT91RM9200_ID_PIOA 2 /* Parallel IO Controller A */ | 22 | #define AT91RM9200_ID_PIOA 2 /* Parallel IO Controller A */ |
25 | #define AT91RM9200_ID_PIOB 3 /* Parallel IO Controller B */ | 23 | #define AT91RM9200_ID_PIOB 3 /* Parallel IO Controller B */ |
26 | #define AT91RM9200_ID_PIOC 4 /* Parallel IO Controller C */ | 24 | #define AT91RM9200_ID_PIOC 4 /* Parallel IO Controller C */ |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 4e79036d3b80..8b6bf835cd73 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h | |||
@@ -20,8 +20,6 @@ | |||
20 | /* | 20 | /* |
21 | * Peripheral identifiers/interrupts. | 21 | * Peripheral identifiers/interrupts. |
22 | */ | 22 | */ |
23 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
24 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
25 | #define AT91SAM9260_ID_PIOA 2 /* Parallel IO Controller A */ | 23 | #define AT91SAM9260_ID_PIOA 2 /* Parallel IO Controller A */ |
26 | #define AT91SAM9260_ID_PIOB 3 /* Parallel IO Controller B */ | 24 | #define AT91SAM9260_ID_PIOB 3 /* Parallel IO Controller B */ |
27 | #define AT91SAM9260_ID_PIOC 4 /* Parallel IO Controller C */ | 25 | #define AT91SAM9260_ID_PIOC 4 /* Parallel IO Controller C */ |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 2b5618518129..eafbddaf523c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h | |||
@@ -18,8 +18,6 @@ | |||
18 | /* | 18 | /* |
19 | * Peripheral identifiers/interrupts. | 19 | * Peripheral identifiers/interrupts. |
20 | */ | 20 | */ |
21 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
22 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
23 | #define AT91SAM9261_ID_PIOA 2 /* Parallel IO Controller A */ | 21 | #define AT91SAM9261_ID_PIOA 2 /* Parallel IO Controller A */ |
24 | #define AT91SAM9261_ID_PIOB 3 /* Parallel IO Controller B */ | 22 | #define AT91SAM9261_ID_PIOB 3 /* Parallel IO Controller B */ |
25 | #define AT91SAM9261_ID_PIOC 4 /* Parallel IO Controller C */ | 23 | #define AT91SAM9261_ID_PIOC 4 /* Parallel IO Controller C */ |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 2091f1e42d43..e2d348213a7b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h | |||
@@ -18,8 +18,6 @@ | |||
18 | /* | 18 | /* |
19 | * Peripheral identifiers/interrupts. | 19 | * Peripheral identifiers/interrupts. |
20 | */ | 20 | */ |
21 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
22 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
23 | #define AT91SAM9263_ID_PIOA 2 /* Parallel IO Controller A */ | 21 | #define AT91SAM9263_ID_PIOA 2 /* Parallel IO Controller A */ |
24 | #define AT91SAM9263_ID_PIOB 3 /* Parallel IO Controller B */ | 22 | #define AT91SAM9263_ID_PIOB 3 /* Parallel IO Controller B */ |
25 | #define AT91SAM9263_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */ | 23 | #define AT91SAM9263_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */ |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index a526869aee37..659304aa73d9 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h | |||
@@ -18,8 +18,6 @@ | |||
18 | /* | 18 | /* |
19 | * Peripheral identifiers/interrupts. | 19 | * Peripheral identifiers/interrupts. |
20 | */ | 20 | */ |
21 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
22 | #define AT91_ID_SYS 1 /* System Controller Interrupt */ | ||
23 | #define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */ | 21 | #define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */ |
24 | #define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */ | 22 | #define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */ |
25 | #define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */ | 23 | #define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */ |
@@ -131,8 +129,6 @@ | |||
131 | #define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */ | 129 | #define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */ |
132 | #define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */ | 130 | #define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */ |
133 | 131 | ||
134 | #define CONFIG_DRAM_BASE AT91_CHIPSELECT_6 | ||
135 | |||
136 | #define CONSISTENT_DMA_SIZE SZ_4M | 132 | #define CONSISTENT_DMA_SIZE SZ_4M |
137 | 133 | ||
138 | /* | 134 | /* |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 87ba8517ad98..41dbbe61055c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h | |||
@@ -17,8 +17,6 @@ | |||
17 | /* | 17 | /* |
18 | * Peripheral identifiers/interrupts. | 18 | * Peripheral identifiers/interrupts. |
19 | */ | 19 | */ |
20 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
21 | #define AT91_ID_SYS 1 /* System Controller */ | ||
22 | #define AT91SAM9RL_ID_PIOA 2 /* Parallel IO Controller A */ | 20 | #define AT91SAM9RL_ID_PIOA 2 /* Parallel IO Controller A */ |
23 | #define AT91SAM9RL_ID_PIOB 3 /* Parallel IO Controller B */ | 21 | #define AT91SAM9RL_ID_PIOB 3 /* Parallel IO Controller B */ |
24 | #define AT91SAM9RL_ID_PIOC 4 /* Parallel IO Controller C */ | 22 | #define AT91SAM9RL_ID_PIOC 4 /* Parallel IO Controller C */ |
diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h index 063ac44a0204..a152ff87e688 100644 --- a/arch/arm/mach-at91/include/mach/at91x40.h +++ b/arch/arm/mach-at91/include/mach/at91x40.h | |||
@@ -15,8 +15,6 @@ | |||
15 | /* | 15 | /* |
16 | * IRQ list. | 16 | * IRQ list. |
17 | */ | 17 | */ |
18 | #define AT91_ID_FIQ 0 /* FIQ */ | ||
19 | #define AT91_ID_SYS 1 /* System Peripheral */ | ||
20 | #define AT91X40_ID_USART0 2 /* USART port 0 */ | 18 | #define AT91X40_ID_USART0 2 /* USART port 0 */ |
21 | #define AT91X40_ID_USART1 3 /* USART port 1 */ | 19 | #define AT91X40_ID_USART1 3 /* USART port 1 */ |
22 | #define AT91X40_ID_TC0 4 /* Timer/Counter 0 */ | 20 | #define AT91X40_ID_TC0 4 /* Timer/Counter 0 */ |
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 2b499eb343a1..ed544a0d5a1d 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h | |||
@@ -90,7 +90,7 @@ struct at91_eth_data { | |||
90 | extern void __init at91_add_device_eth(struct at91_eth_data *data); | 90 | extern void __init at91_add_device_eth(struct at91_eth_data *data); |
91 | 91 | ||
92 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \ | 92 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \ |
93 | || defined(CONFIG_ARCH_AT91SAM9G45) || defined(CONFIG_ARCH_AT572D940HF) | 93 | || defined(CONFIG_ARCH_AT91SAM9G45) |
94 | #define eth_platform_data at91_eth_data | 94 | #define eth_platform_data at91_eth_data |
95 | #endif | 95 | #endif |
96 | 96 | ||
@@ -140,6 +140,7 @@ extern void __init at91_set_serial_console(unsigned portnr); | |||
140 | extern struct platform_device *atmel_default_console_device; | 140 | extern struct platform_device *atmel_default_console_device; |
141 | 141 | ||
142 | struct atmel_uart_data { | 142 | struct atmel_uart_data { |
143 | int num; /* port num */ | ||
143 | short use_dma_tx; /* use transmit DMA? */ | 144 | short use_dma_tx; /* use transmit DMA? */ |
144 | short use_dma_rx; /* use receive DMA? */ | 145 | short use_dma_rx; /* use receive DMA? */ |
145 | void __iomem *regs; /* virt. base address, if any */ | 146 | void __iomem *regs; /* virt. base address, if any */ |
@@ -203,9 +204,6 @@ extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); | |||
203 | extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); | 204 | extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); |
204 | extern void __init at91_pwm_leds(struct gpio_led *leds, int nr); | 205 | extern void __init at91_pwm_leds(struct gpio_led *leds, int nr); |
205 | 206 | ||
206 | /* AT572D940HF DSP */ | ||
207 | extern void __init at91_add_device_mAgic(void); | ||
208 | |||
209 | /* FIXME: this needs a better location, but gets stuff building again */ | 207 | /* FIXME: this needs a better location, but gets stuff building again */ |
210 | extern int at91_suspend_entering_slow_clock(void); | 208 | extern int at91_suspend_entering_slow_clock(void); |
211 | 209 | ||
diff --git a/arch/arm/mach-at91/include/mach/clkdev.h b/arch/arm/mach-at91/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/mach-at91/include/mach/clkdev.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_CLKDEV_H | ||
2 | #define __ASM_MACH_CLKDEV_H | ||
3 | |||
4 | #define __clk_get(clk) ({ 1; }) | ||
5 | #define __clk_put(clk) do { } while (0) | ||
6 | |||
7 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index 0700f2125305..df966c2bc2d4 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h | |||
@@ -34,8 +34,6 @@ | |||
34 | #define ARCH_ID_AT91SAM9XE256 0x329a93a0 | 34 | #define ARCH_ID_AT91SAM9XE256 0x329a93a0 |
35 | #define ARCH_ID_AT91SAM9XE512 0x329aa3a0 | 35 | #define ARCH_ID_AT91SAM9XE512 0x329aa3a0 |
36 | 36 | ||
37 | #define ARCH_ID_AT572D940HF 0x0e0303e0 | ||
38 | |||
39 | #define ARCH_ID_AT91M40800 0x14080044 | 37 | #define ARCH_ID_AT91M40800 0x14080044 |
40 | #define ARCH_ID_AT91R40807 0x44080746 | 38 | #define ARCH_ID_AT91R40807 0x44080746 |
41 | #define ARCH_ID_AT91M40807 0x14080745 | 39 | #define ARCH_ID_AT91M40807 0x14080745 |
@@ -90,9 +88,16 @@ static inline unsigned long at91cap9_rev_identify(void) | |||
90 | #endif | 88 | #endif |
91 | 89 | ||
92 | #ifdef CONFIG_ARCH_AT91RM9200 | 90 | #ifdef CONFIG_ARCH_AT91RM9200 |
91 | extern int rm9200_type; | ||
92 | #define ARCH_REVISON_9200_BGA (0 << 0) | ||
93 | #define ARCH_REVISON_9200_PQFP (1 << 0) | ||
93 | #define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200) | 94 | #define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200) |
95 | #define cpu_is_at91rm9200_bga() (!cpu_is_at91rm9200_pqfp()) | ||
96 | #define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP) | ||
94 | #else | 97 | #else |
95 | #define cpu_is_at91rm9200() (0) | 98 | #define cpu_is_at91rm9200() (0) |
99 | #define cpu_is_at91rm9200_bga() (0) | ||
100 | #define cpu_is_at91rm9200_pqfp() (0) | ||
96 | #endif | 101 | #endif |
97 | 102 | ||
98 | #ifdef CONFIG_ARCH_AT91SAM9260 | 103 | #ifdef CONFIG_ARCH_AT91SAM9260 |
@@ -181,12 +186,6 @@ static inline unsigned long at91cap9_rev_identify(void) | |||
181 | #define cpu_is_at91cap9_revC() (0) | 186 | #define cpu_is_at91cap9_revC() (0) |
182 | #endif | 187 | #endif |
183 | 188 | ||
184 | #ifdef CONFIG_ARCH_AT572D940HF | ||
185 | #define cpu_is_at572d940hf() (at91_cpu_identify() == ARCH_ID_AT572D940HF) | ||
186 | #else | ||
187 | #define cpu_is_at572d940hf() (0) | ||
188 | #endif | ||
189 | |||
190 | /* | 189 | /* |
191 | * Since this is ARM, we will never run on any AVR32 CPU. But these | 190 | * Since this is ARM, we will never run on any AVR32 CPU. But these |
192 | * definitions may reduce clutter in common drivers. | 191 | * definitions may reduce clutter in common drivers. |
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 3d64a75e3ed5..1008b9fb5074 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h | |||
@@ -32,13 +32,17 @@ | |||
32 | #include <mach/at91cap9.h> | 32 | #include <mach/at91cap9.h> |
33 | #elif defined(CONFIG_ARCH_AT91X40) | 33 | #elif defined(CONFIG_ARCH_AT91X40) |
34 | #include <mach/at91x40.h> | 34 | #include <mach/at91x40.h> |
35 | #elif defined(CONFIG_ARCH_AT572D940HF) | ||
36 | #include <mach/at572d940hf.h> | ||
37 | #else | 35 | #else |
38 | #error "Unsupported AT91 processor" | 36 | #error "Unsupported AT91 processor" |
39 | #endif | 37 | #endif |
40 | 38 | ||
41 | 39 | ||
40 | /* | ||
41 | * Peripheral identifiers/interrupts. | ||
42 | */ | ||
43 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
44 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
45 | |||
42 | #ifdef CONFIG_MMU | 46 | #ifdef CONFIG_MMU |
43 | /* | 47 | /* |
44 | * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF | 48 | * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF |
@@ -82,13 +86,6 @@ | |||
82 | #define AT91_CHIPSELECT_6 0x70000000 | 86 | #define AT91_CHIPSELECT_6 0x70000000 |
83 | #define AT91_CHIPSELECT_7 0x80000000 | 87 | #define AT91_CHIPSELECT_7 0x80000000 |
84 | 88 | ||
85 | /* SDRAM */ | ||
86 | #ifdef CONFIG_DRAM_BASE | ||
87 | #define AT91_SDRAM_BASE CONFIG_DRAM_BASE | ||
88 | #else | ||
89 | #define AT91_SDRAM_BASE AT91_CHIPSELECT_1 | ||
90 | #endif | ||
91 | |||
92 | /* Clocks */ | 89 | /* Clocks */ |
93 | #define AT91_SLOW_CLOCK 32768 /* slow clock */ | 90 | #define AT91_SLOW_CLOCK 32768 /* slow clock */ |
94 | 91 | ||
diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/arm/mach-at91/include/mach/memory.h index c2cfe5040642..401c207f2f39 100644 --- a/arch/arm/mach-at91/include/mach/memory.h +++ b/arch/arm/mach-at91/include/mach/memory.h | |||
@@ -23,6 +23,4 @@ | |||
23 | 23 | ||
24 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
25 | 25 | ||
26 | #define PLAT_PHYS_OFFSET (AT91_SDRAM_BASE) | ||
27 | |||
28 | #endif | 26 | #endif |
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h index 6120f9c46d59..f62c0abca4b4 100644 --- a/arch/arm/mach-at91/include/mach/stamp9g20.h +++ b/arch/arm/mach-at91/include/mach/stamp9g20.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __MACH_STAMP9G20_H | 1 | #ifndef __MACH_STAMP9G20_H |
2 | #define __MACH_STAMP9G20_H | 2 | #define __MACH_STAMP9G20_H |
3 | 3 | ||
4 | void stamp9g20_map_io(void); | 4 | void stamp9g20_init_early(void); |
5 | void stamp9g20_board_init(void); | 5 | void stamp9g20_board_init(void); |
6 | 6 | ||
7 | #endif | 7 | #endif |
diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h new file mode 100644 index 000000000000..b855ee75f72c --- /dev/null +++ b/arch/arm/mach-at91/include/mach/system_rev.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | ||
3 | * | ||
4 | * Under GPLv2 only | ||
5 | */ | ||
6 | |||
7 | #ifndef __ARCH_SYSTEM_REV_H__ | ||
8 | #define __ARCH_SYSTEM_REV_H__ | ||
9 | |||
10 | /* | ||
11 | * board revision encoding | ||
12 | * mach specific | ||
13 | * the 16-31 bit are reserved for at91 generic information | ||
14 | * | ||
15 | * bit 31: | ||
16 | * 0 => nand 16 bit | ||
17 | * 1 => nand 8 bit | ||
18 | */ | ||
19 | #define BOARD_HAVE_NAND_8BIT (1 << 31) | ||
20 | static int inline board_have_nand_8bit(void) | ||
21 | { | ||
22 | return system_rev & BOARD_HAVE_NAND_8BIT; | ||
23 | } | ||
24 | |||
25 | #endif /* __ARCH_SYSTEM_REV_H__ */ | ||
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h index 05a6e8af80c4..31ac2d97f14c 100644 --- a/arch/arm/mach-at91/include/mach/timex.h +++ b/arch/arm/mach-at91/include/mach/timex.h | |||
@@ -82,11 +82,6 @@ | |||
82 | #define AT91X40_MASTER_CLOCK 40000000 | 82 | #define AT91X40_MASTER_CLOCK 40000000 |
83 | #define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) | 83 | #define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) |
84 | 84 | ||
85 | #elif defined(CONFIG_ARCH_AT572D940HF) | ||
86 | |||
87 | #define AT572D940HF_MASTER_CLOCK 80000000 | ||
88 | #define CLOCK_TICK_RATE (AT572D940HF_MASTER_CLOCK/16) | ||
89 | |||
90 | #endif | 85 | #endif |
91 | 86 | ||
92 | #endif | 87 | #endif |
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index b95b9196deed..133aac405853 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -1055,7 +1055,7 @@ int da850_register_pm(struct platform_device *pdev) | |||
1055 | if (!pdata->cpupll_reg_base) | 1055 | if (!pdata->cpupll_reg_base) |
1056 | return -ENOMEM; | 1056 | return -ENOMEM; |
1057 | 1057 | ||
1058 | pdata->ddrpll_reg_base = ioremap(DA8XX_PLL1_BASE, SZ_4K); | 1058 | pdata->ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K); |
1059 | if (!pdata->ddrpll_reg_base) { | 1059 | if (!pdata->ddrpll_reg_base) { |
1060 | ret = -ENOMEM; | 1060 | ret = -ENOMEM; |
1061 | goto no_ddrpll_mem; | 1061 | goto no_ddrpll_mem; |
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 58a02dc7b15a..4e66881c7aee 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c | |||
@@ -24,23 +24,25 @@ | |||
24 | #include "clock.h" | 24 | #include "clock.h" |
25 | 25 | ||
26 | #define DA8XX_TPCC_BASE 0x01c00000 | 26 | #define DA8XX_TPCC_BASE 0x01c00000 |
27 | #define DA850_MMCSD1_BASE 0x01e1b000 | ||
28 | #define DA850_TPCC1_BASE 0x01e30000 | ||
29 | #define DA8XX_TPTC0_BASE 0x01c08000 | 27 | #define DA8XX_TPTC0_BASE 0x01c08000 |
30 | #define DA8XX_TPTC1_BASE 0x01c08400 | 28 | #define DA8XX_TPTC1_BASE 0x01c08400 |
31 | #define DA850_TPTC2_BASE 0x01e38000 | ||
32 | #define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */ | 29 | #define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */ |
33 | #define DA8XX_I2C0_BASE 0x01c22000 | 30 | #define DA8XX_I2C0_BASE 0x01c22000 |
34 | #define DA8XX_RTC_BASE 0x01C23000 | 31 | #define DA8XX_RTC_BASE 0x01c23000 |
32 | #define DA8XX_MMCSD0_BASE 0x01c40000 | ||
33 | #define DA8XX_SPI0_BASE 0x01c41000 | ||
34 | #define DA830_SPI1_BASE 0x01e12000 | ||
35 | #define DA8XX_LCD_CNTRL_BASE 0x01e13000 | ||
36 | #define DA850_MMCSD1_BASE 0x01e1b000 | ||
35 | #define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000 | 37 | #define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000 |
36 | #define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000 | 38 | #define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000 |
37 | #define DA8XX_EMAC_CPGMAC_BASE 0x01e23000 | 39 | #define DA8XX_EMAC_CPGMAC_BASE 0x01e23000 |
38 | #define DA8XX_EMAC_MDIO_BASE 0x01e24000 | 40 | #define DA8XX_EMAC_MDIO_BASE 0x01e24000 |
39 | #define DA8XX_GPIO_BASE 0x01e26000 | ||
40 | #define DA8XX_I2C1_BASE 0x01e28000 | 41 | #define DA8XX_I2C1_BASE 0x01e28000 |
41 | #define DA8XX_SPI0_BASE 0x01c41000 | 42 | #define DA850_TPCC1_BASE 0x01e30000 |
42 | #define DA830_SPI1_BASE 0x01e12000 | 43 | #define DA850_TPTC2_BASE 0x01e38000 |
43 | #define DA850_SPI1_BASE 0x01f0e000 | 44 | #define DA850_SPI1_BASE 0x01f0e000 |
45 | #define DA8XX_DDR2_CTL_BASE 0xb0000000 | ||
44 | 46 | ||
45 | #define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 | 47 | #define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 |
46 | #define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 | 48 | #define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 |
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 22ebc64bc9d9..8f4f736aa267 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #define DM365_MMCSD0_BASE 0x01D11000 | 33 | #define DM365_MMCSD0_BASE 0x01D11000 |
34 | #define DM365_MMCSD1_BASE 0x01D00000 | 34 | #define DM365_MMCSD1_BASE 0x01D00000 |
35 | 35 | ||
36 | /* System control register offsets */ | ||
37 | #define DM64XX_VDD3P3V_PWDN 0x48 | ||
38 | |||
36 | static struct resource i2c_resources[] = { | 39 | static struct resource i2c_resources[] = { |
37 | { | 40 | { |
38 | .start = DAVINCI_I2C_BASE, | 41 | .start = DAVINCI_I2C_BASE, |
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index e4fc1af8500e..ad64da713fc8 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h | |||
@@ -64,13 +64,9 @@ extern unsigned int da850_max_speed; | |||
64 | #define DA8XX_TIMER64P1_BASE 0x01c21000 | 64 | #define DA8XX_TIMER64P1_BASE 0x01c21000 |
65 | #define DA8XX_GPIO_BASE 0x01e26000 | 65 | #define DA8XX_GPIO_BASE 0x01e26000 |
66 | #define DA8XX_PSC1_BASE 0x01e27000 | 66 | #define DA8XX_PSC1_BASE 0x01e27000 |
67 | #define DA8XX_LCD_CNTRL_BASE 0x01e13000 | ||
68 | #define DA8XX_PLL1_BASE 0x01e1a000 | ||
69 | #define DA8XX_MMCSD0_BASE 0x01c40000 | ||
70 | #define DA8XX_AEMIF_CS2_BASE 0x60000000 | 67 | #define DA8XX_AEMIF_CS2_BASE 0x60000000 |
71 | #define DA8XX_AEMIF_CS3_BASE 0x62000000 | 68 | #define DA8XX_AEMIF_CS3_BASE 0x62000000 |
72 | #define DA8XX_AEMIF_CTL_BASE 0x68000000 | 69 | #define DA8XX_AEMIF_CTL_BASE 0x68000000 |
73 | #define DA8XX_DDR2_CTL_BASE 0xb0000000 | ||
74 | #define DA8XX_ARM_RAM_BASE 0xffff0000 | 70 | #define DA8XX_ARM_RAM_BASE 0xffff0000 |
75 | 71 | ||
76 | void __init da830_init(void); | 72 | void __init da830_init(void); |
diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h index c45ba1f62a11..414e0b93e741 100644 --- a/arch/arm/mach-davinci/include/mach/hardware.h +++ b/arch/arm/mach-davinci/include/mach/hardware.h | |||
@@ -21,9 +21,6 @@ | |||
21 | */ | 21 | */ |
22 | #define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000 | 22 | #define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000 |
23 | 23 | ||
24 | /* System control register offsets */ | ||
25 | #define DM64XX_VDD3P3V_PWDN 0x48 | ||
26 | |||
27 | /* | 24 | /* |
28 | * I/O mapping | 25 | * I/O mapping |
29 | */ | 26 | */ |
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 805196207ce8..b92c1e557145 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig | |||
@@ -169,9 +169,11 @@ config MACH_NURI | |||
169 | select S3C_DEV_HSMMC2 | 169 | select S3C_DEV_HSMMC2 |
170 | select S3C_DEV_HSMMC3 | 170 | select S3C_DEV_HSMMC3 |
171 | select S3C_DEV_I2C1 | 171 | select S3C_DEV_I2C1 |
172 | select S3C_DEV_I2C3 | ||
172 | select S3C_DEV_I2C5 | 173 | select S3C_DEV_I2C5 |
173 | select S5P_DEV_USB_EHCI | 174 | select S5P_DEV_USB_EHCI |
174 | select EXYNOS4_SETUP_I2C1 | 175 | select EXYNOS4_SETUP_I2C1 |
176 | select EXYNOS4_SETUP_I2C3 | ||
175 | select EXYNOS4_SETUP_I2C5 | 177 | select EXYNOS4_SETUP_I2C5 |
176 | select EXYNOS4_SETUP_SDHCI | 178 | select EXYNOS4_SETUP_SDHCI |
177 | select SAMSUNG_DEV_PWM | 179 | select SAMSUNG_DEV_PWM |
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index 777897551e42..a9bb94fabaa7 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile | |||
@@ -13,9 +13,10 @@ obj- := | |||
13 | # Core support for EXYNOS4 system | 13 | # Core support for EXYNOS4 system |
14 | 14 | ||
15 | obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o | 15 | obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o |
16 | obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o gpiolib.o irq-eint.o dma.o | 16 | obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o irq-eint.o dma.o |
17 | obj-$(CONFIG_PM) += pm.o sleep.o | 17 | obj-$(CONFIG_PM) += pm.o sleep.o |
18 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | 18 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o |
19 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
19 | 20 | ||
20 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 21 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
21 | 22 | ||
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c new file mode 100644 index 000000000000..bf7e96f2793a --- /dev/null +++ b/arch/arm/mach-exynos4/cpuidle.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* linux/arch/arm/mach-exynos4/cpuidle.c | ||
2 | * | ||
3 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/cpuidle.h> | ||
14 | #include <linux/io.h> | ||
15 | |||
16 | #include <asm/proc-fns.h> | ||
17 | |||
18 | static int exynos4_enter_idle(struct cpuidle_device *dev, | ||
19 | struct cpuidle_state *state); | ||
20 | |||
21 | static struct cpuidle_state exynos4_cpuidle_set[] = { | ||
22 | [0] = { | ||
23 | .enter = exynos4_enter_idle, | ||
24 | .exit_latency = 1, | ||
25 | .target_residency = 100000, | ||
26 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
27 | .name = "IDLE", | ||
28 | .desc = "ARM clock gating(WFI)", | ||
29 | }, | ||
30 | }; | ||
31 | |||
32 | static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); | ||
33 | |||
34 | static struct cpuidle_driver exynos4_idle_driver = { | ||
35 | .name = "exynos4_idle", | ||
36 | .owner = THIS_MODULE, | ||
37 | }; | ||
38 | |||
39 | static int exynos4_enter_idle(struct cpuidle_device *dev, | ||
40 | struct cpuidle_state *state) | ||
41 | { | ||
42 | struct timeval before, after; | ||
43 | int idle_time; | ||
44 | |||
45 | local_irq_disable(); | ||
46 | do_gettimeofday(&before); | ||
47 | |||
48 | cpu_do_idle(); | ||
49 | |||
50 | do_gettimeofday(&after); | ||
51 | local_irq_enable(); | ||
52 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | ||
53 | (after.tv_usec - before.tv_usec); | ||
54 | |||
55 | return idle_time; | ||
56 | } | ||
57 | |||
58 | static int __init exynos4_init_cpuidle(void) | ||
59 | { | ||
60 | int i, max_cpuidle_state, cpu_id; | ||
61 | struct cpuidle_device *device; | ||
62 | |||
63 | cpuidle_register_driver(&exynos4_idle_driver); | ||
64 | |||
65 | for_each_cpu(cpu_id, cpu_online_mask) { | ||
66 | device = &per_cpu(exynos4_cpuidle_device, cpu_id); | ||
67 | device->cpu = cpu_id; | ||
68 | |||
69 | device->state_count = (sizeof(exynos4_cpuidle_set) / | ||
70 | sizeof(struct cpuidle_state)); | ||
71 | |||
72 | max_cpuidle_state = device->state_count; | ||
73 | |||
74 | for (i = 0; i < max_cpuidle_state; i++) { | ||
75 | memcpy(&device->states[i], &exynos4_cpuidle_set[i], | ||
76 | sizeof(struct cpuidle_state)); | ||
77 | } | ||
78 | |||
79 | if (cpuidle_register_device(device)) { | ||
80 | printk(KERN_ERR "CPUidle register device failed\n,"); | ||
81 | return -EIO; | ||
82 | } | ||
83 | } | ||
84 | return 0; | ||
85 | } | ||
86 | device_initcall(exynos4_init_cpuidle); | ||
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c index bb5d12f43af8..642702bb5b12 100644 --- a/arch/arm/mach-exynos4/mach-nuri.c +++ b/arch/arm/mach-exynos4/mach-nuri.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/serial_core.h> | 12 | #include <linux/serial_core.h> |
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/i2c/atmel_mxt_ts.h> | ||
15 | #include <linux/gpio_keys.h> | 16 | #include <linux/gpio_keys.h> |
16 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
17 | #include <linux/regulator/machine.h> | 18 | #include <linux/regulator/machine.h> |
@@ -32,6 +33,8 @@ | |||
32 | #include <plat/sdhci.h> | 33 | #include <plat/sdhci.h> |
33 | #include <plat/ehci.h> | 34 | #include <plat/ehci.h> |
34 | #include <plat/clock.h> | 35 | #include <plat/clock.h> |
36 | #include <plat/gpio-cfg.h> | ||
37 | #include <plat/iic.h> | ||
35 | 38 | ||
36 | #include <mach/map.h> | 39 | #include <mach/map.h> |
37 | 40 | ||
@@ -259,6 +262,88 @@ static struct i2c_board_info i2c1_devs[] __initdata = { | |||
259 | /* Gyro, To be updated */ | 262 | /* Gyro, To be updated */ |
260 | }; | 263 | }; |
261 | 264 | ||
265 | /* TSP */ | ||
266 | static u8 mxt_init_vals[] = { | ||
267 | /* MXT_GEN_COMMAND(6) */ | ||
268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
269 | /* MXT_GEN_POWER(7) */ | ||
270 | 0x20, 0xff, 0x32, | ||
271 | /* MXT_GEN_ACQUIRE(8) */ | ||
272 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
273 | /* MXT_TOUCH_MULTI(9) */ | ||
274 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
275 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
276 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
277 | 0x00, | ||
278 | /* MXT_TOUCH_KEYARRAY(15) */ | ||
279 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
280 | 0x00, | ||
281 | /* MXT_SPT_GPIOPWM(19) */ | ||
282 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
283 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
284 | /* MXT_PROCI_GRIPFACE(20) */ | ||
285 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
286 | 0x0f, 0x0a, | ||
287 | /* MXT_PROCG_NOISE(22) */ | ||
288 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
289 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
290 | /* MXT_TOUCH_PROXIMITY(23) */ | ||
291 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
292 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
293 | /* MXT_PROCI_ONETOUCH(24) */ | ||
294 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
295 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
296 | /* MXT_SPT_SELFTEST(25) */ | ||
297 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
298 | 0x00, 0x00, 0x00, 0x00, | ||
299 | /* MXT_PROCI_TWOTOUCH(27) */ | ||
300 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
301 | /* MXT_SPT_CTECONFIG(28) */ | ||
302 | 0x00, 0x00, 0x02, 0x08, 0x10, 0x00, | ||
303 | }; | ||
304 | |||
305 | static struct mxt_platform_data mxt_platform_data = { | ||
306 | .config = mxt_init_vals, | ||
307 | .config_length = ARRAY_SIZE(mxt_init_vals), | ||
308 | |||
309 | .x_line = 18, | ||
310 | .y_line = 11, | ||
311 | .x_size = 1024, | ||
312 | .y_size = 600, | ||
313 | .blen = 0x1, | ||
314 | .threshold = 0x28, | ||
315 | .voltage = 2800000, /* 2.8V */ | ||
316 | .orient = MXT_DIAGONAL_COUNTER, | ||
317 | .irqflags = IRQF_TRIGGER_FALLING, | ||
318 | }; | ||
319 | |||
320 | static struct s3c2410_platform_i2c i2c3_data __initdata = { | ||
321 | .flags = 0, | ||
322 | .bus_num = 3, | ||
323 | .slave_addr = 0x10, | ||
324 | .frequency = 400 * 1000, | ||
325 | .sda_delay = 100, | ||
326 | }; | ||
327 | |||
328 | static struct i2c_board_info i2c3_devs[] __initdata = { | ||
329 | { | ||
330 | I2C_BOARD_INFO("atmel_mxt_ts", 0x4a), | ||
331 | .platform_data = &mxt_platform_data, | ||
332 | .irq = IRQ_EINT(4), | ||
333 | }, | ||
334 | }; | ||
335 | |||
336 | static void __init nuri_tsp_init(void) | ||
337 | { | ||
338 | int gpio; | ||
339 | |||
340 | /* TOUCH_INT: XEINT_4 */ | ||
341 | gpio = EXYNOS4_GPX0(4); | ||
342 | gpio_request(gpio, "TOUCH_INT"); | ||
343 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); | ||
344 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); | ||
345 | } | ||
346 | |||
262 | /* GPIO I2C 5 (PMIC) */ | 347 | /* GPIO I2C 5 (PMIC) */ |
263 | static struct i2c_board_info i2c5_devs[] __initdata = { | 348 | static struct i2c_board_info i2c5_devs[] __initdata = { |
264 | /* max8997, To be updated */ | 349 | /* max8997, To be updated */ |
@@ -283,6 +368,7 @@ static struct platform_device *nuri_devices[] __initdata = { | |||
283 | &s3c_device_wdt, | 368 | &s3c_device_wdt, |
284 | &s3c_device_timer[0], | 369 | &s3c_device_timer[0], |
285 | &s5p_device_ehci, | 370 | &s5p_device_ehci, |
371 | &s3c_device_i2c3, | ||
286 | 372 | ||
287 | /* NURI Devices */ | 373 | /* NURI Devices */ |
288 | &nuri_gpio_keys, | 374 | &nuri_gpio_keys, |
@@ -300,8 +386,11 @@ static void __init nuri_map_io(void) | |||
300 | static void __init nuri_machine_init(void) | 386 | static void __init nuri_machine_init(void) |
301 | { | 387 | { |
302 | nuri_sdhci_init(); | 388 | nuri_sdhci_init(); |
389 | nuri_tsp_init(); | ||
303 | 390 | ||
304 | i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); | 391 | i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); |
392 | s3c_i2c3_set_platdata(&i2c3_data); | ||
393 | i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs)); | ||
305 | i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); | 394 | i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); |
306 | 395 | ||
307 | nuri_ehci_init(); | 396 | nuri_ehci_init(); |
diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c index af7b68a6b258..88cc422ee444 100644 --- a/arch/arm/mach-gemini/board-wbd111.c +++ b/arch/arm/mach-gemini/board-wbd111.c | |||
@@ -84,7 +84,6 @@ static struct sys_timer wbd111_timer = { | |||
84 | .init = gemini_timer_init, | 84 | .init = gemini_timer_init, |
85 | }; | 85 | }; |
86 | 86 | ||
87 | #ifdef CONFIG_MTD_PARTITIONS | ||
88 | static struct mtd_partition wbd111_partitions[] = { | 87 | static struct mtd_partition wbd111_partitions[] = { |
89 | { | 88 | { |
90 | .name = "RedBoot", | 89 | .name = "RedBoot", |
@@ -116,11 +115,7 @@ static struct mtd_partition wbd111_partitions[] = { | |||
116 | .mask_flags = MTD_WRITEABLE, | 115 | .mask_flags = MTD_WRITEABLE, |
117 | } | 116 | } |
118 | }; | 117 | }; |
119 | #define wbd111_num_partitions ARRAY_SIZE(wbd111_partitions) | 118 | #define wbd111_num_partitions ARRAY_SIZE(wbd111_partitions) |
120 | #else | ||
121 | #define wbd111_partitions NULL | ||
122 | #define wbd111_num_partitions 0 | ||
123 | #endif /* CONFIG_MTD_PARTITIONS */ | ||
124 | 119 | ||
125 | static void __init wbd111_init(void) | 120 | static void __init wbd111_init(void) |
126 | { | 121 | { |
diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c index 99e5bbecf923..3a220347bc88 100644 --- a/arch/arm/mach-gemini/board-wbd222.c +++ b/arch/arm/mach-gemini/board-wbd222.c | |||
@@ -84,7 +84,6 @@ static struct sys_timer wbd222_timer = { | |||
84 | .init = gemini_timer_init, | 84 | .init = gemini_timer_init, |
85 | }; | 85 | }; |
86 | 86 | ||
87 | #ifdef CONFIG_MTD_PARTITIONS | ||
88 | static struct mtd_partition wbd222_partitions[] = { | 87 | static struct mtd_partition wbd222_partitions[] = { |
89 | { | 88 | { |
90 | .name = "RedBoot", | 89 | .name = "RedBoot", |
@@ -116,11 +115,7 @@ static struct mtd_partition wbd222_partitions[] = { | |||
116 | .mask_flags = MTD_WRITEABLE, | 115 | .mask_flags = MTD_WRITEABLE, |
117 | } | 116 | } |
118 | }; | 117 | }; |
119 | #define wbd222_num_partitions ARRAY_SIZE(wbd222_partitions) | 118 | #define wbd222_num_partitions ARRAY_SIZE(wbd222_partitions) |
120 | #else | ||
121 | #define wbd222_partitions NULL | ||
122 | #define wbd222_num_partitions 0 | ||
123 | #endif /* CONFIG_MTD_PARTITIONS */ | ||
124 | 119 | ||
125 | static void __init wbd222_init(void) | 120 | static void __init wbd222_init(void) |
126 | { | 121 | { |
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 140783386785..dca4f7f9f4f7 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c | |||
@@ -60,7 +60,6 @@ static struct platform_device ixdp425_flash = { | |||
60 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ | 60 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ |
61 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 61 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) |
62 | 62 | ||
63 | #ifdef CONFIG_MTD_PARTITIONS | ||
64 | const char *part_probes[] = { "cmdlinepart", NULL }; | 63 | const char *part_probes[] = { "cmdlinepart", NULL }; |
65 | 64 | ||
66 | static struct mtd_partition ixdp425_partitions[] = { | 65 | static struct mtd_partition ixdp425_partitions[] = { |
@@ -74,7 +73,6 @@ static struct mtd_partition ixdp425_partitions[] = { | |||
74 | .size = MTDPART_SIZ_FULL | 73 | .size = MTDPART_SIZ_FULL |
75 | }, | 74 | }, |
76 | }; | 75 | }; |
77 | #endif | ||
78 | 76 | ||
79 | static void | 77 | static void |
80 | ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 78 | ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
@@ -103,11 +101,9 @@ static struct platform_nand_data ixdp425_flash_nand_data = { | |||
103 | .nr_chips = 1, | 101 | .nr_chips = 1, |
104 | .chip_delay = 30, | 102 | .chip_delay = 30, |
105 | .options = NAND_NO_AUTOINCR, | 103 | .options = NAND_NO_AUTOINCR, |
106 | #ifdef CONFIG_MTD_PARTITIONS | ||
107 | .part_probe_types = part_probes, | 104 | .part_probe_types = part_probes, |
108 | .partitions = ixdp425_partitions, | 105 | .partitions = ixdp425_partitions, |
109 | .nr_partitions = ARRAY_SIZE(ixdp425_partitions), | 106 | .nr_partitions = ARRAY_SIZE(ixdp425_partitions), |
110 | #endif | ||
111 | }, | 107 | }, |
112 | .ctrl = { | 108 | .ctrl = { |
113 | .cmd_ctrl = ixdp425_flash_nand_cmd_ctrl | 109 | .cmd_ctrl = ixdp425_flash_nand_cmd_ctrl |
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c index 5b84bcd30271..b9913234bbf6 100644 --- a/arch/arm/mach-netx/fb.c +++ b/arch/arm/mach-netx/fb.c | |||
@@ -103,7 +103,6 @@ static struct amba_device fb_device = { | |||
103 | .flags = IORESOURCE_MEM, | 103 | .flags = IORESOURCE_MEM, |
104 | }, | 104 | }, |
105 | .irq = { NETX_IRQ_LCD, NO_IRQ }, | 105 | .irq = { NETX_IRQ_LCD, NO_IRQ }, |
106 | .periphid = 0x10112400, | ||
107 | }; | 106 | }; |
108 | 107 | ||
109 | int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) | 108 | int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) |
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig index 71f3ea623974..3c5e0f522e9c 100644 --- a/arch/arm/mach-nomadik/Kconfig +++ b/arch/arm/mach-nomadik/Kconfig | |||
@@ -6,7 +6,6 @@ config MACH_NOMADIK_8815NHK | |||
6 | bool "ST 8815 Nomadik Hardware Kit (evaluation board)" | 6 | bool "ST 8815 Nomadik Hardware Kit (evaluation board)" |
7 | select NOMADIK_8815 | 7 | select NOMADIK_8815 |
8 | select HAS_MTU | 8 | select HAS_MTU |
9 | select NOMADIK_GPIO | ||
10 | 9 | ||
11 | endmenu | 10 | endmenu |
12 | 11 | ||
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 2fc9f94cdd29..cd19309fd3b8 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -153,7 +153,6 @@ config MACH_XCEP | |||
153 | bool "Iskratel Electronics XCEP" | 153 | bool "Iskratel Electronics XCEP" |
154 | select PXA25x | 154 | select PXA25x |
155 | select MTD | 155 | select MTD |
156 | select MTD_PARTITIONS | ||
157 | select MTD_PHYSMAP | 156 | select MTD_PHYSMAP |
158 | select MTD_CFI_INTELEXT | 157 | select MTD_CFI_INTELEXT |
159 | select MTD_CFI | 158 | select MTD_CFI |
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 44440cbd7620..dabc141243f3 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c | |||
@@ -58,8 +58,6 @@ | |||
58 | #include <plat/cpu.h> | 58 | #include <plat/cpu.h> |
59 | #include <plat/gpio-cfg.h> | 59 | #include <plat/gpio-cfg.h> |
60 | 60 | ||
61 | #ifdef CONFIG_MTD_PARTITIONS | ||
62 | |||
63 | #include <linux/mtd/mtd.h> | 61 | #include <linux/mtd/mtd.h> |
64 | #include <linux/mtd/partitions.h> | 62 | #include <linux/mtd/partitions.h> |
65 | #include <linux/mtd/map.h> | 63 | #include <linux/mtd/map.h> |
@@ -113,7 +111,6 @@ static struct platform_device amlm5900_device_nor = { | |||
113 | .num_resources = 1, | 111 | .num_resources = 1, |
114 | .resource = &amlm5900_nor_resource, | 112 | .resource = &amlm5900_nor_resource, |
115 | }; | 113 | }; |
116 | #endif | ||
117 | 114 | ||
118 | static struct map_desc amlm5900_iodesc[] __initdata = { | 115 | static struct map_desc amlm5900_iodesc[] __initdata = { |
119 | }; | 116 | }; |
@@ -158,9 +155,7 @@ static struct platform_device *amlm5900_devices[] __initdata = { | |||
158 | &s3c_device_rtc, | 155 | &s3c_device_rtc, |
159 | &s3c_device_usbgadget, | 156 | &s3c_device_usbgadget, |
160 | &s3c_device_sdi, | 157 | &s3c_device_sdi, |
161 | #ifdef CONFIG_MTD_PARTITIONS | ||
162 | &amlm5900_device_nor, | 158 | &amlm5900_device_nor, |
163 | #endif | ||
164 | }; | 159 | }; |
165 | 160 | ||
166 | static void __init amlm5900_map_io(void) | 161 | static void __init amlm5900_map_io(void) |
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c index a15d0621c22f..43c2b831b9e8 100644 --- a/arch/arm/mach-s3c2410/mach-tct_hammer.c +++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c | |||
@@ -49,8 +49,6 @@ | |||
49 | #include <plat/devs.h> | 49 | #include <plat/devs.h> |
50 | #include <plat/cpu.h> | 50 | #include <plat/cpu.h> |
51 | 51 | ||
52 | #ifdef CONFIG_MTD_PARTITIONS | ||
53 | |||
54 | #include <linux/mtd/mtd.h> | 52 | #include <linux/mtd/mtd.h> |
55 | #include <linux/mtd/partitions.h> | 53 | #include <linux/mtd/partitions.h> |
56 | #include <linux/mtd/map.h> | 54 | #include <linux/mtd/map.h> |
@@ -91,8 +89,6 @@ static struct platform_device tct_hammer_device_nor = { | |||
91 | .resource = &tct_hammer_nor_resource, | 89 | .resource = &tct_hammer_nor_resource, |
92 | }; | 90 | }; |
93 | 91 | ||
94 | #endif | ||
95 | |||
96 | static struct map_desc tct_hammer_iodesc[] __initdata = { | 92 | static struct map_desc tct_hammer_iodesc[] __initdata = { |
97 | }; | 93 | }; |
98 | 94 | ||
@@ -133,9 +129,7 @@ static struct platform_device *tct_hammer_devices[] __initdata = { | |||
133 | &s3c_device_rtc, | 129 | &s3c_device_rtc, |
134 | &s3c_device_usbgadget, | 130 | &s3c_device_usbgadget, |
135 | &s3c_device_sdi, | 131 | &s3c_device_sdi, |
136 | #ifdef CONFIG_MTD_PARTITIONS | ||
137 | &tct_hammer_device_nor, | 132 | &tct_hammer_device_nor, |
138 | #endif | ||
139 | }; | 133 | }; |
140 | 134 | ||
141 | static void __init tct_hammer_map_io(void) | 135 | static void __init tct_hammer_map_io(void) |
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index 405e62128917..82db072cb836 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #include <mach/dma.h> | 17 | #include <mach/dma.h> |
18 | #include <mach/map.h> | 18 | #include <mach/map.h> |
19 | #include <mach/gpio-bank-c.h> | ||
20 | #include <mach/spi-clocks.h> | 19 | #include <mach/spi-clocks.h> |
21 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
22 | 21 | ||
@@ -40,23 +39,15 @@ static char *spi_src_clks[] = { | |||
40 | */ | 39 | */ |
41 | static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev) | 40 | static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev) |
42 | { | 41 | { |
42 | unsigned int base; | ||
43 | |||
43 | switch (pdev->id) { | 44 | switch (pdev->id) { |
44 | case 0: | 45 | case 0: |
45 | s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0); | 46 | base = S3C64XX_GPC(0); |
46 | s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLKO); | ||
47 | s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSIO); | ||
48 | s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP); | ||
49 | s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP); | ||
50 | s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP); | ||
51 | break; | 47 | break; |
52 | 48 | ||
53 | case 1: | 49 | case 1: |
54 | s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1); | 50 | base = S3C64XX_GPC(4); |
55 | s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1); | ||
56 | s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1); | ||
57 | s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP); | ||
58 | s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP); | ||
59 | s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP); | ||
60 | break; | 51 | break; |
61 | 52 | ||
62 | default: | 53 | default: |
@@ -64,6 +55,9 @@ static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev) | |||
64 | return -EINVAL; | 55 | return -EINVAL; |
65 | } | 56 | } |
66 | 57 | ||
58 | s3c_gpio_cfgall_range(base, 3, | ||
59 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); | ||
60 | |||
67 | return 0; | 61 | return 0; |
68 | } | 62 | } |
69 | 63 | ||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h deleted file mode 100644 index 34212e1a7e81..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank A register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPACON (S3C64XX_GPA_BASE + 0x00) | ||
16 | #define S3C64XX_GPADAT (S3C64XX_GPA_BASE + 0x04) | ||
17 | #define S3C64XX_GPAPUD (S3C64XX_GPA_BASE + 0x08) | ||
18 | #define S3C64XX_GPACONSLP (S3C64XX_GPA_BASE + 0x0c) | ||
19 | #define S3C64XX_GPAPUDSLP (S3C64XX_GPA_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPA_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
22 | #define S3C64XX_GPA_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPA_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
24 | |||
25 | #define S3C64XX_GPA0_UART_RXD0 (0x02 << 0) | ||
26 | #define S3C64XX_GPA0_EINT_G1_0 (0x07 << 0) | ||
27 | |||
28 | #define S3C64XX_GPA1_UART_TXD0 (0x02 << 4) | ||
29 | #define S3C64XX_GPA1_EINT_G1_1 (0x07 << 4) | ||
30 | |||
31 | #define S3C64XX_GPA2_UART_nCTS0 (0x02 << 8) | ||
32 | #define S3C64XX_GPA2_EINT_G1_2 (0x07 << 8) | ||
33 | |||
34 | #define S3C64XX_GPA3_UART_nRTS0 (0x02 << 12) | ||
35 | #define S3C64XX_GPA3_EINT_G1_3 (0x07 << 12) | ||
36 | |||
37 | #define S3C64XX_GPA4_UART_RXD1 (0x02 << 16) | ||
38 | #define S3C64XX_GPA4_EINT_G1_4 (0x07 << 16) | ||
39 | |||
40 | #define S3C64XX_GPA5_UART_TXD1 (0x02 << 20) | ||
41 | #define S3C64XX_GPA5_EINT_G1_5 (0x07 << 20) | ||
42 | |||
43 | #define S3C64XX_GPA6_UART_nCTS1 (0x02 << 24) | ||
44 | #define S3C64XX_GPA6_EINT_G1_6 (0x07 << 24) | ||
45 | |||
46 | #define S3C64XX_GPA7_UART_nRTS1 (0x02 << 28) | ||
47 | #define S3C64XX_GPA7_EINT_G1_7 (0x07 << 28) | ||
48 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h deleted file mode 100644 index 7232c037e642..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank B register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPBCON (S3C64XX_GPB_BASE + 0x00) | ||
16 | #define S3C64XX_GPBDAT (S3C64XX_GPB_BASE + 0x04) | ||
17 | #define S3C64XX_GPBPUD (S3C64XX_GPB_BASE + 0x08) | ||
18 | #define S3C64XX_GPBCONSLP (S3C64XX_GPB_BASE + 0x0c) | ||
19 | #define S3C64XX_GPBPUDSLP (S3C64XX_GPB_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPB_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
22 | #define S3C64XX_GPB_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPB_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
24 | |||
25 | #define S3C64XX_GPB0_UART_RXD2 (0x02 << 0) | ||
26 | #define S3C64XX_GPB0_EXTDMA_REQ (0x03 << 0) | ||
27 | #define S3C64XX_GPB0_IrDA_RXD (0x04 << 0) | ||
28 | #define S3C64XX_GPB0_ADDR_CF0 (0x05 << 0) | ||
29 | #define S3C64XX_GPB0_EINT_G1_8 (0x07 << 0) | ||
30 | |||
31 | #define S3C64XX_GPB1_UART_TXD2 (0x02 << 4) | ||
32 | #define S3C64XX_GPB1_EXTDMA_ACK (0x03 << 4) | ||
33 | #define S3C64XX_GPB1_IrDA_TXD (0x04 << 4) | ||
34 | #define S3C64XX_GPB1_ADDR_CF1 (0x05 << 4) | ||
35 | #define S3C64XX_GPB1_EINT_G1_9 (0x07 << 4) | ||
36 | |||
37 | #define S3C64XX_GPB2_UART_RXD3 (0x02 << 8) | ||
38 | #define S3C64XX_GPB2_IrDA_RXD (0x03 << 8) | ||
39 | #define S3C64XX_GPB2_EXTDMA_REQ (0x04 << 8) | ||
40 | #define S3C64XX_GPB2_ADDR_CF2 (0x05 << 8) | ||
41 | #define S3C64XX_GPB2_I2C_SCL1 (0x06 << 8) | ||
42 | #define S3C64XX_GPB2_EINT_G1_10 (0x07 << 8) | ||
43 | |||
44 | #define S3C64XX_GPB3_UART_TXD3 (0x02 << 12) | ||
45 | #define S3C64XX_GPB3_IrDA_TXD (0x03 << 12) | ||
46 | #define S3C64XX_GPB3_EXTDMA_ACK (0x04 << 12) | ||
47 | #define S3C64XX_GPB3_I2C_SDA1 (0x06 << 12) | ||
48 | #define S3C64XX_GPB3_EINT_G1_11 (0x07 << 12) | ||
49 | |||
50 | #define S3C64XX_GPB4_IrDA_SDBW (0x02 << 16) | ||
51 | #define S3C64XX_GPB4_CAM_FIELD (0x03 << 16) | ||
52 | #define S3C64XX_GPB4_CF_DATA_DIR (0x04 << 16) | ||
53 | #define S3C64XX_GPB4_EINT_G1_12 (0x07 << 16) | ||
54 | |||
55 | #define S3C64XX_GPB5_I2C_SCL0 (0x02 << 20) | ||
56 | #define S3C64XX_GPB5_EINT_G1_13 (0x07 << 20) | ||
57 | |||
58 | #define S3C64XX_GPB6_I2C_SDA0 (0x02 << 24) | ||
59 | #define S3C64XX_GPB6_EINT_G1_14 (0x07 << 24) | ||
60 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h deleted file mode 100644 index db189ab1639a..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank C register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPCCON (S3C64XX_GPC_BASE + 0x00) | ||
16 | #define S3C64XX_GPCDAT (S3C64XX_GPC_BASE + 0x04) | ||
17 | #define S3C64XX_GPCPUD (S3C64XX_GPC_BASE + 0x08) | ||
18 | #define S3C64XX_GPCCONSLP (S3C64XX_GPC_BASE + 0x0c) | ||
19 | #define S3C64XX_GPCPUDSLP (S3C64XX_GPC_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPC_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
22 | #define S3C64XX_GPC_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPC_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
24 | |||
25 | #define S3C64XX_GPC0_SPI_MISO0 (0x02 << 0) | ||
26 | #define S3C64XX_GPC0_EINT_G2_0 (0x07 << 0) | ||
27 | |||
28 | #define S3C64XX_GPC1_SPI_CLKO (0x02 << 4) | ||
29 | #define S3C64XX_GPC1_EINT_G2_1 (0x07 << 4) | ||
30 | |||
31 | #define S3C64XX_GPC2_SPI_MOSIO (0x02 << 8) | ||
32 | #define S3C64XX_GPC2_EINT_G2_2 (0x07 << 8) | ||
33 | |||
34 | #define S3C64XX_GPC3_SPI_nCSO (0x02 << 12) | ||
35 | #define S3C64XX_GPC3_EINT_G2_3 (0x07 << 12) | ||
36 | |||
37 | #define S3C64XX_GPC4_SPI_MISO1 (0x02 << 16) | ||
38 | #define S3C64XX_GPC4_MMC2_CMD (0x03 << 16) | ||
39 | #define S3C64XX_GPC4_I2S_V40_DO0 (0x05 << 16) | ||
40 | #define S3C64XX_GPC4_EINT_G2_4 (0x07 << 16) | ||
41 | |||
42 | #define S3C64XX_GPC5_SPI_CLK1 (0x02 << 20) | ||
43 | #define S3C64XX_GPC5_MMC2_CLK (0x03 << 20) | ||
44 | #define S3C64XX_GPC5_I2S_V40_DO1 (0x05 << 20) | ||
45 | #define S3C64XX_GPC5_EINT_G2_5 (0x07 << 20) | ||
46 | |||
47 | #define S3C64XX_GPC6_SPI_MOSI1 (0x02 << 24) | ||
48 | #define S3C64XX_GPC6_EINT_G2_6 (0x07 << 24) | ||
49 | |||
50 | #define S3C64XX_GPC7_SPI_nCS1 (0x02 << 28) | ||
51 | #define S3C64XX_GPC7_I2S_V40_DO2 (0x05 << 28) | ||
52 | #define S3C64XX_GPC7_EINT_G2_7 (0x07 << 28) | ||
53 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h deleted file mode 100644 index 1a01cee7aca3..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank D register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPDCON (S3C64XX_GPD_BASE + 0x00) | ||
16 | #define S3C64XX_GPDDAT (S3C64XX_GPD_BASE + 0x04) | ||
17 | #define S3C64XX_GPDPUD (S3C64XX_GPD_BASE + 0x08) | ||
18 | #define S3C64XX_GPDCONSLP (S3C64XX_GPD_BASE + 0x0c) | ||
19 | #define S3C64XX_GPDPUDSLP (S3C64XX_GPD_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPD_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
22 | #define S3C64XX_GPD_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPD_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
24 | |||
25 | #define S3C64XX_GPD0_PCM0_SCLK (0x02 << 0) | ||
26 | #define S3C64XX_GPD0_I2S0_CLK (0x03 << 0) | ||
27 | #define S3C64XX_GPD0_AC97_BITCLK (0x04 << 0) | ||
28 | #define S3C64XX_GPD0_EINT_G3_0 (0x07 << 0) | ||
29 | |||
30 | #define S3C64XX_GPD1_PCM0_EXTCLK (0x02 << 4) | ||
31 | #define S3C64XX_GPD1_I2S0_CDCLK (0x03 << 4) | ||
32 | #define S3C64XX_GPD1_AC97_nRESET (0x04 << 4) | ||
33 | #define S3C64XX_GPD1_EINT_G3_1 (0x07 << 4) | ||
34 | |||
35 | #define S3C64XX_GPD2_PCM0_FSYNC (0x02 << 8) | ||
36 | #define S3C64XX_GPD2_I2S0_LRCLK (0x03 << 8) | ||
37 | #define S3C64XX_GPD2_AC97_SYNC (0x04 << 8) | ||
38 | #define S3C64XX_GPD2_EINT_G3_2 (0x07 << 8) | ||
39 | |||
40 | #define S3C64XX_GPD3_PCM0_SIN (0x02 << 12) | ||
41 | #define S3C64XX_GPD3_I2S0_DI (0x03 << 12) | ||
42 | #define S3C64XX_GPD3_AC97_SDI (0x04 << 12) | ||
43 | #define S3C64XX_GPD3_EINT_G3_3 (0x07 << 12) | ||
44 | |||
45 | #define S3C64XX_GPD4_PCM0_SOUT (0x02 << 16) | ||
46 | #define S3C64XX_GPD4_I2S0_D0 (0x03 << 16) | ||
47 | #define S3C64XX_GPD4_AC97_SDO (0x04 << 16) | ||
48 | #define S3C64XX_GPD4_EINT_G3_4 (0x07 << 16) | ||
49 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h deleted file mode 100644 index f057adb627dd..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank E register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPECON (S3C64XX_GPE_BASE + 0x00) | ||
16 | #define S3C64XX_GPEDAT (S3C64XX_GPE_BASE + 0x04) | ||
17 | #define S3C64XX_GPEPUD (S3C64XX_GPE_BASE + 0x08) | ||
18 | #define S3C64XX_GPECONSLP (S3C64XX_GPE_BASE + 0x0c) | ||
19 | #define S3C64XX_GPEPUDSLP (S3C64XX_GPE_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPE_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
22 | #define S3C64XX_GPE_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPE_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
24 | |||
25 | #define S3C64XX_GPE0_PCM1_SCLK (0x02 << 0) | ||
26 | #define S3C64XX_GPE0_I2S1_CLK (0x03 << 0) | ||
27 | #define S3C64XX_GPE0_AC97_BITCLK (0x04 << 0) | ||
28 | |||
29 | #define S3C64XX_GPE1_PCM1_EXTCLK (0x02 << 4) | ||
30 | #define S3C64XX_GPE1_I2S1_CDCLK (0x03 << 4) | ||
31 | #define S3C64XX_GPE1_AC97_nRESET (0x04 << 4) | ||
32 | |||
33 | #define S3C64XX_GPE2_PCM1_FSYNC (0x02 << 8) | ||
34 | #define S3C64XX_GPE2_I2S1_LRCLK (0x03 << 8) | ||
35 | #define S3C64XX_GPE2_AC97_SYNC (0x04 << 8) | ||
36 | |||
37 | #define S3C64XX_GPE3_PCM1_SIN (0x02 << 12) | ||
38 | #define S3C64XX_GPE3_I2S1_DI (0x03 << 12) | ||
39 | #define S3C64XX_GPE3_AC97_SDI (0x04 << 12) | ||
40 | |||
41 | #define S3C64XX_GPE4_PCM1_SOUT (0x02 << 16) | ||
42 | #define S3C64XX_GPE4_I2S1_D0 (0x03 << 16) | ||
43 | #define S3C64XX_GPE4_AC97_SDO (0x04 << 16) | ||
44 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h deleted file mode 100644 index 62ab8f5e7835..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank F register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPFCON (S3C64XX_GPF_BASE + 0x00) | ||
16 | #define S3C64XX_GPFDAT (S3C64XX_GPF_BASE + 0x04) | ||
17 | #define S3C64XX_GPFPUD (S3C64XX_GPF_BASE + 0x08) | ||
18 | #define S3C64XX_GPFCONSLP (S3C64XX_GPF_BASE + 0x0c) | ||
19 | #define S3C64XX_GPFPUDSLP (S3C64XX_GPF_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPF_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
22 | #define S3C64XX_GPF_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
23 | #define S3C64XX_GPF_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
24 | |||
25 | #define S3C64XX_GPF0_CAMIF_CLK (0x02 << 0) | ||
26 | #define S3C64XX_GPF0_EINT_G4_0 (0x03 << 0) | ||
27 | |||
28 | #define S3C64XX_GPF1_CAMIF_HREF (0x02 << 2) | ||
29 | #define S3C64XX_GPF1_EINT_G4_1 (0x03 << 2) | ||
30 | |||
31 | #define S3C64XX_GPF2_CAMIF_PCLK (0x02 << 4) | ||
32 | #define S3C64XX_GPF2_EINT_G4_2 (0x03 << 4) | ||
33 | |||
34 | #define S3C64XX_GPF3_CAMIF_nRST (0x02 << 6) | ||
35 | #define S3C64XX_GPF3_EINT_G4_3 (0x03 << 6) | ||
36 | |||
37 | #define S3C64XX_GPF4_CAMIF_VSYNC (0x02 << 8) | ||
38 | #define S3C64XX_GPF4_EINT_G4_4 (0x03 << 8) | ||
39 | |||
40 | #define S3C64XX_GPF5_CAMIF_YDATA0 (0x02 << 10) | ||
41 | #define S3C64XX_GPF5_EINT_G4_5 (0x03 << 10) | ||
42 | |||
43 | #define S3C64XX_GPF6_CAMIF_YDATA1 (0x02 << 12) | ||
44 | #define S3C64XX_GPF6_EINT_G4_6 (0x03 << 12) | ||
45 | |||
46 | #define S3C64XX_GPF7_CAMIF_YDATA2 (0x02 << 14) | ||
47 | #define S3C64XX_GPF7_EINT_G4_7 (0x03 << 14) | ||
48 | |||
49 | #define S3C64XX_GPF8_CAMIF_YDATA3 (0x02 << 16) | ||
50 | #define S3C64XX_GPF8_EINT_G4_8 (0x03 << 16) | ||
51 | |||
52 | #define S3C64XX_GPF9_CAMIF_YDATA4 (0x02 << 18) | ||
53 | #define S3C64XX_GPF9_EINT_G4_9 (0x03 << 18) | ||
54 | |||
55 | #define S3C64XX_GPF10_CAMIF_YDATA5 (0x02 << 20) | ||
56 | #define S3C64XX_GPF10_EINT_G4_10 (0x03 << 20) | ||
57 | |||
58 | #define S3C64XX_GPF11_CAMIF_YDATA6 (0x02 << 22) | ||
59 | #define S3C64XX_GPF11_EINT_G4_11 (0x03 << 22) | ||
60 | |||
61 | #define S3C64XX_GPF12_CAMIF_YDATA7 (0x02 << 24) | ||
62 | #define S3C64XX_GPF12_EINT_G4_12 (0x03 << 24) | ||
63 | |||
64 | #define S3C64XX_GPF13_PWM_ECLK (0x02 << 26) | ||
65 | #define S3C64XX_GPF13_EINT_G4_13 (0x03 << 26) | ||
66 | |||
67 | #define S3C64XX_GPF14_PWM_TOUT0 (0x02 << 28) | ||
68 | #define S3C64XX_GPF14_CLKOUT0 (0x03 << 28) | ||
69 | |||
70 | #define S3C64XX_GPF15_PWM_TOUT1 (0x02 << 30) | ||
71 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h deleted file mode 100644 index b94954af1598..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank G register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPGCON (S3C64XX_GPG_BASE + 0x00) | ||
16 | #define S3C64XX_GPGDAT (S3C64XX_GPG_BASE + 0x04) | ||
17 | #define S3C64XX_GPGPUD (S3C64XX_GPG_BASE + 0x08) | ||
18 | #define S3C64XX_GPGCONSLP (S3C64XX_GPG_BASE + 0x0c) | ||
19 | #define S3C64XX_GPGPUDSLP (S3C64XX_GPG_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPG_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
22 | #define S3C64XX_GPG_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPG_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
24 | |||
25 | #define S3C64XX_GPG0_MMC0_CLK (0x02 << 0) | ||
26 | #define S3C64XX_GPG0_EINT_G5_0 (0x07 << 0) | ||
27 | |||
28 | #define S3C64XX_GPG1_MMC0_CMD (0x02 << 4) | ||
29 | #define S3C64XX_GPG1_EINT_G5_1 (0x07 << 4) | ||
30 | |||
31 | #define S3C64XX_GPG2_MMC0_DATA0 (0x02 << 8) | ||
32 | #define S3C64XX_GPG2_EINT_G5_2 (0x07 << 8) | ||
33 | |||
34 | #define S3C64XX_GPG3_MMC0_DATA1 (0x02 << 12) | ||
35 | #define S3C64XX_GPG3_EINT_G5_3 (0x07 << 12) | ||
36 | |||
37 | #define S3C64XX_GPG4_MMC0_DATA2 (0x02 << 16) | ||
38 | #define S3C64XX_GPG4_EINT_G5_4 (0x07 << 16) | ||
39 | |||
40 | #define S3C64XX_GPG5_MMC0_DATA3 (0x02 << 20) | ||
41 | #define S3C64XX_GPG5_EINT_G5_5 (0x07 << 20) | ||
42 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h deleted file mode 100644 index 5d75aaad865e..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank H register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPHCON0 (S3C64XX_GPH_BASE + 0x00) | ||
16 | #define S3C64XX_GPHCON1 (S3C64XX_GPH_BASE + 0x04) | ||
17 | #define S3C64XX_GPHDAT (S3C64XX_GPH_BASE + 0x08) | ||
18 | #define S3C64XX_GPHPUD (S3C64XX_GPH_BASE + 0x0c) | ||
19 | #define S3C64XX_GPHCONSLP (S3C64XX_GPH_BASE + 0x10) | ||
20 | #define S3C64XX_GPHPUDSLP (S3C64XX_GPH_BASE + 0x14) | ||
21 | |||
22 | #define S3C64XX_GPH_CONMASK(__gpio) (0xf << ((__gpio) * 4)) | ||
23 | #define S3C64XX_GPH_INPUT(__gpio) (0x0 << ((__gpio) * 4)) | ||
24 | #define S3C64XX_GPH_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) | ||
25 | |||
26 | #define S3C64XX_GPH0_MMC1_CLK (0x02 << 0) | ||
27 | #define S3C64XX_GPH0_KP_COL0 (0x04 << 0) | ||
28 | #define S3C64XX_GPH0_EINT_G6_0 (0x07 << 0) | ||
29 | |||
30 | #define S3C64XX_GPH1_MMC1_CMD (0x02 << 4) | ||
31 | #define S3C64XX_GPH1_KP_COL1 (0x04 << 4) | ||
32 | #define S3C64XX_GPH1_EINT_G6_1 (0x07 << 4) | ||
33 | |||
34 | #define S3C64XX_GPH2_MMC1_DATA0 (0x02 << 8) | ||
35 | #define S3C64XX_GPH2_KP_COL2 (0x04 << 8) | ||
36 | #define S3C64XX_GPH2_EINT_G6_2 (0x07 << 8) | ||
37 | |||
38 | #define S3C64XX_GPH3_MMC1_DATA1 (0x02 << 12) | ||
39 | #define S3C64XX_GPH3_KP_COL3 (0x04 << 12) | ||
40 | #define S3C64XX_GPH3_EINT_G6_3 (0x07 << 12) | ||
41 | |||
42 | #define S3C64XX_GPH4_MMC1_DATA2 (0x02 << 16) | ||
43 | #define S3C64XX_GPH4_KP_COL4 (0x04 << 16) | ||
44 | #define S3C64XX_GPH4_EINT_G6_4 (0x07 << 16) | ||
45 | |||
46 | #define S3C64XX_GPH5_MMC1_DATA3 (0x02 << 20) | ||
47 | #define S3C64XX_GPH5_KP_COL5 (0x04 << 20) | ||
48 | #define S3C64XX_GPH5_EINT_G6_5 (0x07 << 20) | ||
49 | |||
50 | #define S3C64XX_GPH6_MMC1_DATA4 (0x02 << 24) | ||
51 | #define S3C64XX_GPH6_MMC2_DATA0 (0x03 << 24) | ||
52 | #define S3C64XX_GPH6_KP_COL6 (0x04 << 24) | ||
53 | #define S3C64XX_GPH6_I2S_V40_BCLK (0x05 << 24) | ||
54 | #define S3C64XX_GPH6_ADDR_CF0 (0x06 << 24) | ||
55 | #define S3C64XX_GPH6_EINT_G6_6 (0x07 << 24) | ||
56 | |||
57 | #define S3C64XX_GPH7_MMC1_DATA5 (0x02 << 28) | ||
58 | #define S3C64XX_GPH7_MMC2_DATA1 (0x03 << 28) | ||
59 | #define S3C64XX_GPH7_KP_COL7 (0x04 << 28) | ||
60 | #define S3C64XX_GPH7_I2S_V40_CDCLK (0x05 << 28) | ||
61 | #define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28) | ||
62 | #define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28) | ||
63 | |||
64 | #define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 0) | ||
65 | #define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 0) | ||
66 | #define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 0) | ||
67 | #define S3C64XX_GPH8_ADDR_CF2 (0x06 << 0) | ||
68 | #define S3C64XX_GPH8_EINT_G6_8 (0x07 << 0) | ||
69 | |||
70 | #define S3C64XX_GPH9_OUTPUT (0x01 << 4) | ||
71 | #define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 4) | ||
72 | #define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 4) | ||
73 | #define S3C64XX_GPH9_I2S_V40_DI (0x05 << 4) | ||
74 | #define S3C64XX_GPH9_EINT_G6_9 (0x07 << 4) | ||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h deleted file mode 100644 index 4ceaa6098bc7..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank I register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPICON (S3C64XX_GPI_BASE + 0x00) | ||
16 | #define S3C64XX_GPIDAT (S3C64XX_GPI_BASE + 0x04) | ||
17 | #define S3C64XX_GPIPUD (S3C64XX_GPI_BASE + 0x08) | ||
18 | #define S3C64XX_GPICONSLP (S3C64XX_GPI_BASE + 0x0c) | ||
19 | #define S3C64XX_GPIPUDSLP (S3C64XX_GPI_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPI_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
22 | #define S3C64XX_GPI_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
23 | #define S3C64XX_GPI_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
24 | |||
25 | #define S3C64XX_GPI0_VD0 (0x02 << 0) | ||
26 | #define S3C64XX_GPI1_VD1 (0x02 << 2) | ||
27 | #define S3C64XX_GPI2_VD2 (0x02 << 4) | ||
28 | #define S3C64XX_GPI3_VD3 (0x02 << 6) | ||
29 | #define S3C64XX_GPI4_VD4 (0x02 << 8) | ||
30 | #define S3C64XX_GPI5_VD5 (0x02 << 10) | ||
31 | #define S3C64XX_GPI6_VD6 (0x02 << 12) | ||
32 | #define S3C64XX_GPI7_VD7 (0x02 << 14) | ||
33 | #define S3C64XX_GPI8_VD8 (0x02 << 16) | ||
34 | #define S3C64XX_GPI9_VD9 (0x02 << 18) | ||
35 | #define S3C64XX_GPI10_VD10 (0x02 << 20) | ||
36 | #define S3C64XX_GPI11_VD11 (0x02 << 22) | ||
37 | #define S3C64XX_GPI12_VD12 (0x02 << 24) | ||
38 | #define S3C64XX_GPI13_VD13 (0x02 << 26) | ||
39 | #define S3C64XX_GPI14_VD14 (0x02 << 28) | ||
40 | #define S3C64XX_GPI15_VD15 (0x02 << 30) | ||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h deleted file mode 100644 index 6f25cd079a40..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank J register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPJCON (S3C64XX_GPJ_BASE + 0x00) | ||
16 | #define S3C64XX_GPJDAT (S3C64XX_GPJ_BASE + 0x04) | ||
17 | #define S3C64XX_GPJPUD (S3C64XX_GPJ_BASE + 0x08) | ||
18 | #define S3C64XX_GPJCONSLP (S3C64XX_GPJ_BASE + 0x0c) | ||
19 | #define S3C64XX_GPJPUDSLP (S3C64XX_GPJ_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPJ_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
22 | #define S3C64XX_GPJ_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
23 | #define S3C64XX_GPJ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
24 | |||
25 | #define S3C64XX_GPJ0_VD16 (0x02 << 0) | ||
26 | #define S3C64XX_GPJ1_VD17 (0x02 << 2) | ||
27 | #define S3C64XX_GPJ2_VD18 (0x02 << 4) | ||
28 | #define S3C64XX_GPJ3_VD19 (0x02 << 6) | ||
29 | #define S3C64XX_GPJ4_VD20 (0x02 << 8) | ||
30 | #define S3C64XX_GPJ5_VD21 (0x02 << 10) | ||
31 | #define S3C64XX_GPJ6_VD22 (0x02 << 12) | ||
32 | #define S3C64XX_GPJ7_VD23 (0x02 << 14) | ||
33 | #define S3C64XX_GPJ8_LCD_HSYNC (0x02 << 16) | ||
34 | #define S3C64XX_GPJ9_LCD_VSYNC (0x02 << 18) | ||
35 | #define S3C64XX_GPJ10_LCD_VDEN (0x02 << 20) | ||
36 | #define S3C64XX_GPJ11_LCD_VCLK (0x02 << 22) | ||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h deleted file mode 100644 index d0aeda1cd9de..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank N register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00) | ||
16 | #define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04) | ||
17 | #define S3C64XX_GPNPUD (S3C64XX_GPN_BASE + 0x08) | ||
18 | |||
19 | #define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
20 | #define S3C64XX_GPN_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
21 | #define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
22 | |||
23 | #define S3C64XX_GPN0_EINT0 (0x02 << 0) | ||
24 | #define S3C64XX_GPN0_KP_ROW0 (0x03 << 0) | ||
25 | |||
26 | #define S3C64XX_GPN1_EINT1 (0x02 << 2) | ||
27 | #define S3C64XX_GPN1_KP_ROW1 (0x03 << 2) | ||
28 | |||
29 | #define S3C64XX_GPN2_EINT2 (0x02 << 4) | ||
30 | #define S3C64XX_GPN2_KP_ROW2 (0x03 << 4) | ||
31 | |||
32 | #define S3C64XX_GPN3_EINT3 (0x02 << 6) | ||
33 | #define S3C64XX_GPN3_KP_ROW3 (0x03 << 6) | ||
34 | |||
35 | #define S3C64XX_GPN4_EINT4 (0x02 << 8) | ||
36 | #define S3C64XX_GPN4_KP_ROW4 (0x03 << 8) | ||
37 | |||
38 | #define S3C64XX_GPN5_EINT5 (0x02 << 10) | ||
39 | #define S3C64XX_GPN5_KP_ROW5 (0x03 << 10) | ||
40 | |||
41 | #define S3C64XX_GPN6_EINT6 (0x02 << 12) | ||
42 | #define S3C64XX_GPN6_KP_ROW6 (0x03 << 12) | ||
43 | |||
44 | #define S3C64XX_GPN7_EINT7 (0x02 << 14) | ||
45 | #define S3C64XX_GPN7_KP_ROW7 (0x03 << 14) | ||
46 | |||
47 | #define S3C64XX_GPN8_EINT8 (0x02 << 16) | ||
48 | #define S3C64XX_GPN9_EINT9 (0x02 << 18) | ||
49 | #define S3C64XX_GPN10_EINT10 (0x02 << 20) | ||
50 | #define S3C64XX_GPN11_EINT11 (0x02 << 22) | ||
51 | #define S3C64XX_GPN12_EINT12 (0x02 << 24) | ||
52 | #define S3C64XX_GPN13_EINT13 (0x02 << 26) | ||
53 | #define S3C64XX_GPN14_EINT14 (0x02 << 28) | ||
54 | #define S3C64XX_GPN15_EINT15 (0x02 << 30) | ||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h deleted file mode 100644 index 21868fa102d0..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank O register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPOCON (S3C64XX_GPO_BASE + 0x00) | ||
16 | #define S3C64XX_GPODAT (S3C64XX_GPO_BASE + 0x04) | ||
17 | #define S3C64XX_GPOPUD (S3C64XX_GPO_BASE + 0x08) | ||
18 | #define S3C64XX_GPOCONSLP (S3C64XX_GPO_BASE + 0x0c) | ||
19 | #define S3C64XX_GPOPUDSLP (S3C64XX_GPO_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPO_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
22 | #define S3C64XX_GPO_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
23 | #define S3C64XX_GPO_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
24 | |||
25 | #define S3C64XX_GPO0_MEM0_nCS2 (0x02 << 0) | ||
26 | #define S3C64XX_GPO0_EINT_G7_0 (0x03 << 0) | ||
27 | |||
28 | #define S3C64XX_GPO1_MEM0_nCS3 (0x02 << 2) | ||
29 | #define S3C64XX_GPO1_EINT_G7_1 (0x03 << 2) | ||
30 | |||
31 | #define S3C64XX_GPO2_MEM0_nCS4 (0x02 << 4) | ||
32 | #define S3C64XX_GPO2_EINT_G7_2 (0x03 << 4) | ||
33 | |||
34 | #define S3C64XX_GPO3_MEM0_nCS5 (0x02 << 6) | ||
35 | #define S3C64XX_GPO3_EINT_G7_3 (0x03 << 6) | ||
36 | |||
37 | #define S3C64XX_GPO4_EINT_G7_4 (0x03 << 8) | ||
38 | |||
39 | #define S3C64XX_GPO5_EINT_G7_5 (0x03 << 10) | ||
40 | |||
41 | #define S3C64XX_GPO6_MEM0_ADDR6 (0x02 << 12) | ||
42 | #define S3C64XX_GPO6_EINT_G7_6 (0x03 << 12) | ||
43 | |||
44 | #define S3C64XX_GPO7_MEM0_ADDR7 (0x02 << 14) | ||
45 | #define S3C64XX_GPO7_EINT_G7_7 (0x03 << 14) | ||
46 | |||
47 | #define S3C64XX_GPO8_MEM0_ADDR8 (0x02 << 16) | ||
48 | #define S3C64XX_GPO8_EINT_G7_8 (0x03 << 16) | ||
49 | |||
50 | #define S3C64XX_GPO9_MEM0_ADDR9 (0x02 << 18) | ||
51 | #define S3C64XX_GPO9_EINT_G7_9 (0x03 << 18) | ||
52 | |||
53 | #define S3C64XX_GPO10_MEM0_ADDR10 (0x02 << 20) | ||
54 | #define S3C64XX_GPO10_EINT_G7_10 (0x03 << 20) | ||
55 | |||
56 | #define S3C64XX_GPO11_MEM0_ADDR11 (0x02 << 22) | ||
57 | #define S3C64XX_GPO11_EINT_G7_11 (0x03 << 22) | ||
58 | |||
59 | #define S3C64XX_GPO12_MEM0_ADDR12 (0x02 << 24) | ||
60 | #define S3C64XX_GPO12_EINT_G7_12 (0x03 << 24) | ||
61 | |||
62 | #define S3C64XX_GPO13_MEM0_ADDR13 (0x02 << 26) | ||
63 | #define S3C64XX_GPO13_EINT_G7_13 (0x03 << 26) | ||
64 | |||
65 | #define S3C64XX_GPO14_MEM0_ADDR14 (0x02 << 28) | ||
66 | #define S3C64XX_GPO14_EINT_G7_14 (0x03 << 28) | ||
67 | |||
68 | #define S3C64XX_GPO15_MEM0_ADDR15 (0x02 << 30) | ||
69 | #define S3C64XX_GPO15_EINT_G7_15 (0x03 << 30) | ||
70 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h deleted file mode 100644 index 46bcfb63b8de..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank P register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPPCON (S3C64XX_GPP_BASE + 0x00) | ||
16 | #define S3C64XX_GPPDAT (S3C64XX_GPP_BASE + 0x04) | ||
17 | #define S3C64XX_GPPPUD (S3C64XX_GPP_BASE + 0x08) | ||
18 | #define S3C64XX_GPPCONSLP (S3C64XX_GPP_BASE + 0x0c) | ||
19 | #define S3C64XX_GPPPUDSLP (S3C64XX_GPP_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPP_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
22 | #define S3C64XX_GPP_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
23 | #define S3C64XX_GPP_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
24 | |||
25 | #define S3C64XX_GPP0_MEM0_ADDRV (0x02 << 0) | ||
26 | #define S3C64XX_GPP0_EINT_G8_0 (0x03 << 0) | ||
27 | |||
28 | #define S3C64XX_GPP1_MEM0_SMCLK (0x02 << 2) | ||
29 | #define S3C64XX_GPP1_EINT_G8_1 (0x03 << 2) | ||
30 | |||
31 | #define S3C64XX_GPP2_MEM0_nWAIT (0x02 << 4) | ||
32 | #define S3C64XX_GPP2_EINT_G8_2 (0x03 << 4) | ||
33 | |||
34 | #define S3C64XX_GPP3_MEM0_RDY0_ALE (0x02 << 6) | ||
35 | #define S3C64XX_GPP3_EINT_G8_3 (0x03 << 6) | ||
36 | |||
37 | #define S3C64XX_GPP4_MEM0_RDY1_CLE (0x02 << 8) | ||
38 | #define S3C64XX_GPP4_EINT_G8_4 (0x03 << 8) | ||
39 | |||
40 | #define S3C64XX_GPP5_MEM0_INTsm0_FWE (0x02 << 10) | ||
41 | #define S3C64XX_GPP5_EINT_G8_5 (0x03 << 10) | ||
42 | |||
43 | #define S3C64XX_GPP6_MEM0_(null) (0x02 << 12) | ||
44 | #define S3C64XX_GPP6_EINT_G8_6 (0x03 << 12) | ||
45 | |||
46 | #define S3C64XX_GPP7_MEM0_INTsm1_FRE (0x02 << 14) | ||
47 | #define S3C64XX_GPP7_EINT_G8_7 (0x03 << 14) | ||
48 | |||
49 | #define S3C64XX_GPP8_MEM0_RPn_RnB (0x02 << 16) | ||
50 | #define S3C64XX_GPP8_EINT_G8_8 (0x03 << 16) | ||
51 | |||
52 | #define S3C64XX_GPP9_MEM0_ATA_RESET (0x02 << 18) | ||
53 | #define S3C64XX_GPP9_EINT_G8_9 (0x03 << 18) | ||
54 | |||
55 | #define S3C64XX_GPP10_MEM0_ATA_INPACK (0x02 << 20) | ||
56 | #define S3C64XX_GPP10_EINT_G8_10 (0x03 << 20) | ||
57 | |||
58 | #define S3C64XX_GPP11_MEM0_ATA_REG (0x02 << 22) | ||
59 | #define S3C64XX_GPP11_EINT_G8_11 (0x03 << 22) | ||
60 | |||
61 | #define S3C64XX_GPP12_MEM0_ATA_WE (0x02 << 24) | ||
62 | #define S3C64XX_GPP12_EINT_G8_12 (0x03 << 24) | ||
63 | |||
64 | #define S3C64XX_GPP13_MEM0_ATA_OE (0x02 << 26) | ||
65 | #define S3C64XX_GPP13_EINT_G8_13 (0x03 << 26) | ||
66 | |||
67 | #define S3C64XX_GPP14_MEM0_ATA_CD (0x02 << 28) | ||
68 | #define S3C64XX_GPP14_EINT_G8_14 (0x03 << 28) | ||
69 | |||
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h deleted file mode 100644 index 1712223487b0..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * GPIO Bank Q register and configuration definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #define S3C64XX_GPQCON (S3C64XX_GPQ_BASE + 0x00) | ||
16 | #define S3C64XX_GPQDAT (S3C64XX_GPQ_BASE + 0x04) | ||
17 | #define S3C64XX_GPQPUD (S3C64XX_GPQ_BASE + 0x08) | ||
18 | #define S3C64XX_GPQCONSLP (S3C64XX_GPQ_BASE + 0x0c) | ||
19 | #define S3C64XX_GPQPUDSLP (S3C64XX_GPQ_BASE + 0x10) | ||
20 | |||
21 | #define S3C64XX_GPQ_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
22 | #define S3C64XX_GPQ_INPUT(__gpio) (0x0 << ((__gpio) * 2)) | ||
23 | #define S3C64XX_GPQ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
24 | |||
25 | #define S3C64XX_GPQ0_MEM0_ADDR18_RAS (0x02 << 0) | ||
26 | #define S3C64XX_GPQ0_EINT_G9_0 (0x03 << 0) | ||
27 | |||
28 | #define S3C64XX_GPQ1_MEM0_ADDR19_CAS (0x02 << 2) | ||
29 | #define S3C64XX_GPQ1_EINT_G9_1 (0x03 << 2) | ||
30 | |||
31 | #define S3C64XX_GPQ2_EINT_G9_2 (0x03 << 4) | ||
32 | |||
33 | #define S3C64XX_GPQ3_EINT_G9_3 (0x03 << 6) | ||
34 | |||
35 | #define S3C64XX_GPQ4_EINT_G9_4 (0x03 << 8) | ||
36 | |||
37 | #define S3C64XX_GPQ5_EINT_G9_5 (0x03 << 10) | ||
38 | |||
39 | #define S3C64XX_GPQ6_EINT_G9_6 (0x03 << 12) | ||
40 | |||
41 | #define S3C64XX_GPQ7_MEM0_ADDR17_WENDMC (0x02 << 14) | ||
42 | #define S3C64XX_GPQ7_EINT_G9_7 (0x03 << 14) | ||
43 | |||
44 | #define S3C64XX_GPQ8_MEM0_ADDR16_APDMC (0x02 << 16) | ||
45 | #define S3C64XX_GPQ8_EINT_G9_8 (0x03 << 16) | ||
46 | |||
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 686a4f270b12..2c0353a80906 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <mach/hardware.h> | 50 | #include <mach/hardware.h> |
51 | #include <mach/regs-fb.h> | 51 | #include <mach/regs-fb.h> |
52 | #include <mach/map.h> | 52 | #include <mach/map.h> |
53 | #include <mach/gpio-bank-f.h> | ||
54 | 53 | ||
55 | #include <asm/irq.h> | 54 | #include <asm/irq.h> |
56 | #include <asm/mach-types.h> | 55 | #include <asm/mach-types.h> |
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 79412f735a8d..bc1c470b7de6 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c | |||
@@ -30,26 +30,18 @@ | |||
30 | #include <mach/regs-gpio-memport.h> | 30 | #include <mach/regs-gpio-memport.h> |
31 | 31 | ||
32 | #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK | 32 | #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK |
33 | #include <mach/gpio-bank-n.h> | ||
34 | |||
35 | void s3c_pm_debug_smdkled(u32 set, u32 clear) | 33 | void s3c_pm_debug_smdkled(u32 set, u32 clear) |
36 | { | 34 | { |
37 | unsigned long flags; | 35 | unsigned long flags; |
38 | u32 reg; | 36 | int i; |
39 | 37 | ||
40 | local_irq_save(flags); | 38 | local_irq_save(flags); |
41 | reg = __raw_readl(S3C64XX_GPNCON); | 39 | for (i = 0; i < 4; i++) { |
42 | reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | | 40 | if (clear & (1 << i)) |
43 | S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15)); | 41 | gpio_set_value(S3C64XX_GPN(12 + i), 0); |
44 | reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | | 42 | if (set & (1 << i)) |
45 | S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15); | 43 | gpio_set_value(S3C64XX_GPN(12 + i), 1); |
46 | __raw_writel(reg, S3C64XX_GPNCON); | 44 | } |
47 | |||
48 | reg = __raw_readl(S3C64XX_GPNDAT); | ||
49 | reg &= ~(clear << 12); | ||
50 | reg |= set << 12; | ||
51 | __raw_writel(reg, S3C64XX_GPNDAT); | ||
52 | |||
53 | local_irq_restore(flags); | 45 | local_irq_restore(flags); |
54 | } | 46 | } |
55 | #endif | 47 | #endif |
@@ -187,6 +179,18 @@ static int s3c64xx_pm_init(void) | |||
187 | pm_cpu_prep = s3c64xx_pm_prepare; | 179 | pm_cpu_prep = s3c64xx_pm_prepare; |
188 | pm_cpu_sleep = s3c64xx_cpu_suspend; | 180 | pm_cpu_sleep = s3c64xx_cpu_suspend; |
189 | pm_uart_udivslot = 1; | 181 | pm_uart_udivslot = 1; |
182 | |||
183 | #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK | ||
184 | gpio_request(S3C64XX_GPN(12), "DEBUG_LED0"); | ||
185 | gpio_request(S3C64XX_GPN(13), "DEBUG_LED1"); | ||
186 | gpio_request(S3C64XX_GPN(14), "DEBUG_LED2"); | ||
187 | gpio_request(S3C64XX_GPN(15), "DEBUG_LED3"); | ||
188 | gpio_direction_output(S3C64XX_GPN(12), 0); | ||
189 | gpio_direction_output(S3C64XX_GPN(13), 0); | ||
190 | gpio_direction_output(S3C64XX_GPN(14), 0); | ||
191 | gpio_direction_output(S3C64XX_GPN(15), 0); | ||
192 | #endif | ||
193 | |||
190 | return 0; | 194 | return 0; |
191 | } | 195 | } |
192 | 196 | ||
diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c index 406192a43c6e..241af94a9e70 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c0.c +++ b/arch/arm/mach-s3c64xx/setup-i2c0.c | |||
@@ -18,14 +18,11 @@ | |||
18 | 18 | ||
19 | struct platform_device; /* don't need the contents */ | 19 | struct platform_device; /* don't need the contents */ |
20 | 20 | ||
21 | #include <mach/gpio-bank-b.h> | ||
22 | #include <plat/iic.h> | 21 | #include <plat/iic.h> |
23 | #include <plat/gpio-cfg.h> | 22 | #include <plat/gpio-cfg.h> |
24 | 23 | ||
25 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | 24 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) |
26 | { | 25 | { |
27 | s3c_gpio_cfgpin(S3C64XX_GPB(5), S3C64XX_GPB5_I2C_SCL0); | 26 | s3c_gpio_cfgall_range(S3C64XX_GPB(5), 2, |
28 | s3c_gpio_cfgpin(S3C64XX_GPB(6), S3C64XX_GPB6_I2C_SDA0); | 27 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); |
29 | s3c_gpio_setpull(S3C64XX_GPB(5), S3C_GPIO_PULL_UP); | ||
30 | s3c_gpio_setpull(S3C64XX_GPB(6), S3C_GPIO_PULL_UP); | ||
31 | } | 28 | } |
diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c index 1ee62c97cd7f..3d13a961986d 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c1.c +++ b/arch/arm/mach-s3c64xx/setup-i2c1.c | |||
@@ -18,14 +18,11 @@ | |||
18 | 18 | ||
19 | struct platform_device; /* don't need the contents */ | 19 | struct platform_device; /* don't need the contents */ |
20 | 20 | ||
21 | #include <mach/gpio-bank-b.h> | ||
22 | #include <plat/iic.h> | 21 | #include <plat/iic.h> |
23 | #include <plat/gpio-cfg.h> | 22 | #include <plat/gpio-cfg.h> |
24 | 23 | ||
25 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) | 24 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) |
26 | { | 25 | { |
27 | s3c_gpio_cfgpin(S3C64XX_GPB(2), S3C64XX_GPB2_I2C_SCL1); | 26 | s3c_gpio_cfgall_range(S3C64XX_GPB(2), 2, |
28 | s3c_gpio_cfgpin(S3C64XX_GPB(3), S3C64XX_GPB3_I2C_SDA1); | 27 | S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP); |
29 | s3c_gpio_setpull(S3C64XX_GPB(2), S3C_GPIO_PULL_UP); | ||
30 | s3c_gpio_setpull(S3C64XX_GPB(3), S3C_GPIO_PULL_UP); | ||
31 | } | 28 | } |
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S index afe5a762f46e..1f87732b2320 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c64xx/sleep.S | |||
@@ -20,7 +20,6 @@ | |||
20 | #define S3C64XX_VA_GPIO (0x0) | 20 | #define S3C64XX_VA_GPIO (0x0) |
21 | 21 | ||
22 | #include <mach/regs-gpio.h> | 22 | #include <mach/regs-gpio.h> |
23 | #include <mach/gpio-bank-n.h> | ||
24 | 23 | ||
25 | #define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT)) | 24 | #define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT)) |
26 | 25 | ||
@@ -68,6 +67,13 @@ ENTRY(s3c_cpu_resume) | |||
68 | ldr r2, =LL_UART /* for debug */ | 67 | ldr r2, =LL_UART /* for debug */ |
69 | 68 | ||
70 | #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK | 69 | #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK |
70 | |||
71 | #define S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00) | ||
72 | #define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04) | ||
73 | |||
74 | #define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) | ||
75 | #define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) | ||
76 | |||
71 | /* Initialise the GPIO state if we are debugging via the SMDK LEDs, | 77 | /* Initialise the GPIO state if we are debugging via the SMDK LEDs, |
72 | * as the uboot version supplied resets these to inputs during the | 78 | * as the uboot version supplied resets these to inputs during the |
73 | * resume checks. | 79 | * resume checks. |
diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig deleted file mode 100644 index 33569e4007c4..000000000000 --- a/arch/arm/mach-s5p6442/Kconfig +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | # arch/arm/mach-s5p6442/Kconfig | ||
2 | # | ||
3 | # Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | # http://www.samsung.com/ | ||
5 | # | ||
6 | # Licensed under GPLv2 | ||
7 | |||
8 | # Configuration options for the S5P6442 | ||
9 | |||
10 | if ARCH_S5P6442 | ||
11 | |||
12 | config CPU_S5P6442 | ||
13 | bool | ||
14 | select S3C_PL330_DMA | ||
15 | help | ||
16 | Enable S5P6442 CPU support | ||
17 | |||
18 | config MACH_SMDK6442 | ||
19 | bool "SMDK6442" | ||
20 | select CPU_S5P6442 | ||
21 | select S3C_DEV_WDT | ||
22 | help | ||
23 | Machine support for Samsung SMDK6442 | ||
24 | |||
25 | endif | ||
diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile deleted file mode 100644 index 90a3d8373416..000000000000 --- a/arch/arm/mach-s5p6442/Makefile +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | # arch/arm/mach-s5p6442/Makefile | ||
2 | # | ||
3 | # Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | # http://www.samsung.com/ | ||
5 | # | ||
6 | # Licensed under GPLv2 | ||
7 | |||
8 | obj-y := | ||
9 | obj-m := | ||
10 | obj-n := | ||
11 | obj- := | ||
12 | |||
13 | # Core support for S5P6442 system | ||
14 | |||
15 | obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o dma.o | ||
16 | obj-$(CONFIG_CPU_S5P6442) += setup-i2c0.o | ||
17 | |||
18 | # machine support | ||
19 | |||
20 | obj-$(CONFIG_MACH_SMDK6442) += mach-smdk6442.o | ||
21 | |||
22 | # device support | ||
23 | obj-y += dev-audio.o | ||
24 | obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o | ||
diff --git a/arch/arm/mach-s5p6442/Makefile.boot b/arch/arm/mach-s5p6442/Makefile.boot deleted file mode 100644 index ff90aa13bd67..000000000000 --- a/arch/arm/mach-s5p6442/Makefile.boot +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | zreladdr-y := 0x20008000 | ||
2 | params_phys-y := 0x20000100 | ||
diff --git a/arch/arm/mach-s5p6442/clock.c b/arch/arm/mach-s5p6442/clock.c deleted file mode 100644 index fbbc7bede685..000000000000 --- a/arch/arm/mach-s5p6442/clock.c +++ /dev/null | |||
@@ -1,420 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/clock.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - Clock support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include <mach/map.h> | ||
22 | |||
23 | #include <plat/cpu-freq.h> | ||
24 | #include <mach/regs-clock.h> | ||
25 | #include <plat/clock.h> | ||
26 | #include <plat/cpu.h> | ||
27 | #include <plat/pll.h> | ||
28 | #include <plat/s5p-clock.h> | ||
29 | #include <plat/clock-clksrc.h> | ||
30 | #include <plat/s5p6442.h> | ||
31 | |||
32 | static struct clksrc_clk clk_mout_apll = { | ||
33 | .clk = { | ||
34 | .name = "mout_apll", | ||
35 | .id = -1, | ||
36 | }, | ||
37 | .sources = &clk_src_apll, | ||
38 | .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, | ||
39 | }; | ||
40 | |||
41 | static struct clksrc_clk clk_mout_mpll = { | ||
42 | .clk = { | ||
43 | .name = "mout_mpll", | ||
44 | .id = -1, | ||
45 | }, | ||
46 | .sources = &clk_src_mpll, | ||
47 | .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, | ||
48 | }; | ||
49 | |||
50 | static struct clksrc_clk clk_mout_epll = { | ||
51 | .clk = { | ||
52 | .name = "mout_epll", | ||
53 | .id = -1, | ||
54 | }, | ||
55 | .sources = &clk_src_epll, | ||
56 | .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 }, | ||
57 | }; | ||
58 | |||
59 | /* Possible clock sources for ARM Mux */ | ||
60 | static struct clk *clk_src_arm_list[] = { | ||
61 | [1] = &clk_mout_apll.clk, | ||
62 | [2] = &clk_mout_mpll.clk, | ||
63 | }; | ||
64 | |||
65 | static struct clksrc_sources clk_src_arm = { | ||
66 | .sources = clk_src_arm_list, | ||
67 | .nr_sources = ARRAY_SIZE(clk_src_arm_list), | ||
68 | }; | ||
69 | |||
70 | static struct clksrc_clk clk_mout_arm = { | ||
71 | .clk = { | ||
72 | .name = "mout_arm", | ||
73 | .id = -1, | ||
74 | }, | ||
75 | .sources = &clk_src_arm, | ||
76 | .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 16, .size = 3 }, | ||
77 | }; | ||
78 | |||
79 | static struct clk clk_dout_a2m = { | ||
80 | .name = "dout_a2m", | ||
81 | .id = -1, | ||
82 | .parent = &clk_mout_apll.clk, | ||
83 | }; | ||
84 | |||
85 | /* Possible clock sources for D0 Mux */ | ||
86 | static struct clk *clk_src_d0_list[] = { | ||
87 | [1] = &clk_mout_mpll.clk, | ||
88 | [2] = &clk_dout_a2m, | ||
89 | }; | ||
90 | |||
91 | static struct clksrc_sources clk_src_d0 = { | ||
92 | .sources = clk_src_d0_list, | ||
93 | .nr_sources = ARRAY_SIZE(clk_src_d0_list), | ||
94 | }; | ||
95 | |||
96 | static struct clksrc_clk clk_mout_d0 = { | ||
97 | .clk = { | ||
98 | .name = "mout_d0", | ||
99 | .id = -1, | ||
100 | }, | ||
101 | .sources = &clk_src_d0, | ||
102 | .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 20, .size = 3 }, | ||
103 | }; | ||
104 | |||
105 | static struct clk clk_dout_apll = { | ||
106 | .name = "dout_apll", | ||
107 | .id = -1, | ||
108 | .parent = &clk_mout_arm.clk, | ||
109 | }; | ||
110 | |||
111 | /* Possible clock sources for D0SYNC Mux */ | ||
112 | static struct clk *clk_src_d0sync_list[] = { | ||
113 | [1] = &clk_mout_d0.clk, | ||
114 | [2] = &clk_dout_apll, | ||
115 | }; | ||
116 | |||
117 | static struct clksrc_sources clk_src_d0sync = { | ||
118 | .sources = clk_src_d0sync_list, | ||
119 | .nr_sources = ARRAY_SIZE(clk_src_d0sync_list), | ||
120 | }; | ||
121 | |||
122 | static struct clksrc_clk clk_mout_d0sync = { | ||
123 | .clk = { | ||
124 | .name = "mout_d0sync", | ||
125 | .id = -1, | ||
126 | }, | ||
127 | .sources = &clk_src_d0sync, | ||
128 | .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 }, | ||
129 | }; | ||
130 | |||
131 | /* Possible clock sources for D1 Mux */ | ||
132 | static struct clk *clk_src_d1_list[] = { | ||
133 | [1] = &clk_mout_mpll.clk, | ||
134 | [2] = &clk_dout_a2m, | ||
135 | }; | ||
136 | |||
137 | static struct clksrc_sources clk_src_d1 = { | ||
138 | .sources = clk_src_d1_list, | ||
139 | .nr_sources = ARRAY_SIZE(clk_src_d1_list), | ||
140 | }; | ||
141 | |||
142 | static struct clksrc_clk clk_mout_d1 = { | ||
143 | .clk = { | ||
144 | .name = "mout_d1", | ||
145 | .id = -1, | ||
146 | }, | ||
147 | .sources = &clk_src_d1, | ||
148 | .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 24, .size = 3 }, | ||
149 | }; | ||
150 | |||
151 | /* Possible clock sources for D1SYNC Mux */ | ||
152 | static struct clk *clk_src_d1sync_list[] = { | ||
153 | [1] = &clk_mout_d1.clk, | ||
154 | [2] = &clk_dout_apll, | ||
155 | }; | ||
156 | |||
157 | static struct clksrc_sources clk_src_d1sync = { | ||
158 | .sources = clk_src_d1sync_list, | ||
159 | .nr_sources = ARRAY_SIZE(clk_src_d1sync_list), | ||
160 | }; | ||
161 | |||
162 | static struct clksrc_clk clk_mout_d1sync = { | ||
163 | .clk = { | ||
164 | .name = "mout_d1sync", | ||
165 | .id = -1, | ||
166 | }, | ||
167 | .sources = &clk_src_d1sync, | ||
168 | .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 }, | ||
169 | }; | ||
170 | |||
171 | static struct clk clk_hclkd0 = { | ||
172 | .name = "hclkd0", | ||
173 | .id = -1, | ||
174 | .parent = &clk_mout_d0sync.clk, | ||
175 | }; | ||
176 | |||
177 | static struct clk clk_hclkd1 = { | ||
178 | .name = "hclkd1", | ||
179 | .id = -1, | ||
180 | .parent = &clk_mout_d1sync.clk, | ||
181 | }; | ||
182 | |||
183 | static struct clk clk_pclkd0 = { | ||
184 | .name = "pclkd0", | ||
185 | .id = -1, | ||
186 | .parent = &clk_hclkd0, | ||
187 | }; | ||
188 | |||
189 | static struct clk clk_pclkd1 = { | ||
190 | .name = "pclkd1", | ||
191 | .id = -1, | ||
192 | .parent = &clk_hclkd1, | ||
193 | }; | ||
194 | |||
195 | int s5p6442_clk_ip0_ctrl(struct clk *clk, int enable) | ||
196 | { | ||
197 | return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); | ||
198 | } | ||
199 | |||
200 | int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable) | ||
201 | { | ||
202 | return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); | ||
203 | } | ||
204 | |||
205 | static struct clksrc_clk clksrcs[] = { | ||
206 | { | ||
207 | .clk = { | ||
208 | .name = "dout_a2m", | ||
209 | .id = -1, | ||
210 | .parent = &clk_mout_apll.clk, | ||
211 | }, | ||
212 | .sources = &clk_src_apll, | ||
213 | .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, | ||
214 | .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 }, | ||
215 | }, { | ||
216 | .clk = { | ||
217 | .name = "dout_apll", | ||
218 | .id = -1, | ||
219 | .parent = &clk_mout_arm.clk, | ||
220 | }, | ||
221 | .sources = &clk_src_arm, | ||
222 | .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 16, .size = 3 }, | ||
223 | .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 }, | ||
224 | }, { | ||
225 | .clk = { | ||
226 | .name = "hclkd1", | ||
227 | .id = -1, | ||
228 | .parent = &clk_mout_d1sync.clk, | ||
229 | }, | ||
230 | .sources = &clk_src_d1sync, | ||
231 | .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 }, | ||
232 | .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 }, | ||
233 | }, { | ||
234 | .clk = { | ||
235 | .name = "hclkd0", | ||
236 | .id = -1, | ||
237 | .parent = &clk_mout_d0sync.clk, | ||
238 | }, | ||
239 | .sources = &clk_src_d0sync, | ||
240 | .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 }, | ||
241 | .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 }, | ||
242 | }, { | ||
243 | .clk = { | ||
244 | .name = "pclkd0", | ||
245 | .id = -1, | ||
246 | .parent = &clk_hclkd0, | ||
247 | }, | ||
248 | .sources = &clk_src_d0sync, | ||
249 | .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 }, | ||
250 | .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 }, | ||
251 | }, { | ||
252 | .clk = { | ||
253 | .name = "pclkd1", | ||
254 | .id = -1, | ||
255 | .parent = &clk_hclkd1, | ||
256 | }, | ||
257 | .sources = &clk_src_d1sync, | ||
258 | .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 }, | ||
259 | .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 }, | ||
260 | } | ||
261 | }; | ||
262 | |||
263 | /* Clock initialisation code */ | ||
264 | static struct clksrc_clk *init_parents[] = { | ||
265 | &clk_mout_apll, | ||
266 | &clk_mout_mpll, | ||
267 | &clk_mout_epll, | ||
268 | &clk_mout_arm, | ||
269 | &clk_mout_d0, | ||
270 | &clk_mout_d0sync, | ||
271 | &clk_mout_d1, | ||
272 | &clk_mout_d1sync, | ||
273 | }; | ||
274 | |||
275 | void __init_or_cpufreq s5p6442_setup_clocks(void) | ||
276 | { | ||
277 | struct clk *pclkd0_clk; | ||
278 | struct clk *pclkd1_clk; | ||
279 | |||
280 | unsigned long xtal; | ||
281 | unsigned long arm; | ||
282 | unsigned long hclkd0 = 0; | ||
283 | unsigned long hclkd1 = 0; | ||
284 | unsigned long pclkd0 = 0; | ||
285 | unsigned long pclkd1 = 0; | ||
286 | |||
287 | unsigned long apll; | ||
288 | unsigned long mpll; | ||
289 | unsigned long epll; | ||
290 | unsigned int ptr; | ||
291 | |||
292 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); | ||
293 | |||
294 | xtal = clk_get_rate(&clk_xtal); | ||
295 | |||
296 | printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); | ||
297 | |||
298 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); | ||
299 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); | ||
300 | epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); | ||
301 | |||
302 | printk(KERN_INFO "S5P6442: PLL settings, A=%ld, M=%ld, E=%ld", | ||
303 | apll, mpll, epll); | ||
304 | |||
305 | clk_fout_apll.rate = apll; | ||
306 | clk_fout_mpll.rate = mpll; | ||
307 | clk_fout_epll.rate = epll; | ||
308 | |||
309 | for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) | ||
310 | s3c_set_clksrc(init_parents[ptr], true); | ||
311 | |||
312 | for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) | ||
313 | s3c_set_clksrc(&clksrcs[ptr], true); | ||
314 | |||
315 | arm = clk_get_rate(&clk_dout_apll); | ||
316 | hclkd0 = clk_get_rate(&clk_hclkd0); | ||
317 | hclkd1 = clk_get_rate(&clk_hclkd1); | ||
318 | |||
319 | pclkd0_clk = clk_get(NULL, "pclkd0"); | ||
320 | BUG_ON(IS_ERR(pclkd0_clk)); | ||
321 | |||
322 | pclkd0 = clk_get_rate(pclkd0_clk); | ||
323 | clk_put(pclkd0_clk); | ||
324 | |||
325 | pclkd1_clk = clk_get(NULL, "pclkd1"); | ||
326 | BUG_ON(IS_ERR(pclkd1_clk)); | ||
327 | |||
328 | pclkd1 = clk_get_rate(pclkd1_clk); | ||
329 | clk_put(pclkd1_clk); | ||
330 | |||
331 | printk(KERN_INFO "S5P6442: HCLKD0=%ld, HCLKD1=%ld, PCLKD0=%ld, PCLKD1=%ld\n", | ||
332 | hclkd0, hclkd1, pclkd0, pclkd1); | ||
333 | |||
334 | /* For backward compatibility */ | ||
335 | clk_f.rate = arm; | ||
336 | clk_h.rate = hclkd1; | ||
337 | clk_p.rate = pclkd1; | ||
338 | |||
339 | clk_pclkd0.rate = pclkd0; | ||
340 | clk_pclkd1.rate = pclkd1; | ||
341 | } | ||
342 | |||
343 | static struct clk init_clocks_off[] = { | ||
344 | { | ||
345 | .name = "pdma", | ||
346 | .id = -1, | ||
347 | .parent = &clk_pclkd1, | ||
348 | .enable = s5p6442_clk_ip0_ctrl, | ||
349 | .ctrlbit = (1 << 3), | ||
350 | }, | ||
351 | }; | ||
352 | |||
353 | static struct clk init_clocks[] = { | ||
354 | { | ||
355 | .name = "systimer", | ||
356 | .id = -1, | ||
357 | .parent = &clk_pclkd1, | ||
358 | .enable = s5p6442_clk_ip3_ctrl, | ||
359 | .ctrlbit = (1<<16), | ||
360 | }, { | ||
361 | .name = "uart", | ||
362 | .id = 0, | ||
363 | .parent = &clk_pclkd1, | ||
364 | .enable = s5p6442_clk_ip3_ctrl, | ||
365 | .ctrlbit = (1<<17), | ||
366 | }, { | ||
367 | .name = "uart", | ||
368 | .id = 1, | ||
369 | .parent = &clk_pclkd1, | ||
370 | .enable = s5p6442_clk_ip3_ctrl, | ||
371 | .ctrlbit = (1<<18), | ||
372 | }, { | ||
373 | .name = "uart", | ||
374 | .id = 2, | ||
375 | .parent = &clk_pclkd1, | ||
376 | .enable = s5p6442_clk_ip3_ctrl, | ||
377 | .ctrlbit = (1<<19), | ||
378 | }, { | ||
379 | .name = "watchdog", | ||
380 | .id = -1, | ||
381 | .parent = &clk_pclkd1, | ||
382 | .enable = s5p6442_clk_ip3_ctrl, | ||
383 | .ctrlbit = (1 << 22), | ||
384 | }, { | ||
385 | .name = "timers", | ||
386 | .id = -1, | ||
387 | .parent = &clk_pclkd1, | ||
388 | .enable = s5p6442_clk_ip3_ctrl, | ||
389 | .ctrlbit = (1<<23), | ||
390 | }, | ||
391 | }; | ||
392 | |||
393 | static struct clk *clks[] __initdata = { | ||
394 | &clk_ext, | ||
395 | &clk_epll, | ||
396 | &clk_mout_apll.clk, | ||
397 | &clk_mout_mpll.clk, | ||
398 | &clk_mout_epll.clk, | ||
399 | &clk_mout_d0.clk, | ||
400 | &clk_mout_d0sync.clk, | ||
401 | &clk_mout_d1.clk, | ||
402 | &clk_mout_d1sync.clk, | ||
403 | &clk_hclkd0, | ||
404 | &clk_pclkd0, | ||
405 | &clk_hclkd1, | ||
406 | &clk_pclkd1, | ||
407 | }; | ||
408 | |||
409 | void __init s5p6442_register_clocks(void) | ||
410 | { | ||
411 | s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); | ||
412 | |||
413 | s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); | ||
414 | s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); | ||
415 | |||
416 | s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | ||
417 | s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | ||
418 | |||
419 | s3c_pwmclk_init(); | ||
420 | } | ||
diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c deleted file mode 100644 index 842af86bda6d..000000000000 --- a/arch/arm/mach-s5p6442/cpu.c +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/cpu.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/list.h> | ||
15 | #include <linux/timer.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/sysdev.h> | ||
20 | #include <linux/serial_core.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/sched.h> | ||
23 | |||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/mach/map.h> | ||
26 | #include <asm/mach/irq.h> | ||
27 | |||
28 | #include <asm/proc-fns.h> | ||
29 | |||
30 | #include <mach/hardware.h> | ||
31 | #include <mach/map.h> | ||
32 | #include <asm/irq.h> | ||
33 | |||
34 | #include <plat/regs-serial.h> | ||
35 | #include <mach/regs-clock.h> | ||
36 | |||
37 | #include <plat/cpu.h> | ||
38 | #include <plat/devs.h> | ||
39 | #include <plat/clock.h> | ||
40 | #include <plat/s5p6442.h> | ||
41 | |||
42 | /* Initial IO mappings */ | ||
43 | |||
44 | static struct map_desc s5p6442_iodesc[] __initdata = { | ||
45 | { | ||
46 | .virtual = (unsigned long)S5P_VA_SYSTIMER, | ||
47 | .pfn = __phys_to_pfn(S5P6442_PA_SYSTIMER), | ||
48 | .length = SZ_16K, | ||
49 | .type = MT_DEVICE, | ||
50 | }, { | ||
51 | .virtual = (unsigned long)S5P_VA_GPIO, | ||
52 | .pfn = __phys_to_pfn(S5P6442_PA_GPIO), | ||
53 | .length = SZ_4K, | ||
54 | .type = MT_DEVICE, | ||
55 | }, { | ||
56 | .virtual = (unsigned long)VA_VIC0, | ||
57 | .pfn = __phys_to_pfn(S5P6442_PA_VIC0), | ||
58 | .length = SZ_16K, | ||
59 | .type = MT_DEVICE, | ||
60 | }, { | ||
61 | .virtual = (unsigned long)VA_VIC1, | ||
62 | .pfn = __phys_to_pfn(S5P6442_PA_VIC1), | ||
63 | .length = SZ_16K, | ||
64 | .type = MT_DEVICE, | ||
65 | }, { | ||
66 | .virtual = (unsigned long)VA_VIC2, | ||
67 | .pfn = __phys_to_pfn(S5P6442_PA_VIC2), | ||
68 | .length = SZ_16K, | ||
69 | .type = MT_DEVICE, | ||
70 | }, { | ||
71 | .virtual = (unsigned long)S3C_VA_UART, | ||
72 | .pfn = __phys_to_pfn(S3C_PA_UART), | ||
73 | .length = SZ_512K, | ||
74 | .type = MT_DEVICE, | ||
75 | } | ||
76 | }; | ||
77 | |||
78 | static void s5p6442_idle(void) | ||
79 | { | ||
80 | if (!need_resched()) | ||
81 | cpu_do_idle(); | ||
82 | |||
83 | local_irq_enable(); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * s5p6442_map_io | ||
88 | * | ||
89 | * register the standard cpu IO areas | ||
90 | */ | ||
91 | |||
92 | void __init s5p6442_map_io(void) | ||
93 | { | ||
94 | iotable_init(s5p6442_iodesc, ARRAY_SIZE(s5p6442_iodesc)); | ||
95 | } | ||
96 | |||
97 | void __init s5p6442_init_clocks(int xtal) | ||
98 | { | ||
99 | printk(KERN_DEBUG "%s: initializing clocks\n", __func__); | ||
100 | |||
101 | s3c24xx_register_baseclocks(xtal); | ||
102 | s5p_register_clocks(xtal); | ||
103 | s5p6442_register_clocks(); | ||
104 | s5p6442_setup_clocks(); | ||
105 | } | ||
106 | |||
107 | void __init s5p6442_init_irq(void) | ||
108 | { | ||
109 | /* S5P6442 supports 3 VIC */ | ||
110 | u32 vic[3]; | ||
111 | |||
112 | /* VIC0, VIC1, and VIC2: some interrupt reserved */ | ||
113 | vic[0] = 0x7fefffff; | ||
114 | vic[1] = 0X7f389c81; | ||
115 | vic[2] = 0X1bbbcfff; | ||
116 | |||
117 | s5p_init_irq(vic, ARRAY_SIZE(vic)); | ||
118 | } | ||
119 | |||
120 | struct sysdev_class s5p6442_sysclass = { | ||
121 | .name = "s5p6442-core", | ||
122 | }; | ||
123 | |||
124 | static struct sys_device s5p6442_sysdev = { | ||
125 | .cls = &s5p6442_sysclass, | ||
126 | }; | ||
127 | |||
128 | static int __init s5p6442_core_init(void) | ||
129 | { | ||
130 | return sysdev_class_register(&s5p6442_sysclass); | ||
131 | } | ||
132 | |||
133 | core_initcall(s5p6442_core_init); | ||
134 | |||
135 | int __init s5p6442_init(void) | ||
136 | { | ||
137 | printk(KERN_INFO "S5P6442: Initializing architecture\n"); | ||
138 | |||
139 | /* set idle function */ | ||
140 | pm_idle = s5p6442_idle; | ||
141 | |||
142 | return sysdev_register(&s5p6442_sysdev); | ||
143 | } | ||
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c deleted file mode 100644 index 8719dc41fe32..000000000000 --- a/arch/arm/mach-s5p6442/dev-audio.c +++ /dev/null | |||
@@ -1,217 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/dev-audio.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co. Ltd | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/gpio.h> | ||
14 | |||
15 | #include <plat/gpio-cfg.h> | ||
16 | #include <plat/audio.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | #include <mach/dma.h> | ||
20 | #include <mach/irqs.h> | ||
21 | |||
22 | static int s5p6442_cfg_i2s(struct platform_device *pdev) | ||
23 | { | ||
24 | unsigned int base; | ||
25 | |||
26 | /* configure GPIO for i2s port */ | ||
27 | switch (pdev->id) { | ||
28 | case 1: | ||
29 | base = S5P6442_GPC1(0); | ||
30 | break; | ||
31 | |||
32 | case 0: | ||
33 | base = S5P6442_GPC0(0); | ||
34 | break; | ||
35 | |||
36 | default: | ||
37 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); | ||
38 | return -EINVAL; | ||
39 | } | ||
40 | |||
41 | s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2)); | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static const char *rclksrc_v35[] = { | ||
46 | [0] = "busclk", | ||
47 | [1] = "i2sclk", | ||
48 | }; | ||
49 | |||
50 | static struct s3c_audio_pdata i2sv35_pdata = { | ||
51 | .cfg_gpio = s5p6442_cfg_i2s, | ||
52 | .type = { | ||
53 | .i2s = { | ||
54 | .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, | ||
55 | .src_clk = rclksrc_v35, | ||
56 | }, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | static struct resource s5p6442_iis0_resource[] = { | ||
61 | [0] = { | ||
62 | .start = S5P6442_PA_I2S0, | ||
63 | .end = S5P6442_PA_I2S0 + 0x100 - 1, | ||
64 | .flags = IORESOURCE_MEM, | ||
65 | }, | ||
66 | [1] = { | ||
67 | .start = DMACH_I2S0_TX, | ||
68 | .end = DMACH_I2S0_TX, | ||
69 | .flags = IORESOURCE_DMA, | ||
70 | }, | ||
71 | [2] = { | ||
72 | .start = DMACH_I2S0_RX, | ||
73 | .end = DMACH_I2S0_RX, | ||
74 | .flags = IORESOURCE_DMA, | ||
75 | }, | ||
76 | [3] = { | ||
77 | .start = DMACH_I2S0S_TX, | ||
78 | .end = DMACH_I2S0S_TX, | ||
79 | .flags = IORESOURCE_DMA, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | struct platform_device s5p6442_device_iis0 = { | ||
84 | .name = "samsung-i2s", | ||
85 | .id = 0, | ||
86 | .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), | ||
87 | .resource = s5p6442_iis0_resource, | ||
88 | .dev = { | ||
89 | .platform_data = &i2sv35_pdata, | ||
90 | }, | ||
91 | }; | ||
92 | |||
93 | static const char *rclksrc_v3[] = { | ||
94 | [0] = "iis", | ||
95 | [1] = "sclk_audio", | ||
96 | }; | ||
97 | |||
98 | static struct s3c_audio_pdata i2sv3_pdata = { | ||
99 | .cfg_gpio = s5p6442_cfg_i2s, | ||
100 | .type = { | ||
101 | .i2s = { | ||
102 | .src_clk = rclksrc_v3, | ||
103 | }, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | static struct resource s5p6442_iis1_resource[] = { | ||
108 | [0] = { | ||
109 | .start = S5P6442_PA_I2S1, | ||
110 | .end = S5P6442_PA_I2S1 + 0x100 - 1, | ||
111 | .flags = IORESOURCE_MEM, | ||
112 | }, | ||
113 | [1] = { | ||
114 | .start = DMACH_I2S1_TX, | ||
115 | .end = DMACH_I2S1_TX, | ||
116 | .flags = IORESOURCE_DMA, | ||
117 | }, | ||
118 | [2] = { | ||
119 | .start = DMACH_I2S1_RX, | ||
120 | .end = DMACH_I2S1_RX, | ||
121 | .flags = IORESOURCE_DMA, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | struct platform_device s5p6442_device_iis1 = { | ||
126 | .name = "samsung-i2s", | ||
127 | .id = 1, | ||
128 | .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), | ||
129 | .resource = s5p6442_iis1_resource, | ||
130 | .dev = { | ||
131 | .platform_data = &i2sv3_pdata, | ||
132 | }, | ||
133 | }; | ||
134 | |||
135 | /* PCM Controller platform_devices */ | ||
136 | |||
137 | static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) | ||
138 | { | ||
139 | unsigned int base; | ||
140 | |||
141 | switch (pdev->id) { | ||
142 | case 0: | ||
143 | base = S5P6442_GPC0(0); | ||
144 | break; | ||
145 | |||
146 | case 1: | ||
147 | base = S5P6442_GPC1(0); | ||
148 | break; | ||
149 | |||
150 | default: | ||
151 | printk(KERN_DEBUG "Invalid PCM Controller number!"); | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3)); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static struct s3c_audio_pdata s3c_pcm_pdata = { | ||
160 | .cfg_gpio = s5p6442_pcm_cfg_gpio, | ||
161 | }; | ||
162 | |||
163 | static struct resource s5p6442_pcm0_resource[] = { | ||
164 | [0] = { | ||
165 | .start = S5P6442_PA_PCM0, | ||
166 | .end = S5P6442_PA_PCM0 + 0x100 - 1, | ||
167 | .flags = IORESOURCE_MEM, | ||
168 | }, | ||
169 | [1] = { | ||
170 | .start = DMACH_PCM0_TX, | ||
171 | .end = DMACH_PCM0_TX, | ||
172 | .flags = IORESOURCE_DMA, | ||
173 | }, | ||
174 | [2] = { | ||
175 | .start = DMACH_PCM0_RX, | ||
176 | .end = DMACH_PCM0_RX, | ||
177 | .flags = IORESOURCE_DMA, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | struct platform_device s5p6442_device_pcm0 = { | ||
182 | .name = "samsung-pcm", | ||
183 | .id = 0, | ||
184 | .num_resources = ARRAY_SIZE(s5p6442_pcm0_resource), | ||
185 | .resource = s5p6442_pcm0_resource, | ||
186 | .dev = { | ||
187 | .platform_data = &s3c_pcm_pdata, | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | static struct resource s5p6442_pcm1_resource[] = { | ||
192 | [0] = { | ||
193 | .start = S5P6442_PA_PCM1, | ||
194 | .end = S5P6442_PA_PCM1 + 0x100 - 1, | ||
195 | .flags = IORESOURCE_MEM, | ||
196 | }, | ||
197 | [1] = { | ||
198 | .start = DMACH_PCM1_TX, | ||
199 | .end = DMACH_PCM1_TX, | ||
200 | .flags = IORESOURCE_DMA, | ||
201 | }, | ||
202 | [2] = { | ||
203 | .start = DMACH_PCM1_RX, | ||
204 | .end = DMACH_PCM1_RX, | ||
205 | .flags = IORESOURCE_DMA, | ||
206 | }, | ||
207 | }; | ||
208 | |||
209 | struct platform_device s5p6442_device_pcm1 = { | ||
210 | .name = "samsung-pcm", | ||
211 | .id = 1, | ||
212 | .num_resources = ARRAY_SIZE(s5p6442_pcm1_resource), | ||
213 | .resource = s5p6442_pcm1_resource, | ||
214 | .dev = { | ||
215 | .platform_data = &s3c_pcm_pdata, | ||
216 | }, | ||
217 | }; | ||
diff --git a/arch/arm/mach-s5p6442/dev-spi.c b/arch/arm/mach-s5p6442/dev-spi.c deleted file mode 100644 index cce8c2470709..000000000000 --- a/arch/arm/mach-s5p6442/dev-spi.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/dev-spi.c | ||
2 | * | ||
3 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/gpio.h> | ||
14 | |||
15 | #include <mach/dma.h> | ||
16 | #include <mach/map.h> | ||
17 | #include <mach/irqs.h> | ||
18 | #include <mach/spi-clocks.h> | ||
19 | |||
20 | #include <plat/s3c64xx-spi.h> | ||
21 | #include <plat/gpio-cfg.h> | ||
22 | |||
23 | static char *spi_src_clks[] = { | ||
24 | [S5P6442_SPI_SRCCLK_PCLK] = "pclk", | ||
25 | [S5P6442_SPI_SRCCLK_SCLK] = "spi_epll", | ||
26 | }; | ||
27 | |||
28 | /* SPI Controller platform_devices */ | ||
29 | |||
30 | /* Since we emulate multi-cs capability, we do not touch the CS. | ||
31 | * The emulated CS is toggled by board specific mechanism, as it can | ||
32 | * be either some immediate GPIO or some signal out of some other | ||
33 | * chip in between ... or some yet another way. | ||
34 | * We simply do not assume anything about CS. | ||
35 | */ | ||
36 | static int s5p6442_spi_cfg_gpio(struct platform_device *pdev) | ||
37 | { | ||
38 | switch (pdev->id) { | ||
39 | case 0: | ||
40 | s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2)); | ||
41 | s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP); | ||
42 | s3c_gpio_cfgall_range(S5P6442_GPB(2), 2, | ||
43 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); | ||
44 | break; | ||
45 | |||
46 | default: | ||
47 | dev_err(&pdev->dev, "Invalid SPI Controller number!"); | ||
48 | return -EINVAL; | ||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static struct resource s5p6442_spi0_resource[] = { | ||
55 | [0] = { | ||
56 | .start = S5P6442_PA_SPI, | ||
57 | .end = S5P6442_PA_SPI + 0x100 - 1, | ||
58 | .flags = IORESOURCE_MEM, | ||
59 | }, | ||
60 | [1] = { | ||
61 | .start = DMACH_SPI0_TX, | ||
62 | .end = DMACH_SPI0_TX, | ||
63 | .flags = IORESOURCE_DMA, | ||
64 | }, | ||
65 | [2] = { | ||
66 | .start = DMACH_SPI0_RX, | ||
67 | .end = DMACH_SPI0_RX, | ||
68 | .flags = IORESOURCE_DMA, | ||
69 | }, | ||
70 | [3] = { | ||
71 | .start = IRQ_SPI0, | ||
72 | .end = IRQ_SPI0, | ||
73 | .flags = IORESOURCE_IRQ, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | static struct s3c64xx_spi_info s5p6442_spi0_pdata = { | ||
78 | .cfg_gpio = s5p6442_spi_cfg_gpio, | ||
79 | .fifo_lvl_mask = 0x1ff, | ||
80 | .rx_lvl_offset = 15, | ||
81 | }; | ||
82 | |||
83 | static u64 spi_dmamask = DMA_BIT_MASK(32); | ||
84 | |||
85 | struct platform_device s5p6442_device_spi = { | ||
86 | .name = "s3c64xx-spi", | ||
87 | .id = 0, | ||
88 | .num_resources = ARRAY_SIZE(s5p6442_spi0_resource), | ||
89 | .resource = s5p6442_spi0_resource, | ||
90 | .dev = { | ||
91 | .dma_mask = &spi_dmamask, | ||
92 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
93 | .platform_data = &s5p6442_spi0_pdata, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | void __init s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) | ||
98 | { | ||
99 | struct s3c64xx_spi_info *pd; | ||
100 | |||
101 | /* Reject invalid configuration */ | ||
102 | if (!num_cs || src_clk_nr < 0 | ||
103 | || src_clk_nr > S5P6442_SPI_SRCCLK_SCLK) { | ||
104 | printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | switch (cntrlr) { | ||
109 | case 0: | ||
110 | pd = &s5p6442_spi0_pdata; | ||
111 | break; | ||
112 | default: | ||
113 | printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", | ||
114 | __func__, cntrlr); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | pd->num_cs = num_cs; | ||
119 | pd->src_clk_nr = src_clk_nr; | ||
120 | pd->src_clk_name = spi_src_clks[src_clk_nr]; | ||
121 | } | ||
diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c deleted file mode 100644 index 7dfb13654f8a..000000000000 --- a/arch/arm/mach-s5p6442/dma.c +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
3 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | |||
23 | #include <plat/devs.h> | ||
24 | #include <plat/irqs.h> | ||
25 | |||
26 | #include <mach/map.h> | ||
27 | #include <mach/irqs.h> | ||
28 | |||
29 | #include <plat/s3c-pl330-pdata.h> | ||
30 | |||
31 | static u64 dma_dmamask = DMA_BIT_MASK(32); | ||
32 | |||
33 | static struct resource s5p6442_pdma_resource[] = { | ||
34 | [0] = { | ||
35 | .start = S5P6442_PA_PDMA, | ||
36 | .end = S5P6442_PA_PDMA + SZ_4K, | ||
37 | .flags = IORESOURCE_MEM, | ||
38 | }, | ||
39 | [1] = { | ||
40 | .start = IRQ_PDMA, | ||
41 | .end = IRQ_PDMA, | ||
42 | .flags = IORESOURCE_IRQ, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | static struct s3c_pl330_platdata s5p6442_pdma_pdata = { | ||
47 | .peri = { | ||
48 | [0] = DMACH_UART0_RX, | ||
49 | [1] = DMACH_UART0_TX, | ||
50 | [2] = DMACH_UART1_RX, | ||
51 | [3] = DMACH_UART1_TX, | ||
52 | [4] = DMACH_UART2_RX, | ||
53 | [5] = DMACH_UART2_TX, | ||
54 | [6] = DMACH_MAX, | ||
55 | [7] = DMACH_MAX, | ||
56 | [8] = DMACH_MAX, | ||
57 | [9] = DMACH_I2S0_RX, | ||
58 | [10] = DMACH_I2S0_TX, | ||
59 | [11] = DMACH_I2S0S_TX, | ||
60 | [12] = DMACH_I2S1_RX, | ||
61 | [13] = DMACH_I2S1_TX, | ||
62 | [14] = DMACH_MAX, | ||
63 | [15] = DMACH_MAX, | ||
64 | [16] = DMACH_SPI0_RX, | ||
65 | [17] = DMACH_SPI0_TX, | ||
66 | [18] = DMACH_MAX, | ||
67 | [19] = DMACH_MAX, | ||
68 | [20] = DMACH_PCM0_RX, | ||
69 | [21] = DMACH_PCM0_TX, | ||
70 | [22] = DMACH_PCM1_RX, | ||
71 | [23] = DMACH_PCM1_TX, | ||
72 | [24] = DMACH_MAX, | ||
73 | [25] = DMACH_MAX, | ||
74 | [26] = DMACH_MAX, | ||
75 | [27] = DMACH_MSM_REQ0, | ||
76 | [28] = DMACH_MSM_REQ1, | ||
77 | [29] = DMACH_MSM_REQ2, | ||
78 | [30] = DMACH_MSM_REQ3, | ||
79 | [31] = DMACH_MAX, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | static struct platform_device s5p6442_device_pdma = { | ||
84 | .name = "s3c-pl330", | ||
85 | .id = -1, | ||
86 | .num_resources = ARRAY_SIZE(s5p6442_pdma_resource), | ||
87 | .resource = s5p6442_pdma_resource, | ||
88 | .dev = { | ||
89 | .dma_mask = &dma_dmamask, | ||
90 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
91 | .platform_data = &s5p6442_pdma_pdata, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static struct platform_device *s5p6442_dmacs[] __initdata = { | ||
96 | &s5p6442_device_pdma, | ||
97 | }; | ||
98 | |||
99 | static int __init s5p6442_dma_init(void) | ||
100 | { | ||
101 | platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs)); | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | arch_initcall(s5p6442_dma_init); | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/debug-macro.S b/arch/arm/mach-s5p6442/include/mach/debug-macro.S deleted file mode 100644 index e2213205d780..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | /* pull in the relevant register and map files. */ | ||
14 | |||
15 | #include <mach/map.h> | ||
16 | #include <plat/regs-serial.h> | ||
17 | |||
18 | .macro addruart, rp, rv | ||
19 | ldr \rp, = S3C_PA_UART | ||
20 | ldr \rv, = S3C_VA_UART | ||
21 | #if CONFIG_DEBUG_S3C_UART != 0 | ||
22 | add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART) | ||
23 | add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART) | ||
24 | #endif | ||
25 | .endm | ||
26 | |||
27 | #define fifo_full fifo_full_s5pv210 | ||
28 | #define fifo_level fifo_level_s5pv210 | ||
29 | |||
30 | /* include the reset of the code which will do the work, we're only | ||
31 | * compiling for a single cpu processor type so the default of s3c2440 | ||
32 | * will be fine with us. | ||
33 | */ | ||
34 | |||
35 | #include <plat/debug-macro.S> | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/dma.h b/arch/arm/mach-s5p6442/include/mach/dma.h deleted file mode 100644 index 81209eb1409b..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/dma.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
3 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __MACH_DMA_H | ||
21 | #define __MACH_DMA_H | ||
22 | |||
23 | /* This platform uses the common S3C DMA API driver for PL330 */ | ||
24 | #include <plat/s3c-dma-pl330.h> | ||
25 | |||
26 | #endif /* __MACH_DMA_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/entry-macro.S b/arch/arm/mach-s5p6442/include/mach/entry-macro.S deleted file mode 100644 index 6d574edbf1ae..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/entry-macro.S +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/entry-macro.S | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Low-level IRQ helper macros for the Samsung S5P6442 | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <asm/hardware/vic.h> | ||
14 | #include <mach/map.h> | ||
15 | #include <plat/irqs.h> | ||
16 | |||
17 | .macro disable_fiq | ||
18 | .endm | ||
19 | |||
20 | .macro get_irqnr_preamble, base, tmp | ||
21 | ldr \base, =VA_VIC0 | ||
22 | .endm | ||
23 | |||
24 | .macro arch_ret_to_user, tmp1, tmp2 | ||
25 | .endm | ||
26 | |||
27 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
28 | |||
29 | @ check the vic0 | ||
30 | mov \irqnr, # S5P_IRQ_OFFSET + 31 | ||
31 | ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] | ||
32 | teq \irqstat, #0 | ||
33 | |||
34 | @ otherwise try vic1 | ||
35 | addeq \tmp, \base, #(VA_VIC1 - VA_VIC0) | ||
36 | addeq \irqnr, \irqnr, #32 | ||
37 | ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] | ||
38 | teqeq \irqstat, #0 | ||
39 | |||
40 | @ otherwise try vic2 | ||
41 | addeq \tmp, \base, #(VA_VIC2 - VA_VIC0) | ||
42 | addeq \irqnr, \irqnr, #32 | ||
43 | ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] | ||
44 | teqeq \irqstat, #0 | ||
45 | |||
46 | clzne \irqstat, \irqstat | ||
47 | subne \irqnr, \irqnr, \irqstat | ||
48 | .endm | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/gpio.h b/arch/arm/mach-s5p6442/include/mach/gpio.h deleted file mode 100644 index b8715df2fdab..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/gpio.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/gpio.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - GPIO lib support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_GPIO_H | ||
14 | #define __ASM_ARCH_GPIO_H __FILE__ | ||
15 | |||
16 | #define gpio_get_value __gpio_get_value | ||
17 | #define gpio_set_value __gpio_set_value | ||
18 | #define gpio_cansleep __gpio_cansleep | ||
19 | #define gpio_to_irq __gpio_to_irq | ||
20 | |||
21 | /* GPIO bank sizes */ | ||
22 | #define S5P6442_GPIO_A0_NR (8) | ||
23 | #define S5P6442_GPIO_A1_NR (2) | ||
24 | #define S5P6442_GPIO_B_NR (4) | ||
25 | #define S5P6442_GPIO_C0_NR (5) | ||
26 | #define S5P6442_GPIO_C1_NR (5) | ||
27 | #define S5P6442_GPIO_D0_NR (2) | ||
28 | #define S5P6442_GPIO_D1_NR (6) | ||
29 | #define S5P6442_GPIO_E0_NR (8) | ||
30 | #define S5P6442_GPIO_E1_NR (5) | ||
31 | #define S5P6442_GPIO_F0_NR (8) | ||
32 | #define S5P6442_GPIO_F1_NR (8) | ||
33 | #define S5P6442_GPIO_F2_NR (8) | ||
34 | #define S5P6442_GPIO_F3_NR (6) | ||
35 | #define S5P6442_GPIO_G0_NR (7) | ||
36 | #define S5P6442_GPIO_G1_NR (7) | ||
37 | #define S5P6442_GPIO_G2_NR (7) | ||
38 | #define S5P6442_GPIO_H0_NR (8) | ||
39 | #define S5P6442_GPIO_H1_NR (8) | ||
40 | #define S5P6442_GPIO_H2_NR (8) | ||
41 | #define S5P6442_GPIO_H3_NR (8) | ||
42 | #define S5P6442_GPIO_J0_NR (8) | ||
43 | #define S5P6442_GPIO_J1_NR (6) | ||
44 | #define S5P6442_GPIO_J2_NR (8) | ||
45 | #define S5P6442_GPIO_J3_NR (8) | ||
46 | #define S5P6442_GPIO_J4_NR (5) | ||
47 | |||
48 | /* GPIO bank numbers */ | ||
49 | |||
50 | /* CONFIG_S3C_GPIO_SPACE allows the user to select extra | ||
51 | * space for debugging purposes so that any accidental | ||
52 | * change from one gpio bank to another can be caught. | ||
53 | */ | ||
54 | |||
55 | #define S5P6442_GPIO_NEXT(__gpio) \ | ||
56 | ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) | ||
57 | |||
58 | enum s5p_gpio_number { | ||
59 | S5P6442_GPIO_A0_START = 0, | ||
60 | S5P6442_GPIO_A1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_A0), | ||
61 | S5P6442_GPIO_B_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_A1), | ||
62 | S5P6442_GPIO_C0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_B), | ||
63 | S5P6442_GPIO_C1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_C0), | ||
64 | S5P6442_GPIO_D0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_C1), | ||
65 | S5P6442_GPIO_D1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_D0), | ||
66 | S5P6442_GPIO_E0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_D1), | ||
67 | S5P6442_GPIO_E1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_E0), | ||
68 | S5P6442_GPIO_F0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_E1), | ||
69 | S5P6442_GPIO_F1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F0), | ||
70 | S5P6442_GPIO_F2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F1), | ||
71 | S5P6442_GPIO_F3_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F2), | ||
72 | S5P6442_GPIO_G0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F3), | ||
73 | S5P6442_GPIO_G1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_G0), | ||
74 | S5P6442_GPIO_G2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_G1), | ||
75 | S5P6442_GPIO_H0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_G2), | ||
76 | S5P6442_GPIO_H1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H0), | ||
77 | S5P6442_GPIO_H2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H1), | ||
78 | S5P6442_GPIO_H3_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H2), | ||
79 | S5P6442_GPIO_J0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H3), | ||
80 | S5P6442_GPIO_J1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J0), | ||
81 | S5P6442_GPIO_J2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J1), | ||
82 | S5P6442_GPIO_J3_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J2), | ||
83 | S5P6442_GPIO_J4_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J3), | ||
84 | }; | ||
85 | |||
86 | /* S5P6442 GPIO number definitions. */ | ||
87 | #define S5P6442_GPA0(_nr) (S5P6442_GPIO_A0_START + (_nr)) | ||
88 | #define S5P6442_GPA1(_nr) (S5P6442_GPIO_A1_START + (_nr)) | ||
89 | #define S5P6442_GPB(_nr) (S5P6442_GPIO_B_START + (_nr)) | ||
90 | #define S5P6442_GPC0(_nr) (S5P6442_GPIO_C0_START + (_nr)) | ||
91 | #define S5P6442_GPC1(_nr) (S5P6442_GPIO_C1_START + (_nr)) | ||
92 | #define S5P6442_GPD0(_nr) (S5P6442_GPIO_D0_START + (_nr)) | ||
93 | #define S5P6442_GPD1(_nr) (S5P6442_GPIO_D1_START + (_nr)) | ||
94 | #define S5P6442_GPE0(_nr) (S5P6442_GPIO_E0_START + (_nr)) | ||
95 | #define S5P6442_GPE1(_nr) (S5P6442_GPIO_E1_START + (_nr)) | ||
96 | #define S5P6442_GPF0(_nr) (S5P6442_GPIO_F0_START + (_nr)) | ||
97 | #define S5P6442_GPF1(_nr) (S5P6442_GPIO_F1_START + (_nr)) | ||
98 | #define S5P6442_GPF2(_nr) (S5P6442_GPIO_F2_START + (_nr)) | ||
99 | #define S5P6442_GPF3(_nr) (S5P6442_GPIO_F3_START + (_nr)) | ||
100 | #define S5P6442_GPG0(_nr) (S5P6442_GPIO_G0_START + (_nr)) | ||
101 | #define S5P6442_GPG1(_nr) (S5P6442_GPIO_G1_START + (_nr)) | ||
102 | #define S5P6442_GPG2(_nr) (S5P6442_GPIO_G2_START + (_nr)) | ||
103 | #define S5P6442_GPH0(_nr) (S5P6442_GPIO_H0_START + (_nr)) | ||
104 | #define S5P6442_GPH1(_nr) (S5P6442_GPIO_H1_START + (_nr)) | ||
105 | #define S5P6442_GPH2(_nr) (S5P6442_GPIO_H2_START + (_nr)) | ||
106 | #define S5P6442_GPH3(_nr) (S5P6442_GPIO_H3_START + (_nr)) | ||
107 | #define S5P6442_GPJ0(_nr) (S5P6442_GPIO_J0_START + (_nr)) | ||
108 | #define S5P6442_GPJ1(_nr) (S5P6442_GPIO_J1_START + (_nr)) | ||
109 | #define S5P6442_GPJ2(_nr) (S5P6442_GPIO_J2_START + (_nr)) | ||
110 | #define S5P6442_GPJ3(_nr) (S5P6442_GPIO_J3_START + (_nr)) | ||
111 | #define S5P6442_GPJ4(_nr) (S5P6442_GPIO_J4_START + (_nr)) | ||
112 | |||
113 | /* the end of the S5P6442 specific gpios */ | ||
114 | #define S5P6442_GPIO_END (S5P6442_GPJ4(S5P6442_GPIO_J4_NR) + 1) | ||
115 | #define S3C_GPIO_END S5P6442_GPIO_END | ||
116 | |||
117 | /* define the number of gpios we need to the one after the GPJ4() range */ | ||
118 | #define ARCH_NR_GPIOS (S5P6442_GPJ4(S5P6442_GPIO_J4_NR) + \ | ||
119 | CONFIG_SAMSUNG_GPIO_EXTRA + 1) | ||
120 | |||
121 | #include <asm-generic/gpio.h> | ||
122 | |||
123 | #endif /* __ASM_ARCH_GPIO_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/hardware.h b/arch/arm/mach-s5p6442/include/mach/hardware.h deleted file mode 100644 index 8cd7b67b49d4..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/hardware.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/hardware.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - Hardware support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_HARDWARE_H | ||
14 | #define __ASM_ARCH_HARDWARE_H __FILE__ | ||
15 | |||
16 | /* currently nothing here, placeholder */ | ||
17 | |||
18 | #endif /* __ASM_ARCH_HARDWARE_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/io.h b/arch/arm/mach-s5p6442/include/mach/io.h deleted file mode 100644 index 5d2195ad0b67..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/io.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* arch/arm/mach-s5p6442/include/mach/io.h | ||
2 | * | ||
3 | * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org> | ||
4 | * | ||
5 | * Default IO routines for S5P6442 | ||
6 | */ | ||
7 | |||
8 | #ifndef __ASM_ARM_ARCH_IO_H | ||
9 | #define __ASM_ARM_ARCH_IO_H | ||
10 | |||
11 | /* No current ISA/PCI bus support. */ | ||
12 | #define __io(a) __typesafe_io(a) | ||
13 | #define __mem_pci(a) (a) | ||
14 | |||
15 | #define IO_SPACE_LIMIT (0xFFFFFFFF) | ||
16 | |||
17 | #endif | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/irqs.h b/arch/arm/mach-s5p6442/include/mach/irqs.h deleted file mode 100644 index 3fbc6c3ad2da..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/irqs.h +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/irqs.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - IRQ definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_IRQS_H | ||
14 | #define __ASM_ARCH_IRQS_H __FILE__ | ||
15 | |||
16 | #include <plat/irqs.h> | ||
17 | |||
18 | /* VIC0 */ | ||
19 | #define IRQ_EINT16_31 S5P_IRQ_VIC0(16) | ||
20 | #define IRQ_BATF S5P_IRQ_VIC0(17) | ||
21 | #define IRQ_MDMA S5P_IRQ_VIC0(18) | ||
22 | #define IRQ_PDMA S5P_IRQ_VIC0(19) | ||
23 | #define IRQ_TIMER0_VIC S5P_IRQ_VIC0(21) | ||
24 | #define IRQ_TIMER1_VIC S5P_IRQ_VIC0(22) | ||
25 | #define IRQ_TIMER2_VIC S5P_IRQ_VIC0(23) | ||
26 | #define IRQ_TIMER3_VIC S5P_IRQ_VIC0(24) | ||
27 | #define IRQ_TIMER4_VIC S5P_IRQ_VIC0(25) | ||
28 | #define IRQ_SYSTIMER S5P_IRQ_VIC0(26) | ||
29 | #define IRQ_WDT S5P_IRQ_VIC0(27) | ||
30 | #define IRQ_RTC_ALARM S5P_IRQ_VIC0(28) | ||
31 | #define IRQ_RTC_TIC S5P_IRQ_VIC0(29) | ||
32 | #define IRQ_GPIOINT S5P_IRQ_VIC0(30) | ||
33 | |||
34 | /* VIC1 */ | ||
35 | #define IRQ_PMU S5P_IRQ_VIC1(0) | ||
36 | #define IRQ_ONENAND S5P_IRQ_VIC1(7) | ||
37 | #define IRQ_UART0 S5P_IRQ_VIC1(10) | ||
38 | #define IRQ_UART1 S5P_IRQ_VIC1(11) | ||
39 | #define IRQ_UART2 S5P_IRQ_VIC1(12) | ||
40 | #define IRQ_SPI0 S5P_IRQ_VIC1(15) | ||
41 | #define IRQ_IIC S5P_IRQ_VIC1(19) | ||
42 | #define IRQ_IIC1 S5P_IRQ_VIC1(20) | ||
43 | #define IRQ_IIC2 S5P_IRQ_VIC1(21) | ||
44 | #define IRQ_OTG S5P_IRQ_VIC1(24) | ||
45 | #define IRQ_MSM S5P_IRQ_VIC1(25) | ||
46 | #define IRQ_HSMMC0 S5P_IRQ_VIC1(26) | ||
47 | #define IRQ_HSMMC1 S5P_IRQ_VIC1(27) | ||
48 | #define IRQ_HSMMC2 S5P_IRQ_VIC1(28) | ||
49 | #define IRQ_COMMRX S5P_IRQ_VIC1(29) | ||
50 | #define IRQ_COMMTX S5P_IRQ_VIC1(30) | ||
51 | |||
52 | /* VIC2 */ | ||
53 | #define IRQ_LCD0 S5P_IRQ_VIC2(0) | ||
54 | #define IRQ_LCD1 S5P_IRQ_VIC2(1) | ||
55 | #define IRQ_LCD2 S5P_IRQ_VIC2(2) | ||
56 | #define IRQ_LCD3 S5P_IRQ_VIC2(3) | ||
57 | #define IRQ_ROTATOR S5P_IRQ_VIC2(4) | ||
58 | #define IRQ_FIMC0 S5P_IRQ_VIC2(5) | ||
59 | #define IRQ_FIMC1 S5P_IRQ_VIC2(6) | ||
60 | #define IRQ_FIMC2 S5P_IRQ_VIC2(7) | ||
61 | #define IRQ_JPEG S5P_IRQ_VIC2(8) | ||
62 | #define IRQ_3D S5P_IRQ_VIC2(10) | ||
63 | #define IRQ_Mixer S5P_IRQ_VIC2(11) | ||
64 | #define IRQ_MFC S5P_IRQ_VIC2(14) | ||
65 | #define IRQ_TVENC S5P_IRQ_VIC2(15) | ||
66 | #define IRQ_I2S0 S5P_IRQ_VIC2(16) | ||
67 | #define IRQ_I2S1 S5P_IRQ_VIC2(17) | ||
68 | #define IRQ_RP S5P_IRQ_VIC2(19) | ||
69 | #define IRQ_PCM0 S5P_IRQ_VIC2(20) | ||
70 | #define IRQ_PCM1 S5P_IRQ_VIC2(21) | ||
71 | #define IRQ_ADC S5P_IRQ_VIC2(23) | ||
72 | #define IRQ_PENDN S5P_IRQ_VIC2(24) | ||
73 | #define IRQ_KEYPAD S5P_IRQ_VIC2(25) | ||
74 | #define IRQ_SSS_INT S5P_IRQ_VIC2(27) | ||
75 | #define IRQ_SSS_HASH S5P_IRQ_VIC2(28) | ||
76 | #define IRQ_VIC_END S5P_IRQ_VIC2(31) | ||
77 | |||
78 | #define S5P_IRQ_EINT_BASE (IRQ_VIC_END + 1) | ||
79 | |||
80 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) | ||
81 | #define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE) | ||
82 | |||
83 | /* Set the default NR_IRQS */ | ||
84 | |||
85 | #define NR_IRQS (IRQ_EINT(31) + 1) | ||
86 | |||
87 | #endif /* __ASM_ARCH_IRQS_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h deleted file mode 100644 index 058dab4482a1..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/map.h +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/map.h | ||
2 | * | ||
3 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - Memory map definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_MAP_H | ||
14 | #define __ASM_ARCH_MAP_H __FILE__ | ||
15 | |||
16 | #include <plat/map-base.h> | ||
17 | #include <plat/map-s5p.h> | ||
18 | |||
19 | #define S5P6442_PA_SDRAM 0x20000000 | ||
20 | |||
21 | #define S5P6442_PA_I2S0 0xC0B00000 | ||
22 | #define S5P6442_PA_I2S1 0xF2200000 | ||
23 | |||
24 | #define S5P6442_PA_CHIPID 0xE0000000 | ||
25 | |||
26 | #define S5P6442_PA_SYSCON 0xE0100000 | ||
27 | |||
28 | #define S5P6442_PA_GPIO 0xE0200000 | ||
29 | |||
30 | #define S5P6442_PA_VIC0 0xE4000000 | ||
31 | #define S5P6442_PA_VIC1 0xE4100000 | ||
32 | #define S5P6442_PA_VIC2 0xE4200000 | ||
33 | |||
34 | #define S5P6442_PA_SROMC 0xE7000000 | ||
35 | |||
36 | #define S5P6442_PA_MDMA 0xE8000000 | ||
37 | #define S5P6442_PA_PDMA 0xE9000000 | ||
38 | |||
39 | #define S5P6442_PA_TIMER 0xEA000000 | ||
40 | |||
41 | #define S5P6442_PA_SYSTIMER 0xEA100000 | ||
42 | |||
43 | #define S5P6442_PA_WATCHDOG 0xEA200000 | ||
44 | |||
45 | #define S5P6442_PA_UART 0xEC000000 | ||
46 | |||
47 | #define S5P6442_PA_IIC0 0xEC100000 | ||
48 | |||
49 | #define S5P6442_PA_SPI 0xEC300000 | ||
50 | |||
51 | #define S5P6442_PA_PCM0 0xF2400000 | ||
52 | #define S5P6442_PA_PCM1 0xF2500000 | ||
53 | |||
54 | /* Compatibiltiy Defines */ | ||
55 | |||
56 | #define S3C_PA_IIC S5P6442_PA_IIC0 | ||
57 | #define S3C_PA_WDT S5P6442_PA_WATCHDOG | ||
58 | |||
59 | #define S5P_PA_CHIPID S5P6442_PA_CHIPID | ||
60 | #define S5P_PA_SDRAM S5P6442_PA_SDRAM | ||
61 | #define S5P_PA_SROMC S5P6442_PA_SROMC | ||
62 | #define S5P_PA_SYSCON S5P6442_PA_SYSCON | ||
63 | #define S5P_PA_TIMER S5P6442_PA_TIMER | ||
64 | |||
65 | /* UART */ | ||
66 | |||
67 | #define S3C_PA_UART S5P6442_PA_UART | ||
68 | |||
69 | #define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET)) | ||
70 | #define S5P_PA_UART0 S5P_PA_UART(0) | ||
71 | #define S5P_PA_UART1 S5P_PA_UART(1) | ||
72 | #define S5P_PA_UART2 S5P_PA_UART(2) | ||
73 | |||
74 | #define S5P_SZ_UART SZ_256 | ||
75 | |||
76 | #endif /* __ASM_ARCH_MAP_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/memory.h b/arch/arm/mach-s5p6442/include/mach/memory.h deleted file mode 100644 index cfe259dded33..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/memory.h +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/memory.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - Memory definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_MEMORY_H | ||
14 | #define __ASM_ARCH_MEMORY_H | ||
15 | |||
16 | #define PLAT_PHYS_OFFSET UL(0x20000000) | ||
17 | #define CONSISTENT_DMA_SIZE SZ_8M | ||
18 | |||
19 | #endif /* __ASM_ARCH_MEMORY_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h deleted file mode 100644 index 2724b37def31..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Copyright 2008 Openmoko, Inc. | ||
7 | * Copyright 2008 Simtec Electronics | ||
8 | * Ben Dooks <ben@simtec.co.uk> | ||
9 | * http://armlinux.simtec.co.uk/ | ||
10 | * | ||
11 | * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h | ||
12 | * | ||
13 | * S5P6442 - pwm clock and timer support | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License version 2 as | ||
17 | * published by the Free Software Foundation. | ||
18 | */ | ||
19 | |||
20 | #ifndef __ASM_ARCH_PWMCLK_H | ||
21 | #define __ASM_ARCH_PWMCLK_H __FILE__ | ||
22 | |||
23 | /** | ||
24 | * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk | ||
25 | * @tcfg: The timer TCFG1 register bits shifted down to 0. | ||
26 | * | ||
27 | * Return true if the given configuration from TCFG1 is a TCLK instead | ||
28 | * any of the TDIV clocks. | ||
29 | */ | ||
30 | static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) | ||
31 | { | ||
32 | return tcfg == S3C64XX_TCFG1_MUX_TCLK; | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * tcfg_to_divisor() - convert tcfg1 setting to a divisor | ||
37 | * @tcfg1: The tcfg1 setting, shifted down. | ||
38 | * | ||
39 | * Get the divisor value for the given tcfg1 setting. We assume the | ||
40 | * caller has already checked to see if this is not a TCLK source. | ||
41 | */ | ||
42 | static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) | ||
43 | { | ||
44 | return 1 << tcfg1; | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * pwm_tdiv_has_div1() - does the tdiv setting have a /1 | ||
49 | * | ||
50 | * Return true if we have a /1 in the tdiv setting. | ||
51 | */ | ||
52 | static inline unsigned int pwm_tdiv_has_div1(void) | ||
53 | { | ||
54 | return 1; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * pwm_tdiv_div_bits() - calculate TCFG1 divisor value. | ||
59 | * @div: The divisor to calculate the bit information for. | ||
60 | * | ||
61 | * Turn a divisor into the necessary bit field for TCFG1. | ||
62 | */ | ||
63 | static inline unsigned long pwm_tdiv_div_bits(unsigned int div) | ||
64 | { | ||
65 | return ilog2(div); | ||
66 | } | ||
67 | |||
68 | #define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK | ||
69 | |||
70 | #endif /* __ASM_ARCH_PWMCLK_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/regs-clock.h b/arch/arm/mach-s5p6442/include/mach/regs-clock.h deleted file mode 100644 index 00828a336991..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/regs-clock.h +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/regs-clock.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - Clock register definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_REGS_CLOCK_H | ||
14 | #define __ASM_ARCH_REGS_CLOCK_H __FILE__ | ||
15 | |||
16 | #include <mach/map.h> | ||
17 | |||
18 | #define S5P_CLKREG(x) (S3C_VA_SYS + (x)) | ||
19 | |||
20 | #define S5P_APLL_LOCK S5P_CLKREG(0x00) | ||
21 | #define S5P_MPLL_LOCK S5P_CLKREG(0x08) | ||
22 | #define S5P_EPLL_LOCK S5P_CLKREG(0x10) | ||
23 | #define S5P_VPLL_LOCK S5P_CLKREG(0x20) | ||
24 | |||
25 | #define S5P_APLL_CON S5P_CLKREG(0x100) | ||
26 | #define S5P_MPLL_CON S5P_CLKREG(0x108) | ||
27 | #define S5P_EPLL_CON S5P_CLKREG(0x110) | ||
28 | #define S5P_VPLL_CON S5P_CLKREG(0x120) | ||
29 | |||
30 | #define S5P_CLK_SRC0 S5P_CLKREG(0x200) | ||
31 | #define S5P_CLK_SRC1 S5P_CLKREG(0x204) | ||
32 | #define S5P_CLK_SRC2 S5P_CLKREG(0x208) | ||
33 | #define S5P_CLK_SRC3 S5P_CLKREG(0x20C) | ||
34 | #define S5P_CLK_SRC4 S5P_CLKREG(0x210) | ||
35 | #define S5P_CLK_SRC5 S5P_CLKREG(0x214) | ||
36 | #define S5P_CLK_SRC6 S5P_CLKREG(0x218) | ||
37 | |||
38 | #define S5P_CLK_SRC_MASK0 S5P_CLKREG(0x280) | ||
39 | #define S5P_CLK_SRC_MASK1 S5P_CLKREG(0x284) | ||
40 | |||
41 | #define S5P_CLK_DIV0 S5P_CLKREG(0x300) | ||
42 | #define S5P_CLK_DIV1 S5P_CLKREG(0x304) | ||
43 | #define S5P_CLK_DIV2 S5P_CLKREG(0x308) | ||
44 | #define S5P_CLK_DIV3 S5P_CLKREG(0x30C) | ||
45 | #define S5P_CLK_DIV4 S5P_CLKREG(0x310) | ||
46 | #define S5P_CLK_DIV5 S5P_CLKREG(0x314) | ||
47 | #define S5P_CLK_DIV6 S5P_CLKREG(0x318) | ||
48 | |||
49 | #define S5P_CLKGATE_IP0 S5P_CLKREG(0x460) | ||
50 | #define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C) | ||
51 | |||
52 | /* CLK_OUT */ | ||
53 | #define S5P_CLK_OUT_SHIFT (12) | ||
54 | #define S5P_CLK_OUT_MASK (0x1F << S5P_CLK_OUT_SHIFT) | ||
55 | #define S5P_CLK_OUT S5P_CLKREG(0x500) | ||
56 | |||
57 | #define S5P_CLK_DIV_STAT0 S5P_CLKREG(0x1000) | ||
58 | #define S5P_CLK_DIV_STAT1 S5P_CLKREG(0x1004) | ||
59 | |||
60 | #define S5P_CLK_MUX_STAT0 S5P_CLKREG(0x1100) | ||
61 | #define S5P_CLK_MUX_STAT1 S5P_CLKREG(0x1104) | ||
62 | |||
63 | #define S5P_MDNIE_SEL S5P_CLKREG(0x7008) | ||
64 | |||
65 | /* Register Bit definition */ | ||
66 | #define S5P_EPLL_EN (1<<31) | ||
67 | #define S5P_EPLL_MASK 0xffffffff | ||
68 | #define S5P_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s))) | ||
69 | |||
70 | /* CLKDIV0 */ | ||
71 | #define S5P_CLKDIV0_APLL_SHIFT (0) | ||
72 | #define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT) | ||
73 | #define S5P_CLKDIV0_A2M_SHIFT (4) | ||
74 | #define S5P_CLKDIV0_A2M_MASK (0x7 << S5P_CLKDIV0_A2M_SHIFT) | ||
75 | #define S5P_CLKDIV0_D0CLK_SHIFT (16) | ||
76 | #define S5P_CLKDIV0_D0CLK_MASK (0xF << S5P_CLKDIV0_D0CLK_SHIFT) | ||
77 | #define S5P_CLKDIV0_P0CLK_SHIFT (20) | ||
78 | #define S5P_CLKDIV0_P0CLK_MASK (0x7 << S5P_CLKDIV0_P0CLK_SHIFT) | ||
79 | #define S5P_CLKDIV0_D1CLK_SHIFT (24) | ||
80 | #define S5P_CLKDIV0_D1CLK_MASK (0xF << S5P_CLKDIV0_D1CLK_SHIFT) | ||
81 | #define S5P_CLKDIV0_P1CLK_SHIFT (28) | ||
82 | #define S5P_CLKDIV0_P1CLK_MASK (0x7 << S5P_CLKDIV0_P1CLK_SHIFT) | ||
83 | |||
84 | /* Clock MUX status Registers */ | ||
85 | #define S5P_CLK_MUX_STAT0_APLL_SHIFT (0) | ||
86 | #define S5P_CLK_MUX_STAT0_APLL_MASK (0x7 << S5P_CLK_MUX_STAT0_APLL_SHIFT) | ||
87 | #define S5P_CLK_MUX_STAT0_MPLL_SHIFT (4) | ||
88 | #define S5P_CLK_MUX_STAT0_MPLL_MASK (0x7 << S5P_CLK_MUX_STAT0_MPLL_SHIFT) | ||
89 | #define S5P_CLK_MUX_STAT0_EPLL_SHIFT (8) | ||
90 | #define S5P_CLK_MUX_STAT0_EPLL_MASK (0x7 << S5P_CLK_MUX_STAT0_EPLL_SHIFT) | ||
91 | #define S5P_CLK_MUX_STAT0_VPLL_SHIFT (12) | ||
92 | #define S5P_CLK_MUX_STAT0_VPLL_MASK (0x7 << S5P_CLK_MUX_STAT0_VPLL_SHIFT) | ||
93 | #define S5P_CLK_MUX_STAT0_MUXARM_SHIFT (16) | ||
94 | #define S5P_CLK_MUX_STAT0_MUXARM_MASK (0x7 << S5P_CLK_MUX_STAT0_MUXARM_SHIFT) | ||
95 | #define S5P_CLK_MUX_STAT0_MUXD0_SHIFT (20) | ||
96 | #define S5P_CLK_MUX_STAT0_MUXD0_MASK (0x7 << S5P_CLK_MUX_STAT0_MUXD0_SHIFT) | ||
97 | #define S5P_CLK_MUX_STAT0_MUXD1_SHIFT (24) | ||
98 | #define S5P_CLK_MUX_STAT0_MUXD1_MASK (0x7 << S5P_CLK_MUX_STAT0_MUXD1_SHIFT) | ||
99 | #define S5P_CLK_MUX_STAT1_D1SYNC_SHIFT (24) | ||
100 | #define S5P_CLK_MUX_STAT1_D1SYNC_MASK (0x7 << S5P_CLK_MUX_STAT1_D1SYNC_SHIFT) | ||
101 | #define S5P_CLK_MUX_STAT1_D0SYNC_SHIFT (28) | ||
102 | #define S5P_CLK_MUX_STAT1_D0SYNC_MASK (0x7 << S5P_CLK_MUX_STAT1_D0SYNC_SHIFT) | ||
103 | |||
104 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/regs-irq.h b/arch/arm/mach-s5p6442/include/mach/regs-irq.h deleted file mode 100644 index 73782b52a83b..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/regs-irq.h +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/regs-irq.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - IRQ register definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_REGS_IRQ_H | ||
14 | #define __ASM_ARCH_REGS_IRQ_H __FILE__ | ||
15 | |||
16 | #include <asm/hardware/vic.h> | ||
17 | #include <mach/map.h> | ||
18 | |||
19 | #endif /* __ASM_ARCH_REGS_IRQ_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/spi-clocks.h b/arch/arm/mach-s5p6442/include/mach/spi-clocks.h deleted file mode 100644 index 7fd88205a97c..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/spi-clocks.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/spi-clocks.h | ||
2 | * | ||
3 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __S5P6442_PLAT_SPI_CLKS_H | ||
12 | #define __S5P6442_PLAT_SPI_CLKS_H __FILE__ | ||
13 | |||
14 | #define S5P6442_SPI_SRCCLK_PCLK 0 | ||
15 | #define S5P6442_SPI_SRCCLK_SCLK 1 | ||
16 | |||
17 | #endif /* __S5P6442_PLAT_SPI_CLKS_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/system.h b/arch/arm/mach-s5p6442/include/mach/system.h deleted file mode 100644 index c30c1cc1b97e..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/system.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/system.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - system support header | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_SYSTEM_H | ||
14 | #define __ASM_ARCH_SYSTEM_H __FILE__ | ||
15 | |||
16 | #include <plat/system-reset.h> | ||
17 | |||
18 | static void arch_idle(void) | ||
19 | { | ||
20 | /* nothing here yet */ | ||
21 | } | ||
22 | |||
23 | #endif /* __ASM_ARCH_SYSTEM_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/tick.h b/arch/arm/mach-s5p6442/include/mach/tick.h deleted file mode 100644 index e1d4cabf8297..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/tick.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/tick.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Based on arch/arm/mach-s3c6400/include/mach/tick.h | ||
7 | * | ||
8 | * S5P6442 - Timer tick support definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ASM_ARCH_TICK_H | ||
16 | #define __ASM_ARCH_TICK_H __FILE__ | ||
17 | |||
18 | static inline u32 s3c24xx_ostimer_pending(void) | ||
19 | { | ||
20 | u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS); | ||
21 | return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0))); | ||
22 | } | ||
23 | |||
24 | #define TICK_MAX (0xffffffff) | ||
25 | |||
26 | #endif /* __ASM_ARCH_TICK_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/timex.h b/arch/arm/mach-s5p6442/include/mach/timex.h deleted file mode 100644 index ff8f2fcadeb7..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/timex.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* arch/arm/mach-s5p6442/include/mach/timex.h | ||
2 | * | ||
3 | * Copyright (c) 2003-2010 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * S5P6442 - time parameters | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_TIMEX_H | ||
14 | #define __ASM_ARCH_TIMEX_H | ||
15 | |||
16 | /* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it | ||
17 | * a variable is useless. It seems as long as we make our timers an | ||
18 | * exact multiple of HZ, any value that makes a 1->1 correspondence | ||
19 | * for the time conversion functions to/from jiffies is acceptable. | ||
20 | */ | ||
21 | |||
22 | #define CLOCK_TICK_RATE 12000000 | ||
23 | |||
24 | #endif /* __ASM_ARCH_TIMEX_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/uncompress.h b/arch/arm/mach-s5p6442/include/mach/uncompress.h deleted file mode 100644 index 5ac7cbeeb987..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/uncompress.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/include/mach/uncompress.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P6442 - uncompress code | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_UNCOMPRESS_H | ||
14 | #define __ASM_ARCH_UNCOMPRESS_H | ||
15 | |||
16 | #include <mach/map.h> | ||
17 | #include <plat/uncompress.h> | ||
18 | |||
19 | static void arch_detect_cpu(void) | ||
20 | { | ||
21 | /* we do not need to do any cpu detection here at the moment. */ | ||
22 | } | ||
23 | |||
24 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-s5p6442/include/mach/vmalloc.h b/arch/arm/mach-s5p6442/include/mach/vmalloc.h deleted file mode 100644 index 4aa55e55ac47..000000000000 --- a/arch/arm/mach-s5p6442/include/mach/vmalloc.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* arch/arm/mach-s5p6442/include/mach/vmalloc.h | ||
2 | * | ||
3 | * Copyright 2010 Ben Dooks <ben-linux@fluff.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * S5P6442 vmalloc definition | ||
10 | */ | ||
11 | |||
12 | #ifndef __ASM_ARCH_VMALLOC_H | ||
13 | #define __ASM_ARCH_VMALLOC_H | ||
14 | |||
15 | #define VMALLOC_END 0xF6000000UL | ||
16 | |||
17 | #endif /* __ASM_ARCH_VMALLOC_H */ | ||
diff --git a/arch/arm/mach-s5p6442/init.c b/arch/arm/mach-s5p6442/init.c deleted file mode 100644 index 1874bdb71e1d..000000000000 --- a/arch/arm/mach-s5p6442/init.c +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/s5p6442-init.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/serial_core.h> | ||
15 | |||
16 | #include <plat/cpu.h> | ||
17 | #include <plat/devs.h> | ||
18 | #include <plat/s5p6442.h> | ||
19 | #include <plat/regs-serial.h> | ||
20 | |||
21 | static struct s3c24xx_uart_clksrc s5p6442_serial_clocks[] = { | ||
22 | [0] = { | ||
23 | .name = "pclk", | ||
24 | .divisor = 1, | ||
25 | .min_baud = 0, | ||
26 | .max_baud = 0, | ||
27 | }, | ||
28 | }; | ||
29 | |||
30 | /* uart registration process */ | ||
31 | void __init s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) | ||
32 | { | ||
33 | struct s3c2410_uartcfg *tcfg = cfg; | ||
34 | u32 ucnt; | ||
35 | |||
36 | for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { | ||
37 | if (!tcfg->clocks) { | ||
38 | tcfg->clocks = s5p6442_serial_clocks; | ||
39 | tcfg->clocks_size = ARRAY_SIZE(s5p6442_serial_clocks); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); | ||
44 | } | ||
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c deleted file mode 100644 index eaf6b9c489ff..000000000000 --- a/arch/arm/mach-s5p6442/mach-smdk6442.c +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/mach-smdk6442.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/serial_core.h> | ||
15 | #include <linux/i2c.h> | ||
16 | |||
17 | #include <asm/mach/arch.h> | ||
18 | #include <asm/mach/map.h> | ||
19 | #include <asm/setup.h> | ||
20 | #include <asm/mach-types.h> | ||
21 | |||
22 | #include <mach/map.h> | ||
23 | #include <mach/regs-clock.h> | ||
24 | |||
25 | #include <plat/regs-serial.h> | ||
26 | #include <plat/s5p6442.h> | ||
27 | #include <plat/devs.h> | ||
28 | #include <plat/cpu.h> | ||
29 | #include <plat/iic.h> | ||
30 | |||
31 | /* Following are default values for UCON, ULCON and UFCON UART registers */ | ||
32 | #define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
33 | S3C2410_UCON_RXILEVEL | \ | ||
34 | S3C2410_UCON_TXIRQMODE | \ | ||
35 | S3C2410_UCON_RXIRQMODE | \ | ||
36 | S3C2410_UCON_RXFIFO_TOI | \ | ||
37 | S3C2443_UCON_RXERR_IRQEN) | ||
38 | |||
39 | #define SMDK6442_ULCON_DEFAULT S3C2410_LCON_CS8 | ||
40 | |||
41 | #define SMDK6442_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
42 | S5PV210_UFCON_TXTRIG4 | \ | ||
43 | S5PV210_UFCON_RXTRIG4) | ||
44 | |||
45 | static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = { | ||
46 | [0] = { | ||
47 | .hwport = 0, | ||
48 | .flags = 0, | ||
49 | .ucon = SMDK6442_UCON_DEFAULT, | ||
50 | .ulcon = SMDK6442_ULCON_DEFAULT, | ||
51 | .ufcon = SMDK6442_UFCON_DEFAULT, | ||
52 | }, | ||
53 | [1] = { | ||
54 | .hwport = 1, | ||
55 | .flags = 0, | ||
56 | .ucon = SMDK6442_UCON_DEFAULT, | ||
57 | .ulcon = SMDK6442_ULCON_DEFAULT, | ||
58 | .ufcon = SMDK6442_UFCON_DEFAULT, | ||
59 | }, | ||
60 | [2] = { | ||
61 | .hwport = 2, | ||
62 | .flags = 0, | ||
63 | .ucon = SMDK6442_UCON_DEFAULT, | ||
64 | .ulcon = SMDK6442_ULCON_DEFAULT, | ||
65 | .ufcon = SMDK6442_UFCON_DEFAULT, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | static struct platform_device *smdk6442_devices[] __initdata = { | ||
70 | &s3c_device_i2c0, | ||
71 | &samsung_asoc_dma, | ||
72 | &s5p6442_device_iis0, | ||
73 | &s3c_device_wdt, | ||
74 | }; | ||
75 | |||
76 | static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = { | ||
77 | { I2C_BOARD_INFO("wm8580", 0x1b), }, | ||
78 | }; | ||
79 | |||
80 | static void __init smdk6442_map_io(void) | ||
81 | { | ||
82 | s5p_init_io(NULL, 0, S5P_VA_CHIPID); | ||
83 | s3c24xx_init_clocks(12000000); | ||
84 | s3c24xx_init_uarts(smdk6442_uartcfgs, ARRAY_SIZE(smdk6442_uartcfgs)); | ||
85 | } | ||
86 | |||
87 | static void __init smdk6442_machine_init(void) | ||
88 | { | ||
89 | s3c_i2c0_set_platdata(NULL); | ||
90 | i2c_register_board_info(0, smdk6442_i2c_devs0, | ||
91 | ARRAY_SIZE(smdk6442_i2c_devs0)); | ||
92 | platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices)); | ||
93 | } | ||
94 | |||
95 | MACHINE_START(SMDK6442, "SMDK6442") | ||
96 | /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ | ||
97 | .boot_params = S5P_PA_SDRAM + 0x100, | ||
98 | .init_irq = s5p6442_init_irq, | ||
99 | .map_io = smdk6442_map_io, | ||
100 | .init_machine = smdk6442_machine_init, | ||
101 | .timer = &s3c24xx_timer, | ||
102 | MACHINE_END | ||
diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c deleted file mode 100644 index aad85656b0cc..000000000000 --- a/arch/arm/mach-s5p6442/setup-i2c0.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s5p6442/setup-i2c0.c | ||
2 | * | ||
3 | * Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * I2C0 GPIO configuration. | ||
7 | * | ||
8 | * Based on plat-s3c64xx/setup-i2c0.c | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | struct platform_device; /* don't need the contents */ | ||
20 | |||
21 | #include <plat/gpio-cfg.h> | ||
22 | #include <plat/iic.h> | ||
23 | |||
24 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | ||
25 | { | ||
26 | s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2, | ||
27 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); | ||
28 | } | ||
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index eecab57d2e5d..a5e6e608b498 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile | |||
@@ -11,7 +11,7 @@ obj- := | |||
11 | 11 | ||
12 | # Core support for S5PC100 system | 12 | # Core support for S5PC100 system |
13 | 13 | ||
14 | obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o | 14 | obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o |
15 | obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o | 15 | obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o |
16 | obj-$(CONFIG_CPU_S5PC100) += dma.o | 16 | obj-$(CONFIG_CPU_S5PC100) += dma.o |
17 | 17 | ||
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 11f17907b4e8..50907aca006c 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile | |||
@@ -12,7 +12,7 @@ obj- := | |||
12 | 12 | ||
13 | # Core support for S5PV210 system | 13 | # Core support for S5PV210 system |
14 | 14 | ||
15 | obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o | 15 | obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o |
16 | obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o | 16 | obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o |
17 | obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o | 17 | obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o |
18 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | 18 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o |
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index fab46fe9a71f..8fd354aaf0a7 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux kernel, U300 machine. | 2 | # Makefile for the linux kernel, U300 machine. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := core.o clock.o timer.o gpio.o padmux.o | 5 | obj-y := core.o clock.o timer.o padmux.o |
6 | obj-m := | 6 | obj-m := |
7 | obj-n := | 7 | obj-n := |
8 | obj- := | 8 | obj- := |
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 54429d015954..f8b9392ee347 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig | |||
@@ -5,7 +5,6 @@ config UX500_SOC_COMMON | |||
5 | default y | 5 | default y |
6 | select ARM_GIC | 6 | select ARM_GIC |
7 | select HAS_MTU | 7 | select HAS_MTU |
8 | select NOMADIK_GPIO | ||
9 | select ARM_ERRATA_753970 | 8 | select ARM_ERRATA_753970 |
10 | 9 | ||
11 | menu "Ux500 SoC" | 10 | menu "Ux500 SoC" |
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index bf0b02414e5b..7c6cb4fa47a9 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
@@ -99,8 +99,11 @@ static void sdi0_configure(void) | |||
99 | gpio_direction_output(sdi0_vsel, 0); | 99 | gpio_direction_output(sdi0_vsel, 0); |
100 | gpio_direction_output(sdi0_en, 1); | 100 | gpio_direction_output(sdi0_en, 1); |
101 | 101 | ||
102 | /* Add the device */ | 102 | /* Add the device, force v2 to subrevision 1 */ |
103 | db8500_add_sdi0(&mop500_sdi0_data); | 103 | if (cpu_is_u8500v2()) |
104 | db8500_add_sdi0(&mop500_sdi0_data, 0x10480180); | ||
105 | else | ||
106 | db8500_add_sdi0(&mop500_sdi0_data, 0); | ||
104 | } | 107 | } |
105 | 108 | ||
106 | void mop500_sdi_tc35892_init(void) | 109 | void mop500_sdi_tc35892_init(void) |
@@ -188,13 +191,18 @@ static struct mmci_platform_data mop500_sdi4_data = { | |||
188 | 191 | ||
189 | void __init mop500_sdi_init(void) | 192 | void __init mop500_sdi_init(void) |
190 | { | 193 | { |
194 | u32 periphid = 0; | ||
195 | |||
196 | /* v2 has a new version of this block that need to be forced */ | ||
197 | if (cpu_is_u8500v2()) | ||
198 | periphid = 0x10480180; | ||
191 | /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ | 199 | /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */ |
192 | if (!cpu_is_u8500v10()) | 200 | if (!cpu_is_u8500v10()) |
193 | mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; | 201 | mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED; |
194 | db8500_add_sdi2(&mop500_sdi2_data); | 202 | db8500_add_sdi2(&mop500_sdi2_data, periphid); |
195 | 203 | ||
196 | /* On-board eMMC */ | 204 | /* On-board eMMC */ |
197 | db8500_add_sdi4(&mop500_sdi4_data); | 205 | db8500_add_sdi4(&mop500_sdi4_data, periphid); |
198 | 206 | ||
199 | if (machine_is_hrefv60()) { | 207 | if (machine_is_hrefv60()) { |
200 | mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; | 208 | mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; |
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index c719b5a1d913..7825705033bf 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h | |||
@@ -28,18 +28,20 @@ dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, | |||
28 | 28 | ||
29 | static inline struct amba_device * | 29 | static inline struct amba_device * |
30 | dbx500_add_spi(const char *name, resource_size_t base, int irq, | 30 | dbx500_add_spi(const char *name, resource_size_t base, int irq, |
31 | struct spi_master_cntlr *pdata) | 31 | struct spi_master_cntlr *pdata, |
32 | u32 periphid) | ||
32 | { | 33 | { |
33 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | 34 | return dbx500_add_amba_device(name, base, irq, pdata, periphid); |
34 | } | 35 | } |
35 | 36 | ||
36 | struct mmci_platform_data; | 37 | struct mmci_platform_data; |
37 | 38 | ||
38 | static inline struct amba_device * | 39 | static inline struct amba_device * |
39 | dbx500_add_sdi(const char *name, resource_size_t base, int irq, | 40 | dbx500_add_sdi(const char *name, resource_size_t base, int irq, |
40 | struct mmci_platform_data *pdata) | 41 | struct mmci_platform_data *pdata, |
42 | u32 periphid) | ||
41 | { | 43 | { |
42 | return dbx500_add_amba_device(name, base, irq, pdata, 0); | 44 | return dbx500_add_amba_device(name, base, irq, pdata, periphid); |
43 | } | 45 | } |
44 | 46 | ||
45 | struct amba_pl011_data; | 47 | struct amba_pl011_data; |
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h index 94627f7783b0..0c4bccd02b90 100644 --- a/arch/arm/mach-ux500/devices-db5500.h +++ b/arch/arm/mach-ux500/devices-db5500.h | |||
@@ -38,24 +38,34 @@ | |||
38 | ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) | 38 | ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) |
39 | 39 | ||
40 | #define db5500_add_sdi0(pdata) \ | 40 | #define db5500_add_sdi0(pdata) \ |
41 | dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata) | 41 | dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \ |
42 | 0x10480180) | ||
42 | #define db5500_add_sdi1(pdata) \ | 43 | #define db5500_add_sdi1(pdata) \ |
43 | dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata) | 44 | dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \ |
45 | 0x10480180) | ||
44 | #define db5500_add_sdi2(pdata) \ | 46 | #define db5500_add_sdi2(pdata) \ |
45 | dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata) | 47 | dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \ |
48 | 0x10480180) | ||
46 | #define db5500_add_sdi3(pdata) \ | 49 | #define db5500_add_sdi3(pdata) \ |
47 | dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata) | 50 | dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \ |
51 | 0x10480180) | ||
48 | #define db5500_add_sdi4(pdata) \ | 52 | #define db5500_add_sdi4(pdata) \ |
49 | dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata) | 53 | dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \ |
54 | 0x10480180) | ||
50 | 55 | ||
56 | /* This one has a bad peripheral ID in the U5500 silicon */ | ||
51 | #define db5500_add_spi0(pdata) \ | 57 | #define db5500_add_spi0(pdata) \ |
52 | dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata) | 58 | dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \ |
59 | 0x10080023) | ||
53 | #define db5500_add_spi1(pdata) \ | 60 | #define db5500_add_spi1(pdata) \ |
54 | dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata) | 61 | dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \ |
62 | 0x10080023) | ||
55 | #define db5500_add_spi2(pdata) \ | 63 | #define db5500_add_spi2(pdata) \ |
56 | dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata) | 64 | dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \ |
65 | 0x10080023) | ||
57 | #define db5500_add_spi3(pdata) \ | 66 | #define db5500_add_spi3(pdata) \ |
58 | dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata) | 67 | dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \ |
68 | 0x10080023) | ||
59 | 69 | ||
60 | #define db5500_add_uart0(plat) \ | 70 | #define db5500_add_uart0(plat) \ |
61 | dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat) | 71 | dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat) |
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index 9cc6f8f5d3e6..cbd4a9ae8109 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h | |||
@@ -25,7 +25,7 @@ static inline struct amba_device * | |||
25 | db8500_add_ssp(const char *name, resource_size_t base, int irq, | 25 | db8500_add_ssp(const char *name, resource_size_t base, int irq, |
26 | struct pl022_ssp_controller *pdata) | 26 | struct pl022_ssp_controller *pdata) |
27 | { | 27 | { |
28 | return dbx500_add_amba_device(name, base, irq, pdata, SSP_PER_ID); | 28 | return dbx500_add_amba_device(name, base, irq, pdata, 0); |
29 | } | 29 | } |
30 | 30 | ||
31 | 31 | ||
@@ -64,18 +64,18 @@ db8500_add_ssp(const char *name, resource_size_t base, int irq, | |||
64 | #define db8500_add_usb(rx_cfg, tx_cfg) \ | 64 | #define db8500_add_usb(rx_cfg, tx_cfg) \ |
65 | ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) | 65 | ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) |
66 | 66 | ||
67 | #define db8500_add_sdi0(pdata) \ | 67 | #define db8500_add_sdi0(pdata, pid) \ |
68 | dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata) | 68 | dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid) |
69 | #define db8500_add_sdi1(pdata) \ | 69 | #define db8500_add_sdi1(pdata, pid) \ |
70 | dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata) | 70 | dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid) |
71 | #define db8500_add_sdi2(pdata) \ | 71 | #define db8500_add_sdi2(pdata, pid) \ |
72 | dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata) | 72 | dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid) |
73 | #define db8500_add_sdi3(pdata) \ | 73 | #define db8500_add_sdi3(pdata, pid) \ |
74 | dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata) | 74 | dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid) |
75 | #define db8500_add_sdi4(pdata) \ | 75 | #define db8500_add_sdi4(pdata, pid) \ |
76 | dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata) | 76 | dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid) |
77 | #define db8500_add_sdi5(pdata) \ | 77 | #define db8500_add_sdi5(pdata, pid) \ |
78 | dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata) | 78 | dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid) |
79 | 79 | ||
80 | #define db8500_add_ssp0(pdata) \ | 80 | #define db8500_add_ssp0(pdata) \ |
81 | db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) | 81 | db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) |
@@ -83,13 +83,13 @@ db8500_add_ssp(const char *name, resource_size_t base, int irq, | |||
83 | db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) | 83 | db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) |
84 | 84 | ||
85 | #define db8500_add_spi0(pdata) \ | 85 | #define db8500_add_spi0(pdata) \ |
86 | dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata) | 86 | dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0) |
87 | #define db8500_add_spi1(pdata) \ | 87 | #define db8500_add_spi1(pdata) \ |
88 | dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata) | 88 | dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0) |
89 | #define db8500_add_spi2(pdata) \ | 89 | #define db8500_add_spi2(pdata) \ |
90 | dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata) | 90 | dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0) |
91 | #define db8500_add_spi3(pdata) \ | 91 | #define db8500_add_spi3(pdata) \ |
92 | dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata) | 92 | dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0) |
93 | 93 | ||
94 | #define db8500_add_uart0(pdata) \ | 94 | #define db8500_add_uart0(pdata) \ |
95 | dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata) | 95 | dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata) |
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 2c6f71049f2e..470ac52663d6 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -29,9 +29,6 @@ | |||
29 | #include <mach/db8500-regs.h> | 29 | #include <mach/db8500-regs.h> |
30 | #include <mach/db5500-regs.h> | 30 | #include <mach/db5500-regs.h> |
31 | 31 | ||
32 | /* ST-Ericsson modified pl022 id */ | ||
33 | #define SSP_PER_ID 0x01080022 | ||
34 | |||
35 | #ifndef __ASSEMBLY__ | 32 | #ifndef __ASSEMBLY__ |
36 | 33 | ||
37 | #include <mach/id.h> | 34 | #include <mach/id.h> |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index c96fa1b3f49f..73b4a8b66a57 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
@@ -176,6 +176,7 @@ ENDPROC(v6_coherent_kern_range) | |||
176 | */ | 176 | */ |
177 | ENTRY(v6_flush_kern_dcache_area) | 177 | ENTRY(v6_flush_kern_dcache_area) |
178 | add r1, r0, r1 | 178 | add r1, r0, r1 |
179 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
179 | 1: | 180 | 1: |
180 | #ifdef HARVARD_CACHE | 181 | #ifdef HARVARD_CACHE |
181 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 182 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index dc18d81ef8ce..d32f02b61866 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -221,6 +221,8 @@ ENDPROC(v7_coherent_user_range) | |||
221 | ENTRY(v7_flush_kern_dcache_area) | 221 | ENTRY(v7_flush_kern_dcache_area) |
222 | dcache_line_size r2, r3 | 222 | dcache_line_size r2, r3 |
223 | add r1, r0, r1 | 223 | add r1, r0, r1 |
224 | sub r3, r2, #1 | ||
225 | bic r0, r0, r3 | ||
224 | 1: | 226 | 1: |
225 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line | 227 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line |
226 | add r0, r0, r2 | 228 | add r0, r0, r2 |
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index b0ee9ba3cfab..8bfae964b133 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c | |||
@@ -24,9 +24,7 @@ DEFINE_PER_CPU(struct mm_struct *, current_mm); | |||
24 | 24 | ||
25 | /* | 25 | /* |
26 | * We fork()ed a process, and we need a new context for the child | 26 | * We fork()ed a process, and we need a new context for the child |
27 | * to run in. We reserve version 0 for initial tasks so we will | 27 | * to run in. |
28 | * always allocate an ASID. The ASID 0 is reserved for the TTBR | ||
29 | * register changing sequence. | ||
30 | */ | 28 | */ |
31 | void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) | 29 | void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) |
32 | { | 30 | { |
@@ -36,8 +34,11 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) | |||
36 | 34 | ||
37 | static void flush_context(void) | 35 | static void flush_context(void) |
38 | { | 36 | { |
39 | /* set the reserved ASID before flushing the TLB */ | 37 | u32 ttb; |
40 | asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (0)); | 38 | /* Copy TTBR1 into TTBR0 */ |
39 | asm volatile("mrc p15, 0, %0, c2, c0, 1\n" | ||
40 | "mcr p15, 0, %0, c2, c0, 0" | ||
41 | : "=r" (ttb)); | ||
41 | isb(); | 42 | isb(); |
42 | local_flush_tlb_all(); | 43 | local_flush_tlb_all(); |
43 | if (icache_is_vivt_asid_tagged()) { | 44 | if (icache_is_vivt_asid_tagged()) { |
@@ -93,7 +94,7 @@ static void reset_context(void *info) | |||
93 | return; | 94 | return; |
94 | 95 | ||
95 | smp_rmb(); | 96 | smp_rmb(); |
96 | asid = cpu_last_asid + cpu + 1; | 97 | asid = cpu_last_asid + cpu; |
97 | 98 | ||
98 | flush_context(); | 99 | flush_context(); |
99 | set_mm_context(mm, asid); | 100 | set_mm_context(mm, asid); |
@@ -143,13 +144,13 @@ void __new_context(struct mm_struct *mm) | |||
143 | * to start a new version and flush the TLB. | 144 | * to start a new version and flush the TLB. |
144 | */ | 145 | */ |
145 | if (unlikely((asid & ~ASID_MASK) == 0)) { | 146 | if (unlikely((asid & ~ASID_MASK) == 0)) { |
146 | asid = cpu_last_asid + smp_processor_id() + 1; | 147 | asid = cpu_last_asid + smp_processor_id(); |
147 | flush_context(); | 148 | flush_context(); |
148 | #ifdef CONFIG_SMP | 149 | #ifdef CONFIG_SMP |
149 | smp_wmb(); | 150 | smp_wmb(); |
150 | smp_call_function(reset_context, NULL, 1); | 151 | smp_call_function(reset_context, NULL, 1); |
151 | #endif | 152 | #endif |
152 | cpu_last_asid += NR_CPUS; | 153 | cpu_last_asid += NR_CPUS - 1; |
153 | } | 154 | } |
154 | 155 | ||
155 | set_mm_context(mm, asid); | 156 | set_mm_context(mm, asid); |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 3f17ea146f0e..2c2cce9cd8c8 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -15,12 +15,14 @@ | |||
15 | #include <linux/mman.h> | 15 | #include <linux/mman.h> |
16 | #include <linux/nodemask.h> | 16 | #include <linux/nodemask.h> |
17 | #include <linux/initrd.h> | 17 | #include <linux/initrd.h> |
18 | #include <linux/of_fdt.h> | ||
18 | #include <linux/highmem.h> | 19 | #include <linux/highmem.h> |
19 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
20 | #include <linux/memblock.h> | 21 | #include <linux/memblock.h> |
21 | #include <linux/sort.h> | 22 | #include <linux/sort.h> |
22 | 23 | ||
23 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
25 | #include <asm/prom.h> | ||
24 | #include <asm/sections.h> | 26 | #include <asm/sections.h> |
25 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
26 | #include <asm/sizes.h> | 28 | #include <asm/sizes.h> |
@@ -71,6 +73,14 @@ static int __init parse_tag_initrd2(const struct tag *tag) | |||
71 | 73 | ||
72 | __tagtable(ATAG_INITRD2, parse_tag_initrd2); | 74 | __tagtable(ATAG_INITRD2, parse_tag_initrd2); |
73 | 75 | ||
76 | #ifdef CONFIG_OF_FLATTREE | ||
77 | void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end) | ||
78 | { | ||
79 | phys_initrd_start = start; | ||
80 | phys_initrd_size = end - start; | ||
81 | } | ||
82 | #endif /* CONFIG_OF_FLATTREE */ | ||
83 | |||
74 | /* | 84 | /* |
75 | * This keeps memory configuration data used by a couple memory | 85 | * This keeps memory configuration data used by a couple memory |
76 | * initialization functions, as well as show_mem() for the skipping | 86 | * initialization functions, as well as show_mem() for the skipping |
@@ -273,13 +283,15 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, | |||
273 | free_area_init_node(0, zone_size, min, zhole_size); | 283 | free_area_init_node(0, zone_size, min, zhole_size); |
274 | } | 284 | } |
275 | 285 | ||
276 | #ifndef CONFIG_SPARSEMEM | 286 | #ifdef CONFIG_HAVE_ARCH_PFN_VALID |
277 | int pfn_valid(unsigned long pfn) | 287 | int pfn_valid(unsigned long pfn) |
278 | { | 288 | { |
279 | return memblock_is_memory(pfn << PAGE_SHIFT); | 289 | return memblock_is_memory(pfn << PAGE_SHIFT); |
280 | } | 290 | } |
281 | EXPORT_SYMBOL(pfn_valid); | 291 | EXPORT_SYMBOL(pfn_valid); |
292 | #endif | ||
282 | 293 | ||
294 | #ifndef CONFIG_SPARSEMEM | ||
283 | static void arm_memory_present(void) | 295 | static void arm_memory_present(void) |
284 | { | 296 | { |
285 | } | 297 | } |
@@ -334,6 +346,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) | |||
334 | #endif | 346 | #endif |
335 | 347 | ||
336 | arm_mm_memblock_reserve(); | 348 | arm_mm_memblock_reserve(); |
349 | arm_dt_memblock_reserve(); | ||
337 | 350 | ||
338 | /* reserve any platform specific memblock areas */ | 351 | /* reserve any platform specific memblock areas */ |
339 | if (mdesc->reserve) | 352 | if (mdesc->reserve) |
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index d2384106af9c..5b3d7d543659 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h | |||
@@ -5,14 +5,9 @@ extern pmd_t *top_pmd; | |||
5 | 5 | ||
6 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | 6 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) |
7 | 7 | ||
8 | static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) | ||
9 | { | ||
10 | return pmd_offset(pud_offset(pgd, virt), virt); | ||
11 | } | ||
12 | |||
13 | static inline pmd_t *pmd_off_k(unsigned long virt) | 8 | static inline pmd_t *pmd_off_k(unsigned long virt) |
14 | { | 9 | { |
15 | return pmd_off(pgd_offset_k(virt), virt); | 10 | return pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt); |
16 | } | 11 | } |
17 | 12 | ||
18 | struct mem_type { | 13 | struct mem_type { |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 08a92368d9d3..9d9e736c2b4f 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -763,15 +763,12 @@ static void __init sanity_check_meminfo(void) | |||
763 | { | 763 | { |
764 | int i, j, highmem = 0; | 764 | int i, j, highmem = 0; |
765 | 765 | ||
766 | lowmem_limit = __pa(vmalloc_min - 1) + 1; | ||
767 | memblock_set_current_limit(lowmem_limit); | ||
768 | |||
769 | for (i = 0, j = 0; i < meminfo.nr_banks; i++) { | 766 | for (i = 0, j = 0; i < meminfo.nr_banks; i++) { |
770 | struct membank *bank = &meminfo.bank[j]; | 767 | struct membank *bank = &meminfo.bank[j]; |
771 | *bank = meminfo.bank[i]; | 768 | *bank = meminfo.bank[i]; |
772 | 769 | ||
773 | #ifdef CONFIG_HIGHMEM | 770 | #ifdef CONFIG_HIGHMEM |
774 | if (__va(bank->start) > vmalloc_min || | 771 | if (__va(bank->start) >= vmalloc_min || |
775 | __va(bank->start) < (void *)PAGE_OFFSET) | 772 | __va(bank->start) < (void *)PAGE_OFFSET) |
776 | highmem = 1; | 773 | highmem = 1; |
777 | 774 | ||
@@ -829,6 +826,9 @@ static void __init sanity_check_meminfo(void) | |||
829 | bank->size = newsize; | 826 | bank->size = newsize; |
830 | } | 827 | } |
831 | #endif | 828 | #endif |
829 | if (!bank->highmem && bank->start + bank->size > lowmem_limit) | ||
830 | lowmem_limit = bank->start + bank->size; | ||
831 | |||
832 | j++; | 832 | j++; |
833 | } | 833 | } |
834 | #ifdef CONFIG_HIGHMEM | 834 | #ifdef CONFIG_HIGHMEM |
@@ -852,6 +852,7 @@ static void __init sanity_check_meminfo(void) | |||
852 | } | 852 | } |
853 | #endif | 853 | #endif |
854 | meminfo.nr_banks = j; | 854 | meminfo.nr_banks = j; |
855 | memblock_set_current_limit(lowmem_limit); | ||
855 | } | 856 | } |
856 | 857 | ||
857 | static inline void prepare_page_table(void) | 858 | static inline void prepare_page_table(void) |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index ab17cc0d3fa7..1d2b8451bf25 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -213,7 +213,9 @@ __v6_setup: | |||
213 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register | 213 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register |
214 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) | 214 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) |
215 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) | 215 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) |
216 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 216 | ALT_SMP(orr r8, r8, #TTB_FLAGS_SMP) |
217 | ALT_UP(orr r8, r8, #TTB_FLAGS_UP) | ||
218 | mcr p15, 0, r8, c2, c0, 1 @ load TTB1 | ||
217 | #endif /* CONFIG_MMU */ | 219 | #endif /* CONFIG_MMU */ |
218 | adr r5, v6_crval | 220 | adr r5, v6_crval |
219 | ldmia r5, {r5, r6} | 221 | ldmia r5, {r5, r6} |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index babfba09c89f..b3b566ec83d3 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -108,18 +108,16 @@ ENTRY(cpu_v7_switch_mm) | |||
108 | #ifdef CONFIG_ARM_ERRATA_430973 | 108 | #ifdef CONFIG_ARM_ERRATA_430973 |
109 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 109 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
110 | #endif | 110 | #endif |
111 | #ifdef CONFIG_ARM_ERRATA_754322 | 111 | mrc p15, 0, r2, c2, c0, 1 @ load TTB 1 |
112 | dsb | 112 | mcr p15, 0, r2, c2, c0, 0 @ into TTB 0 |
113 | #endif | ||
114 | mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID | ||
115 | isb | ||
116 | 1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | ||
117 | isb | 113 | isb |
118 | #ifdef CONFIG_ARM_ERRATA_754322 | 114 | #ifdef CONFIG_ARM_ERRATA_754322 |
119 | dsb | 115 | dsb |
120 | #endif | 116 | #endif |
121 | mcr p15, 0, r1, c13, c0, 1 @ set context ID | 117 | mcr p15, 0, r1, c13, c0, 1 @ set context ID |
122 | isb | 118 | isb |
119 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | ||
120 | isb | ||
123 | #endif | 121 | #endif |
124 | mov pc, lr | 122 | mov pc, lr |
125 | ENDPROC(cpu_v7_switch_mm) | 123 | ENDPROC(cpu_v7_switch_mm) |
@@ -368,7 +366,9 @@ __v7_setup: | |||
368 | mcr p15, 0, r10, c2, c0, 2 @ TTB control register | 366 | mcr p15, 0, r10, c2, c0, 2 @ TTB control register |
369 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) | 367 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) |
370 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) | 368 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) |
371 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 369 | ALT_SMP(orr r8, r8, #TTB_FLAGS_SMP) |
370 | ALT_UP(orr r8, r8, #TTB_FLAGS_UP) | ||
371 | mcr p15, 0, r8, c2, c0, 1 @ load TTB1 | ||
372 | ldr r5, =PRRR @ PRRR | 372 | ldr r5, =PRRR @ PRRR |
373 | ldr r6, =NMRR @ NMRR | 373 | ldr r6, =NMRR @ NMRR |
374 | mcr p15, 0, r5, c10, c2, 0 @ write PRRR | 374 | mcr p15, 0, r5, c10, c2, 0 @ write PRRR |
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig index 18296ee68802..ce659015535e 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig | |||
@@ -21,9 +21,4 @@ config HAS_MTU | |||
21 | to multiple interrupt generating programmable | 21 | to multiple interrupt generating programmable |
22 | 32-bit free running decrementing counters. | 22 | 32-bit free running decrementing counters. |
23 | 23 | ||
24 | config NOMADIK_GPIO | ||
25 | bool | ||
26 | help | ||
27 | Support for the Nomadik GPIO controller. | ||
28 | |||
29 | endif | 24 | endif |
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile index c33547361bd7..37c7cdd0f8f0 100644 --- a/arch/arm/plat-nomadik/Makefile +++ b/arch/arm/plat-nomadik/Makefile | |||
@@ -3,4 +3,3 @@ | |||
3 | # Licensed under GPLv2 | 3 | # Licensed under GPLv2 |
4 | 4 | ||
5 | obj-$(CONFIG_HAS_MTU) += timer.o | 5 | obj-$(CONFIG_HAS_MTU) += timer.o |
6 | obj-$(CONFIG_NOMADIK_GPIO) += gpio.o | ||
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h index 1b9f6f0843d1..ea19a5b2f227 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio.h +++ b/arch/arm/plat-nomadik/include/plat/gpio.h | |||
@@ -78,6 +78,8 @@ extern int nmk_gpio_get_mode(int gpio); | |||
78 | extern void nmk_gpio_wakeups_suspend(void); | 78 | extern void nmk_gpio_wakeups_suspend(void); |
79 | extern void nmk_gpio_wakeups_resume(void); | 79 | extern void nmk_gpio_wakeups_resume(void); |
80 | 80 | ||
81 | extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up); | ||
82 | |||
81 | /* | 83 | /* |
82 | * Platform data to register a block: only the initial gpio/irq number. | 84 | * Platform data to register a block: only the initial gpio/irq number. |
83 | */ | 85 | */ |
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index a4a12859fdd5..f0233e6abcdf 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \ | 6 | obj-y := common.o sram.o clock.o devices.o dma.o mux.o \ |
7 | usb.o fb.o io.o counter_32k.o | 7 | usb.o fb.o io.o counter_32k.o |
8 | obj-m := | 8 | obj-m := |
9 | obj-n := | 9 | obj-n := |
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index cac2e8ac6968..ec97e00cb581 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h | |||
@@ -52,6 +52,109 @@ | |||
52 | 52 | ||
53 | #define OMAP34XX_NR_GPIOS 6 | 53 | #define OMAP34XX_NR_GPIOS 6 |
54 | 54 | ||
55 | /* | ||
56 | * OMAP1510 GPIO registers | ||
57 | */ | ||
58 | #define OMAP1510_GPIO_DATA_INPUT 0x00 | ||
59 | #define OMAP1510_GPIO_DATA_OUTPUT 0x04 | ||
60 | #define OMAP1510_GPIO_DIR_CONTROL 0x08 | ||
61 | #define OMAP1510_GPIO_INT_CONTROL 0x0c | ||
62 | #define OMAP1510_GPIO_INT_MASK 0x10 | ||
63 | #define OMAP1510_GPIO_INT_STATUS 0x14 | ||
64 | #define OMAP1510_GPIO_PIN_CONTROL 0x18 | ||
65 | |||
66 | #define OMAP1510_IH_GPIO_BASE 64 | ||
67 | |||
68 | /* | ||
69 | * OMAP1610 specific GPIO registers | ||
70 | */ | ||
71 | #define OMAP1610_GPIO_REVISION 0x0000 | ||
72 | #define OMAP1610_GPIO_SYSCONFIG 0x0010 | ||
73 | #define OMAP1610_GPIO_SYSSTATUS 0x0014 | ||
74 | #define OMAP1610_GPIO_IRQSTATUS1 0x0018 | ||
75 | #define OMAP1610_GPIO_IRQENABLE1 0x001c | ||
76 | #define OMAP1610_GPIO_WAKEUPENABLE 0x0028 | ||
77 | #define OMAP1610_GPIO_DATAIN 0x002c | ||
78 | #define OMAP1610_GPIO_DATAOUT 0x0030 | ||
79 | #define OMAP1610_GPIO_DIRECTION 0x0034 | ||
80 | #define OMAP1610_GPIO_EDGE_CTRL1 0x0038 | ||
81 | #define OMAP1610_GPIO_EDGE_CTRL2 0x003c | ||
82 | #define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c | ||
83 | #define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 | ||
84 | #define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 | ||
85 | #define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc | ||
86 | #define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 | ||
87 | #define OMAP1610_GPIO_SET_DATAOUT 0x00f0 | ||
88 | |||
89 | /* | ||
90 | * OMAP7XX specific GPIO registers | ||
91 | */ | ||
92 | #define OMAP7XX_GPIO_DATA_INPUT 0x00 | ||
93 | #define OMAP7XX_GPIO_DATA_OUTPUT 0x04 | ||
94 | #define OMAP7XX_GPIO_DIR_CONTROL 0x08 | ||
95 | #define OMAP7XX_GPIO_INT_CONTROL 0x0c | ||
96 | #define OMAP7XX_GPIO_INT_MASK 0x10 | ||
97 | #define OMAP7XX_GPIO_INT_STATUS 0x14 | ||
98 | |||
99 | /* | ||
100 | * omap2+ specific GPIO registers | ||
101 | */ | ||
102 | #define OMAP24XX_GPIO_REVISION 0x0000 | ||
103 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 | ||
104 | #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 | ||
105 | #define OMAP24XX_GPIO_IRQENABLE2 0x002c | ||
106 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c | ||
107 | #define OMAP24XX_GPIO_WAKE_EN 0x0020 | ||
108 | #define OMAP24XX_GPIO_CTRL 0x0030 | ||
109 | #define OMAP24XX_GPIO_OE 0x0034 | ||
110 | #define OMAP24XX_GPIO_DATAIN 0x0038 | ||
111 | #define OMAP24XX_GPIO_DATAOUT 0x003c | ||
112 | #define OMAP24XX_GPIO_LEVELDETECT0 0x0040 | ||
113 | #define OMAP24XX_GPIO_LEVELDETECT1 0x0044 | ||
114 | #define OMAP24XX_GPIO_RISINGDETECT 0x0048 | ||
115 | #define OMAP24XX_GPIO_FALLINGDETECT 0x004c | ||
116 | #define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 | ||
117 | #define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 | ||
118 | #define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 | ||
119 | #define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 | ||
120 | #define OMAP24XX_GPIO_CLEARWKUENA 0x0080 | ||
121 | #define OMAP24XX_GPIO_SETWKUENA 0x0084 | ||
122 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 | ||
123 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 | ||
124 | |||
125 | #define OMAP4_GPIO_REVISION 0x0000 | ||
126 | #define OMAP4_GPIO_EOI 0x0020 | ||
127 | #define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 | ||
128 | #define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 | ||
129 | #define OMAP4_GPIO_IRQSTATUS0 0x002c | ||
130 | #define OMAP4_GPIO_IRQSTATUS1 0x0030 | ||
131 | #define OMAP4_GPIO_IRQSTATUSSET0 0x0034 | ||
132 | #define OMAP4_GPIO_IRQSTATUSSET1 0x0038 | ||
133 | #define OMAP4_GPIO_IRQSTATUSCLR0 0x003c | ||
134 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 | ||
135 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 | ||
136 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 | ||
137 | #define OMAP4_GPIO_IRQENABLE1 0x011c | ||
138 | #define OMAP4_GPIO_WAKE_EN 0x0120 | ||
139 | #define OMAP4_GPIO_IRQSTATUS2 0x0128 | ||
140 | #define OMAP4_GPIO_IRQENABLE2 0x012c | ||
141 | #define OMAP4_GPIO_CTRL 0x0130 | ||
142 | #define OMAP4_GPIO_OE 0x0134 | ||
143 | #define OMAP4_GPIO_DATAIN 0x0138 | ||
144 | #define OMAP4_GPIO_DATAOUT 0x013c | ||
145 | #define OMAP4_GPIO_LEVELDETECT0 0x0140 | ||
146 | #define OMAP4_GPIO_LEVELDETECT1 0x0144 | ||
147 | #define OMAP4_GPIO_RISINGDETECT 0x0148 | ||
148 | #define OMAP4_GPIO_FALLINGDETECT 0x014c | ||
149 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 | ||
150 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 | ||
151 | #define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 | ||
152 | #define OMAP4_GPIO_SETIRQENABLE1 0x0164 | ||
153 | #define OMAP4_GPIO_CLEARWKUENA 0x0180 | ||
154 | #define OMAP4_GPIO_SETWKUENA 0x0184 | ||
155 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 | ||
156 | #define OMAP4_GPIO_SETDATAOUT 0x0194 | ||
157 | |||
55 | #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) | 158 | #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) |
56 | #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) | 159 | #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) |
57 | 160 | ||
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 6751bcf7b888..e98f5c5c7879 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | config PLAT_S5P | 8 | config PLAT_S5P |
9 | bool | 9 | bool |
10 | depends on (ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4) | 10 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4) |
11 | default y | 11 | default y |
12 | select ARM_VIC if !ARCH_EXYNOS4 | 12 | select ARM_VIC if !ARCH_EXYNOS4 |
13 | select ARM_GIC if ARCH_EXYNOS4 | 13 | select ARM_GIC if ARCH_EXYNOS4 |
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c index 5cf5e721e6ca..bbc2aa7449ca 100644 --- a/arch/arm/plat-s5p/cpu.c +++ b/arch/arm/plat-s5p/cpu.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <plat/cpu.h> | 22 | #include <plat/cpu.h> |
23 | #include <plat/s5p6440.h> | 23 | #include <plat/s5p6440.h> |
24 | #include <plat/s5p6442.h> | ||
25 | #include <plat/s5p6450.h> | 24 | #include <plat/s5p6450.h> |
26 | #include <plat/s5pc100.h> | 25 | #include <plat/s5pc100.h> |
27 | #include <plat/s5pv210.h> | 26 | #include <plat/s5pv210.h> |
@@ -30,7 +29,6 @@ | |||
30 | /* table of supported CPUs */ | 29 | /* table of supported CPUs */ |
31 | 30 | ||
32 | static const char name_s5p6440[] = "S5P6440"; | 31 | static const char name_s5p6440[] = "S5P6440"; |
33 | static const char name_s5p6442[] = "S5P6442"; | ||
34 | static const char name_s5p6450[] = "S5P6450"; | 32 | static const char name_s5p6450[] = "S5P6450"; |
35 | static const char name_s5pc100[] = "S5PC100"; | 33 | static const char name_s5pc100[] = "S5PC100"; |
36 | static const char name_s5pv210[] = "S5PV210/S5PC110"; | 34 | static const char name_s5pv210[] = "S5PV210/S5PC110"; |
@@ -46,14 +44,6 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
46 | .init = s5p64x0_init, | 44 | .init = s5p64x0_init, |
47 | .name = name_s5p6440, | 45 | .name = name_s5p6440, |
48 | }, { | 46 | }, { |
49 | .idcode = 0x36442000, | ||
50 | .idmask = 0xfffff000, | ||
51 | .map_io = s5p6442_map_io, | ||
52 | .init_clocks = s5p6442_init_clocks, | ||
53 | .init_uarts = s5p6442_init_uarts, | ||
54 | .init = s5p6442_init, | ||
55 | .name = name_s5p6442, | ||
56 | }, { | ||
57 | .idcode = 0x36450000, | 47 | .idcode = 0x36450000, |
58 | .idmask = 0xfffff000, | 48 | .idmask = 0xfffff000, |
59 | .map_io = s5p6450_map_io, | 49 | .map_io = s5p6450_map_io, |
diff --git a/arch/arm/plat-s5p/include/plat/s5p6442.h b/arch/arm/plat-s5p/include/plat/s5p6442.h deleted file mode 100644 index 7b8801349c94..000000000000 --- a/arch/arm/plat-s5p/include/plat/s5p6442.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* arch/arm/plat-s5p/include/plat/s5p6442.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Header file for s5p6442 cpu support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | /* Common init code for S5P6442 related SoCs */ | ||
14 | |||
15 | extern void s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
16 | extern void s5p6442_register_clocks(void); | ||
17 | extern void s5p6442_setup_clocks(void); | ||
18 | |||
19 | #ifdef CONFIG_CPU_S5P6442 | ||
20 | |||
21 | extern int s5p6442_init(void); | ||
22 | extern void s5p6442_init_irq(void); | ||
23 | extern void s5p6442_map_io(void); | ||
24 | extern void s5p6442_init_clocks(int xtal); | ||
25 | |||
26 | #define s5p6442_init_uarts s5p6442_common_init_uarts | ||
27 | |||
28 | #else | ||
29 | #define s5p6442_init_clocks NULL | ||
30 | #define s5p6442_init_uarts NULL | ||
31 | #define s5p6442_map_io NULL | ||
32 | #define s5p6442_init NULL | ||
33 | #endif | ||
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index e9de58a2e294..53eb15b0a07d 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
@@ -19,7 +19,6 @@ obj-y += gpio.o | |||
19 | obj-y += gpio-config.o | 19 | obj-y += gpio-config.o |
20 | obj-y += dev-asocdma.o | 20 | obj-y += dev-asocdma.o |
21 | 21 | ||
22 | obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o | ||
23 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o | 22 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o |
24 | 23 | ||
25 | obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o | 24 | obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o |
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 3aedac0034ba..c0a5741b23e6 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h | |||
@@ -86,7 +86,6 @@ extern struct sysdev_class s3c2443_sysclass; | |||
86 | extern struct sysdev_class s3c6410_sysclass; | 86 | extern struct sysdev_class s3c6410_sysclass; |
87 | extern struct sysdev_class s3c64xx_sysclass; | 87 | extern struct sysdev_class s3c64xx_sysclass; |
88 | extern struct sysdev_class s5p64x0_sysclass; | 88 | extern struct sysdev_class s5p64x0_sysclass; |
89 | extern struct sysdev_class s5p6442_sysclass; | ||
90 | extern struct sysdev_class s5pv210_sysclass; | 89 | extern struct sysdev_class s5pv210_sysclass; |
91 | extern struct sysdev_class exynos4_sysclass; | 90 | extern struct sysdev_class exynos4_sysclass; |
92 | 91 | ||
diff --git a/arch/arm/plat-samsung/include/plat/debug-macro.S b/arch/arm/plat-samsung/include/plat/debug-macro.S index dc6efd90e8ff..207e275362a8 100644 --- a/arch/arm/plat-samsung/include/plat/debug-macro.S +++ b/arch/arm/plat-samsung/include/plat/debug-macro.S | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #include <plat/regs-serial.h> | 12 | #include <plat/regs-serial.h> |
13 | 13 | ||
14 | /* The S5PV210/S5PC110 and S5P6442 implementations are as belows. */ | 14 | /* The S5PV210/S5PC110 implementations are as belows. */ |
15 | 15 | ||
16 | .macro fifo_level_s5pv210 rd, rx | 16 | .macro fifo_level_s5pv210 rd, rx |
17 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] | 17 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] |
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 39818d8da420..b61b8ee7cc52 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h | |||
@@ -111,12 +111,6 @@ extern struct platform_device exynos4_device_spdif; | |||
111 | extern struct platform_device exynos4_device_pd[]; | 111 | extern struct platform_device exynos4_device_pd[]; |
112 | extern struct platform_device exynos4_device_ahci; | 112 | extern struct platform_device exynos4_device_ahci; |
113 | 113 | ||
114 | extern struct platform_device s5p6442_device_pcm0; | ||
115 | extern struct platform_device s5p6442_device_pcm1; | ||
116 | extern struct platform_device s5p6442_device_iis0; | ||
117 | extern struct platform_device s5p6442_device_iis1; | ||
118 | extern struct platform_device s5p6442_device_spi; | ||
119 | |||
120 | extern struct platform_device s5p6440_device_pcm; | 114 | extern struct platform_device s5p6440_device_pcm; |
121 | extern struct platform_device s5p6440_device_iis; | 115 | extern struct platform_device s5p6440_device_iis; |
122 | 116 | ||
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index 788837e99cb3..c151c5f94a87 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h | |||
@@ -194,7 +194,7 @@ | |||
194 | #define S3C64XX_UINTSP 0x34 | 194 | #define S3C64XX_UINTSP 0x34 |
195 | #define S3C64XX_UINTM 0x38 | 195 | #define S3C64XX_UINTM 0x38 |
196 | 196 | ||
197 | /* Following are specific to S5PV210 and S5P6442 */ | 197 | /* Following are specific to S5PV210 */ |
198 | #define S5PV210_UCON_CLKMASK (1<<10) | 198 | #define S5PV210_UCON_CLKMASK (1<<10) |
199 | #define S5PV210_UCON_PCLK (0<<10) | 199 | #define S5PV210_UCON_PCLK (0<<10) |
200 | #define S5PV210_UCON_UCLK (1<<10) | 200 | #define S5PV210_UCON_UCLK (1<<10) |
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index ff1a561b326e..0ffe34a21554 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | |||
@@ -69,6 +69,5 @@ extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | |||
69 | extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | 69 | extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); |
70 | extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | 70 | extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); |
71 | extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | 71 | extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); |
72 | extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); | ||
73 | 72 | ||
74 | #endif /* __S3C64XX_PLAT_SPI_H */ | 73 | #endif /* __S3C64XX_PLAT_SPI_H */ |
diff --git a/arch/avr32/include/asm/unistd.h b/arch/avr32/include/asm/unistd.h index 89861a27543e..f714544e5560 100644 --- a/arch/avr32/include/asm/unistd.h +++ b/arch/avr32/include/asm/unistd.h | |||
@@ -299,9 +299,10 @@ | |||
299 | #define __NR_signalfd 279 | 299 | #define __NR_signalfd 279 |
300 | /* 280 was __NR_timerfd */ | 300 | /* 280 was __NR_timerfd */ |
301 | #define __NR_eventfd 281 | 301 | #define __NR_eventfd 281 |
302 | #define __NR_setns 283 | ||
302 | 303 | ||
303 | #ifdef __KERNEL__ | 304 | #ifdef __KERNEL__ |
304 | #define NR_syscalls 282 | 305 | #define NR_syscalls 284 |
305 | 306 | ||
306 | /* Old stuff */ | 307 | /* Old stuff */ |
307 | #define __IGNORE_uselib | 308 | #define __IGNORE_uselib |
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index e76bad16b0f0..c7fd394d28a4 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S | |||
@@ -296,4 +296,5 @@ sys_call_table: | |||
296 | .long sys_ni_syscall /* 280, was sys_timerfd */ | 296 | .long sys_ni_syscall /* 280, was sys_timerfd */ |
297 | .long sys_eventfd | 297 | .long sys_eventfd |
298 | .long sys_recvmmsg | 298 | .long sys_recvmmsg |
299 | .long sys_setns | ||
299 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ | 300 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ |
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index bfc9d071db9b..aa677e2a3823 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
@@ -1014,6 +1014,7 @@ static struct platform_device *__initdata at32_usarts[4]; | |||
1014 | void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags) | 1014 | void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags) |
1015 | { | 1015 | { |
1016 | struct platform_device *pdev; | 1016 | struct platform_device *pdev; |
1017 | struct atmel_uart_data *pdata; | ||
1017 | 1018 | ||
1018 | switch (hw_id) { | 1019 | switch (hw_id) { |
1019 | case 0: | 1020 | case 0: |
@@ -1042,7 +1043,8 @@ void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags) | |||
1042 | data->regs = (void __iomem *)pdev->resource[0].start; | 1043 | data->regs = (void __iomem *)pdev->resource[0].start; |
1043 | } | 1044 | } |
1044 | 1045 | ||
1045 | pdev->id = line; | 1046 | pdata = pdev->dev.platform_data; |
1047 | pdata->num = portnr; | ||
1046 | at32_usarts[line] = pdev; | 1048 | at32_usarts[line] = pdev; |
1047 | } | 1049 | } |
1048 | 1050 | ||
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index 61740201b311..679458d9a622 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h | |||
@@ -33,6 +33,7 @@ extern struct platform_device *atmel_default_console_device; | |||
33 | #define ATMEL_USART_CLK 0x04 | 33 | #define ATMEL_USART_CLK 0x04 |
34 | 34 | ||
35 | struct atmel_uart_data { | 35 | struct atmel_uart_data { |
36 | int num; /* port num */ | ||
36 | short use_dma_tx; /* use transmit DMA? */ | 37 | short use_dma_tx; /* use transmit DMA? */ |
37 | short use_dma_rx; /* use receive DMA? */ | 38 | short use_dma_rx; /* use receive DMA? */ |
38 | void __iomem *regs; /* virtual base address, if any */ | 39 | void __iomem *regs; /* virtual base address, if any */ |
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h index 7dbc664eab1e..7fd0ec7b5b0f 100644 --- a/arch/blackfin/include/asm/bfin_serial.h +++ b/arch/blackfin/include/asm/bfin_serial.h | |||
@@ -184,7 +184,7 @@ struct bfin_uart_regs { | |||
184 | #undef __BFP | 184 | #undef __BFP |
185 | 185 | ||
186 | #ifndef port_membase | 186 | #ifndef port_membase |
187 | # define port_membase(p) (((struct bfin_serial_port *)(p))->port.membase) | 187 | # define port_membase(p) 0 |
188 | #endif | 188 | #endif |
189 | 189 | ||
190 | #define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR) | 190 | #define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR) |
@@ -235,10 +235,10 @@ struct bfin_uart_regs { | |||
235 | #define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0) | 235 | #define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0) |
236 | 236 | ||
237 | #ifndef put_lsr_cache | 237 | #ifndef put_lsr_cache |
238 | # define put_lsr_cache(p, v) (((struct bfin_serial_port *)(p))->lsr = (v)) | 238 | # define put_lsr_cache(p, v) |
239 | #endif | 239 | #endif |
240 | #ifndef get_lsr_cache | 240 | #ifndef get_lsr_cache |
241 | # define get_lsr_cache(p) (((struct bfin_serial_port *)(p))->lsr) | 241 | # define get_lsr_cache(p) 0 |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | /* The hardware clears the LSR bits upon read, so we need to cache | 244 | /* The hardware clears the LSR bits upon read, so we need to cache |
diff --git a/arch/blackfin/include/asm/gptimers.h b/arch/blackfin/include/asm/gptimers.h index c722acdda0d3..38657dac1235 100644 --- a/arch/blackfin/include/asm/gptimers.h +++ b/arch/blackfin/include/asm/gptimers.h | |||
@@ -193,4 +193,22 @@ uint16_t get_enabled_gptimers(void); | |||
193 | uint32_t get_gptimer_status(unsigned int group); | 193 | uint32_t get_gptimer_status(unsigned int group); |
194 | void set_gptimer_status(unsigned int group, uint32_t value); | 194 | void set_gptimer_status(unsigned int group, uint32_t value); |
195 | 195 | ||
196 | /* | ||
197 | * All Blackfin system MMRs are padded to 32bits even if the register | ||
198 | * itself is only 16bits. So use a helper macro to streamline this. | ||
199 | */ | ||
200 | #define __BFP(m) u16 m; u16 __pad_##m | ||
201 | |||
202 | /* | ||
203 | * bfin timer registers layout | ||
204 | */ | ||
205 | struct bfin_gptimer_regs { | ||
206 | __BFP(config); | ||
207 | u32 counter; | ||
208 | u32 period; | ||
209 | u32 width; | ||
210 | }; | ||
211 | |||
212 | #undef __BFP | ||
213 | |||
196 | #endif | 214 | #endif |
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index ff9a9f35d50b..0ccba60b9ccf 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h | |||
@@ -397,8 +397,10 @@ | |||
397 | #define __NR_open_by_handle_at 376 | 397 | #define __NR_open_by_handle_at 376 |
398 | #define __NR_clock_adjtime 377 | 398 | #define __NR_clock_adjtime 377 |
399 | #define __NR_syncfs 378 | 399 | #define __NR_syncfs 378 |
400 | #define __NR_setns 379 | ||
401 | #define __NR_sendmmsg 380 | ||
400 | 402 | ||
401 | #define __NR_syscall 379 | 403 | #define __NR_syscall 381 |
402 | #define NR_syscalls __NR_syscall | 404 | #define NR_syscalls __NR_syscall |
403 | 405 | ||
404 | /* Old optional stuff no one actually uses */ | 406 | /* Old optional stuff no one actually uses */ |
diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c index 94b1d8a0256a..fce4807ceef9 100644 --- a/arch/blackfin/kernel/debug-mmrs.c +++ b/arch/blackfin/kernel/debug-mmrs.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <asm/blackfin.h> | 14 | #include <asm/blackfin.h> |
15 | #include <asm/gpio.h> | 15 | #include <asm/gpio.h> |
16 | #include <asm/gptimers.h> | ||
16 | #include <asm/bfin_can.h> | 17 | #include <asm/bfin_can.h> |
17 | #include <asm/bfin_dma.h> | 18 | #include <asm/bfin_dma.h> |
18 | #include <asm/bfin_ppi.h> | 19 | #include <asm/bfin_ppi.h> |
@@ -230,8 +231,8 @@ bfin_debug_mmrs_dma(struct dentry *parent, unsigned long base, int num, char mdm | |||
230 | #define DMA(num) _DMA(num, DMA##num##_NEXT_DESC_PTR, 0, "") | 231 | #define DMA(num) _DMA(num, DMA##num##_NEXT_DESC_PTR, 0, "") |
231 | #define _MDMA(num, x) \ | 232 | #define _MDMA(num, x) \ |
232 | do { \ | 233 | do { \ |
233 | _DMA(num, x##DMA_D##num##_CONFIG, 'D', #x); \ | 234 | _DMA(num, x##DMA_D##num##_NEXT_DESC_PTR, 'D', #x); \ |
234 | _DMA(num, x##DMA_S##num##_CONFIG, 'S', #x); \ | 235 | _DMA(num, x##DMA_S##num##_NEXT_DESC_PTR, 'S', #x); \ |
235 | } while (0) | 236 | } while (0) |
236 | #define MDMA(num) _MDMA(num, M) | 237 | #define MDMA(num) _MDMA(num, M) |
237 | #define IMDMA(num) _MDMA(num, IM) | 238 | #define IMDMA(num) _MDMA(num, IM) |
@@ -264,20 +265,15 @@ bfin_debug_mmrs_eppi(struct dentry *parent, unsigned long base, int num) | |||
264 | /* | 265 | /* |
265 | * General Purpose Timers | 266 | * General Purpose Timers |
266 | */ | 267 | */ |
267 | #define GPTIMER_OFF(mmr) (TIMER0_##mmr - TIMER0_CONFIG) | 268 | #define __GPTIMER(uname, lname) __REGS(gptimer, #uname, lname) |
268 | #define __GPTIMER(name) \ | ||
269 | do { \ | ||
270 | strcpy(_buf, #name); \ | ||
271 | debugfs_create_x16(buf, S_IRUSR|S_IWUSR, parent, (u16 *)(base + GPTIMER_OFF(name))); \ | ||
272 | } while (0) | ||
273 | static void __init __maybe_unused | 269 | static void __init __maybe_unused |
274 | bfin_debug_mmrs_gptimer(struct dentry *parent, unsigned long base, int num) | 270 | bfin_debug_mmrs_gptimer(struct dentry *parent, unsigned long base, int num) |
275 | { | 271 | { |
276 | char buf[32], *_buf = REGS_STR_PFX(buf, TIMER, num); | 272 | char buf[32], *_buf = REGS_STR_PFX(buf, TIMER, num); |
277 | __GPTIMER(CONFIG); | 273 | __GPTIMER(CONFIG, config); |
278 | __GPTIMER(COUNTER); | 274 | __GPTIMER(COUNTER, counter); |
279 | __GPTIMER(PERIOD); | 275 | __GPTIMER(PERIOD, period); |
280 | __GPTIMER(WIDTH); | 276 | __GPTIMER(WIDTH, width); |
281 | } | 277 | } |
282 | #define GPTIMER(num) bfin_debug_mmrs_gptimer(parent, TIMER##num##_CONFIG, num) | 278 | #define GPTIMER(num) bfin_debug_mmrs_gptimer(parent, TIMER##num##_CONFIG, num) |
283 | 279 | ||
@@ -355,7 +351,7 @@ bfin_debug_mmrs_ppi(struct dentry *parent, unsigned long base, int num) | |||
355 | __PPI(DELAY, delay); | 351 | __PPI(DELAY, delay); |
356 | __PPI(FRAME, frame); | 352 | __PPI(FRAME, frame); |
357 | } | 353 | } |
358 | #define PPI(num) bfin_debug_mmrs_ppi(parent, PPI##num##_STATUS, num) | 354 | #define PPI(num) bfin_debug_mmrs_ppi(parent, PPI##num##_CONTROL, num) |
359 | 355 | ||
360 | /* | 356 | /* |
361 | * SPI | 357 | * SPI |
@@ -1288,15 +1284,15 @@ static int __init bfin_debug_mmrs_init(void) | |||
1288 | D16(VR_CTL); | 1284 | D16(VR_CTL); |
1289 | D32(CHIPID); /* it's part of this hardware block */ | 1285 | D32(CHIPID); /* it's part of this hardware block */ |
1290 | 1286 | ||
1291 | #if defined(PPI_STATUS) || defined(PPI0_STATUS) || defined(PPI1_STATUS) | 1287 | #if defined(PPI_CONTROL) || defined(PPI0_CONTROL) || defined(PPI1_CONTROL) |
1292 | parent = debugfs_create_dir("ppi", top); | 1288 | parent = debugfs_create_dir("ppi", top); |
1293 | # ifdef PPI_STATUS | 1289 | # ifdef PPI_CONTROL |
1294 | bfin_debug_mmrs_ppi(parent, PPI_STATUS, -1); | 1290 | bfin_debug_mmrs_ppi(parent, PPI_CONTROL, -1); |
1295 | # endif | 1291 | # endif |
1296 | # ifdef PPI0_STATUS | 1292 | # ifdef PPI0_CONTROL |
1297 | PPI(0); | 1293 | PPI(0); |
1298 | # endif | 1294 | # endif |
1299 | # ifdef PPI1_STATUS | 1295 | # ifdef PPI1_CONTROL |
1300 | PPI(1); | 1296 | PPI(1); |
1301 | # endif | 1297 | # endif |
1302 | #endif | 1298 | #endif |
@@ -1341,6 +1337,10 @@ static int __init bfin_debug_mmrs_init(void) | |||
1341 | D16(RSI_PID1); | 1337 | D16(RSI_PID1); |
1342 | D16(RSI_PID2); | 1338 | D16(RSI_PID2); |
1343 | D16(RSI_PID3); | 1339 | D16(RSI_PID3); |
1340 | D16(RSI_PID4); | ||
1341 | D16(RSI_PID5); | ||
1342 | D16(RSI_PID6); | ||
1343 | D16(RSI_PID7); | ||
1344 | D16(RSI_PWR_CONTROL); | 1344 | D16(RSI_PWR_CONTROL); |
1345 | D16(RSI_RD_WAIT_EN); | 1345 | D16(RSI_RD_WAIT_EN); |
1346 | D32(RSI_RESPONSE0); | 1346 | D32(RSI_RESPONSE0); |
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h deleted file mode 100644 index f6d924ac0c44..000000000000 --- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define DRIVER_NAME "bfin-uart" | ||
78 | |||
79 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h index 98a51c479290..cfab428e577c 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF514.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h | |||
@@ -36,13 +36,13 @@ | |||
36 | #define RSI_EMASK 0xFFC038C4 /* RSI Exception Mask Register */ | 36 | #define RSI_EMASK 0xFFC038C4 /* RSI Exception Mask Register */ |
37 | #define RSI_CONFIG 0xFFC038C8 /* RSI Configuration Register */ | 37 | #define RSI_CONFIG 0xFFC038C8 /* RSI Configuration Register */ |
38 | #define RSI_RD_WAIT_EN 0xFFC038CC /* RSI Read Wait Enable Register */ | 38 | #define RSI_RD_WAIT_EN 0xFFC038CC /* RSI Read Wait Enable Register */ |
39 | #define RSI_PID0 0xFFC03FE0 /* RSI Peripheral ID Register 0 */ | 39 | #define RSI_PID0 0xFFC038D0 /* RSI Peripheral ID Register 0 */ |
40 | #define RSI_PID1 0xFFC03FE4 /* RSI Peripheral ID Register 1 */ | 40 | #define RSI_PID1 0xFFC038D4 /* RSI Peripheral ID Register 1 */ |
41 | #define RSI_PID2 0xFFC03FE8 /* RSI Peripheral ID Register 2 */ | 41 | #define RSI_PID2 0xFFC038D8 /* RSI Peripheral ID Register 2 */ |
42 | #define RSI_PID3 0xFFC03FEC /* RSI Peripheral ID Register 3 */ | 42 | #define RSI_PID3 0xFFC038DC /* RSI Peripheral ID Register 3 */ |
43 | #define RSI_PID4 0xFFC03FF0 /* RSI Peripheral ID Register 4 */ | 43 | #define RSI_PID4 0xFFC038E0 /* RSI Peripheral ID Register 0 */ |
44 | #define RSI_PID5 0xFFC03FF4 /* RSI Peripheral ID Register 5 */ | 44 | #define RSI_PID5 0xFFC038E4 /* RSI Peripheral ID Register 1 */ |
45 | #define RSI_PID6 0xFFC03FF8 /* RSI Peripheral ID Register 6 */ | 45 | #define RSI_PID6 0xFFC038E8 /* RSI Peripheral ID Register 2 */ |
46 | #define RSI_PID7 0xFFC03FFC /* RSI Peripheral ID Register 7 */ | 46 | #define RSI_PID7 0xFFC038EC /* RSI Peripheral ID Register 3 */ |
47 | 47 | ||
48 | #endif /* _DEF_BF514_H */ | 48 | #endif /* _DEF_BF514_H */ |
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 960e08919def..000000000000 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2007-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define DRIVER_NAME "bfin-uart" | ||
78 | |||
79 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h index cc383adfdffa..aab80bb1a683 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF525.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h | |||
@@ -185,8 +185,8 @@ | |||
185 | #define USB_EP_NI7_TXTYPE 0xffc03bd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ | 185 | #define USB_EP_NI7_TXTYPE 0xffc03bd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ |
186 | #define USB_EP_NI7_TXINTERVAL 0xffc03bd8 /* Sets the NAK response timeout on Endpoint7 */ | 186 | #define USB_EP_NI7_TXINTERVAL 0xffc03bd8 /* Sets the NAK response timeout on Endpoint7 */ |
187 | #define USB_EP_NI7_RXTYPE 0xffc03bdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ | 187 | #define USB_EP_NI7_RXTYPE 0xffc03bdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ |
188 | #define USB_EP_NI7_RXINTERVAL 0xffc03bf0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ | 188 | #define USB_EP_NI7_RXINTERVAL 0xffc03be0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ |
189 | #define USB_EP_NI7_TXCOUNT 0xffc03bf8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ | 189 | #define USB_EP_NI7_TXCOUNT 0xffc03be8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ |
190 | 190 | ||
191 | #define USB_DMA_INTERRUPT 0xffc03c00 /* Indicates pending interrupts for the DMA channels */ | 191 | #define USB_DMA_INTERRUPT 0xffc03c00 /* Indicates pending interrupts for the DMA channels */ |
192 | 192 | ||
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 45dcaa4f3e41..000000000000 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #ifdef CONFIG_BFIN_UART0_CTSRTS | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | # ifndef CONFIG_UART0_CTS_PIN | ||
13 | # define CONFIG_UART0_CTS_PIN -1 | ||
14 | # endif | ||
15 | # ifndef CONFIG_UART0_RTS_PIN | ||
16 | # define CONFIG_UART0_RTS_PIN -1 | ||
17 | # endif | ||
18 | #endif | ||
19 | |||
20 | struct bfin_serial_res { | ||
21 | unsigned long uart_base_addr; | ||
22 | int uart_irq; | ||
23 | int uart_status_irq; | ||
24 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
25 | unsigned int uart_tx_dma_channel; | ||
26 | unsigned int uart_rx_dma_channel; | ||
27 | #endif | ||
28 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
29 | int uart_cts_pin; | ||
30 | int uart_rts_pin; | ||
31 | #endif | ||
32 | }; | ||
33 | |||
34 | struct bfin_serial_res bfin_serial_resource[] = { | ||
35 | { | ||
36 | 0xFFC00400, | ||
37 | IRQ_UART0_RX, | ||
38 | IRQ_UART0_ERROR, | ||
39 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
40 | CH_UART0_TX, | ||
41 | CH_UART0_RX, | ||
42 | #endif | ||
43 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
44 | CONFIG_UART0_CTS_PIN, | ||
45 | CONFIG_UART0_RTS_PIN, | ||
46 | #endif | ||
47 | } | ||
48 | }; | ||
49 | |||
50 | #define DRIVER_NAME "bfin-uart" | ||
51 | |||
52 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index e16dc4560048..76db1d483173 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c | |||
@@ -382,7 +382,6 @@ static struct platform_device net2272_bfin_device = { | |||
382 | #endif | 382 | #endif |
383 | 383 | ||
384 | #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 384 | #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) |
385 | #ifdef CONFIG_MTD_PARTITIONS | ||
386 | const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; | 385 | const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; |
387 | 386 | ||
388 | static struct mtd_partition bfin_plat_nand_partitions[] = { | 387 | static struct mtd_partition bfin_plat_nand_partitions[] = { |
@@ -396,7 +395,6 @@ static struct mtd_partition bfin_plat_nand_partitions[] = { | |||
396 | .offset = MTDPART_OFS_APPEND, | 395 | .offset = MTDPART_OFS_APPEND, |
397 | }, | 396 | }, |
398 | }; | 397 | }; |
399 | #endif | ||
400 | 398 | ||
401 | #define BFIN_NAND_PLAT_CLE 2 | 399 | #define BFIN_NAND_PLAT_CLE 2 |
402 | #define BFIN_NAND_PLAT_ALE 1 | 400 | #define BFIN_NAND_PLAT_ALE 1 |
@@ -423,11 +421,9 @@ static struct platform_nand_data bfin_plat_nand_data = { | |||
423 | .chip = { | 421 | .chip = { |
424 | .nr_chips = 1, | 422 | .nr_chips = 1, |
425 | .chip_delay = 30, | 423 | .chip_delay = 30, |
426 | #ifdef CONFIG_MTD_PARTITIONS | ||
427 | .part_probe_types = part_probes, | 424 | .part_probe_types = part_probes, |
428 | .partitions = bfin_plat_nand_partitions, | 425 | .partitions = bfin_plat_nand_partitions, |
429 | .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), | 426 | .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), |
430 | #endif | ||
431 | }, | 427 | }, |
432 | .ctrl = { | 428 | .ctrl = { |
433 | .cmd_ctrl = bfin_plat_nand_cmd_ctrl, | 429 | .cmd_ctrl = bfin_plat_nand_cmd_ctrl, |
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 3e955dba8951..000000000000 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define DRIVER_NAME "bfin-uart" | ||
78 | |||
79 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h deleted file mode 100644 index beb502e9cb33..000000000000 --- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | #ifdef CONFIG_SERIAL_BFIN_UART2 | ||
76 | { | ||
77 | 0xFFC02100, | ||
78 | IRQ_UART2_RX, | ||
79 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
80 | CH_UART2_TX, | ||
81 | CH_UART2_RX, | ||
82 | #endif | ||
83 | #ifdef CONFIG_BFIN_UART2_CTSRTS | ||
84 | CONFIG_UART2_CTS_PIN, | ||
85 | CONFIG_UART2_RTS_PIN, | ||
86 | #endif | ||
87 | }, | ||
88 | #endif | ||
89 | }; | ||
90 | |||
91 | #define DRIVER_NAME "bfin-uart" | ||
92 | |||
93 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 0d94edaaaa2e..000000000000 --- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2007-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \ | ||
11 | defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS) | ||
12 | # define CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
13 | #endif | ||
14 | |||
15 | struct bfin_serial_res { | ||
16 | unsigned long uart_base_addr; | ||
17 | int uart_irq; | ||
18 | int uart_status_irq; | ||
19 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
20 | unsigned int uart_tx_dma_channel; | ||
21 | unsigned int uart_rx_dma_channel; | ||
22 | #endif | ||
23 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
24 | int uart_cts_pin; | ||
25 | int uart_rts_pin; | ||
26 | #endif | ||
27 | }; | ||
28 | |||
29 | struct bfin_serial_res bfin_serial_resource[] = { | ||
30 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
31 | { | ||
32 | 0xFFC00400, | ||
33 | IRQ_UART0_RX, | ||
34 | IRQ_UART0_ERROR, | ||
35 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
36 | CH_UART0_TX, | ||
37 | CH_UART0_RX, | ||
38 | #endif | ||
39 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
40 | 0, | ||
41 | 0, | ||
42 | #endif | ||
43 | }, | ||
44 | #endif | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
46 | { | ||
47 | 0xFFC02000, | ||
48 | IRQ_UART1_RX, | ||
49 | IRQ_UART1_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART1_TX, | ||
52 | CH_UART1_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
55 | GPIO_PE10, | ||
56 | GPIO_PE9, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART2 | ||
61 | { | ||
62 | 0xFFC02100, | ||
63 | IRQ_UART2_RX, | ||
64 | IRQ_UART2_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART2_TX, | ||
67 | CH_UART2_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
70 | 0, | ||
71 | 0, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | #ifdef CONFIG_SERIAL_BFIN_UART3 | ||
76 | { | ||
77 | 0xFFC03100, | ||
78 | IRQ_UART3_RX, | ||
79 | IRQ_UART3_ERROR, | ||
80 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
81 | CH_UART3_TX, | ||
82 | CH_UART3_RX, | ||
83 | #endif | ||
84 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
85 | GPIO_PB3, | ||
86 | GPIO_PB2, | ||
87 | #endif | ||
88 | }, | ||
89 | #endif | ||
90 | }; | ||
91 | |||
92 | #define DRIVER_NAME "bfin-uart" | ||
93 | |||
94 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h index 1cbba115f96f..1fa41ec03f31 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF547.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h | |||
@@ -271,10 +271,10 @@ | |||
271 | #define USB_EP_NI0_TXINTERVAL 0xffc03e18 /* Sets the NAK response timeout on Endpoint 0 */ | 271 | #define USB_EP_NI0_TXINTERVAL 0xffc03e18 /* Sets the NAK response timeout on Endpoint 0 */ |
272 | #define USB_EP_NI0_RXTYPE 0xffc03e1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ | 272 | #define USB_EP_NI0_RXTYPE 0xffc03e1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ |
273 | #define USB_EP_NI0_RXINTERVAL 0xffc03e20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ | 273 | #define USB_EP_NI0_RXINTERVAL 0xffc03e20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ |
274 | #define USB_EP_NI0_TXCOUNT 0xffc03e28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ | ||
274 | 275 | ||
275 | /* USB Endpoint 1 Control Registers */ | 276 | /* USB Endpoint 1 Control Registers */ |
276 | 277 | ||
277 | #define USB_EP_NI0_TXCOUNT 0xffc03e28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ | ||
278 | #define USB_EP_NI1_TXMAXP 0xffc03e40 /* Maximum packet size for Host Tx endpoint1 */ | 278 | #define USB_EP_NI1_TXMAXP 0xffc03e40 /* Maximum packet size for Host Tx endpoint1 */ |
279 | #define USB_EP_NI1_TXCSR 0xffc03e44 /* Control Status register for endpoint1 */ | 279 | #define USB_EP_NI1_TXCSR 0xffc03e44 /* Control Status register for endpoint1 */ |
280 | #define USB_EP_NI1_RXMAXP 0xffc03e48 /* Maximum packet size for Host Rx endpoint1 */ | 280 | #define USB_EP_NI1_RXMAXP 0xffc03e48 /* Maximum packet size for Host Rx endpoint1 */ |
@@ -284,10 +284,10 @@ | |||
284 | #define USB_EP_NI1_TXINTERVAL 0xffc03e58 /* Sets the NAK response timeout on Endpoint1 */ | 284 | #define USB_EP_NI1_TXINTERVAL 0xffc03e58 /* Sets the NAK response timeout on Endpoint1 */ |
285 | #define USB_EP_NI1_RXTYPE 0xffc03e5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ | 285 | #define USB_EP_NI1_RXTYPE 0xffc03e5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ |
286 | #define USB_EP_NI1_RXINTERVAL 0xffc03e60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ | 286 | #define USB_EP_NI1_RXINTERVAL 0xffc03e60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ |
287 | #define USB_EP_NI1_TXCOUNT 0xffc03e68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ | ||
287 | 288 | ||
288 | /* USB Endpoint 2 Control Registers */ | 289 | /* USB Endpoint 2 Control Registers */ |
289 | 290 | ||
290 | #define USB_EP_NI1_TXCOUNT 0xffc03e68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ | ||
291 | #define USB_EP_NI2_TXMAXP 0xffc03e80 /* Maximum packet size for Host Tx endpoint2 */ | 291 | #define USB_EP_NI2_TXMAXP 0xffc03e80 /* Maximum packet size for Host Tx endpoint2 */ |
292 | #define USB_EP_NI2_TXCSR 0xffc03e84 /* Control Status register for endpoint2 */ | 292 | #define USB_EP_NI2_TXCSR 0xffc03e84 /* Control Status register for endpoint2 */ |
293 | #define USB_EP_NI2_RXMAXP 0xffc03e88 /* Maximum packet size for Host Rx endpoint2 */ | 293 | #define USB_EP_NI2_RXMAXP 0xffc03e88 /* Maximum packet size for Host Rx endpoint2 */ |
@@ -297,10 +297,10 @@ | |||
297 | #define USB_EP_NI2_TXINTERVAL 0xffc03e98 /* Sets the NAK response timeout on Endpoint2 */ | 297 | #define USB_EP_NI2_TXINTERVAL 0xffc03e98 /* Sets the NAK response timeout on Endpoint2 */ |
298 | #define USB_EP_NI2_RXTYPE 0xffc03e9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ | 298 | #define USB_EP_NI2_RXTYPE 0xffc03e9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ |
299 | #define USB_EP_NI2_RXINTERVAL 0xffc03ea0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ | 299 | #define USB_EP_NI2_RXINTERVAL 0xffc03ea0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ |
300 | #define USB_EP_NI2_TXCOUNT 0xffc03ea8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ | ||
300 | 301 | ||
301 | /* USB Endpoint 3 Control Registers */ | 302 | /* USB Endpoint 3 Control Registers */ |
302 | 303 | ||
303 | #define USB_EP_NI2_TXCOUNT 0xffc03ea8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ | ||
304 | #define USB_EP_NI3_TXMAXP 0xffc03ec0 /* Maximum packet size for Host Tx endpoint3 */ | 304 | #define USB_EP_NI3_TXMAXP 0xffc03ec0 /* Maximum packet size for Host Tx endpoint3 */ |
305 | #define USB_EP_NI3_TXCSR 0xffc03ec4 /* Control Status register for endpoint3 */ | 305 | #define USB_EP_NI3_TXCSR 0xffc03ec4 /* Control Status register for endpoint3 */ |
306 | #define USB_EP_NI3_RXMAXP 0xffc03ec8 /* Maximum packet size for Host Rx endpoint3 */ | 306 | #define USB_EP_NI3_RXMAXP 0xffc03ec8 /* Maximum packet size for Host Rx endpoint3 */ |
@@ -310,10 +310,10 @@ | |||
310 | #define USB_EP_NI3_TXINTERVAL 0xffc03ed8 /* Sets the NAK response timeout on Endpoint3 */ | 310 | #define USB_EP_NI3_TXINTERVAL 0xffc03ed8 /* Sets the NAK response timeout on Endpoint3 */ |
311 | #define USB_EP_NI3_RXTYPE 0xffc03edc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ | 311 | #define USB_EP_NI3_RXTYPE 0xffc03edc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ |
312 | #define USB_EP_NI3_RXINTERVAL 0xffc03ee0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ | 312 | #define USB_EP_NI3_RXINTERVAL 0xffc03ee0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ |
313 | #define USB_EP_NI3_TXCOUNT 0xffc03ee8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ | ||
313 | 314 | ||
314 | /* USB Endpoint 4 Control Registers */ | 315 | /* USB Endpoint 4 Control Registers */ |
315 | 316 | ||
316 | #define USB_EP_NI3_TXCOUNT 0xffc03ee8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ | ||
317 | #define USB_EP_NI4_TXMAXP 0xffc03f00 /* Maximum packet size for Host Tx endpoint4 */ | 317 | #define USB_EP_NI4_TXMAXP 0xffc03f00 /* Maximum packet size for Host Tx endpoint4 */ |
318 | #define USB_EP_NI4_TXCSR 0xffc03f04 /* Control Status register for endpoint4 */ | 318 | #define USB_EP_NI4_TXCSR 0xffc03f04 /* Control Status register for endpoint4 */ |
319 | #define USB_EP_NI4_RXMAXP 0xffc03f08 /* Maximum packet size for Host Rx endpoint4 */ | 319 | #define USB_EP_NI4_RXMAXP 0xffc03f08 /* Maximum packet size for Host Rx endpoint4 */ |
@@ -323,10 +323,10 @@ | |||
323 | #define USB_EP_NI4_TXINTERVAL 0xffc03f18 /* Sets the NAK response timeout on Endpoint4 */ | 323 | #define USB_EP_NI4_TXINTERVAL 0xffc03f18 /* Sets the NAK response timeout on Endpoint4 */ |
324 | #define USB_EP_NI4_RXTYPE 0xffc03f1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ | 324 | #define USB_EP_NI4_RXTYPE 0xffc03f1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ |
325 | #define USB_EP_NI4_RXINTERVAL 0xffc03f20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ | 325 | #define USB_EP_NI4_RXINTERVAL 0xffc03f20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ |
326 | #define USB_EP_NI4_TXCOUNT 0xffc03f28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ | ||
326 | 327 | ||
327 | /* USB Endpoint 5 Control Registers */ | 328 | /* USB Endpoint 5 Control Registers */ |
328 | 329 | ||
329 | #define USB_EP_NI4_TXCOUNT 0xffc03f28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ | ||
330 | #define USB_EP_NI5_TXMAXP 0xffc03f40 /* Maximum packet size for Host Tx endpoint5 */ | 330 | #define USB_EP_NI5_TXMAXP 0xffc03f40 /* Maximum packet size for Host Tx endpoint5 */ |
331 | #define USB_EP_NI5_TXCSR 0xffc03f44 /* Control Status register for endpoint5 */ | 331 | #define USB_EP_NI5_TXCSR 0xffc03f44 /* Control Status register for endpoint5 */ |
332 | #define USB_EP_NI5_RXMAXP 0xffc03f48 /* Maximum packet size for Host Rx endpoint5 */ | 332 | #define USB_EP_NI5_RXMAXP 0xffc03f48 /* Maximum packet size for Host Rx endpoint5 */ |
@@ -336,10 +336,10 @@ | |||
336 | #define USB_EP_NI5_TXINTERVAL 0xffc03f58 /* Sets the NAK response timeout on Endpoint5 */ | 336 | #define USB_EP_NI5_TXINTERVAL 0xffc03f58 /* Sets the NAK response timeout on Endpoint5 */ |
337 | #define USB_EP_NI5_RXTYPE 0xffc03f5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ | 337 | #define USB_EP_NI5_RXTYPE 0xffc03f5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ |
338 | #define USB_EP_NI5_RXINTERVAL 0xffc03f60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ | 338 | #define USB_EP_NI5_RXINTERVAL 0xffc03f60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ |
339 | #define USB_EP_NI5_TXCOUNT 0xffc03f68 /* Number of bytes to be written to the H145endpoint5 Tx FIFO */ | ||
339 | 340 | ||
340 | /* USB Endpoint 6 Control Registers */ | 341 | /* USB Endpoint 6 Control Registers */ |
341 | 342 | ||
342 | #define USB_EP_NI5_TXCOUNT 0xffc03f68 /* Number of bytes to be written to the H145endpoint5 Tx FIFO */ | ||
343 | #define USB_EP_NI6_TXMAXP 0xffc03f80 /* Maximum packet size for Host Tx endpoint6 */ | 343 | #define USB_EP_NI6_TXMAXP 0xffc03f80 /* Maximum packet size for Host Tx endpoint6 */ |
344 | #define USB_EP_NI6_TXCSR 0xffc03f84 /* Control Status register for endpoint6 */ | 344 | #define USB_EP_NI6_TXCSR 0xffc03f84 /* Control Status register for endpoint6 */ |
345 | #define USB_EP_NI6_RXMAXP 0xffc03f88 /* Maximum packet size for Host Rx endpoint6 */ | 345 | #define USB_EP_NI6_RXMAXP 0xffc03f88 /* Maximum packet size for Host Rx endpoint6 */ |
@@ -349,10 +349,10 @@ | |||
349 | #define USB_EP_NI6_TXINTERVAL 0xffc03f98 /* Sets the NAK response timeout on Endpoint6 */ | 349 | #define USB_EP_NI6_TXINTERVAL 0xffc03f98 /* Sets the NAK response timeout on Endpoint6 */ |
350 | #define USB_EP_NI6_RXTYPE 0xffc03f9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ | 350 | #define USB_EP_NI6_RXTYPE 0xffc03f9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ |
351 | #define USB_EP_NI6_RXINTERVAL 0xffc03fa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ | 351 | #define USB_EP_NI6_RXINTERVAL 0xffc03fa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ |
352 | #define USB_EP_NI6_TXCOUNT 0xffc03fa8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ | ||
352 | 353 | ||
353 | /* USB Endpoint 7 Control Registers */ | 354 | /* USB Endpoint 7 Control Registers */ |
354 | 355 | ||
355 | #define USB_EP_NI6_TXCOUNT 0xffc03fa8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ | ||
356 | #define USB_EP_NI7_TXMAXP 0xffc03fc0 /* Maximum packet size for Host Tx endpoint7 */ | 356 | #define USB_EP_NI7_TXMAXP 0xffc03fc0 /* Maximum packet size for Host Tx endpoint7 */ |
357 | #define USB_EP_NI7_TXCSR 0xffc03fc4 /* Control Status register for endpoint7 */ | 357 | #define USB_EP_NI7_TXCSR 0xffc03fc4 /* Control Status register for endpoint7 */ |
358 | #define USB_EP_NI7_RXMAXP 0xffc03fc8 /* Maximum packet size for Host Rx endpoint7 */ | 358 | #define USB_EP_NI7_RXMAXP 0xffc03fc8 /* Maximum packet size for Host Rx endpoint7 */ |
@@ -361,8 +361,9 @@ | |||
361 | #define USB_EP_NI7_TXTYPE 0xffc03fd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ | 361 | #define USB_EP_NI7_TXTYPE 0xffc03fd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ |
362 | #define USB_EP_NI7_TXINTERVAL 0xffc03fd8 /* Sets the NAK response timeout on Endpoint7 */ | 362 | #define USB_EP_NI7_TXINTERVAL 0xffc03fd8 /* Sets the NAK response timeout on Endpoint7 */ |
363 | #define USB_EP_NI7_RXTYPE 0xffc03fdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ | 363 | #define USB_EP_NI7_RXTYPE 0xffc03fdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ |
364 | #define USB_EP_NI7_RXINTERVAL 0xffc03ff0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ | 364 | #define USB_EP_NI7_RXINTERVAL 0xffc03fe0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ |
365 | #define USB_EP_NI7_TXCOUNT 0xffc03ff8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ | 365 | #define USB_EP_NI7_TXCOUNT 0xffc03fe8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ |
366 | |||
366 | #define USB_DMA_INTERRUPT 0xffc04000 /* Indicates pending interrupts for the DMA channels */ | 367 | #define USB_DMA_INTERRUPT 0xffc04000 /* Indicates pending interrupts for the DMA channels */ |
367 | 368 | ||
368 | /* USB Channel 0 Config Registers */ | 369 | /* USB Channel 0 Config Registers */ |
diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 3926cd909b66..9231a942892b 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c | |||
@@ -243,7 +243,6 @@ static struct platform_device bfin_uart0_device = { | |||
243 | 243 | ||
244 | #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 244 | #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) |
245 | 245 | ||
246 | #ifdef CONFIG_MTD_PARTITIONS | ||
247 | const char *part_probes[] = { "cmdlinepart", NULL }; | 246 | const char *part_probes[] = { "cmdlinepart", NULL }; |
248 | 247 | ||
249 | static struct mtd_partition bfin_plat_nand_partitions[] = { | 248 | static struct mtd_partition bfin_plat_nand_partitions[] = { |
@@ -257,7 +256,6 @@ static struct mtd_partition bfin_plat_nand_partitions[] = { | |||
257 | .offset = MTDPART_OFS_APPEND, | 256 | .offset = MTDPART_OFS_APPEND, |
258 | }, | 257 | }, |
259 | }; | 258 | }; |
260 | #endif | ||
261 | 259 | ||
262 | #define BFIN_NAND_PLAT_CLE 2 | 260 | #define BFIN_NAND_PLAT_CLE 2 |
263 | #define BFIN_NAND_PLAT_ALE 3 | 261 | #define BFIN_NAND_PLAT_ALE 3 |
@@ -286,11 +284,9 @@ static struct platform_nand_data bfin_plat_nand_data = { | |||
286 | .chip = { | 284 | .chip = { |
287 | .nr_chips = 1, | 285 | .nr_chips = 1, |
288 | .chip_delay = 30, | 286 | .chip_delay = 30, |
289 | #ifdef CONFIG_MTD_PARTITIONS | ||
290 | .part_probe_types = part_probes, | 287 | .part_probe_types = part_probes, |
291 | .partitions = bfin_plat_nand_partitions, | 288 | .partitions = bfin_plat_nand_partitions, |
292 | .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), | 289 | .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), |
293 | #endif | ||
294 | }, | 290 | }, |
295 | .ctrl = { | 291 | .ctrl = { |
296 | .cmd_ctrl = bfin_plat_nand_cmd_ctrl, | 292 | .cmd_ctrl = bfin_plat_nand_cmd_ctrl, |
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 3a6947456cf1..000000000000 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #ifdef CONFIG_BFIN_UART0_CTSRTS | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | # ifndef CONFIG_UART0_CTS_PIN | ||
13 | # define CONFIG_UART0_CTS_PIN -1 | ||
14 | # endif | ||
15 | # ifndef CONFIG_UART0_RTS_PIN | ||
16 | # define CONFIG_UART0_RTS_PIN -1 | ||
17 | # endif | ||
18 | #endif | ||
19 | |||
20 | struct bfin_serial_res { | ||
21 | unsigned long uart_base_addr; | ||
22 | int uart_irq; | ||
23 | int uart_status_irq; | ||
24 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
25 | unsigned int uart_tx_dma_channel; | ||
26 | unsigned int uart_rx_dma_channel; | ||
27 | #endif | ||
28 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
29 | int uart_cts_pin; | ||
30 | int uart_rts_pin; | ||
31 | #endif | ||
32 | }; | ||
33 | |||
34 | struct bfin_serial_res bfin_serial_resource[] = { | ||
35 | { | ||
36 | 0xFFC00400, | ||
37 | IRQ_UART_RX, | ||
38 | IRQ_UART_ERROR, | ||
39 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
40 | CH_UART_TX, | ||
41 | CH_UART_RX, | ||
42 | #endif | ||
43 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
44 | CONFIG_UART0_CTS_PIN, | ||
45 | CONFIG_UART0_RTS_PIN, | ||
46 | #endif | ||
47 | } | ||
48 | }; | ||
49 | |||
50 | #define DRIVER_NAME "bfin-uart" | ||
51 | |||
52 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index f96933f48a7f..225d311c9701 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -1753,6 +1753,8 @@ ENTRY(_sys_call_table) | |||
1753 | .long _sys_open_by_handle_at | 1753 | .long _sys_open_by_handle_at |
1754 | .long _sys_clock_adjtime | 1754 | .long _sys_clock_adjtime |
1755 | .long _sys_syncfs | 1755 | .long _sys_syncfs |
1756 | .long _sys_setns | ||
1757 | .long _sys_sendmmsg /* 380 */ | ||
1756 | 1758 | ||
1757 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1759 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1758 | .long _sys_ni_syscall | 1760 | .long _sys_ni_syscall |
diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c index b71cebc1f8a3..e2532114c5fd 100644 --- a/arch/blackfin/mm/maccess.c +++ b/arch/blackfin/mm/maccess.c | |||
@@ -16,7 +16,7 @@ static int validate_memory_access_address(unsigned long addr, int size) | |||
16 | return bfin_mem_access_type(addr, size); | 16 | return bfin_mem_access_type(addr, size); |
17 | } | 17 | } |
18 | 18 | ||
19 | long probe_kernel_read(void *dst, void *src, size_t size) | 19 | long probe_kernel_read(void *dst, const void *src, size_t size) |
20 | { | 20 | { |
21 | unsigned long lsrc = (unsigned long)src; | 21 | unsigned long lsrc = (unsigned long)src; |
22 | int mem_type; | 22 | int mem_type; |
@@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *src, size_t size) | |||
55 | return -EFAULT; | 55 | return -EFAULT; |
56 | } | 56 | } |
57 | 57 | ||
58 | long probe_kernel_write(void *dst, void *src, size_t size) | 58 | long probe_kernel_write(void *dst, const void *src, size_t size) |
59 | { | 59 | { |
60 | unsigned long ldst = (unsigned long)dst; | 60 | unsigned long ldst = (unsigned long)dst; |
61 | int mem_type; | 61 | int mem_type; |
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index b6b94a27d276..17addacb169e 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
@@ -270,7 +270,6 @@ config ETRAX_AXISFLASHMAP | |||
270 | select MTD_JEDECPROBE if ETRAX_ARCH_V32 | 270 | select MTD_JEDECPROBE if ETRAX_ARCH_V32 |
271 | select MTD_CHAR | 271 | select MTD_CHAR |
272 | select MTD_BLOCK | 272 | select MTD_BLOCK |
273 | select MTD_PARTITIONS | ||
274 | select MTD_COMPLEX_MAPPINGS | 273 | select MTD_COMPLEX_MAPPINGS |
275 | help | 274 | help |
276 | This option enables MTD mapping of flash devices. Needed to use | 275 | This option enables MTD mapping of flash devices. Needed to use |
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c index ed708e19d09e..a4bbdfd37bd8 100644 --- a/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/arch/cris/arch-v10/drivers/axisflashmap.c | |||
@@ -372,7 +372,7 @@ static int __init init_axis_flash(void) | |||
372 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE | 372 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE |
373 | if (mymtd) { | 373 | if (mymtd) { |
374 | main_partition.size = mymtd->size; | 374 | main_partition.size = mymtd->size; |
375 | err = add_mtd_partitions(mymtd, &main_partition, 1); | 375 | err = mtd_device_register(mymtd, &main_partition, 1); |
376 | if (err) | 376 | if (err) |
377 | panic("axisflashmap: Could not initialize " | 377 | panic("axisflashmap: Could not initialize " |
378 | "partition for whole main mtd device!\n"); | 378 | "partition for whole main mtd device!\n"); |
@@ -382,10 +382,12 @@ static int __init init_axis_flash(void) | |||
382 | if (mymtd) { | 382 | if (mymtd) { |
383 | if (use_default_ptable) { | 383 | if (use_default_ptable) { |
384 | printk(KERN_INFO " Using default partition table.\n"); | 384 | printk(KERN_INFO " Using default partition table.\n"); |
385 | err = add_mtd_partitions(mymtd, axis_default_partitions, | 385 | err = mtd_device_register(mymtd, |
386 | NUM_DEFAULT_PARTITIONS); | 386 | axis_default_partitions, |
387 | NUM_DEFAULT_PARTITIONS); | ||
387 | } else { | 388 | } else { |
388 | err = add_mtd_partitions(mymtd, axis_partitions, pidx); | 389 | err = mtd_device_register(mymtd, axis_partitions, |
390 | pidx); | ||
389 | } | 391 | } |
390 | 392 | ||
391 | if (err) | 393 | if (err) |
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index 0d6420d087fd..1161883eb582 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S | |||
@@ -937,6 +937,7 @@ sys_call_table: | |||
937 | .long sys_inotify_init1 | 937 | .long sys_inotify_init1 |
938 | .long sys_preadv | 938 | .long sys_preadv |
939 | .long sys_pwritev | 939 | .long sys_pwritev |
940 | .long sys_setns /* 335 */ | ||
940 | 941 | ||
941 | /* | 942 | /* |
942 | * NOTE!! This doesn't have to be exact - we just have | 943 | * NOTE!! This doesn't have to be exact - we just have |
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index 1633b120aa81..41a2732e8b9c 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig | |||
@@ -405,7 +405,6 @@ config ETRAX_AXISFLASHMAP | |||
405 | select MTD_JEDECPROBE | 405 | select MTD_JEDECPROBE |
406 | select MTD_CHAR | 406 | select MTD_CHAR |
407 | select MTD_BLOCK | 407 | select MTD_BLOCK |
408 | select MTD_PARTITIONS | ||
409 | select MTD_COMPLEX_MAPPINGS | 408 | select MTD_COMPLEX_MAPPINGS |
410 | help | 409 | help |
411 | This option enables MTD mapping of flash devices. Needed to use | 410 | This option enables MTD mapping of flash devices. Needed to use |
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c index 7b155f8203b8..a2bde3744622 100644 --- a/arch/cris/arch-v32/drivers/axisflashmap.c +++ b/arch/cris/arch-v32/drivers/axisflashmap.c | |||
@@ -561,7 +561,7 @@ static int __init init_axis_flash(void) | |||
561 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE | 561 | #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE |
562 | if (main_mtd) { | 562 | if (main_mtd) { |
563 | main_partition.size = main_mtd->size; | 563 | main_partition.size = main_mtd->size; |
564 | err = add_mtd_partitions(main_mtd, &main_partition, 1); | 564 | err = mtd_device_register(main_mtd, &main_partition, 1); |
565 | if (err) | 565 | if (err) |
566 | panic("axisflashmap: Could not initialize " | 566 | panic("axisflashmap: Could not initialize " |
567 | "partition for whole main mtd device!\n"); | 567 | "partition for whole main mtd device!\n"); |
@@ -597,7 +597,8 @@ static int __init init_axis_flash(void) | |||
597 | mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize : | 597 | mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize : |
598 | CONFIG_ETRAX_PTABLE_SECTOR); | 598 | CONFIG_ETRAX_PTABLE_SECTOR); |
599 | } else { | 599 | } else { |
600 | err = add_mtd_partitions(main_mtd, &partition[part], 1); | 600 | err = mtd_device_register(main_mtd, &partition[part], |
601 | 1); | ||
601 | if (err) | 602 | if (err) |
602 | panic("axisflashmap: Could not add mtd " | 603 | panic("axisflashmap: Could not add mtd " |
603 | "partition %d\n", part); | 604 | "partition %d\n", part); |
@@ -633,7 +634,7 @@ static int __init init_axis_flash(void) | |||
633 | #ifndef CONFIG_ETRAX_VCS_SIM | 634 | #ifndef CONFIG_ETRAX_VCS_SIM |
634 | if (aux_mtd) { | 635 | if (aux_mtd) { |
635 | aux_partition.size = aux_mtd->size; | 636 | aux_partition.size = aux_mtd->size; |
636 | err = add_mtd_partitions(aux_mtd, &aux_partition, 1); | 637 | err = mtd_device_register(aux_mtd, &aux_partition, 1); |
637 | if (err) | 638 | if (err) |
638 | panic("axisflashmap: Could not initialize " | 639 | panic("axisflashmap: Could not initialize " |
639 | "aux mtd device!\n"); | 640 | "aux mtd device!\n"); |
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 3abf12c23e5f..84fed7e91ada 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S | |||
@@ -880,6 +880,7 @@ sys_call_table: | |||
880 | .long sys_inotify_init1 | 880 | .long sys_inotify_init1 |
881 | .long sys_preadv | 881 | .long sys_preadv |
882 | .long sys_pwritev | 882 | .long sys_pwritev |
883 | .long sys_setns /* 335 */ | ||
883 | 884 | ||
884 | /* | 885 | /* |
885 | * NOTE!! This doesn't have to be exact - we just have | 886 | * NOTE!! This doesn't have to be exact - we just have |
diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h index f6fad83b3a8c..f921b8b0f97e 100644 --- a/arch/cris/include/asm/unistd.h +++ b/arch/cris/include/asm/unistd.h | |||
@@ -339,10 +339,11 @@ | |||
339 | #define __NR_inotify_init1 332 | 339 | #define __NR_inotify_init1 332 |
340 | #define __NR_preadv 333 | 340 | #define __NR_preadv 333 |
341 | #define __NR_pwritev 334 | 341 | #define __NR_pwritev 334 |
342 | #define __NR_setns 335 | ||
342 | 343 | ||
343 | #ifdef __KERNEL__ | 344 | #ifdef __KERNEL__ |
344 | 345 | ||
345 | #define NR_syscalls 335 | 346 | #define NR_syscalls 336 |
346 | 347 | ||
347 | #include <arch/unistd.h> | 348 | #include <arch/unistd.h> |
348 | 349 | ||
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index b28da499e22a..a569dff7cd59 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h | |||
@@ -343,10 +343,11 @@ | |||
343 | #define __NR_pwritev 334 | 343 | #define __NR_pwritev 334 |
344 | #define __NR_rt_tgsigqueueinfo 335 | 344 | #define __NR_rt_tgsigqueueinfo 335 |
345 | #define __NR_perf_event_open 336 | 345 | #define __NR_perf_event_open 336 |
346 | #define __NR_setns 337 | ||
346 | 347 | ||
347 | #ifdef __KERNEL__ | 348 | #ifdef __KERNEL__ |
348 | 349 | ||
349 | #define NR_syscalls 337 | 350 | #define NR_syscalls 338 |
350 | 351 | ||
351 | #define __ARCH_WANT_IPC_PARSE_VERSION | 352 | #define __ARCH_WANT_IPC_PARSE_VERSION |
352 | /* #define __ARCH_WANT_OLD_READDIR */ | 353 | /* #define __ARCH_WANT_OLD_READDIR */ |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 63d579bf1c29..017d6d7b784f 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -1526,5 +1526,6 @@ sys_call_table: | |||
1526 | .long sys_pwritev | 1526 | .long sys_pwritev |
1527 | .long sys_rt_tgsigqueueinfo /* 335 */ | 1527 | .long sys_rt_tgsigqueueinfo /* 335 */ |
1528 | .long sys_perf_event_open | 1528 | .long sys_perf_event_open |
1529 | .long sys_setns | ||
1529 | 1530 | ||
1530 | syscall_table_size = (. - sys_call_table) | 1531 | syscall_table_size = (. - sys_call_table) |
diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h index 50f2c5a36591..2c3f8e60b1e0 100644 --- a/arch/h8300/include/asm/unistd.h +++ b/arch/h8300/include/asm/unistd.h | |||
@@ -325,10 +325,11 @@ | |||
325 | #define __NR_move_pages 317 | 325 | #define __NR_move_pages 317 |
326 | #define __NR_getcpu 318 | 326 | #define __NR_getcpu 318 |
327 | #define __NR_epoll_pwait 319 | 327 | #define __NR_epoll_pwait 319 |
328 | #define __NR_setns 320 | ||
328 | 329 | ||
329 | #ifdef __KERNEL__ | 330 | #ifdef __KERNEL__ |
330 | 331 | ||
331 | #define NR_syscalls 320 | 332 | #define NR_syscalls 321 |
332 | 333 | ||
333 | #define __ARCH_WANT_IPC_PARSE_VERSION | 334 | #define __ARCH_WANT_IPC_PARSE_VERSION |
334 | #define __ARCH_WANT_OLD_READDIR | 335 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S index faefaff7d43d..f4b2e67bcc34 100644 --- a/arch/h8300/kernel/syscalls.S +++ b/arch/h8300/kernel/syscalls.S | |||
@@ -333,6 +333,7 @@ SYMBOL_NAME_LABEL(sys_call_table) | |||
333 | .long SYMBOL_NAME(sys_ni_syscall) /* sys_move_pages */ | 333 | .long SYMBOL_NAME(sys_ni_syscall) /* sys_move_pages */ |
334 | .long SYMBOL_NAME(sys_getcpu) | 334 | .long SYMBOL_NAME(sys_getcpu) |
335 | .long SYMBOL_NAME(sys_ni_syscall) /* sys_epoll_pwait */ | 335 | .long SYMBOL_NAME(sys_ni_syscall) /* sys_epoll_pwait */ |
336 | .long SYMBOL_NAME(sys_setns) /* 320 */ | ||
336 | 337 | ||
337 | .macro call_sp addr | 338 | .macro call_sp addr |
338 | mov.l #SYMBOL_NAME(\addr),er6 | 339 | mov.l #SYMBOL_NAME(\addr),er6 |
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 404d037c5e10..7c928da35b17 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h | |||
@@ -319,11 +319,13 @@ | |||
319 | #define __NR_open_by_handle_at 1327 | 319 | #define __NR_open_by_handle_at 1327 |
320 | #define __NR_clock_adjtime 1328 | 320 | #define __NR_clock_adjtime 1328 |
321 | #define __NR_syncfs 1329 | 321 | #define __NR_syncfs 1329 |
322 | #define __NR_setns 1330 | ||
323 | #define __NR_sendmmsg 1331 | ||
322 | 324 | ||
323 | #ifdef __KERNEL__ | 325 | #ifdef __KERNEL__ |
324 | 326 | ||
325 | 327 | ||
326 | #define NR_syscalls 306 /* length of syscall table */ | 328 | #define NR_syscalls 308 /* length of syscall table */ |
327 | 329 | ||
328 | /* | 330 | /* |
329 | * The following defines stop scripts/checksyscalls.sh from complaining about | 331 | * The following defines stop scripts/checksyscalls.sh from complaining about |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 6de2e23b3636..97dd2abdeb1a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1775,6 +1775,8 @@ sys_call_table: | |||
1775 | data8 sys_open_by_handle_at | 1775 | data8 sys_open_by_handle_at |
1776 | data8 sys_clock_adjtime | 1776 | data8 sys_clock_adjtime |
1777 | data8 sys_syncfs | 1777 | data8 sys_syncfs |
1778 | data8 sys_setns // 1330 | ||
1779 | data8 sys_sendmmsg | ||
1778 | 1780 | ||
1779 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1781 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
1780 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ | 1782 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ |
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index c70545689da8..3e1db561aacc 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h | |||
@@ -330,10 +330,11 @@ | |||
330 | /* #define __NR_timerfd 322 removed */ | 330 | /* #define __NR_timerfd 322 removed */ |
331 | #define __NR_eventfd 323 | 331 | #define __NR_eventfd 323 |
332 | #define __NR_fallocate 324 | 332 | #define __NR_fallocate 324 |
333 | #define __NR_setns 325 | ||
333 | 334 | ||
334 | #ifdef __KERNEL__ | 335 | #ifdef __KERNEL__ |
335 | 336 | ||
336 | #define NR_syscalls 325 | 337 | #define NR_syscalls 326 |
337 | 338 | ||
338 | #define __ARCH_WANT_IPC_PARSE_VERSION | 339 | #define __ARCH_WANT_IPC_PARSE_VERSION |
339 | #define __ARCH_WANT_STAT64 | 340 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S index 60536e271233..528f2e6ad064 100644 --- a/arch/m32r/kernel/syscall_table.S +++ b/arch/m32r/kernel/syscall_table.S | |||
@@ -324,3 +324,4 @@ ENTRY(sys_call_table) | |||
324 | .long sys_ni_syscall | 324 | .long sys_ni_syscall |
325 | .long sys_eventfd | 325 | .long sys_eventfd |
326 | .long sys_fallocate | 326 | .long sys_fallocate |
327 | .long sys_setns /* 325 */ | ||
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index f3b649de2a1b..43f984e93970 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
@@ -349,10 +349,11 @@ | |||
349 | #define __NR_open_by_handle_at 341 | 349 | #define __NR_open_by_handle_at 341 |
350 | #define __NR_clock_adjtime 342 | 350 | #define __NR_clock_adjtime 342 |
351 | #define __NR_syncfs 343 | 351 | #define __NR_syncfs 343 |
352 | #define __NR_setns 344 | ||
352 | 353 | ||
353 | #ifdef __KERNEL__ | 354 | #ifdef __KERNEL__ |
354 | 355 | ||
355 | #define NR_syscalls 344 | 356 | #define NR_syscalls 345 |
356 | 357 | ||
357 | #define __ARCH_WANT_IPC_PARSE_VERSION | 358 | #define __ARCH_WANT_IPC_PARSE_VERSION |
358 | #define __ARCH_WANT_OLD_READDIR | 359 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 6f7b09122a00..00d1452f9571 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S | |||
@@ -364,4 +364,5 @@ ENTRY(sys_call_table) | |||
364 | .long sys_open_by_handle_at | 364 | .long sys_open_by_handle_at |
365 | .long sys_clock_adjtime | 365 | .long sys_clock_adjtime |
366 | .long sys_syncfs | 366 | .long sys_syncfs |
367 | .long sys_setns | ||
367 | 368 | ||
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index 30edd61a6b8f..7d7092b917ac 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h | |||
@@ -390,8 +390,9 @@ | |||
390 | #define __NR_open_by_handle_at 372 | 390 | #define __NR_open_by_handle_at 372 |
391 | #define __NR_clock_adjtime 373 | 391 | #define __NR_clock_adjtime 373 |
392 | #define __NR_syncfs 374 | 392 | #define __NR_syncfs 374 |
393 | #define __NR_setns 375 | ||
393 | 394 | ||
394 | #define __NR_syscalls 375 | 395 | #define __NR_syscalls 376 |
395 | 396 | ||
396 | #ifdef __KERNEL__ | 397 | #ifdef __KERNEL__ |
397 | #ifndef __ASSEMBLY__ | 398 | #ifndef __ASSEMBLY__ |
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 00ee90f08343..b15cc219b1d9 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c | |||
@@ -130,7 +130,7 @@ void __init early_init_devtree(void *params) | |||
130 | * device-tree, including the platform type, initrd location and | 130 | * device-tree, including the platform type, initrd location and |
131 | * size, TCE reserve, and more ... | 131 | * size, TCE reserve, and more ... |
132 | */ | 132 | */ |
133 | of_scan_flat_dt(early_init_dt_scan_chosen, NULL); | 133 | of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line); |
134 | 134 | ||
135 | /* Scan memory nodes and rebuild MEMBLOCKs */ | 135 | /* Scan memory nodes and rebuild MEMBLOCKs */ |
136 | memblock_init(); | 136 | memblock_init(); |
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 85cea81d1ca1..d915a122c865 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S | |||
@@ -379,3 +379,4 @@ ENTRY(sys_call_table) | |||
379 | .long sys_open_by_handle_at | 379 | .long sys_open_by_handle_at |
380 | .long sys_clock_adjtime | 380 | .long sys_clock_adjtime |
381 | .long sys_syncfs | 381 | .long sys_syncfs |
382 | .long sys_setns /* 375 */ | ||
diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c index 008f657116eb..0ee02f5e51cc 100644 --- a/arch/mips/cavium-octeon/flash_setup.c +++ b/arch/mips/cavium-octeon/flash_setup.c | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | static struct map_info flash_map; | 17 | static struct map_info flash_map; |
18 | static struct mtd_info *mymtd; | 18 | static struct mtd_info *mymtd; |
19 | #ifdef CONFIG_MTD_PARTITIONS | ||
20 | static int nr_parts; | 19 | static int nr_parts; |
21 | static struct mtd_partition *parts; | 20 | static struct mtd_partition *parts; |
22 | static const char *part_probe_types[] = { | 21 | static const char *part_probe_types[] = { |
@@ -26,7 +25,6 @@ static const char *part_probe_types[] = { | |||
26 | #endif | 25 | #endif |
27 | NULL | 26 | NULL |
28 | }; | 27 | }; |
29 | #endif | ||
30 | 28 | ||
31 | /** | 29 | /** |
32 | * Module/ driver initialization. | 30 | * Module/ driver initialization. |
@@ -63,17 +61,10 @@ static int __init flash_init(void) | |||
63 | if (mymtd) { | 61 | if (mymtd) { |
64 | mymtd->owner = THIS_MODULE; | 62 | mymtd->owner = THIS_MODULE; |
65 | 63 | ||
66 | #ifdef CONFIG_MTD_PARTITIONS | ||
67 | nr_parts = parse_mtd_partitions(mymtd, | 64 | nr_parts = parse_mtd_partitions(mymtd, |
68 | part_probe_types, | 65 | part_probe_types, |
69 | &parts, 0); | 66 | &parts, 0); |
70 | if (nr_parts > 0) | 67 | mtd_device_register(mymtd, parts, nr_parts); |
71 | add_mtd_partitions(mymtd, parts, nr_parts); | ||
72 | else | ||
73 | add_mtd_device(mymtd); | ||
74 | #else | ||
75 | add_mtd_device(mymtd); | ||
76 | #endif | ||
77 | } else { | 68 | } else { |
78 | pr_err("Failed to register MTD device for flash\n"); | 69 | pr_err("Failed to register MTD device for flash\n"); |
79 | } | 70 | } |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index f29b862d9db3..857d9b7858ad 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
@@ -14,9 +14,6 @@ | |||
14 | #ifdef CONFIG_OF | 14 | #ifdef CONFIG_OF |
15 | #include <asm/bootinfo.h> | 15 | #include <asm/bootinfo.h> |
16 | 16 | ||
17 | /* which is compatible with the flattened device tree (FDT) */ | ||
18 | #define cmd_line arcs_cmdline | ||
19 | |||
20 | extern int early_init_dt_scan_memory_arch(unsigned long node, | 17 | extern int early_init_dt_scan_memory_arch(unsigned long node, |
21 | const char *uname, int depth, void *data); | 18 | const char *uname, int depth, void *data); |
22 | 19 | ||
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index fa2e37ea2be1..6fcfc480e9d0 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h | |||
@@ -363,16 +363,17 @@ | |||
363 | #define __NR_open_by_handle_at (__NR_Linux + 340) | 363 | #define __NR_open_by_handle_at (__NR_Linux + 340) |
364 | #define __NR_clock_adjtime (__NR_Linux + 341) | 364 | #define __NR_clock_adjtime (__NR_Linux + 341) |
365 | #define __NR_syncfs (__NR_Linux + 342) | 365 | #define __NR_syncfs (__NR_Linux + 342) |
366 | #define __NR_setns (__NR_Linux + 343) | ||
366 | 367 | ||
367 | /* | 368 | /* |
368 | * Offset of the last Linux o32 flavoured syscall | 369 | * Offset of the last Linux o32 flavoured syscall |
369 | */ | 370 | */ |
370 | #define __NR_Linux_syscalls 342 | 371 | #define __NR_Linux_syscalls 343 |
371 | 372 | ||
372 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 373 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
373 | 374 | ||
374 | #define __NR_O32_Linux 4000 | 375 | #define __NR_O32_Linux 4000 |
375 | #define __NR_O32_Linux_syscalls 342 | 376 | #define __NR_O32_Linux_syscalls 343 |
376 | 377 | ||
377 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 378 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
378 | 379 | ||
@@ -682,16 +683,17 @@ | |||
682 | #define __NR_open_by_handle_at (__NR_Linux + 299) | 683 | #define __NR_open_by_handle_at (__NR_Linux + 299) |
683 | #define __NR_clock_adjtime (__NR_Linux + 300) | 684 | #define __NR_clock_adjtime (__NR_Linux + 300) |
684 | #define __NR_syncfs (__NR_Linux + 301) | 685 | #define __NR_syncfs (__NR_Linux + 301) |
686 | #define __NR_setns (__NR_Linux + 302) | ||
685 | 687 | ||
686 | /* | 688 | /* |
687 | * Offset of the last Linux 64-bit flavoured syscall | 689 | * Offset of the last Linux 64-bit flavoured syscall |
688 | */ | 690 | */ |
689 | #define __NR_Linux_syscalls 301 | 691 | #define __NR_Linux_syscalls 302 |
690 | 692 | ||
691 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 693 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
692 | 694 | ||
693 | #define __NR_64_Linux 5000 | 695 | #define __NR_64_Linux 5000 |
694 | #define __NR_64_Linux_syscalls 301 | 696 | #define __NR_64_Linux_syscalls 302 |
695 | 697 | ||
696 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 698 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
697 | 699 | ||
@@ -1006,16 +1008,17 @@ | |||
1006 | #define __NR_open_by_handle_at (__NR_Linux + 304) | 1008 | #define __NR_open_by_handle_at (__NR_Linux + 304) |
1007 | #define __NR_clock_adjtime (__NR_Linux + 305) | 1009 | #define __NR_clock_adjtime (__NR_Linux + 305) |
1008 | #define __NR_syncfs (__NR_Linux + 306) | 1010 | #define __NR_syncfs (__NR_Linux + 306) |
1011 | #define __NR_setns (__NR_Linux + 307) | ||
1009 | 1012 | ||
1010 | /* | 1013 | /* |
1011 | * Offset of the last N32 flavoured syscall | 1014 | * Offset of the last N32 flavoured syscall |
1012 | */ | 1015 | */ |
1013 | #define __NR_Linux_syscalls 306 | 1016 | #define __NR_Linux_syscalls 307 |
1014 | 1017 | ||
1015 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 1018 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
1016 | 1019 | ||
1017 | #define __NR_N32_Linux 6000 | 1020 | #define __NR_N32_Linux 6000 |
1018 | #define __NR_N32_Linux_syscalls 306 | 1021 | #define __NR_N32_Linux_syscalls 307 |
1019 | 1022 | ||
1020 | #ifdef __KERNEL__ | 1023 | #ifdef __KERNEL__ |
1021 | 1024 | ||
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index a19811e98a41..5b7eade41fa3 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -83,7 +83,8 @@ void __init early_init_devtree(void *params) | |||
83 | * device-tree, including the platform type, initrd location and | 83 | * device-tree, including the platform type, initrd location and |
84 | * size, and more ... | 84 | * size, and more ... |
85 | */ | 85 | */ |
86 | of_scan_flat_dt(early_init_dt_scan_chosen, NULL); | 86 | of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline); |
87 | |||
87 | 88 | ||
88 | /* Scan memory nodes */ | 89 | /* Scan memory nodes */ |
89 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | 90 | of_scan_flat_dt(early_init_dt_scan_root, NULL); |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 7a8e1dd7f6f2..99e656e425f3 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -589,6 +589,7 @@ einval: li v0, -ENOSYS | |||
589 | sys sys_open_by_handle_at 3 /* 4340 */ | 589 | sys sys_open_by_handle_at 3 /* 4340 */ |
590 | sys sys_clock_adjtime 2 | 590 | sys sys_clock_adjtime 2 |
591 | sys sys_syncfs 1 | 591 | sys sys_syncfs 1 |
592 | sys sys_setns 2 | ||
592 | .endm | 593 | .endm |
593 | 594 | ||
594 | /* We pre-compute the number of _instruction_ bytes needed to | 595 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 2d31c83224f9..fb0575f47f3d 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -428,4 +428,5 @@ sys_call_table: | |||
428 | PTR sys_open_by_handle_at | 428 | PTR sys_open_by_handle_at |
429 | PTR sys_clock_adjtime /* 5300 */ | 429 | PTR sys_clock_adjtime /* 5300 */ |
430 | PTR sys_syncfs | 430 | PTR sys_syncfs |
431 | PTR sys_setns | ||
431 | .size sys_call_table,.-sys_call_table | 432 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 38a0503b9a4a..4de0c5534e73 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -428,4 +428,5 @@ EXPORT(sysn32_call_table) | |||
428 | PTR sys_open_by_handle_at | 428 | PTR sys_open_by_handle_at |
429 | PTR compat_sys_clock_adjtime /* 6305 */ | 429 | PTR compat_sys_clock_adjtime /* 6305 */ |
430 | PTR sys_syncfs | 430 | PTR sys_syncfs |
431 | PTR sys_setns | ||
431 | .size sysn32_call_table,.-sysn32_call_table | 432 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 91ea5e4041dd..4a387de08bfa 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -546,4 +546,5 @@ sys_call_table: | |||
546 | PTR compat_sys_open_by_handle_at /* 4340 */ | 546 | PTR compat_sys_open_by_handle_at /* 4340 */ |
547 | PTR compat_sys_clock_adjtime | 547 | PTR compat_sys_clock_adjtime |
548 | PTR sys_syncfs | 548 | PTR sys_syncfs |
549 | PTR sys_setns | ||
549 | .size sys_call_table,.-sys_call_table | 550 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 812816c45662..ec38e00b2559 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -639,7 +639,6 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, | |||
639 | .flags = IORESOURCE_MEM, | 639 | .flags = IORESOURCE_MEM, |
640 | }; | 640 | }; |
641 | struct platform_device *pdev; | 641 | struct platform_device *pdev; |
642 | #ifdef CONFIG_MTD_PARTITIONS | ||
643 | static struct mtd_partition parts[2]; | 642 | static struct mtd_partition parts[2]; |
644 | struct physmap_flash_data pdata_part; | 643 | struct physmap_flash_data pdata_part; |
645 | 644 | ||
@@ -658,7 +657,7 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, | |||
658 | pdata_part.parts = parts; | 657 | pdata_part.parts = parts; |
659 | pdata = &pdata_part; | 658 | pdata = &pdata_part; |
660 | } | 659 | } |
661 | #endif | 660 | |
662 | pdev = platform_device_alloc("physmap-flash", no); | 661 | pdev = platform_device_alloc("physmap-flash", no); |
663 | if (!pdev || | 662 | if (!pdev || |
664 | platform_device_add_resources(pdev, &res, 1) || | 663 | platform_device_add_resources(pdev, &res, 1) || |
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h index 9d056f515929..9051f921cbc7 100644 --- a/arch/mn10300/include/asm/unistd.h +++ b/arch/mn10300/include/asm/unistd.h | |||
@@ -349,10 +349,11 @@ | |||
349 | #define __NR_rt_tgsigqueueinfo 336 | 349 | #define __NR_rt_tgsigqueueinfo 336 |
350 | #define __NR_perf_event_open 337 | 350 | #define __NR_perf_event_open 337 |
351 | #define __NR_recvmmsg 338 | 351 | #define __NR_recvmmsg 338 |
352 | #define __NR_setns 339 | ||
352 | 353 | ||
353 | #ifdef __KERNEL__ | 354 | #ifdef __KERNEL__ |
354 | 355 | ||
355 | #define NR_syscalls 339 | 356 | #define NR_syscalls 340 |
356 | 357 | ||
357 | /* | 358 | /* |
358 | * specify the deprecated syscalls we want to support on this arch | 359 | * specify the deprecated syscalls we want to support on this arch |
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index fb93ad720b82..ae435e1d5669 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S | |||
@@ -759,6 +759,7 @@ ENTRY(sys_call_table) | |||
759 | .long sys_rt_tgsigqueueinfo | 759 | .long sys_rt_tgsigqueueinfo |
760 | .long sys_perf_event_open | 760 | .long sys_perf_event_open |
761 | .long sys_recvmmsg | 761 | .long sys_recvmmsg |
762 | .long sys_setns | ||
762 | 763 | ||
763 | 764 | ||
764 | nr_syscalls=(.-sys_call_table)/4 | 765 | nr_syscalls=(.-sys_call_table)/4 |
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 9cbc2c3bf630..3392de3e7be0 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h | |||
@@ -820,8 +820,9 @@ | |||
820 | #define __NR_name_to_handle_at (__NR_Linux + 325) | 820 | #define __NR_name_to_handle_at (__NR_Linux + 325) |
821 | #define __NR_open_by_handle_at (__NR_Linux + 326) | 821 | #define __NR_open_by_handle_at (__NR_Linux + 326) |
822 | #define __NR_syncfs (__NR_Linux + 327) | 822 | #define __NR_syncfs (__NR_Linux + 327) |
823 | #define __NR_setns (__NR_Linux + 328) | ||
823 | 824 | ||
824 | #define __NR_Linux_syscalls (__NR_syncfs + 1) | 825 | #define __NR_Linux_syscalls (__NR_setns + 1) |
825 | 826 | ||
826 | 827 | ||
827 | #define __IGNORE_select /* newselect */ | 828 | #define __IGNORE_select /* newselect */ |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index a5b02ce4d41e..34a4f5a2fffb 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -426,6 +426,7 @@ | |||
426 | ENTRY_SAME(name_to_handle_at) /* 325 */ | 426 | ENTRY_SAME(name_to_handle_at) /* 325 */ |
427 | ENTRY_COMP(open_by_handle_at) | 427 | ENTRY_COMP(open_by_handle_at) |
428 | ENTRY_SAME(syncfs) | 428 | ENTRY_SAME(syncfs) |
429 | ENTRY_SAME(setns) | ||
429 | 430 | ||
430 | /* Nothing yet */ | 431 | /* Nothing yet */ |
431 | 432 | ||
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 8489d372077f..f6736b7da463 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -353,3 +353,4 @@ COMPAT_SYS_SPU(open_by_handle_at) | |||
353 | COMPAT_SYS_SPU(clock_adjtime) | 353 | COMPAT_SYS_SPU(clock_adjtime) |
354 | SYSCALL_SPU(syncfs) | 354 | SYSCALL_SPU(syncfs) |
355 | COMPAT_SYS_SPU(sendmmsg) | 355 | COMPAT_SYS_SPU(sendmmsg) |
356 | SYSCALL_SPU(setns) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 6d23c8193caa..b8b3f599362b 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -372,10 +372,11 @@ | |||
372 | #define __NR_clock_adjtime 347 | 372 | #define __NR_clock_adjtime 347 |
373 | #define __NR_syncfs 348 | 373 | #define __NR_syncfs 348 |
374 | #define __NR_sendmmsg 349 | 374 | #define __NR_sendmmsg 349 |
375 | #define __NR_setns 350 | ||
375 | 376 | ||
376 | #ifdef __KERNEL__ | 377 | #ifdef __KERNEL__ |
377 | 378 | ||
378 | #define __NR_syscalls 350 | 379 | #define __NR_syscalls 351 |
379 | 380 | ||
380 | #define __NR__exit __NR_exit | 381 | #define __NR__exit __NR_exit |
381 | #define NR_syscalls __NR_syscalls | 382 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 48aeb55faae9..f2c906b1d8d3 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -694,7 +694,7 @@ void __init early_init_devtree(void *params) | |||
694 | * device-tree, including the platform type, initrd location and | 694 | * device-tree, including the platform type, initrd location and |
695 | * size, TCE reserve, and more ... | 695 | * size, TCE reserve, and more ... |
696 | */ | 696 | */ |
697 | of_scan_flat_dt(early_init_dt_scan_chosen_ppc, NULL); | 697 | of_scan_flat_dt(early_init_dt_scan_chosen_ppc, cmd_line); |
698 | 698 | ||
699 | /* Scan memory nodes and rebuild MEMBLOCKs */ | 699 | /* Scan memory nodes and rebuild MEMBLOCKs */ |
700 | memblock_init(); | 700 | memblock_init(); |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 9089b0421191..7667db448aa7 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -715,7 +715,8 @@ static struct syscore_ops pmacpic_syscore_ops = { | |||
715 | 715 | ||
716 | static int __init init_pmacpic_syscore(void) | 716 | static int __init init_pmacpic_syscore(void) |
717 | { | 717 | { |
718 | register_syscore_ops(&pmacpic_syscore_ops); | 718 | if (pmac_irq_hw[0]) |
719 | register_syscore_ops(&pmacpic_syscore_ops); | ||
719 | return 0; | 720 | return 0; |
720 | } | 721 | } |
721 | 722 | ||
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index c4773a2ef3d3..e4efacfe1b63 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -577,16 +577,16 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) | |||
577 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | 577 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) |
578 | { | 578 | { |
579 | #ifdef CONFIG_PGSTE | 579 | #ifdef CONFIG_PGSTE |
580 | unsigned long pfn, bits; | 580 | unsigned long address, bits; |
581 | unsigned char skey; | 581 | unsigned char skey; |
582 | 582 | ||
583 | pfn = pte_val(*ptep) >> PAGE_SHIFT; | 583 | address = pte_val(*ptep) & PAGE_MASK; |
584 | skey = page_get_storage_key(pfn); | 584 | skey = page_get_storage_key(address); |
585 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); | 585 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); |
586 | /* Clear page changed & referenced bit in the storage key */ | 586 | /* Clear page changed & referenced bit in the storage key */ |
587 | if (bits) { | 587 | if (bits) { |
588 | skey ^= bits; | 588 | skey ^= bits; |
589 | page_set_storage_key(pfn, skey, 1); | 589 | page_set_storage_key(address, skey, 1); |
590 | } | 590 | } |
591 | /* Transfer page changed & referenced bit to guest bits in pgste */ | 591 | /* Transfer page changed & referenced bit to guest bits in pgste */ |
592 | pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ | 592 | pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ |
@@ -628,16 +628,16 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) | |||
628 | static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste) | 628 | static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste) |
629 | { | 629 | { |
630 | #ifdef CONFIG_PGSTE | 630 | #ifdef CONFIG_PGSTE |
631 | unsigned long pfn; | 631 | unsigned long address; |
632 | unsigned long okey, nkey; | 632 | unsigned long okey, nkey; |
633 | 633 | ||
634 | pfn = pte_val(*ptep) >> PAGE_SHIFT; | 634 | address = pte_val(*ptep) & PAGE_MASK; |
635 | okey = nkey = page_get_storage_key(pfn); | 635 | okey = nkey = page_get_storage_key(address); |
636 | nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); | 636 | nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); |
637 | /* Set page access key and fetch protection bit from pgste */ | 637 | /* Set page access key and fetch protection bit from pgste */ |
638 | nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; | 638 | nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; |
639 | if (okey != nkey) | 639 | if (okey != nkey) |
640 | page_set_storage_key(pfn, nkey, 1); | 640 | page_set_storage_key(address, nkey, 1); |
641 | #endif | 641 | #endif |
642 | } | 642 | } |
643 | 643 | ||
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 9208e69245a0..404bdb9671b4 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h | |||
@@ -276,7 +276,8 @@ | |||
276 | #define __NR_open_by_handle_at 336 | 276 | #define __NR_open_by_handle_at 336 |
277 | #define __NR_clock_adjtime 337 | 277 | #define __NR_clock_adjtime 337 |
278 | #define __NR_syncfs 338 | 278 | #define __NR_syncfs 338 |
279 | #define NR_syscalls 339 | 279 | #define __NR_setns 339 |
280 | #define NR_syscalls 340 | ||
280 | 281 | ||
281 | /* | 282 | /* |
282 | * There are some system calls that are not present on 64 bit, some | 283 | * There are some system calls that are not present on 64 bit, some |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 1dc96ea08fa8..1f5eb789c3a7 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1904,3 +1904,9 @@ compat_sys_clock_adjtime_wrapper: | |||
1904 | sys_syncfs_wrapper: | 1904 | sys_syncfs_wrapper: |
1905 | lgfr %r2,%r2 # int | 1905 | lgfr %r2,%r2 # int |
1906 | jg sys_syncfs | 1906 | jg sys_syncfs |
1907 | |||
1908 | .globl sys_setns_wrapper | ||
1909 | sys_setns_wrapper: | ||
1910 | lgfr %r2,%r2 # int | ||
1911 | lgfr %r3,%r3 # int | ||
1912 | jg sys_setns | ||
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 9c65fd4ddce0..6ee39ef8fe4a 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -347,3 +347,4 @@ SYSCALL(sys_name_to_handle_at,sys_name_to_handle_at,sys_name_to_handle_at_wrappe | |||
347 | SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at_wrapper) | 347 | SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at_wrapper) |
348 | SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper) | 348 | SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper) |
349 | SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper) | 349 | SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper) |
350 | SYSCALL(sys_setns,sys_setns,sys_setns_wrapper) | ||
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 71a4b0d34be0..51e5cd9b906a 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * using the stura instruction. | 19 | * using the stura instruction. |
20 | * Returns the number of bytes copied or -EFAULT. | 20 | * Returns the number of bytes copied or -EFAULT. |
21 | */ | 21 | */ |
22 | static long probe_kernel_write_odd(void *dst, void *src, size_t size) | 22 | static long probe_kernel_write_odd(void *dst, const void *src, size_t size) |
23 | { | 23 | { |
24 | unsigned long count, aligned; | 24 | unsigned long count, aligned; |
25 | int offset, mask; | 25 | int offset, mask; |
@@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void *dst, void *src, size_t size) | |||
45 | return rc ? rc : count; | 45 | return rc ? rc : count; |
46 | } | 46 | } |
47 | 47 | ||
48 | long probe_kernel_write(void *dst, void *src, size_t size) | 48 | long probe_kernel_write(void *dst, const void *src, size_t size) |
49 | { | 49 | { |
50 | long copied = 0; | 50 | long copied = 0; |
51 | 51 | ||
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 14c6fae6fe6b..b09763fe5da1 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -71,12 +71,15 @@ static void rcu_table_freelist_callback(struct rcu_head *head) | |||
71 | 71 | ||
72 | void rcu_table_freelist_finish(void) | 72 | void rcu_table_freelist_finish(void) |
73 | { | 73 | { |
74 | struct rcu_table_freelist *batch = __get_cpu_var(rcu_table_freelist); | 74 | struct rcu_table_freelist **batchp = &get_cpu_var(rcu_table_freelist); |
75 | struct rcu_table_freelist *batch = *batchp; | ||
75 | 76 | ||
76 | if (!batch) | 77 | if (!batch) |
77 | return; | 78 | goto out; |
78 | call_rcu(&batch->rcu, rcu_table_freelist_callback); | 79 | call_rcu(&batch->rcu, rcu_table_freelist_callback); |
79 | __get_cpu_var(rcu_table_freelist) = NULL; | 80 | *batchp = NULL; |
81 | out: | ||
82 | put_cpu_var(rcu_table_freelist); | ||
80 | } | 83 | } |
81 | 84 | ||
82 | static void smp_sync(void *arg) | 85 | static void smp_sync(void *arg) |
@@ -141,20 +144,23 @@ void crst_table_free_rcu(struct mm_struct *mm, unsigned long *table) | |||
141 | { | 144 | { |
142 | struct rcu_table_freelist *batch; | 145 | struct rcu_table_freelist *batch; |
143 | 146 | ||
147 | preempt_disable(); | ||
144 | if (atomic_read(&mm->mm_users) < 2 && | 148 | if (atomic_read(&mm->mm_users) < 2 && |
145 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { | 149 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { |
146 | crst_table_free(mm, table); | 150 | crst_table_free(mm, table); |
147 | return; | 151 | goto out; |
148 | } | 152 | } |
149 | batch = rcu_table_freelist_get(mm); | 153 | batch = rcu_table_freelist_get(mm); |
150 | if (!batch) { | 154 | if (!batch) { |
151 | smp_call_function(smp_sync, NULL, 1); | 155 | smp_call_function(smp_sync, NULL, 1); |
152 | crst_table_free(mm, table); | 156 | crst_table_free(mm, table); |
153 | return; | 157 | goto out; |
154 | } | 158 | } |
155 | batch->table[--batch->crst_index] = table; | 159 | batch->table[--batch->crst_index] = table; |
156 | if (batch->pgt_index >= batch->crst_index) | 160 | if (batch->pgt_index >= batch->crst_index) |
157 | rcu_table_freelist_finish(); | 161 | rcu_table_freelist_finish(); |
162 | out: | ||
163 | preempt_enable(); | ||
158 | } | 164 | } |
159 | 165 | ||
160 | #ifdef CONFIG_64BIT | 166 | #ifdef CONFIG_64BIT |
@@ -323,16 +329,17 @@ void page_table_free_rcu(struct mm_struct *mm, unsigned long *table) | |||
323 | struct page *page; | 329 | struct page *page; |
324 | unsigned long bits; | 330 | unsigned long bits; |
325 | 331 | ||
332 | preempt_disable(); | ||
326 | if (atomic_read(&mm->mm_users) < 2 && | 333 | if (atomic_read(&mm->mm_users) < 2 && |
327 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { | 334 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { |
328 | page_table_free(mm, table); | 335 | page_table_free(mm, table); |
329 | return; | 336 | goto out; |
330 | } | 337 | } |
331 | batch = rcu_table_freelist_get(mm); | 338 | batch = rcu_table_freelist_get(mm); |
332 | if (!batch) { | 339 | if (!batch) { |
333 | smp_call_function(smp_sync, NULL, 1); | 340 | smp_call_function(smp_sync, NULL, 1); |
334 | page_table_free(mm, table); | 341 | page_table_free(mm, table); |
335 | return; | 342 | goto out; |
336 | } | 343 | } |
337 | bits = (mm->context.has_pgste) ? 3UL : 1UL; | 344 | bits = (mm->context.has_pgste) ? 3UL : 1UL; |
338 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); | 345 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); |
@@ -345,6 +352,8 @@ void page_table_free_rcu(struct mm_struct *mm, unsigned long *table) | |||
345 | batch->table[batch->pgt_index++] = table; | 352 | batch->table[batch->pgt_index++] = table; |
346 | if (batch->pgt_index >= batch->crst_index) | 353 | if (batch->pgt_index >= batch->crst_index) |
347 | rcu_table_freelist_finish(); | 354 | rcu_table_freelist_finish(); |
355 | out: | ||
356 | preempt_enable(); | ||
348 | } | 357 | } |
349 | 358 | ||
350 | /* | 359 | /* |
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index bb7d2702c2c9..3432008d2888 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h | |||
@@ -374,8 +374,9 @@ | |||
374 | #define __NR_clock_adjtime 361 | 374 | #define __NR_clock_adjtime 361 |
375 | #define __NR_syncfs 362 | 375 | #define __NR_syncfs 362 |
376 | #define __NR_sendmmsg 363 | 376 | #define __NR_sendmmsg 363 |
377 | #define __NR_setns 364 | ||
377 | 378 | ||
378 | #define NR_syscalls 364 | 379 | #define NR_syscalls 365 |
379 | 380 | ||
380 | #ifdef __KERNEL__ | 381 | #ifdef __KERNEL__ |
381 | 382 | ||
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h index 46327cea1e5c..ec9898665f23 100644 --- a/arch/sh/include/asm/unistd_64.h +++ b/arch/sh/include/asm/unistd_64.h | |||
@@ -395,10 +395,11 @@ | |||
395 | #define __NR_clock_adjtime 372 | 395 | #define __NR_clock_adjtime 372 |
396 | #define __NR_syncfs 373 | 396 | #define __NR_syncfs 373 |
397 | #define __NR_sendmmsg 374 | 397 | #define __NR_sendmmsg 374 |
398 | #define __NR_setns 375 | ||
398 | 399 | ||
399 | #ifdef __KERNEL__ | 400 | #ifdef __KERNEL__ |
400 | 401 | ||
401 | #define NR_syscalls 375 | 402 | #define NR_syscalls 376 |
402 | 403 | ||
403 | #define __ARCH_WANT_IPC_PARSE_VERSION | 404 | #define __ARCH_WANT_IPC_PARSE_VERSION |
404 | #define __ARCH_WANT_OLD_READDIR | 405 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 7c486f3e3a3c..39b051de4c7c 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
@@ -381,3 +381,4 @@ ENTRY(sys_call_table) | |||
381 | .long sys_clock_adjtime | 381 | .long sys_clock_adjtime |
382 | .long sys_syncfs | 382 | .long sys_syncfs |
383 | .long sys_sendmmsg | 383 | .long sys_sendmmsg |
384 | .long sys_setns | ||
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index ba1a737afe80..089c4d825d08 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S | |||
@@ -401,3 +401,4 @@ sys_call_table: | |||
401 | .long sys_clock_adjtime | 401 | .long sys_clock_adjtime |
402 | .long sys_syncfs | 402 | .long sys_syncfs |
403 | .long sys_sendmmsg | 403 | .long sys_sendmmsg |
404 | .long sys_setns /* 375 */ | ||
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index c5387ed0add8..6260d5deeabc 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
@@ -405,8 +405,9 @@ | |||
405 | #define __NR_clock_adjtime 334 | 405 | #define __NR_clock_adjtime 334 |
406 | #define __NR_syncfs 335 | 406 | #define __NR_syncfs 335 |
407 | #define __NR_sendmmsg 336 | 407 | #define __NR_sendmmsg 336 |
408 | #define __NR_setns 337 | ||
408 | 409 | ||
409 | #define NR_syscalls 337 | 410 | #define NR_syscalls 338 |
410 | 411 | ||
411 | #ifdef __32bit_syscall_numbers__ | 412 | #ifdef __32bit_syscall_numbers__ |
412 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 413 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 332c83ff7701..6e492d59f6b1 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
@@ -84,4 +84,4 @@ sys_call_table: | |||
84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime | 86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
87 | /*335*/ .long sys_syncfs, sys_sendmmsg | 87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns |
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 43887ca0be0e..f566518483b5 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -85,7 +85,7 @@ sys_call_table32: | |||
85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv | 85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv |
86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init |
87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime | 87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime |
88 | .word sys_syncfs, compat_sys_sendmmsg | 88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns |
89 | 89 | ||
90 | #endif /* CONFIG_COMPAT */ | 90 | #endif /* CONFIG_COMPAT */ |
91 | 91 | ||
@@ -162,4 +162,4 @@ sys_call_table: | |||
162 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 162 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
163 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init | 163 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
164 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime | 164 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
165 | .word sys_syncfs, sys_sendmmsg | 165 | .word sys_syncfs, sys_sendmmsg, sys_setns |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index e1e50101b3bb..0249b8b4db54 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -11,6 +11,7 @@ config TILE | |||
11 | select GENERIC_IRQ_PROBE | 11 | select GENERIC_IRQ_PROBE |
12 | select GENERIC_PENDING_IRQ if SMP | 12 | select GENERIC_PENDING_IRQ if SMP |
13 | select GENERIC_IRQ_SHOW | 13 | select GENERIC_IRQ_SHOW |
14 | select SYS_HYPERVISOR | ||
14 | 15 | ||
15 | # FIXME: investigate whether we need/want these options. | 16 | # FIXME: investigate whether we need/want these options. |
16 | # select HAVE_IOREMAP_PROT | 17 | # select HAVE_IOREMAP_PROT |
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h index 0bed3ec7b42c..2ac422848c7d 100644 --- a/arch/tile/include/asm/hardwall.h +++ b/arch/tile/include/asm/hardwall.h | |||
@@ -40,6 +40,10 @@ | |||
40 | #define HARDWALL_DEACTIVATE \ | 40 | #define HARDWALL_DEACTIVATE \ |
41 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE) | 41 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE) |
42 | 42 | ||
43 | #define _HARDWALL_GET_ID 4 | ||
44 | #define HARDWALL_GET_ID \ | ||
45 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID) | ||
46 | |||
43 | #ifndef __KERNEL__ | 47 | #ifndef __KERNEL__ |
44 | 48 | ||
45 | /* This is the canonical name expected by userspace. */ | 49 | /* This is the canonical name expected by userspace. */ |
@@ -47,9 +51,14 @@ | |||
47 | 51 | ||
48 | #else | 52 | #else |
49 | 53 | ||
50 | /* Hook for /proc/tile/hardwall. */ | 54 | /* /proc hooks for hardwall. */ |
51 | struct seq_file; | 55 | struct proc_dir_entry; |
52 | int proc_tile_hardwall_show(struct seq_file *sf, void *v); | 56 | #ifdef CONFIG_HARDWALL |
57 | void proc_tile_hardwall_init(struct proc_dir_entry *root); | ||
58 | int proc_pid_hardwall(struct task_struct *task, char *buffer); | ||
59 | #else | ||
60 | static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {} | ||
61 | #endif | ||
53 | 62 | ||
54 | #endif | 63 | #endif |
55 | 64 | ||
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile index b4c8e8ec45dc..b4dbc057baad 100644 --- a/arch/tile/kernel/Makefile +++ b/arch/tile/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := vmlinux.lds head_$(BITS).o | 5 | extra-y := vmlinux.lds head_$(BITS).o |
6 | obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \ | 6 | obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \ |
7 | pci-dma.o proc.o process.o ptrace.o reboot.o \ | 7 | pci-dma.o proc.o process.o ptrace.o reboot.o \ |
8 | setup.o signal.o single_step.o stack.o sys.o time.o traps.o \ | 8 | setup.o signal.o single_step.o stack.o sys.o sysfs.o time.o traps.o \ |
9 | intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o | 9 | intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o |
10 | 10 | ||
11 | obj-$(CONFIG_HARDWALL) += hardwall.o | 11 | obj-$(CONFIG_HARDWALL) += hardwall.o |
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 3bddef710de4..8c41891aab34 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c | |||
@@ -40,16 +40,25 @@ | |||
40 | struct hardwall_info { | 40 | struct hardwall_info { |
41 | struct list_head list; /* "rectangles" list */ | 41 | struct list_head list; /* "rectangles" list */ |
42 | struct list_head task_head; /* head of tasks in this hardwall */ | 42 | struct list_head task_head; /* head of tasks in this hardwall */ |
43 | struct cpumask cpumask; /* cpus in the rectangle */ | ||
43 | int ulhc_x; /* upper left hand corner x coord */ | 44 | int ulhc_x; /* upper left hand corner x coord */ |
44 | int ulhc_y; /* upper left hand corner y coord */ | 45 | int ulhc_y; /* upper left hand corner y coord */ |
45 | int width; /* rectangle width */ | 46 | int width; /* rectangle width */ |
46 | int height; /* rectangle height */ | 47 | int height; /* rectangle height */ |
48 | int id; /* integer id for this hardwall */ | ||
47 | int teardown_in_progress; /* are we tearing this one down? */ | 49 | int teardown_in_progress; /* are we tearing this one down? */ |
48 | }; | 50 | }; |
49 | 51 | ||
50 | /* Currently allocated hardwall rectangles */ | 52 | /* Currently allocated hardwall rectangles */ |
51 | static LIST_HEAD(rectangles); | 53 | static LIST_HEAD(rectangles); |
52 | 54 | ||
55 | /* /proc/tile/hardwall */ | ||
56 | static struct proc_dir_entry *hardwall_proc_dir; | ||
57 | |||
58 | /* Functions to manage files in /proc/tile/hardwall. */ | ||
59 | static void hardwall_add_proc(struct hardwall_info *rect); | ||
60 | static void hardwall_remove_proc(struct hardwall_info *rect); | ||
61 | |||
53 | /* | 62 | /* |
54 | * Guard changes to the hardwall data structures. | 63 | * Guard changes to the hardwall data structures. |
55 | * This could be finer grained (e.g. one lock for the list of hardwall | 64 | * This could be finer grained (e.g. one lock for the list of hardwall |
@@ -105,6 +114,8 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask) | |||
105 | r->ulhc_y = cpu_y(ulhc); | 114 | r->ulhc_y = cpu_y(ulhc); |
106 | r->width = cpu_x(lrhc) - r->ulhc_x + 1; | 115 | r->width = cpu_x(lrhc) - r->ulhc_x + 1; |
107 | r->height = cpu_y(lrhc) - r->ulhc_y + 1; | 116 | r->height = cpu_y(lrhc) - r->ulhc_y + 1; |
117 | cpumask_copy(&r->cpumask, mask); | ||
118 | r->id = ulhc; /* The ulhc cpu id can be the hardwall id. */ | ||
108 | 119 | ||
109 | /* Width and height must be positive */ | 120 | /* Width and height must be positive */ |
110 | if (r->width <= 0 || r->height <= 0) | 121 | if (r->width <= 0 || r->height <= 0) |
@@ -388,6 +399,9 @@ static struct hardwall_info *hardwall_create( | |||
388 | /* Set up appropriate hardwalling on all affected cpus. */ | 399 | /* Set up appropriate hardwalling on all affected cpus. */ |
389 | hardwall_setup(rect); | 400 | hardwall_setup(rect); |
390 | 401 | ||
402 | /* Create a /proc/tile/hardwall entry. */ | ||
403 | hardwall_add_proc(rect); | ||
404 | |||
391 | return rect; | 405 | return rect; |
392 | } | 406 | } |
393 | 407 | ||
@@ -645,6 +659,9 @@ static void hardwall_destroy(struct hardwall_info *rect) | |||
645 | /* Restart switch and disable firewall. */ | 659 | /* Restart switch and disable firewall. */ |
646 | on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1); | 660 | on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1); |
647 | 661 | ||
662 | /* Remove the /proc/tile/hardwall entry. */ | ||
663 | hardwall_remove_proc(rect); | ||
664 | |||
648 | /* Now free the rectangle from the list. */ | 665 | /* Now free the rectangle from the list. */ |
649 | spin_lock_irqsave(&hardwall_lock, flags); | 666 | spin_lock_irqsave(&hardwall_lock, flags); |
650 | BUG_ON(!list_empty(&rect->task_head)); | 667 | BUG_ON(!list_empty(&rect->task_head)); |
@@ -654,35 +671,57 @@ static void hardwall_destroy(struct hardwall_info *rect) | |||
654 | } | 671 | } |
655 | 672 | ||
656 | 673 | ||
657 | /* | 674 | static int hardwall_proc_show(struct seq_file *sf, void *v) |
658 | * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c. | ||
659 | */ | ||
660 | int proc_tile_hardwall_show(struct seq_file *sf, void *v) | ||
661 | { | 675 | { |
662 | struct hardwall_info *r; | 676 | struct hardwall_info *rect = sf->private; |
677 | char buf[256]; | ||
663 | 678 | ||
664 | if (udn_disabled) { | 679 | int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask); |
665 | seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height); | 680 | buf[rc++] = '\n'; |
666 | return 0; | 681 | seq_write(sf, buf, rc); |
667 | } | ||
668 | |||
669 | spin_lock_irq(&hardwall_lock); | ||
670 | list_for_each_entry(r, &rectangles, list) { | ||
671 | struct task_struct *p; | ||
672 | seq_printf(sf, "%dx%d %d,%d pids:", | ||
673 | r->width, r->height, r->ulhc_x, r->ulhc_y); | ||
674 | list_for_each_entry(p, &r->task_head, thread.hardwall_list) { | ||
675 | unsigned int cpu = cpumask_first(&p->cpus_allowed); | ||
676 | unsigned int x = cpu % smp_width; | ||
677 | unsigned int y = cpu / smp_width; | ||
678 | seq_printf(sf, " %d@%d,%d", p->pid, x, y); | ||
679 | } | ||
680 | seq_printf(sf, "\n"); | ||
681 | } | ||
682 | spin_unlock_irq(&hardwall_lock); | ||
683 | return 0; | 682 | return 0; |
684 | } | 683 | } |
685 | 684 | ||
685 | static int hardwall_proc_open(struct inode *inode, | ||
686 | struct file *file) | ||
687 | { | ||
688 | return single_open(file, hardwall_proc_show, PDE(inode)->data); | ||
689 | } | ||
690 | |||
691 | static const struct file_operations hardwall_proc_fops = { | ||
692 | .open = hardwall_proc_open, | ||
693 | .read = seq_read, | ||
694 | .llseek = seq_lseek, | ||
695 | .release = single_release, | ||
696 | }; | ||
697 | |||
698 | static void hardwall_add_proc(struct hardwall_info *rect) | ||
699 | { | ||
700 | char buf[64]; | ||
701 | snprintf(buf, sizeof(buf), "%d", rect->id); | ||
702 | proc_create_data(buf, 0444, hardwall_proc_dir, | ||
703 | &hardwall_proc_fops, rect); | ||
704 | } | ||
705 | |||
706 | static void hardwall_remove_proc(struct hardwall_info *rect) | ||
707 | { | ||
708 | char buf[64]; | ||
709 | snprintf(buf, sizeof(buf), "%d", rect->id); | ||
710 | remove_proc_entry(buf, hardwall_proc_dir); | ||
711 | } | ||
712 | |||
713 | int proc_pid_hardwall(struct task_struct *task, char *buffer) | ||
714 | { | ||
715 | struct hardwall_info *rect = task->thread.hardwall; | ||
716 | return rect ? sprintf(buffer, "%d\n", rect->id) : 0; | ||
717 | } | ||
718 | |||
719 | void proc_tile_hardwall_init(struct proc_dir_entry *root) | ||
720 | { | ||
721 | if (!udn_disabled) | ||
722 | hardwall_proc_dir = proc_mkdir("hardwall", root); | ||
723 | } | ||
724 | |||
686 | 725 | ||
687 | /* | 726 | /* |
688 | * Character device support via ioctl/close. | 727 | * Character device support via ioctl/close. |
@@ -716,6 +755,9 @@ static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b) | |||
716 | return -EINVAL; | 755 | return -EINVAL; |
717 | return hardwall_deactivate(current); | 756 | return hardwall_deactivate(current); |
718 | 757 | ||
758 | case _HARDWALL_GET_ID: | ||
759 | return rect ? rect->id : -EINVAL; | ||
760 | |||
719 | default: | 761 | default: |
720 | return -EINVAL; | 762 | return -EINVAL; |
721 | } | 763 | } |
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c index 2e02c41ddf3b..62d820833c68 100644 --- a/arch/tile/kernel/proc.c +++ b/arch/tile/kernel/proc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
28 | #include <asm/sections.h> | 28 | #include <asm/sections.h> |
29 | #include <asm/homecache.h> | 29 | #include <asm/homecache.h> |
30 | #include <asm/hardwall.h> | ||
30 | #include <arch/chip.h> | 31 | #include <arch/chip.h> |
31 | 32 | ||
32 | 33 | ||
@@ -88,3 +89,75 @@ const struct seq_operations cpuinfo_op = { | |||
88 | .stop = c_stop, | 89 | .stop = c_stop, |
89 | .show = show_cpuinfo, | 90 | .show = show_cpuinfo, |
90 | }; | 91 | }; |
92 | |||
93 | /* | ||
94 | * Support /proc/tile directory | ||
95 | */ | ||
96 | |||
97 | static int __init proc_tile_init(void) | ||
98 | { | ||
99 | struct proc_dir_entry *root = proc_mkdir("tile", NULL); | ||
100 | if (root == NULL) | ||
101 | return 0; | ||
102 | |||
103 | proc_tile_hardwall_init(root); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | arch_initcall(proc_tile_init); | ||
109 | |||
110 | /* | ||
111 | * Support /proc/sys/tile directory | ||
112 | */ | ||
113 | |||
114 | #ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ | ||
115 | static ctl_table unaligned_subtable[] = { | ||
116 | { | ||
117 | .procname = "enabled", | ||
118 | .data = &unaligned_fixup, | ||
119 | .maxlen = sizeof(int), | ||
120 | .mode = 0644, | ||
121 | .proc_handler = &proc_dointvec | ||
122 | }, | ||
123 | { | ||
124 | .procname = "printk", | ||
125 | .data = &unaligned_printk, | ||
126 | .maxlen = sizeof(int), | ||
127 | .mode = 0644, | ||
128 | .proc_handler = &proc_dointvec | ||
129 | }, | ||
130 | { | ||
131 | .procname = "count", | ||
132 | .data = &unaligned_fixup_count, | ||
133 | .maxlen = sizeof(int), | ||
134 | .mode = 0644, | ||
135 | .proc_handler = &proc_dointvec | ||
136 | }, | ||
137 | {} | ||
138 | }; | ||
139 | |||
140 | static ctl_table unaligned_table[] = { | ||
141 | { | ||
142 | .procname = "unaligned_fixup", | ||
143 | .mode = 0555, | ||
144 | .child = unaligned_subtable | ||
145 | }, | ||
146 | {} | ||
147 | }; | ||
148 | #endif | ||
149 | |||
150 | static struct ctl_path tile_path[] = { | ||
151 | { .procname = "tile" }, | ||
152 | { } | ||
153 | }; | ||
154 | |||
155 | static int __init proc_sys_tile_init(void) | ||
156 | { | ||
157 | #ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ | ||
158 | register_sysctl_paths(tile_path, unaligned_table); | ||
159 | #endif | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | arch_initcall(proc_sys_tile_init); | ||
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c new file mode 100644 index 000000000000..b671a86f4515 --- /dev/null +++ b/arch/tile/kernel/sysfs.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * /sys entry support. | ||
15 | */ | ||
16 | |||
17 | #include <linux/sysdev.h> | ||
18 | #include <linux/cpu.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/smp.h> | ||
21 | #include <hv/hypervisor.h> | ||
22 | |||
23 | /* Return a string queried from the hypervisor, truncated to page size. */ | ||
24 | static ssize_t get_hv_confstr(char *page, int query) | ||
25 | { | ||
26 | ssize_t n = hv_confstr(query, (unsigned long)page, PAGE_SIZE - 1); | ||
27 | n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1) - 1; | ||
28 | if (n) | ||
29 | page[n++] = '\n'; | ||
30 | page[n] = '\0'; | ||
31 | return n; | ||
32 | } | ||
33 | |||
34 | static ssize_t chip_width_show(struct sysdev_class *dev, | ||
35 | struct sysdev_class_attribute *attr, | ||
36 | char *page) | ||
37 | { | ||
38 | return sprintf(page, "%u\n", smp_width); | ||
39 | } | ||
40 | static SYSDEV_CLASS_ATTR(chip_width, 0444, chip_width_show, NULL); | ||
41 | |||
42 | static ssize_t chip_height_show(struct sysdev_class *dev, | ||
43 | struct sysdev_class_attribute *attr, | ||
44 | char *page) | ||
45 | { | ||
46 | return sprintf(page, "%u\n", smp_height); | ||
47 | } | ||
48 | static SYSDEV_CLASS_ATTR(chip_height, 0444, chip_height_show, NULL); | ||
49 | |||
50 | static ssize_t chip_serial_show(struct sysdev_class *dev, | ||
51 | struct sysdev_class_attribute *attr, | ||
52 | char *page) | ||
53 | { | ||
54 | return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM); | ||
55 | } | ||
56 | static SYSDEV_CLASS_ATTR(chip_serial, 0444, chip_serial_show, NULL); | ||
57 | |||
58 | static ssize_t chip_revision_show(struct sysdev_class *dev, | ||
59 | struct sysdev_class_attribute *attr, | ||
60 | char *page) | ||
61 | { | ||
62 | return get_hv_confstr(page, HV_CONFSTR_CHIP_REV); | ||
63 | } | ||
64 | static SYSDEV_CLASS_ATTR(chip_revision, 0444, chip_revision_show, NULL); | ||
65 | |||
66 | |||
67 | static ssize_t type_show(struct sysdev_class *dev, | ||
68 | struct sysdev_class_attribute *attr, | ||
69 | char *page) | ||
70 | { | ||
71 | return sprintf(page, "tilera\n"); | ||
72 | } | ||
73 | static SYSDEV_CLASS_ATTR(type, 0444, type_show, NULL); | ||
74 | |||
75 | #define HV_CONF_ATTR(name, conf) \ | ||
76 | static ssize_t name ## _show(struct sysdev_class *dev, \ | ||
77 | struct sysdev_class_attribute *attr, \ | ||
78 | char *page) \ | ||
79 | { \ | ||
80 | return get_hv_confstr(page, conf); \ | ||
81 | } \ | ||
82 | static SYSDEV_CLASS_ATTR(name, 0444, name ## _show, NULL); | ||
83 | |||
84 | HV_CONF_ATTR(version, HV_CONFSTR_HV_SW_VER) | ||
85 | HV_CONF_ATTR(config_version, HV_CONFSTR_HV_CONFIG_VER) | ||
86 | |||
87 | HV_CONF_ATTR(board_part, HV_CONFSTR_BOARD_PART_NUM) | ||
88 | HV_CONF_ATTR(board_serial, HV_CONFSTR_BOARD_SERIAL_NUM) | ||
89 | HV_CONF_ATTR(board_revision, HV_CONFSTR_BOARD_REV) | ||
90 | HV_CONF_ATTR(board_description, HV_CONFSTR_BOARD_DESC) | ||
91 | HV_CONF_ATTR(mezz_part, HV_CONFSTR_MEZZ_PART_NUM) | ||
92 | HV_CONF_ATTR(mezz_serial, HV_CONFSTR_MEZZ_SERIAL_NUM) | ||
93 | HV_CONF_ATTR(mezz_revision, HV_CONFSTR_MEZZ_REV) | ||
94 | HV_CONF_ATTR(mezz_description, HV_CONFSTR_MEZZ_DESC) | ||
95 | HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL) | ||
96 | |||
97 | static struct attribute *board_attrs[] = { | ||
98 | &attr_board_part.attr, | ||
99 | &attr_board_serial.attr, | ||
100 | &attr_board_revision.attr, | ||
101 | &attr_board_description.attr, | ||
102 | &attr_mezz_part.attr, | ||
103 | &attr_mezz_serial.attr, | ||
104 | &attr_mezz_revision.attr, | ||
105 | &attr_mezz_description.attr, | ||
106 | &attr_switch_control.attr, | ||
107 | NULL | ||
108 | }; | ||
109 | |||
110 | static struct attribute_group board_attr_group = { | ||
111 | .name = "board", | ||
112 | .attrs = board_attrs, | ||
113 | }; | ||
114 | |||
115 | |||
116 | static struct bin_attribute hvconfig_bin; | ||
117 | |||
118 | static ssize_t | ||
119 | hvconfig_bin_read(struct file *filp, struct kobject *kobj, | ||
120 | struct bin_attribute *bin_attr, | ||
121 | char *buf, loff_t off, size_t count) | ||
122 | { | ||
123 | static size_t size; | ||
124 | |||
125 | /* Lazily learn the true size (minus the trailing NUL). */ | ||
126 | if (size == 0) | ||
127 | size = hv_confstr(HV_CONFSTR_HV_CONFIG, 0, 0) - 1; | ||
128 | |||
129 | /* Check and adjust input parameters. */ | ||
130 | if (off > size) | ||
131 | return -EINVAL; | ||
132 | if (count > size - off) | ||
133 | count = size - off; | ||
134 | |||
135 | if (count) { | ||
136 | /* Get a copy of the hvc and copy out the relevant portion. */ | ||
137 | char *hvc; | ||
138 | |||
139 | size = off + count; | ||
140 | hvc = kmalloc(size, GFP_KERNEL); | ||
141 | if (hvc == NULL) | ||
142 | return -ENOMEM; | ||
143 | hv_confstr(HV_CONFSTR_HV_CONFIG, (unsigned long)hvc, size); | ||
144 | memcpy(buf, hvc + off, count); | ||
145 | kfree(hvc); | ||
146 | } | ||
147 | |||
148 | return count; | ||
149 | } | ||
150 | |||
151 | static int __init create_sysfs_entries(void) | ||
152 | { | ||
153 | struct sysdev_class *cls = &cpu_sysdev_class; | ||
154 | int err = 0; | ||
155 | |||
156 | #define create_cpu_attr(name) \ | ||
157 | if (!err) \ | ||
158 | err = sysfs_create_file(&cls->kset.kobj, &attr_##name.attr); | ||
159 | create_cpu_attr(chip_width); | ||
160 | create_cpu_attr(chip_height); | ||
161 | create_cpu_attr(chip_serial); | ||
162 | create_cpu_attr(chip_revision); | ||
163 | |||
164 | #define create_hv_attr(name) \ | ||
165 | if (!err) \ | ||
166 | err = sysfs_create_file(hypervisor_kobj, &attr_##name.attr); | ||
167 | create_hv_attr(type); | ||
168 | create_hv_attr(version); | ||
169 | create_hv_attr(config_version); | ||
170 | |||
171 | if (!err) | ||
172 | err = sysfs_create_group(hypervisor_kobj, &board_attr_group); | ||
173 | |||
174 | if (!err) { | ||
175 | sysfs_bin_attr_init(&hvconfig_bin); | ||
176 | hvconfig_bin.attr.name = "hvconfig"; | ||
177 | hvconfig_bin.attr.mode = S_IRUGO; | ||
178 | hvconfig_bin.read = hvconfig_bin_read; | ||
179 | hvconfig_bin.size = PAGE_SIZE; | ||
180 | err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin); | ||
181 | } | ||
182 | |||
183 | return err; | ||
184 | } | ||
185 | subsys_initcall(create_sysfs_entries); | ||
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 95f5826be458..c1870dddd322 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -849,4 +849,5 @@ ia32_sys_call_table: | |||
849 | .quad compat_sys_clock_adjtime | 849 | .quad compat_sys_clock_adjtime |
850 | .quad sys_syncfs | 850 | .quad sys_syncfs |
851 | .quad compat_sys_sendmmsg /* 345 */ | 851 | .quad compat_sys_sendmmsg /* 345 */ |
852 | .quad sys_setns | ||
852 | ia32_syscall_end: | 853 | ia32_syscall_end: |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 416d865eae39..610001d385dd 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -139,7 +139,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) | |||
139 | boot_cpu_data.x86_model <= 0x05 && | 139 | boot_cpu_data.x86_model <= 0x05 && |
140 | boot_cpu_data.x86_mask < 0x0A) | 140 | boot_cpu_data.x86_mask < 0x0A) |
141 | return 1; | 141 | return 1; |
142 | else if (c1e_detected) | 142 | else if (amd_e400_c1e_detected) |
143 | return 1; | 143 | return 1; |
144 | else | 144 | else |
145 | return max_cstate; | 145 | return max_cstate; |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 5dc6acc98dbd..71cc3800712c 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -125,7 +125,7 @@ | |||
125 | #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ | 125 | #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ |
126 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ | 126 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ |
127 | #define X86_FEATURE_F16C (4*32+29) /* 16-bit fp conversions */ | 127 | #define X86_FEATURE_F16C (4*32+29) /* 16-bit fp conversions */ |
128 | #define X86_FEATURE_RDRND (4*32+30) /* The RDRAND instruction */ | 128 | #define X86_FEATURE_RDRAND (4*32+30) /* The RDRAND instruction */ |
129 | #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ | 129 | #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ |
130 | 130 | ||
131 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ | 131 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ |
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 617bd56b3070..7b439d9aea2a 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -4,30 +4,33 @@ | |||
4 | #include <asm/desc_defs.h> | 4 | #include <asm/desc_defs.h> |
5 | #include <asm/ldt.h> | 5 | #include <asm/ldt.h> |
6 | #include <asm/mmu.h> | 6 | #include <asm/mmu.h> |
7 | |||
7 | #include <linux/smp.h> | 8 | #include <linux/smp.h> |
8 | 9 | ||
9 | static inline void fill_ldt(struct desc_struct *desc, | 10 | static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info) |
10 | const struct user_desc *info) | 11 | { |
11 | { | 12 | desc->limit0 = info->limit & 0x0ffff; |
12 | desc->limit0 = info->limit & 0x0ffff; | 13 | |
13 | desc->base0 = info->base_addr & 0x0000ffff; | 14 | desc->base0 = (info->base_addr & 0x0000ffff); |
14 | 15 | desc->base1 = (info->base_addr & 0x00ff0000) >> 16; | |
15 | desc->base1 = (info->base_addr & 0x00ff0000) >> 16; | 16 | |
16 | desc->type = (info->read_exec_only ^ 1) << 1; | 17 | desc->type = (info->read_exec_only ^ 1) << 1; |
17 | desc->type |= info->contents << 2; | 18 | desc->type |= info->contents << 2; |
18 | desc->s = 1; | 19 | |
19 | desc->dpl = 0x3; | 20 | desc->s = 1; |
20 | desc->p = info->seg_not_present ^ 1; | 21 | desc->dpl = 0x3; |
21 | desc->limit = (info->limit & 0xf0000) >> 16; | 22 | desc->p = info->seg_not_present ^ 1; |
22 | desc->avl = info->useable; | 23 | desc->limit = (info->limit & 0xf0000) >> 16; |
23 | desc->d = info->seg_32bit; | 24 | desc->avl = info->useable; |
24 | desc->g = info->limit_in_pages; | 25 | desc->d = info->seg_32bit; |
25 | desc->base2 = (info->base_addr & 0xff000000) >> 24; | 26 | desc->g = info->limit_in_pages; |
27 | |||
28 | desc->base2 = (info->base_addr & 0xff000000) >> 24; | ||
26 | /* | 29 | /* |
27 | * Don't allow setting of the lm bit. It is useless anyway | 30 | * Don't allow setting of the lm bit. It is useless anyway |
28 | * because 64bit system calls require __USER_CS: | 31 | * because 64bit system calls require __USER_CS: |
29 | */ | 32 | */ |
30 | desc->l = 0; | 33 | desc->l = 0; |
31 | } | 34 | } |
32 | 35 | ||
33 | extern struct desc_ptr idt_descr; | 36 | extern struct desc_ptr idt_descr; |
@@ -36,6 +39,7 @@ extern gate_desc idt_table[]; | |||
36 | struct gdt_page { | 39 | struct gdt_page { |
37 | struct desc_struct gdt[GDT_ENTRIES]; | 40 | struct desc_struct gdt[GDT_ENTRIES]; |
38 | } __attribute__((aligned(PAGE_SIZE))); | 41 | } __attribute__((aligned(PAGE_SIZE))); |
42 | |||
39 | DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page); | 43 | DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page); |
40 | 44 | ||
41 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | 45 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) |
@@ -48,16 +52,16 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | |||
48 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, | 52 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, |
49 | unsigned dpl, unsigned ist, unsigned seg) | 53 | unsigned dpl, unsigned ist, unsigned seg) |
50 | { | 54 | { |
51 | gate->offset_low = PTR_LOW(func); | 55 | gate->offset_low = PTR_LOW(func); |
52 | gate->segment = __KERNEL_CS; | 56 | gate->segment = __KERNEL_CS; |
53 | gate->ist = ist; | 57 | gate->ist = ist; |
54 | gate->p = 1; | 58 | gate->p = 1; |
55 | gate->dpl = dpl; | 59 | gate->dpl = dpl; |
56 | gate->zero0 = 0; | 60 | gate->zero0 = 0; |
57 | gate->zero1 = 0; | 61 | gate->zero1 = 0; |
58 | gate->type = type; | 62 | gate->type = type; |
59 | gate->offset_middle = PTR_MIDDLE(func); | 63 | gate->offset_middle = PTR_MIDDLE(func); |
60 | gate->offset_high = PTR_HIGH(func); | 64 | gate->offset_high = PTR_HIGH(func); |
61 | } | 65 | } |
62 | 66 | ||
63 | #else | 67 | #else |
@@ -66,8 +70,7 @@ static inline void pack_gate(gate_desc *gate, unsigned char type, | |||
66 | unsigned short seg) | 70 | unsigned short seg) |
67 | { | 71 | { |
68 | gate->a = (seg << 16) | (base & 0xffff); | 72 | gate->a = (seg << 16) | (base & 0xffff); |
69 | gate->b = (base & 0xffff0000) | | 73 | gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8); |
70 | (((0x80 | type | (dpl << 5)) & 0xff) << 8); | ||
71 | } | 74 | } |
72 | 75 | ||
73 | #endif | 76 | #endif |
@@ -75,31 +78,29 @@ static inline void pack_gate(gate_desc *gate, unsigned char type, | |||
75 | static inline int desc_empty(const void *ptr) | 78 | static inline int desc_empty(const void *ptr) |
76 | { | 79 | { |
77 | const u32 *desc = ptr; | 80 | const u32 *desc = ptr; |
81 | |||
78 | return !(desc[0] | desc[1]); | 82 | return !(desc[0] | desc[1]); |
79 | } | 83 | } |
80 | 84 | ||
81 | #ifdef CONFIG_PARAVIRT | 85 | #ifdef CONFIG_PARAVIRT |
82 | #include <asm/paravirt.h> | 86 | #include <asm/paravirt.h> |
83 | #else | 87 | #else |
84 | #define load_TR_desc() native_load_tr_desc() | 88 | #define load_TR_desc() native_load_tr_desc() |
85 | #define load_gdt(dtr) native_load_gdt(dtr) | 89 | #define load_gdt(dtr) native_load_gdt(dtr) |
86 | #define load_idt(dtr) native_load_idt(dtr) | 90 | #define load_idt(dtr) native_load_idt(dtr) |
87 | #define load_tr(tr) asm volatile("ltr %0"::"m" (tr)) | 91 | #define load_tr(tr) asm volatile("ltr %0"::"m" (tr)) |
88 | #define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt)) | 92 | #define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt)) |
89 | 93 | ||
90 | #define store_gdt(dtr) native_store_gdt(dtr) | 94 | #define store_gdt(dtr) native_store_gdt(dtr) |
91 | #define store_idt(dtr) native_store_idt(dtr) | 95 | #define store_idt(dtr) native_store_idt(dtr) |
92 | #define store_tr(tr) (tr = native_store_tr()) | 96 | #define store_tr(tr) (tr = native_store_tr()) |
93 | 97 | ||
94 | #define load_TLS(t, cpu) native_load_tls(t, cpu) | 98 | #define load_TLS(t, cpu) native_load_tls(t, cpu) |
95 | #define set_ldt native_set_ldt | 99 | #define set_ldt native_set_ldt |
96 | 100 | ||
97 | #define write_ldt_entry(dt, entry, desc) \ | 101 | #define write_ldt_entry(dt, entry, desc) native_write_ldt_entry(dt, entry, desc) |
98 | native_write_ldt_entry(dt, entry, desc) | 102 | #define write_gdt_entry(dt, entry, desc, type) native_write_gdt_entry(dt, entry, desc, type) |
99 | #define write_gdt_entry(dt, entry, desc, type) \ | 103 | #define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) |
100 | native_write_gdt_entry(dt, entry, desc, type) | ||
101 | #define write_idt_entry(dt, entry, g) \ | ||
102 | native_write_idt_entry(dt, entry, g) | ||
103 | 104 | ||
104 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) | 105 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) |
105 | { | 106 | { |
@@ -112,33 +113,27 @@ static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) | |||
112 | 113 | ||
113 | #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) | 114 | #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) |
114 | 115 | ||
115 | static inline void native_write_idt_entry(gate_desc *idt, int entry, | 116 | static inline void native_write_idt_entry(gate_desc *idt, int entry, const gate_desc *gate) |
116 | const gate_desc *gate) | ||
117 | { | 117 | { |
118 | memcpy(&idt[entry], gate, sizeof(*gate)); | 118 | memcpy(&idt[entry], gate, sizeof(*gate)); |
119 | } | 119 | } |
120 | 120 | ||
121 | static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, | 121 | static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, const void *desc) |
122 | const void *desc) | ||
123 | { | 122 | { |
124 | memcpy(&ldt[entry], desc, 8); | 123 | memcpy(&ldt[entry], desc, 8); |
125 | } | 124 | } |
126 | 125 | ||
127 | static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, | 126 | static inline void |
128 | const void *desc, int type) | 127 | native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int type) |
129 | { | 128 | { |
130 | unsigned int size; | 129 | unsigned int size; |
130 | |||
131 | switch (type) { | 131 | switch (type) { |
132 | case DESC_TSS: | 132 | case DESC_TSS: size = sizeof(tss_desc); break; |
133 | size = sizeof(tss_desc); | 133 | case DESC_LDT: size = sizeof(ldt_desc); break; |
134 | break; | 134 | default: size = sizeof(*gdt); break; |
135 | case DESC_LDT: | ||
136 | size = sizeof(ldt_desc); | ||
137 | break; | ||
138 | default: | ||
139 | size = sizeof(struct desc_struct); | ||
140 | break; | ||
141 | } | 135 | } |
136 | |||
142 | memcpy(&gdt[entry], desc, size); | 137 | memcpy(&gdt[entry], desc, size); |
143 | } | 138 | } |
144 | 139 | ||
@@ -154,20 +149,21 @@ static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, | |||
154 | } | 149 | } |
155 | 150 | ||
156 | 151 | ||
157 | static inline void set_tssldt_descriptor(void *d, unsigned long addr, | 152 | static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size) |
158 | unsigned type, unsigned size) | ||
159 | { | 153 | { |
160 | #ifdef CONFIG_X86_64 | 154 | #ifdef CONFIG_X86_64 |
161 | struct ldttss_desc64 *desc = d; | 155 | struct ldttss_desc64 *desc = d; |
156 | |||
162 | memset(desc, 0, sizeof(*desc)); | 157 | memset(desc, 0, sizeof(*desc)); |
163 | desc->limit0 = size & 0xFFFF; | 158 | |
164 | desc->base0 = PTR_LOW(addr); | 159 | desc->limit0 = size & 0xFFFF; |
165 | desc->base1 = PTR_MIDDLE(addr) & 0xFF; | 160 | desc->base0 = PTR_LOW(addr); |
166 | desc->type = type; | 161 | desc->base1 = PTR_MIDDLE(addr) & 0xFF; |
167 | desc->p = 1; | 162 | desc->type = type; |
168 | desc->limit1 = (size >> 16) & 0xF; | 163 | desc->p = 1; |
169 | desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; | 164 | desc->limit1 = (size >> 16) & 0xF; |
170 | desc->base3 = PTR_HIGH(addr); | 165 | desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; |
166 | desc->base3 = PTR_HIGH(addr); | ||
171 | #else | 167 | #else |
172 | pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); | 168 | pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); |
173 | #endif | 169 | #endif |
@@ -237,14 +233,16 @@ static inline void native_store_idt(struct desc_ptr *dtr) | |||
237 | static inline unsigned long native_store_tr(void) | 233 | static inline unsigned long native_store_tr(void) |
238 | { | 234 | { |
239 | unsigned long tr; | 235 | unsigned long tr; |
236 | |||
240 | asm volatile("str %0":"=r" (tr)); | 237 | asm volatile("str %0":"=r" (tr)); |
238 | |||
241 | return tr; | 239 | return tr; |
242 | } | 240 | } |
243 | 241 | ||
244 | static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) | 242 | static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) |
245 | { | 243 | { |
246 | unsigned int i; | ||
247 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); | 244 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
245 | unsigned int i; | ||
248 | 246 | ||
249 | for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) | 247 | for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) |
250 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; | 248 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; |
@@ -313,6 +311,7 @@ static inline void _set_gate(int gate, unsigned type, void *addr, | |||
313 | unsigned dpl, unsigned ist, unsigned seg) | 311 | unsigned dpl, unsigned ist, unsigned seg) |
314 | { | 312 | { |
315 | gate_desc s; | 313 | gate_desc s; |
314 | |||
316 | pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); | 315 | pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); |
317 | /* | 316 | /* |
318 | * does not need to be atomic because it is only done once at | 317 | * does not need to be atomic because it is only done once at |
@@ -343,8 +342,9 @@ static inline void alloc_system_vector(int vector) | |||
343 | set_bit(vector, used_vectors); | 342 | set_bit(vector, used_vectors); |
344 | if (first_system_vector > vector) | 343 | if (first_system_vector > vector) |
345 | first_system_vector = vector; | 344 | first_system_vector = vector; |
346 | } else | 345 | } else { |
347 | BUG(); | 346 | BUG(); |
347 | } | ||
348 | } | 348 | } |
349 | 349 | ||
350 | static inline void alloc_intr_gate(unsigned int n, void *addr) | 350 | static inline void alloc_intr_gate(unsigned int n, void *addr) |
diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h index 38d87379e270..f49253d75710 100644 --- a/arch/x86/include/asm/idle.h +++ b/arch/x86/include/asm/idle.h | |||
@@ -16,6 +16,6 @@ static inline void enter_idle(void) { } | |||
16 | static inline void exit_idle(void) { } | 16 | static inline void exit_idle(void) { } |
17 | #endif /* CONFIG_X86_64 */ | 17 | #endif /* CONFIG_X86_64 */ |
18 | 18 | ||
19 | void c1e_remove_cpu(int cpu); | 19 | void amd_e400_remove_cpu(int cpu); |
20 | 20 | ||
21 | #endif /* _ASM_X86_IDLE_H */ | 21 | #endif /* _ASM_X86_IDLE_H */ |
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index aeff3e89b222..5f55e6962769 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h | |||
@@ -11,14 +11,14 @@ | |||
11 | typedef struct { | 11 | typedef struct { |
12 | void *ldt; | 12 | void *ldt; |
13 | int size; | 13 | int size; |
14 | struct mutex lock; | ||
15 | void *vdso; | ||
16 | 14 | ||
17 | #ifdef CONFIG_X86_64 | 15 | #ifdef CONFIG_X86_64 |
18 | /* True if mm supports a task running in 32 bit compatibility mode. */ | 16 | /* True if mm supports a task running in 32 bit compatibility mode. */ |
19 | unsigned short ia32_compat; | 17 | unsigned short ia32_compat; |
20 | #endif | 18 | #endif |
21 | 19 | ||
20 | struct mutex lock; | ||
21 | void *vdso; | ||
22 | } mm_context_t; | 22 | } mm_context_t; |
23 | 23 | ||
24 | #ifdef CONFIG_SMP | 24 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 4c25ab48257b..219371546afd 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -754,10 +754,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) | |||
754 | extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); | 754 | extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); |
755 | 755 | ||
756 | extern void select_idle_routine(const struct cpuinfo_x86 *c); | 756 | extern void select_idle_routine(const struct cpuinfo_x86 *c); |
757 | extern void init_c1e_mask(void); | 757 | extern void init_amd_e400_c1e_mask(void); |
758 | 758 | ||
759 | extern unsigned long boot_option_idle_override; | 759 | extern unsigned long boot_option_idle_override; |
760 | extern bool c1e_detected; | 760 | extern bool amd_e400_c1e_detected; |
761 | 761 | ||
762 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, | 762 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, |
763 | IDLE_POLL, IDLE_FORCE_MWAIT}; | 763 | IDLE_POLL, IDLE_FORCE_MWAIT}; |
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h index fb6a625c99bf..593485b38ab3 100644 --- a/arch/x86/include/asm/unistd_32.h +++ b/arch/x86/include/asm/unistd_32.h | |||
@@ -351,10 +351,11 @@ | |||
351 | #define __NR_clock_adjtime 343 | 351 | #define __NR_clock_adjtime 343 |
352 | #define __NR_syncfs 344 | 352 | #define __NR_syncfs 344 |
353 | #define __NR_sendmmsg 345 | 353 | #define __NR_sendmmsg 345 |
354 | #define __NR_setns 346 | ||
354 | 355 | ||
355 | #ifdef __KERNEL__ | 356 | #ifdef __KERNEL__ |
356 | 357 | ||
357 | #define NR_syscalls 346 | 358 | #define NR_syscalls 347 |
358 | 359 | ||
359 | #define __ARCH_WANT_IPC_PARSE_VERSION | 360 | #define __ARCH_WANT_IPC_PARSE_VERSION |
360 | #define __ARCH_WANT_OLD_READDIR | 361 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index 79f90eb15aad..705bf139288c 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h | |||
@@ -679,6 +679,8 @@ __SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) | |||
679 | __SYSCALL(__NR_syncfs, sys_syncfs) | 679 | __SYSCALL(__NR_syncfs, sys_syncfs) |
680 | #define __NR_sendmmsg 307 | 680 | #define __NR_sendmmsg 307 |
681 | __SYSCALL(__NR_sendmmsg, sys_sendmmsg) | 681 | __SYSCALL(__NR_sendmmsg, sys_sendmmsg) |
682 | #define __NR_setns 308 | ||
683 | __SYSCALL(__NR_setns, sys_setns) | ||
682 | 684 | ||
683 | #ifndef __NO_STUBS | 685 | #ifndef __NO_STUBS |
684 | #define __ARCH_WANT_OLD_READDIR | 686 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 130f1eeee5fe..a291c40efd43 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * SGI UV Broadcast Assist Unit definitions | 6 | * SGI UV Broadcast Assist Unit definitions |
7 | * | 7 | * |
8 | * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2008-2011 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _ASM_X86_UV_UV_BAU_H | 11 | #ifndef _ASM_X86_UV_UV_BAU_H |
@@ -35,17 +35,20 @@ | |||
35 | 35 | ||
36 | #define MAX_CPUS_PER_UVHUB 64 | 36 | #define MAX_CPUS_PER_UVHUB 64 |
37 | #define MAX_CPUS_PER_SOCKET 32 | 37 | #define MAX_CPUS_PER_SOCKET 32 |
38 | #define UV_ADP_SIZE 64 /* hardware-provided max. */ | 38 | #define ADP_SZ 64 /* hardware-provided max. */ |
39 | #define UV_CPUS_PER_ACT_STATUS 32 /* hardware-provided max. */ | 39 | #define UV_CPUS_PER_AS 32 /* hardware-provided max. */ |
40 | #define UV_ITEMS_PER_DESCRIPTOR 8 | 40 | #define ITEMS_PER_DESC 8 |
41 | /* the 'throttle' to prevent the hardware stay-busy bug */ | 41 | /* the 'throttle' to prevent the hardware stay-busy bug */ |
42 | #define MAX_BAU_CONCURRENT 3 | 42 | #define MAX_BAU_CONCURRENT 3 |
43 | #define UV_ACT_STATUS_MASK 0x3 | 43 | #define UV_ACT_STATUS_MASK 0x3 |
44 | #define UV_ACT_STATUS_SIZE 2 | 44 | #define UV_ACT_STATUS_SIZE 2 |
45 | #define UV_DISTRIBUTION_SIZE 256 | 45 | #define UV_DISTRIBUTION_SIZE 256 |
46 | #define UV_SW_ACK_NPENDING 8 | 46 | #define UV_SW_ACK_NPENDING 8 |
47 | #define UV_NET_ENDPOINT_INTD 0x38 | 47 | #define UV1_NET_ENDPOINT_INTD 0x38 |
48 | #define UV_DESC_BASE_PNODE_SHIFT 49 | 48 | #define UV2_NET_ENDPOINT_INTD 0x28 |
49 | #define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ | ||
50 | UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD) | ||
51 | #define UV_DESC_PSHIFT 49 | ||
49 | #define UV_PAYLOADQ_PNODE_SHIFT 49 | 52 | #define UV_PAYLOADQ_PNODE_SHIFT 49 |
50 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" | 53 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" |
51 | #define UV_BAU_BASENAME "sgi_uv/bau_tunables" | 54 | #define UV_BAU_BASENAME "sgi_uv/bau_tunables" |
@@ -53,29 +56,64 @@ | |||
53 | #define UV_BAU_TUNABLES_FILE "bau_tunables" | 56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" |
54 | #define WHITESPACE " \t\n" | 57 | #define WHITESPACE " \t\n" |
55 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) | 58 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) |
56 | #define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 | 59 | #define cpubit_isset(cpu, bau_local_cpumask) \ |
57 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 | 60 | test_bit((cpu), (bau_local_cpumask).bits) |
58 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x0000000009UL | 61 | |
59 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ | 62 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ |
60 | #define BAU_MISC_CONTROL_MULT_MASK 3 | 63 | /* |
64 | * UV2: Bit 19 selects between | ||
65 | * (0): 10 microsecond timebase and | ||
66 | * (1): 80 microseconds | ||
67 | * we're using 655us, similar to UV1: 65 units of 10us | ||
68 | */ | ||
69 | #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) | ||
70 | #define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) | ||
71 | |||
72 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ | ||
73 | UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ | ||
74 | UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) | ||
61 | 75 | ||
62 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL | 76 | #define BAU_MISC_CONTROL_MULT_MASK 3 |
77 | |||
78 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL | ||
63 | /* [30:28] URGENCY_7 an index into a table of times */ | 79 | /* [30:28] URGENCY_7 an index into a table of times */ |
64 | #define BAU_URGENCY_7_SHIFT 28 | 80 | #define BAU_URGENCY_7_SHIFT 28 |
65 | #define BAU_URGENCY_7_MASK 7 | 81 | #define BAU_URGENCY_7_MASK 7 |
66 | 82 | ||
67 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL | 83 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL |
68 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ | 84 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ |
69 | #define BAU_TRANS_SHIFT 40 | 85 | #define BAU_TRANS_SHIFT 40 |
70 | #define BAU_TRANS_MASK 0x3f | 86 | #define BAU_TRANS_MASK 0x3f |
87 | |||
88 | /* | ||
89 | * shorten some awkward names | ||
90 | */ | ||
91 | #define AS_PUSH_SHIFT UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT | ||
92 | #define SOFTACK_MSHIFT UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT | ||
93 | #define SOFTACK_PSHIFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT | ||
94 | #define SOFTACK_TIMEOUT_PERIOD UV_INTD_SOFT_ACK_TIMEOUT_PERIOD | ||
95 | #define write_gmmr uv_write_global_mmr64 | ||
96 | #define write_lmmr uv_write_local_mmr | ||
97 | #define read_lmmr uv_read_local_mmr | ||
98 | #define read_gmmr uv_read_global_mmr64 | ||
71 | 99 | ||
72 | /* | 100 | /* |
73 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 | 101 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 |
74 | */ | 102 | */ |
75 | #define DESC_STATUS_IDLE 0 | 103 | #define DS_IDLE 0 |
76 | #define DESC_STATUS_ACTIVE 1 | 104 | #define DS_ACTIVE 1 |
77 | #define DESC_STATUS_DESTINATION_TIMEOUT 2 | 105 | #define DS_DESTINATION_TIMEOUT 2 |
78 | #define DESC_STATUS_SOURCE_TIMEOUT 3 | 106 | #define DS_SOURCE_TIMEOUT 3 |
107 | /* | ||
108 | * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 | ||
109 | * values 1 and 5 will not occur | ||
110 | */ | ||
111 | #define UV2H_DESC_IDLE 0 | ||
112 | #define UV2H_DESC_DEST_TIMEOUT 2 | ||
113 | #define UV2H_DESC_DEST_STRONG_NACK 3 | ||
114 | #define UV2H_DESC_BUSY 4 | ||
115 | #define UV2H_DESC_SOURCE_TIMEOUT 6 | ||
116 | #define UV2H_DESC_DEST_PUT_ERR 7 | ||
79 | 117 | ||
80 | /* | 118 | /* |
81 | * delay for 'plugged' timeout retries, in microseconds | 119 | * delay for 'plugged' timeout retries, in microseconds |
@@ -86,15 +124,24 @@ | |||
86 | * threshholds at which to use IPI to free resources | 124 | * threshholds at which to use IPI to free resources |
87 | */ | 125 | */ |
88 | /* after this # consecutive 'plugged' timeouts, use IPI to release resources */ | 126 | /* after this # consecutive 'plugged' timeouts, use IPI to release resources */ |
89 | #define PLUGSB4RESET 100 | 127 | #define PLUGSB4RESET 100 |
90 | /* after this many consecutive timeouts, use IPI to release resources */ | 128 | /* after this many consecutive timeouts, use IPI to release resources */ |
91 | #define TIMEOUTSB4RESET 1 | 129 | #define TIMEOUTSB4RESET 1 |
92 | /* at this number uses of IPI to release resources, giveup the request */ | 130 | /* at this number uses of IPI to release resources, giveup the request */ |
93 | #define IPI_RESET_LIMIT 1 | 131 | #define IPI_RESET_LIMIT 1 |
94 | /* after this # consecutive successes, bump up the throttle if it was lowered */ | 132 | /* after this # consecutive successes, bump up the throttle if it was lowered */ |
95 | #define COMPLETE_THRESHOLD 5 | 133 | #define COMPLETE_THRESHOLD 5 |
134 | |||
135 | #define UV_LB_SUBNODEID 0x10 | ||
96 | 136 | ||
97 | #define UV_LB_SUBNODEID 0x10 | 137 | /* these two are the same for UV1 and UV2: */ |
138 | #define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT | ||
139 | #define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK | ||
140 | /* 4 bits of software ack period */ | ||
141 | #define UV2_ACK_MASK 0x7UL | ||
142 | #define UV2_ACK_UNITS_SHFT 3 | ||
143 | #define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT | ||
144 | #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT | ||
98 | 145 | ||
99 | /* | 146 | /* |
100 | * number of entries in the destination side payload queue | 147 | * number of entries in the destination side payload queue |
@@ -115,9 +162,16 @@ | |||
115 | /* | 162 | /* |
116 | * tuning the action when the numalink network is extremely delayed | 163 | * tuning the action when the numalink network is extremely delayed |
117 | */ | 164 | */ |
118 | #define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in microseconds */ | 165 | #define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in |
119 | #define CONGESTED_REPS 10 /* long delays averaged over this many broadcasts */ | 166 | microseconds */ |
120 | #define CONGESTED_PERIOD 30 /* time for the bau to be disabled, in seconds */ | 167 | #define CONGESTED_REPS 10 /* long delays averaged over |
168 | this many broadcasts */ | ||
169 | #define CONGESTED_PERIOD 30 /* time for the bau to be | ||
170 | disabled, in seconds */ | ||
171 | /* see msg_type: */ | ||
172 | #define MSG_NOOP 0 | ||
173 | #define MSG_REGULAR 1 | ||
174 | #define MSG_RETRY 2 | ||
121 | 175 | ||
122 | /* | 176 | /* |
123 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) | 177 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) |
@@ -129,8 +183,8 @@ | |||
129 | * 'base_dest_nasid' field of the header corresponds to the | 183 | * 'base_dest_nasid' field of the header corresponds to the |
130 | * destination nodeID associated with that specified bit. | 184 | * destination nodeID associated with that specified bit. |
131 | */ | 185 | */ |
132 | struct bau_target_uvhubmask { | 186 | struct bau_targ_hubmask { |
133 | unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; | 187 | unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; |
134 | }; | 188 | }; |
135 | 189 | ||
136 | /* | 190 | /* |
@@ -139,7 +193,7 @@ struct bau_target_uvhubmask { | |||
139 | * enough bits for max. cpu's per uvhub) | 193 | * enough bits for max. cpu's per uvhub) |
140 | */ | 194 | */ |
141 | struct bau_local_cpumask { | 195 | struct bau_local_cpumask { |
142 | unsigned long bits; | 196 | unsigned long bits; |
143 | }; | 197 | }; |
144 | 198 | ||
145 | /* | 199 | /* |
@@ -160,14 +214,14 @@ struct bau_local_cpumask { | |||
160 | * The payload is software-defined for INTD transactions | 214 | * The payload is software-defined for INTD transactions |
161 | */ | 215 | */ |
162 | struct bau_msg_payload { | 216 | struct bau_msg_payload { |
163 | unsigned long address; /* signifies a page or all TLB's | 217 | unsigned long address; /* signifies a page or all |
164 | of the cpu */ | 218 | TLB's of the cpu */ |
165 | /* 64 bits */ | 219 | /* 64 bits */ |
166 | unsigned short sending_cpu; /* filled in by sender */ | 220 | unsigned short sending_cpu; /* filled in by sender */ |
167 | /* 16 bits */ | 221 | /* 16 bits */ |
168 | unsigned short acknowledge_count;/* filled in by destination */ | 222 | unsigned short acknowledge_count; /* filled in by destination */ |
169 | /* 16 bits */ | 223 | /* 16 bits */ |
170 | unsigned int reserved1:32; /* not usable */ | 224 | unsigned int reserved1:32; /* not usable */ |
171 | }; | 225 | }; |
172 | 226 | ||
173 | 227 | ||
@@ -176,93 +230,96 @@ struct bau_msg_payload { | |||
176 | * see table 4.2.3.0.1 in broacast_assist spec. | 230 | * see table 4.2.3.0.1 in broacast_assist spec. |
177 | */ | 231 | */ |
178 | struct bau_msg_header { | 232 | struct bau_msg_header { |
179 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ | 233 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ |
180 | /* bits 5:0 */ | 234 | /* bits 5:0 */ |
181 | unsigned int base_dest_nasid:15; /* nasid of the */ | 235 | unsigned int base_dest_nasid:15; /* nasid of the first bit */ |
182 | /* bits 20:6 */ /* first bit in uvhub map */ | 236 | /* bits 20:6 */ /* in uvhub map */ |
183 | unsigned int command:8; /* message type */ | 237 | unsigned int command:8; /* message type */ |
184 | /* bits 28:21 */ | 238 | /* bits 28:21 */ |
185 | /* 0x38: SN3net EndPoint Message */ | 239 | /* 0x38: SN3net EndPoint Message */ |
186 | unsigned int rsvd_1:3; /* must be zero */ | 240 | unsigned int rsvd_1:3; /* must be zero */ |
187 | /* bits 31:29 */ | 241 | /* bits 31:29 */ |
188 | /* int will align on 32 bits */ | 242 | /* int will align on 32 bits */ |
189 | unsigned int rsvd_2:9; /* must be zero */ | 243 | unsigned int rsvd_2:9; /* must be zero */ |
190 | /* bits 40:32 */ | 244 | /* bits 40:32 */ |
191 | /* Suppl_A is 56-41 */ | 245 | /* Suppl_A is 56-41 */ |
192 | unsigned int sequence:16;/* message sequence number */ | 246 | unsigned int sequence:16; /* message sequence number */ |
193 | /* bits 56:41 */ /* becomes bytes 16-17 of msg */ | 247 | /* bits 56:41 */ /* becomes bytes 16-17 of msg */ |
194 | /* Address field (96:57) is never used as an | 248 | /* Address field (96:57) is |
195 | address (these are address bits 42:3) */ | 249 | never used as an address |
196 | 250 | (these are address bits | |
197 | unsigned int rsvd_3:1; /* must be zero */ | 251 | 42:3) */ |
252 | |||
253 | unsigned int rsvd_3:1; /* must be zero */ | ||
198 | /* bit 57 */ | 254 | /* bit 57 */ |
199 | /* address bits 27:4 are payload */ | 255 | /* address bits 27:4 are payload */ |
200 | /* these next 24 (58-81) bits become bytes 12-14 of msg */ | 256 | /* these next 24 (58-81) bits become bytes 12-14 of msg */ |
201 | |||
202 | /* bits 65:58 land in byte 12 */ | 257 | /* bits 65:58 land in byte 12 */ |
203 | unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */ | 258 | unsigned int replied_to:1; /* sent as 0 by the source to |
259 | byte 12 */ | ||
204 | /* bit 58 */ | 260 | /* bit 58 */ |
205 | unsigned int msg_type:3; /* software type of the message*/ | 261 | unsigned int msg_type:3; /* software type of the |
262 | message */ | ||
206 | /* bits 61:59 */ | 263 | /* bits 61:59 */ |
207 | unsigned int canceled:1; /* message canceled, resource to be freed*/ | 264 | unsigned int canceled:1; /* message canceled, resource |
265 | is to be freed*/ | ||
208 | /* bit 62 */ | 266 | /* bit 62 */ |
209 | unsigned int payload_1a:1;/* not currently used */ | 267 | unsigned int payload_1a:1; /* not currently used */ |
210 | /* bit 63 */ | 268 | /* bit 63 */ |
211 | unsigned int payload_1b:2;/* not currently used */ | 269 | unsigned int payload_1b:2; /* not currently used */ |
212 | /* bits 65:64 */ | 270 | /* bits 65:64 */ |
213 | 271 | ||
214 | /* bits 73:66 land in byte 13 */ | 272 | /* bits 73:66 land in byte 13 */ |
215 | unsigned int payload_1ca:6;/* not currently used */ | 273 | unsigned int payload_1ca:6; /* not currently used */ |
216 | /* bits 71:66 */ | 274 | /* bits 71:66 */ |
217 | unsigned int payload_1c:2;/* not currently used */ | 275 | unsigned int payload_1c:2; /* not currently used */ |
218 | /* bits 73:72 */ | 276 | /* bits 73:72 */ |
219 | 277 | ||
220 | /* bits 81:74 land in byte 14 */ | 278 | /* bits 81:74 land in byte 14 */ |
221 | unsigned int payload_1d:6;/* not currently used */ | 279 | unsigned int payload_1d:6; /* not currently used */ |
222 | /* bits 79:74 */ | 280 | /* bits 79:74 */ |
223 | unsigned int payload_1e:2;/* not currently used */ | 281 | unsigned int payload_1e:2; /* not currently used */ |
224 | /* bits 81:80 */ | 282 | /* bits 81:80 */ |
225 | 283 | ||
226 | unsigned int rsvd_4:7; /* must be zero */ | 284 | unsigned int rsvd_4:7; /* must be zero */ |
227 | /* bits 88:82 */ | 285 | /* bits 88:82 */ |
228 | unsigned int sw_ack_flag:1;/* software acknowledge flag */ | 286 | unsigned int swack_flag:1; /* software acknowledge flag */ |
229 | /* bit 89 */ | 287 | /* bit 89 */ |
230 | /* INTD trasactions at destination are to | 288 | /* INTD trasactions at |
231 | wait for software acknowledge */ | 289 | destination are to wait for |
232 | unsigned int rsvd_5:6; /* must be zero */ | 290 | software acknowledge */ |
291 | unsigned int rsvd_5:6; /* must be zero */ | ||
233 | /* bits 95:90 */ | 292 | /* bits 95:90 */ |
234 | unsigned int rsvd_6:5; /* must be zero */ | 293 | unsigned int rsvd_6:5; /* must be zero */ |
235 | /* bits 100:96 */ | 294 | /* bits 100:96 */ |
236 | unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */ | 295 | unsigned int int_both:1; /* if 1, interrupt both sockets |
296 | on the uvhub */ | ||
237 | /* bit 101*/ | 297 | /* bit 101*/ |
238 | unsigned int fairness:3;/* usually zero */ | 298 | unsigned int fairness:3; /* usually zero */ |
239 | /* bits 104:102 */ | 299 | /* bits 104:102 */ |
240 | unsigned int multilevel:1; /* multi-level multicast format */ | 300 | unsigned int multilevel:1; /* multi-level multicast |
301 | format */ | ||
241 | /* bit 105 */ | 302 | /* bit 105 */ |
242 | /* 0 for TLB: endpoint multi-unicast messages */ | 303 | /* 0 for TLB: endpoint multi-unicast messages */ |
243 | unsigned int chaining:1;/* next descriptor is part of this activation*/ | 304 | unsigned int chaining:1; /* next descriptor is part of |
305 | this activation*/ | ||
244 | /* bit 106 */ | 306 | /* bit 106 */ |
245 | unsigned int rsvd_7:21; /* must be zero */ | 307 | unsigned int rsvd_7:21; /* must be zero */ |
246 | /* bits 127:107 */ | 308 | /* bits 127:107 */ |
247 | }; | 309 | }; |
248 | 310 | ||
249 | /* see msg_type: */ | ||
250 | #define MSG_NOOP 0 | ||
251 | #define MSG_REGULAR 1 | ||
252 | #define MSG_RETRY 2 | ||
253 | |||
254 | /* | 311 | /* |
255 | * The activation descriptor: | 312 | * The activation descriptor: |
256 | * The format of the message to send, plus all accompanying control | 313 | * The format of the message to send, plus all accompanying control |
257 | * Should be 64 bytes | 314 | * Should be 64 bytes |
258 | */ | 315 | */ |
259 | struct bau_desc { | 316 | struct bau_desc { |
260 | struct bau_target_uvhubmask distribution; | 317 | struct bau_targ_hubmask distribution; |
261 | /* | 318 | /* |
262 | * message template, consisting of header and payload: | 319 | * message template, consisting of header and payload: |
263 | */ | 320 | */ |
264 | struct bau_msg_header header; | 321 | struct bau_msg_header header; |
265 | struct bau_msg_payload payload; | 322 | struct bau_msg_payload payload; |
266 | }; | 323 | }; |
267 | /* | 324 | /* |
268 | * -payload-- ---------header------ | 325 | * -payload-- ---------header------ |
@@ -281,59 +338,51 @@ struct bau_desc { | |||
281 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 | 338 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 |
282 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) | 339 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) |
283 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from | 340 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from |
284 | * sw_ack_vector and payload_2) | 341 | * swack_vec and payload_2) |
285 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software | 342 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software |
286 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload | 343 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload |
287 | * operation." | 344 | * operation." |
288 | */ | 345 | */ |
289 | struct bau_payload_queue_entry { | 346 | struct bau_pq_entry { |
290 | unsigned long address; /* signifies a page or all TLB's | 347 | unsigned long address; /* signifies a page or all TLB's |
291 | of the cpu */ | 348 | of the cpu */ |
292 | /* 64 bits, bytes 0-7 */ | 349 | /* 64 bits, bytes 0-7 */ |
293 | 350 | unsigned short sending_cpu; /* cpu that sent the message */ | |
294 | unsigned short sending_cpu; /* cpu that sent the message */ | ||
295 | /* 16 bits, bytes 8-9 */ | 351 | /* 16 bits, bytes 8-9 */ |
296 | 352 | unsigned short acknowledge_count; /* filled in by destination */ | |
297 | unsigned short acknowledge_count; /* filled in by destination */ | ||
298 | /* 16 bits, bytes 10-11 */ | 353 | /* 16 bits, bytes 10-11 */ |
299 | |||
300 | /* these next 3 bytes come from bits 58-81 of the message header */ | 354 | /* these next 3 bytes come from bits 58-81 of the message header */ |
301 | unsigned short replied_to:1; /* sent as 0 by the source */ | 355 | unsigned short replied_to:1; /* sent as 0 by the source */ |
302 | unsigned short msg_type:3; /* software message type */ | 356 | unsigned short msg_type:3; /* software message type */ |
303 | unsigned short canceled:1; /* sent as 0 by the source */ | 357 | unsigned short canceled:1; /* sent as 0 by the source */ |
304 | unsigned short unused1:3; /* not currently using */ | 358 | unsigned short unused1:3; /* not currently using */ |
305 | /* byte 12 */ | 359 | /* byte 12 */ |
306 | 360 | unsigned char unused2a; /* not currently using */ | |
307 | unsigned char unused2a; /* not currently using */ | ||
308 | /* byte 13 */ | 361 | /* byte 13 */ |
309 | unsigned char unused2; /* not currently using */ | 362 | unsigned char unused2; /* not currently using */ |
310 | /* byte 14 */ | 363 | /* byte 14 */ |
311 | 364 | unsigned char swack_vec; /* filled in by the hardware */ | |
312 | unsigned char sw_ack_vector; /* filled in by the hardware */ | ||
313 | /* byte 15 (bits 127:120) */ | 365 | /* byte 15 (bits 127:120) */ |
314 | 366 | unsigned short sequence; /* message sequence number */ | |
315 | unsigned short sequence; /* message sequence number */ | ||
316 | /* bytes 16-17 */ | 367 | /* bytes 16-17 */ |
317 | unsigned char unused4[2]; /* not currently using bytes 18-19 */ | 368 | unsigned char unused4[2]; /* not currently using bytes 18-19 */ |
318 | /* bytes 18-19 */ | 369 | /* bytes 18-19 */ |
319 | 370 | int number_of_cpus; /* filled in at destination */ | |
320 | int number_of_cpus; /* filled in at destination */ | ||
321 | /* 32 bits, bytes 20-23 (aligned) */ | 371 | /* 32 bits, bytes 20-23 (aligned) */ |
322 | 372 | unsigned char unused5[8]; /* not using */ | |
323 | unsigned char unused5[8]; /* not using */ | ||
324 | /* bytes 24-31 */ | 373 | /* bytes 24-31 */ |
325 | }; | 374 | }; |
326 | 375 | ||
327 | struct msg_desc { | 376 | struct msg_desc { |
328 | struct bau_payload_queue_entry *msg; | 377 | struct bau_pq_entry *msg; |
329 | int msg_slot; | 378 | int msg_slot; |
330 | int sw_ack_slot; | 379 | int swack_slot; |
331 | struct bau_payload_queue_entry *va_queue_first; | 380 | struct bau_pq_entry *queue_first; |
332 | struct bau_payload_queue_entry *va_queue_last; | 381 | struct bau_pq_entry *queue_last; |
333 | }; | 382 | }; |
334 | 383 | ||
335 | struct reset_args { | 384 | struct reset_args { |
336 | int sender; | 385 | int sender; |
337 | }; | 386 | }; |
338 | 387 | ||
339 | /* | 388 | /* |
@@ -341,112 +390,226 @@ struct reset_args { | |||
341 | */ | 390 | */ |
342 | struct ptc_stats { | 391 | struct ptc_stats { |
343 | /* sender statistics */ | 392 | /* sender statistics */ |
344 | unsigned long s_giveup; /* number of fall backs to IPI-style flushes */ | 393 | unsigned long s_giveup; /* number of fall backs to |
345 | unsigned long s_requestor; /* number of shootdown requests */ | 394 | IPI-style flushes */ |
346 | unsigned long s_stimeout; /* source side timeouts */ | 395 | unsigned long s_requestor; /* number of shootdown |
347 | unsigned long s_dtimeout; /* destination side timeouts */ | 396 | requests */ |
348 | unsigned long s_time; /* time spent in sending side */ | 397 | unsigned long s_stimeout; /* source side timeouts */ |
349 | unsigned long s_retriesok; /* successful retries */ | 398 | unsigned long s_dtimeout; /* destination side timeouts */ |
350 | unsigned long s_ntargcpu; /* total number of cpu's targeted */ | 399 | unsigned long s_time; /* time spent in sending side */ |
351 | unsigned long s_ntargself; /* times the sending cpu was targeted */ | 400 | unsigned long s_retriesok; /* successful retries */ |
352 | unsigned long s_ntarglocals; /* targets of cpus on the local blade */ | 401 | unsigned long s_ntargcpu; /* total number of cpu's |
353 | unsigned long s_ntargremotes; /* targets of cpus on remote blades */ | 402 | targeted */ |
354 | unsigned long s_ntarglocaluvhub; /* targets of the local hub */ | 403 | unsigned long s_ntargself; /* times the sending cpu was |
355 | unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ | 404 | targeted */ |
356 | unsigned long s_ntarguvhub; /* total number of uvhubs targeted */ | 405 | unsigned long s_ntarglocals; /* targets of cpus on the local |
357 | unsigned long s_ntarguvhub16; /* number of times target hubs >= 16*/ | 406 | blade */ |
358 | unsigned long s_ntarguvhub8; /* number of times target hubs >= 8 */ | 407 | unsigned long s_ntargremotes; /* targets of cpus on remote |
359 | unsigned long s_ntarguvhub4; /* number of times target hubs >= 4 */ | 408 | blades */ |
360 | unsigned long s_ntarguvhub2; /* number of times target hubs >= 2 */ | 409 | unsigned long s_ntarglocaluvhub; /* targets of the local hub */ |
361 | unsigned long s_ntarguvhub1; /* number of times target hubs == 1 */ | 410 | unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ |
362 | unsigned long s_resets_plug; /* ipi-style resets from plug state */ | 411 | unsigned long s_ntarguvhub; /* total number of uvhubs |
363 | unsigned long s_resets_timeout; /* ipi-style resets from timeouts */ | 412 | targeted */ |
364 | unsigned long s_busy; /* status stayed busy past s/w timer */ | 413 | unsigned long s_ntarguvhub16; /* number of times target |
365 | unsigned long s_throttles; /* waits in throttle */ | 414 | hubs >= 16*/ |
366 | unsigned long s_retry_messages; /* retry broadcasts */ | 415 | unsigned long s_ntarguvhub8; /* number of times target |
367 | unsigned long s_bau_reenabled; /* for bau enable/disable */ | 416 | hubs >= 8 */ |
368 | unsigned long s_bau_disabled; /* for bau enable/disable */ | 417 | unsigned long s_ntarguvhub4; /* number of times target |
418 | hubs >= 4 */ | ||
419 | unsigned long s_ntarguvhub2; /* number of times target | ||
420 | hubs >= 2 */ | ||
421 | unsigned long s_ntarguvhub1; /* number of times target | ||
422 | hubs == 1 */ | ||
423 | unsigned long s_resets_plug; /* ipi-style resets from plug | ||
424 | state */ | ||
425 | unsigned long s_resets_timeout; /* ipi-style resets from | ||
426 | timeouts */ | ||
427 | unsigned long s_busy; /* status stayed busy past | ||
428 | s/w timer */ | ||
429 | unsigned long s_throttles; /* waits in throttle */ | ||
430 | unsigned long s_retry_messages; /* retry broadcasts */ | ||
431 | unsigned long s_bau_reenabled; /* for bau enable/disable */ | ||
432 | unsigned long s_bau_disabled; /* for bau enable/disable */ | ||
369 | /* destination statistics */ | 433 | /* destination statistics */ |
370 | unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ | 434 | unsigned long d_alltlb; /* times all tlb's on this |
371 | unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */ | 435 | cpu were flushed */ |
372 | unsigned long d_multmsg; /* interrupts with multiple messages */ | 436 | unsigned long d_onetlb; /* times just one tlb on this |
373 | unsigned long d_nomsg; /* interrupts with no message */ | 437 | cpu was flushed */ |
374 | unsigned long d_time; /* time spent on destination side */ | 438 | unsigned long d_multmsg; /* interrupts with multiple |
375 | unsigned long d_requestee; /* number of messages processed */ | 439 | messages */ |
376 | unsigned long d_retries; /* number of retry messages processed */ | 440 | unsigned long d_nomsg; /* interrupts with no message */ |
377 | unsigned long d_canceled; /* number of messages canceled by retries */ | 441 | unsigned long d_time; /* time spent on destination |
378 | unsigned long d_nocanceled; /* retries that found nothing to cancel */ | 442 | side */ |
379 | unsigned long d_resets; /* number of ipi-style requests processed */ | 443 | unsigned long d_requestee; /* number of messages |
380 | unsigned long d_rcanceled; /* number of messages canceled by resets */ | 444 | processed */ |
445 | unsigned long d_retries; /* number of retry messages | ||
446 | processed */ | ||
447 | unsigned long d_canceled; /* number of messages canceled | ||
448 | by retries */ | ||
449 | unsigned long d_nocanceled; /* retries that found nothing | ||
450 | to cancel */ | ||
451 | unsigned long d_resets; /* number of ipi-style requests | ||
452 | processed */ | ||
453 | unsigned long d_rcanceled; /* number of messages canceled | ||
454 | by resets */ | ||
455 | }; | ||
456 | |||
457 | struct tunables { | ||
458 | int *tunp; | ||
459 | int deflt; | ||
381 | }; | 460 | }; |
382 | 461 | ||
383 | struct hub_and_pnode { | 462 | struct hub_and_pnode { |
384 | short uvhub; | 463 | short uvhub; |
385 | short pnode; | 464 | short pnode; |
386 | }; | 465 | }; |
466 | |||
467 | struct socket_desc { | ||
468 | short num_cpus; | ||
469 | short cpu_number[MAX_CPUS_PER_SOCKET]; | ||
470 | }; | ||
471 | |||
472 | struct uvhub_desc { | ||
473 | unsigned short socket_mask; | ||
474 | short num_cpus; | ||
475 | short uvhub; | ||
476 | short pnode; | ||
477 | struct socket_desc socket[2]; | ||
478 | }; | ||
479 | |||
387 | /* | 480 | /* |
388 | * one per-cpu; to locate the software tables | 481 | * one per-cpu; to locate the software tables |
389 | */ | 482 | */ |
390 | struct bau_control { | 483 | struct bau_control { |
391 | struct bau_desc *descriptor_base; | 484 | struct bau_desc *descriptor_base; |
392 | struct bau_payload_queue_entry *va_queue_first; | 485 | struct bau_pq_entry *queue_first; |
393 | struct bau_payload_queue_entry *va_queue_last; | 486 | struct bau_pq_entry *queue_last; |
394 | struct bau_payload_queue_entry *bau_msg_head; | 487 | struct bau_pq_entry *bau_msg_head; |
395 | struct bau_control *uvhub_master; | 488 | struct bau_control *uvhub_master; |
396 | struct bau_control *socket_master; | 489 | struct bau_control *socket_master; |
397 | struct ptc_stats *statp; | 490 | struct ptc_stats *statp; |
398 | unsigned long timeout_interval; | 491 | unsigned long timeout_interval; |
399 | unsigned long set_bau_on_time; | 492 | unsigned long set_bau_on_time; |
400 | atomic_t active_descriptor_count; | 493 | atomic_t active_descriptor_count; |
401 | int plugged_tries; | 494 | int plugged_tries; |
402 | int timeout_tries; | 495 | int timeout_tries; |
403 | int ipi_attempts; | 496 | int ipi_attempts; |
404 | int conseccompletes; | 497 | int conseccompletes; |
405 | int baudisabled; | 498 | int baudisabled; |
406 | int set_bau_off; | 499 | int set_bau_off; |
407 | short cpu; | 500 | short cpu; |
408 | short osnode; | 501 | short osnode; |
409 | short uvhub_cpu; | 502 | short uvhub_cpu; |
410 | short uvhub; | 503 | short uvhub; |
411 | short cpus_in_socket; | 504 | short cpus_in_socket; |
412 | short cpus_in_uvhub; | 505 | short cpus_in_uvhub; |
413 | short partition_base_pnode; | 506 | short partition_base_pnode; |
414 | unsigned short message_number; | 507 | unsigned short message_number; |
415 | unsigned short uvhub_quiesce; | 508 | unsigned short uvhub_quiesce; |
416 | short socket_acknowledge_count[DEST_Q_SIZE]; | 509 | short socket_acknowledge_count[DEST_Q_SIZE]; |
417 | cycles_t send_message; | 510 | cycles_t send_message; |
418 | spinlock_t uvhub_lock; | 511 | spinlock_t uvhub_lock; |
419 | spinlock_t queue_lock; | 512 | spinlock_t queue_lock; |
420 | /* tunables */ | 513 | /* tunables */ |
421 | int max_bau_concurrent; | 514 | int max_concurr; |
422 | int max_bau_concurrent_constant; | 515 | int max_concurr_const; |
423 | int plugged_delay; | 516 | int plugged_delay; |
424 | int plugsb4reset; | 517 | int plugsb4reset; |
425 | int timeoutsb4reset; | 518 | int timeoutsb4reset; |
426 | int ipi_reset_limit; | 519 | int ipi_reset_limit; |
427 | int complete_threshold; | 520 | int complete_threshold; |
428 | int congested_response_us; | 521 | int cong_response_us; |
429 | int congested_reps; | 522 | int cong_reps; |
430 | int congested_period; | 523 | int cong_period; |
431 | cycles_t period_time; | 524 | cycles_t period_time; |
432 | long period_requests; | 525 | long period_requests; |
433 | struct hub_and_pnode *target_hub_and_pnode; | 526 | struct hub_and_pnode *thp; |
434 | }; | 527 | }; |
435 | 528 | ||
436 | static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp) | 529 | static unsigned long read_mmr_uv2_status(void) |
530 | { | ||
531 | return read_lmmr(UV2H_LB_BAU_SB_ACTIVATION_STATUS_2); | ||
532 | } | ||
533 | |||
534 | static void write_mmr_data_broadcast(int pnode, unsigned long mmr_image) | ||
535 | { | ||
536 | write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image); | ||
537 | } | ||
538 | |||
539 | static void write_mmr_descriptor_base(int pnode, unsigned long mmr_image) | ||
540 | { | ||
541 | write_gmmr(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, mmr_image); | ||
542 | } | ||
543 | |||
544 | static void write_mmr_activation(unsigned long index) | ||
545 | { | ||
546 | write_lmmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); | ||
547 | } | ||
548 | |||
549 | static void write_gmmr_activation(int pnode, unsigned long mmr_image) | ||
550 | { | ||
551 | write_gmmr(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL, mmr_image); | ||
552 | } | ||
553 | |||
554 | static void write_mmr_payload_first(int pnode, unsigned long mmr_image) | ||
555 | { | ||
556 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, mmr_image); | ||
557 | } | ||
558 | |||
559 | static void write_mmr_payload_tail(int pnode, unsigned long mmr_image) | ||
560 | { | ||
561 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, mmr_image); | ||
562 | } | ||
563 | |||
564 | static void write_mmr_payload_last(int pnode, unsigned long mmr_image) | ||
565 | { | ||
566 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, mmr_image); | ||
567 | } | ||
568 | |||
569 | static void write_mmr_misc_control(int pnode, unsigned long mmr_image) | ||
570 | { | ||
571 | write_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
572 | } | ||
573 | |||
574 | static unsigned long read_mmr_misc_control(int pnode) | ||
575 | { | ||
576 | return read_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL); | ||
577 | } | ||
578 | |||
579 | static void write_mmr_sw_ack(unsigned long mr) | ||
580 | { | ||
581 | uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr); | ||
582 | } | ||
583 | |||
584 | static unsigned long read_mmr_sw_ack(void) | ||
585 | { | ||
586 | return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
587 | } | ||
588 | |||
589 | static unsigned long read_gmmr_sw_ack(int pnode) | ||
590 | { | ||
591 | return read_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
592 | } | ||
593 | |||
594 | static void write_mmr_data_config(int pnode, unsigned long mr) | ||
595 | { | ||
596 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, mr); | ||
597 | } | ||
598 | |||
599 | static inline int bau_uvhub_isset(int uvhub, struct bau_targ_hubmask *dstp) | ||
437 | { | 600 | { |
438 | return constant_test_bit(uvhub, &dstp->bits[0]); | 601 | return constant_test_bit(uvhub, &dstp->bits[0]); |
439 | } | 602 | } |
440 | static inline void bau_uvhub_set(int pnode, struct bau_target_uvhubmask *dstp) | 603 | static inline void bau_uvhub_set(int pnode, struct bau_targ_hubmask *dstp) |
441 | { | 604 | { |
442 | __set_bit(pnode, &dstp->bits[0]); | 605 | __set_bit(pnode, &dstp->bits[0]); |
443 | } | 606 | } |
444 | static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp, | 607 | static inline void bau_uvhubs_clear(struct bau_targ_hubmask *dstp, |
445 | int nbits) | 608 | int nbits) |
446 | { | 609 | { |
447 | bitmap_zero(&dstp->bits[0], nbits); | 610 | bitmap_zero(&dstp->bits[0], nbits); |
448 | } | 611 | } |
449 | static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp) | 612 | static inline int bau_uvhub_weight(struct bau_targ_hubmask *dstp) |
450 | { | 613 | { |
451 | return bitmap_weight((unsigned long *)&dstp->bits[0], | 614 | return bitmap_weight((unsigned long *)&dstp->bits[0], |
452 | UV_DISTRIBUTION_SIZE); | 615 | UV_DISTRIBUTION_SIZE); |
@@ -457,9 +620,6 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) | |||
457 | bitmap_zero(&dstp->bits, nbits); | 620 | bitmap_zero(&dstp->bits, nbits); |
458 | } | 621 | } |
459 | 622 | ||
460 | #define cpubit_isset(cpu, bau_local_cpumask) \ | ||
461 | test_bit((cpu), (bau_local_cpumask).bits) | ||
462 | |||
463 | extern void uv_bau_message_intr1(void); | 623 | extern void uv_bau_message_intr1(void); |
464 | extern void uv_bau_timeout_intr1(void); | 624 | extern void uv_bau_timeout_intr1(void); |
465 | 625 | ||
@@ -467,7 +627,7 @@ struct atomic_short { | |||
467 | short counter; | 627 | short counter; |
468 | }; | 628 | }; |
469 | 629 | ||
470 | /** | 630 | /* |
471 | * atomic_read_short - read a short atomic variable | 631 | * atomic_read_short - read a short atomic variable |
472 | * @v: pointer of type atomic_short | 632 | * @v: pointer of type atomic_short |
473 | * | 633 | * |
@@ -478,14 +638,14 @@ static inline int atomic_read_short(const struct atomic_short *v) | |||
478 | return v->counter; | 638 | return v->counter; |
479 | } | 639 | } |
480 | 640 | ||
481 | /** | 641 | /* |
482 | * atomic_add_short_return - add and return a short int | 642 | * atom_asr - add and return a short int |
483 | * @i: short value to add | 643 | * @i: short value to add |
484 | * @v: pointer of type atomic_short | 644 | * @v: pointer of type atomic_short |
485 | * | 645 | * |
486 | * Atomically adds @i to @v and returns @i + @v | 646 | * Atomically adds @i to @v and returns @i + @v |
487 | */ | 647 | */ |
488 | static inline int atomic_add_short_return(short i, struct atomic_short *v) | 648 | static inline int atom_asr(short i, struct atomic_short *v) |
489 | { | 649 | { |
490 | short __i = i; | 650 | short __i = i; |
491 | asm volatile(LOCK_PREFIX "xaddw %0, %1" | 651 | asm volatile(LOCK_PREFIX "xaddw %0, %1" |
@@ -494,4 +654,26 @@ static inline int atomic_add_short_return(short i, struct atomic_short *v) | |||
494 | return i + __i; | 654 | return i + __i; |
495 | } | 655 | } |
496 | 656 | ||
657 | /* | ||
658 | * conditionally add 1 to *v, unless *v is >= u | ||
659 | * return 0 if we cannot add 1 to *v because it is >= u | ||
660 | * return 1 if we can add 1 to *v because it is < u | ||
661 | * the add is atomic | ||
662 | * | ||
663 | * This is close to atomic_add_unless(), but this allows the 'u' value | ||
664 | * to be lowered below the current 'v'. atomic_add_unless can only stop | ||
665 | * on equal. | ||
666 | */ | ||
667 | static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) | ||
668 | { | ||
669 | spin_lock(lock); | ||
670 | if (atomic_read(v) >= u) { | ||
671 | spin_unlock(lock); | ||
672 | return 0; | ||
673 | } | ||
674 | atomic_inc(v); | ||
675 | spin_unlock(lock); | ||
676 | return 1; | ||
677 | } | ||
678 | |||
497 | #endif /* _ASM_X86_UV_UV_BAU_H */ | 679 | #endif /* _ASM_X86_UV_UV_BAU_H */ |
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 4298002d0c83..f26544a15214 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h | |||
@@ -77,8 +77,9 @@ | |||
77 | * | 77 | * |
78 | * 1111110000000000 | 78 | * 1111110000000000 |
79 | * 5432109876543210 | 79 | * 5432109876543210 |
80 | * pppppppppplc0cch Nehalem-EX | 80 | * pppppppppplc0cch Nehalem-EX (12 bits in hdw reg) |
81 | * ppppppppplcc0cch Westmere-EX | 81 | * ppppppppplcc0cch Westmere-EX (12 bits in hdw reg) |
82 | * pppppppppppcccch SandyBridge (15 bits in hdw reg) | ||
82 | * sssssssssss | 83 | * sssssssssss |
83 | * | 84 | * |
84 | * p = pnode bits | 85 | * p = pnode bits |
@@ -87,7 +88,7 @@ | |||
87 | * h = hyperthread | 88 | * h = hyperthread |
88 | * s = bits that are in the SOCKET_ID CSR | 89 | * s = bits that are in the SOCKET_ID CSR |
89 | * | 90 | * |
90 | * Note: Processor only supports 12 bits in the APICID register. The ACPI | 91 | * Note: Processor may support fewer bits in the APICID register. The ACPI |
91 | * tables hold all 16 bits. Software needs to be aware of this. | 92 | * tables hold all 16 bits. Software needs to be aware of this. |
92 | * | 93 | * |
93 | * Unless otherwise specified, all references to APICID refer to | 94 | * Unless otherwise specified, all references to APICID refer to |
@@ -138,6 +139,8 @@ struct uv_hub_info_s { | |||
138 | unsigned long global_mmr_base; | 139 | unsigned long global_mmr_base; |
139 | unsigned long gpa_mask; | 140 | unsigned long gpa_mask; |
140 | unsigned int gnode_extra; | 141 | unsigned int gnode_extra; |
142 | unsigned char hub_revision; | ||
143 | unsigned char apic_pnode_shift; | ||
141 | unsigned long gnode_upper; | 144 | unsigned long gnode_upper; |
142 | unsigned long lowmem_remap_top; | 145 | unsigned long lowmem_remap_top; |
143 | unsigned long lowmem_remap_base; | 146 | unsigned long lowmem_remap_base; |
@@ -149,13 +152,31 @@ struct uv_hub_info_s { | |||
149 | unsigned char m_val; | 152 | unsigned char m_val; |
150 | unsigned char n_val; | 153 | unsigned char n_val; |
151 | struct uv_scir_s scir; | 154 | struct uv_scir_s scir; |
152 | unsigned char apic_pnode_shift; | ||
153 | }; | 155 | }; |
154 | 156 | ||
155 | DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); | 157 | DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); |
156 | #define uv_hub_info (&__get_cpu_var(__uv_hub_info)) | 158 | #define uv_hub_info (&__get_cpu_var(__uv_hub_info)) |
157 | #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) | 159 | #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) |
158 | 160 | ||
161 | /* | ||
162 | * Hub revisions less than UV2_HUB_REVISION_BASE are UV1 hubs. All UV2 | ||
163 | * hubs have revision numbers greater than or equal to UV2_HUB_REVISION_BASE. | ||
164 | * This is a software convention - NOT the hardware revision numbers in | ||
165 | * the hub chip. | ||
166 | */ | ||
167 | #define UV1_HUB_REVISION_BASE 1 | ||
168 | #define UV2_HUB_REVISION_BASE 3 | ||
169 | |||
170 | static inline int is_uv1_hub(void) | ||
171 | { | ||
172 | return uv_hub_info->hub_revision < UV2_HUB_REVISION_BASE; | ||
173 | } | ||
174 | |||
175 | static inline int is_uv2_hub(void) | ||
176 | { | ||
177 | return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; | ||
178 | } | ||
179 | |||
159 | union uvh_apicid { | 180 | union uvh_apicid { |
160 | unsigned long v; | 181 | unsigned long v; |
161 | struct uvh_apicid_s { | 182 | struct uvh_apicid_s { |
@@ -180,11 +201,25 @@ union uvh_apicid { | |||
180 | #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra) | 201 | #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra) |
181 | #define UV_PNODE_TO_NASID(p) (UV_PNODE_TO_GNODE(p) << 1) | 202 | #define UV_PNODE_TO_NASID(p) (UV_PNODE_TO_GNODE(p) << 1) |
182 | 203 | ||
183 | #define UV_LOCAL_MMR_BASE 0xf4000000UL | 204 | #define UV1_LOCAL_MMR_BASE 0xf4000000UL |
184 | #define UV_GLOBAL_MMR32_BASE 0xf8000000UL | 205 | #define UV1_GLOBAL_MMR32_BASE 0xf8000000UL |
206 | #define UV1_LOCAL_MMR_SIZE (64UL * 1024 * 1024) | ||
207 | #define UV1_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024) | ||
208 | |||
209 | #define UV2_LOCAL_MMR_BASE 0xfa000000UL | ||
210 | #define UV2_GLOBAL_MMR32_BASE 0xfc000000UL | ||
211 | #define UV2_LOCAL_MMR_SIZE (32UL * 1024 * 1024) | ||
212 | #define UV2_GLOBAL_MMR32_SIZE (32UL * 1024 * 1024) | ||
213 | |||
214 | #define UV_LOCAL_MMR_BASE (is_uv1_hub() ? UV1_LOCAL_MMR_BASE \ | ||
215 | : UV2_LOCAL_MMR_BASE) | ||
216 | #define UV_GLOBAL_MMR32_BASE (is_uv1_hub() ? UV1_GLOBAL_MMR32_BASE \ | ||
217 | : UV2_GLOBAL_MMR32_BASE) | ||
218 | #define UV_LOCAL_MMR_SIZE (is_uv1_hub() ? UV1_LOCAL_MMR_SIZE : \ | ||
219 | UV2_LOCAL_MMR_SIZE) | ||
220 | #define UV_GLOBAL_MMR32_SIZE (is_uv1_hub() ? UV1_GLOBAL_MMR32_SIZE :\ | ||
221 | UV2_GLOBAL_MMR32_SIZE) | ||
185 | #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) | 222 | #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) |
186 | #define UV_LOCAL_MMR_SIZE (64UL * 1024 * 1024) | ||
187 | #define UV_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024) | ||
188 | 223 | ||
189 | #define UV_GLOBAL_GRU_MMR_BASE 0x4000000 | 224 | #define UV_GLOBAL_GRU_MMR_BASE 0x4000000 |
190 | 225 | ||
@@ -301,6 +336,17 @@ static inline int uv_apicid_to_pnode(int apicid) | |||
301 | } | 336 | } |
302 | 337 | ||
303 | /* | 338 | /* |
339 | * Convert an apicid to the socket number on the blade | ||
340 | */ | ||
341 | static inline int uv_apicid_to_socket(int apicid) | ||
342 | { | ||
343 | if (is_uv1_hub()) | ||
344 | return (apicid >> (uv_hub_info->apic_pnode_shift - 1)) & 1; | ||
345 | else | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | /* | ||
304 | * Access global MMRs using the low memory MMR32 space. This region supports | 350 | * Access global MMRs using the low memory MMR32 space. This region supports |
305 | * faster MMR access but not all MMRs are accessible in this space. | 351 | * faster MMR access but not all MMRs are accessible in this space. |
306 | */ | 352 | */ |
@@ -519,14 +565,13 @@ static inline void uv_hub_send_ipi(int pnode, int apicid, int vector) | |||
519 | 565 | ||
520 | /* | 566 | /* |
521 | * Get the minimum revision number of the hub chips within the partition. | 567 | * Get the minimum revision number of the hub chips within the partition. |
522 | * 1 - initial rev 1.0 silicon | 568 | * 1 - UV1 rev 1.0 initial silicon |
523 | * 2 - rev 2.0 production silicon | 569 | * 2 - UV1 rev 2.0 production silicon |
570 | * 3 - UV2 rev 1.0 initial silicon | ||
524 | */ | 571 | */ |
525 | static inline int uv_get_min_hub_revision_id(void) | 572 | static inline int uv_get_min_hub_revision_id(void) |
526 | { | 573 | { |
527 | extern int uv_min_hub_revision_id; | 574 | return uv_hub_info->hub_revision; |
528 | |||
529 | return uv_min_hub_revision_id; | ||
530 | } | 575 | } |
531 | 576 | ||
532 | #endif /* CONFIG_X86_64 */ | 577 | #endif /* CONFIG_X86_64 */ |
diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index f5bb64a823d7..4be52c863448 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h | |||
@@ -11,13 +11,64 @@ | |||
11 | #ifndef _ASM_X86_UV_UV_MMRS_H | 11 | #ifndef _ASM_X86_UV_UV_MMRS_H |
12 | #define _ASM_X86_UV_UV_MMRS_H | 12 | #define _ASM_X86_UV_UV_MMRS_H |
13 | 13 | ||
14 | /* | ||
15 | * This file contains MMR definitions for both UV1 & UV2 hubs. | ||
16 | * | ||
17 | * In general, MMR addresses and structures are identical on both hubs. | ||
18 | * These MMRs are identified as: | ||
19 | * #define UVH_xxx <address> | ||
20 | * union uvh_xxx { | ||
21 | * unsigned long v; | ||
22 | * struct uvh_int_cmpd_s { | ||
23 | * } s; | ||
24 | * }; | ||
25 | * | ||
26 | * If the MMR exists on both hub type but has different addresses or | ||
27 | * contents, the MMR definition is similar to: | ||
28 | * #define UV1H_xxx <uv1 address> | ||
29 | * #define UV2H_xxx <uv2address> | ||
30 | * #define UVH_xxx (is_uv1_hub() ? UV1H_xxx : UV2H_xxx) | ||
31 | * union uvh_xxx { | ||
32 | * unsigned long v; | ||
33 | * struct uv1h_int_cmpd_s { (Common fields only) | ||
34 | * } s; | ||
35 | * struct uv1h_int_cmpd_s { (Full UV1 definition) | ||
36 | * } s1; | ||
37 | * struct uv2h_int_cmpd_s { (Full UV2 definition) | ||
38 | * } s2; | ||
39 | * }; | ||
40 | * | ||
41 | * Only essential difference are enumerated. For example, if the address is | ||
42 | * the same for both UV1 & UV2, only a single #define is generated. Likewise, | ||
43 | * if the contents is the same for both hubs, only the "s" structure is | ||
44 | * generated. | ||
45 | * | ||
46 | * If the MMR exists on ONLY 1 type of hub, no generic definition is | ||
47 | * generated: | ||
48 | * #define UVnH_xxx <uvn address> | ||
49 | * union uvnh_xxx { | ||
50 | * unsigned long v; | ||
51 | * struct uvh_int_cmpd_s { | ||
52 | * } sn; | ||
53 | * }; | ||
54 | */ | ||
55 | |||
14 | #define UV_MMR_ENABLE (1UL << 63) | 56 | #define UV_MMR_ENABLE (1UL << 63) |
15 | 57 | ||
58 | #define UV1_HUB_PART_NUMBER 0x88a5 | ||
59 | #define UV2_HUB_PART_NUMBER 0x8eb8 | ||
60 | |||
61 | /* Compat: if this #define is present, UV headers support UV2 */ | ||
62 | #define UV2_HUB_IS_SUPPORTED 1 | ||
63 | |||
64 | /* KABI compat: if this #define is present, KABI hacks are present */ | ||
65 | #define UV2_HUB_KABI_HACKS 1 | ||
66 | |||
16 | /* ========================================================================= */ | 67 | /* ========================================================================= */ |
17 | /* UVH_BAU_DATA_BROADCAST */ | 68 | /* UVH_BAU_DATA_BROADCAST */ |
18 | /* ========================================================================= */ | 69 | /* ========================================================================= */ |
19 | #define UVH_BAU_DATA_BROADCAST 0x61688UL | 70 | #define UVH_BAU_DATA_BROADCAST 0x61688UL |
20 | #define UVH_BAU_DATA_BROADCAST_32 0x0440 | 71 | #define UVH_BAU_DATA_BROADCAST_32 0x440 |
21 | 72 | ||
22 | #define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0 | 73 | #define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0 |
23 | #define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL | 74 | #define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL |
@@ -34,7 +85,7 @@ union uvh_bau_data_broadcast_u { | |||
34 | /* UVH_BAU_DATA_CONFIG */ | 85 | /* UVH_BAU_DATA_CONFIG */ |
35 | /* ========================================================================= */ | 86 | /* ========================================================================= */ |
36 | #define UVH_BAU_DATA_CONFIG 0x61680UL | 87 | #define UVH_BAU_DATA_CONFIG 0x61680UL |
37 | #define UVH_BAU_DATA_CONFIG_32 0x0438 | 88 | #define UVH_BAU_DATA_CONFIG_32 0x438 |
38 | 89 | ||
39 | #define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0 | 90 | #define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0 |
40 | #define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL | 91 | #define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL |
@@ -73,125 +124,245 @@ union uvh_bau_data_config_u { | |||
73 | /* UVH_EVENT_OCCURRED0 */ | 124 | /* UVH_EVENT_OCCURRED0 */ |
74 | /* ========================================================================= */ | 125 | /* ========================================================================= */ |
75 | #define UVH_EVENT_OCCURRED0 0x70000UL | 126 | #define UVH_EVENT_OCCURRED0 0x70000UL |
76 | #define UVH_EVENT_OCCURRED0_32 0x005e8 | 127 | #define UVH_EVENT_OCCURRED0_32 0x5e8 |
77 | 128 | ||
78 | #define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0 | 129 | #define UV1H_EVENT_OCCURRED0_LB_HCERR_SHFT 0 |
79 | #define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL | 130 | #define UV1H_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL |
80 | #define UVH_EVENT_OCCURRED0_GR0_HCERR_SHFT 1 | 131 | #define UV1H_EVENT_OCCURRED0_GR0_HCERR_SHFT 1 |
81 | #define UVH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL | 132 | #define UV1H_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL |
82 | #define UVH_EVENT_OCCURRED0_GR1_HCERR_SHFT 2 | 133 | #define UV1H_EVENT_OCCURRED0_GR1_HCERR_SHFT 2 |
83 | #define UVH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL | 134 | #define UV1H_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL |
84 | #define UVH_EVENT_OCCURRED0_LH_HCERR_SHFT 3 | 135 | #define UV1H_EVENT_OCCURRED0_LH_HCERR_SHFT 3 |
85 | #define UVH_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL | 136 | #define UV1H_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL |
86 | #define UVH_EVENT_OCCURRED0_RH_HCERR_SHFT 4 | 137 | #define UV1H_EVENT_OCCURRED0_RH_HCERR_SHFT 4 |
87 | #define UVH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL | 138 | #define UV1H_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL |
88 | #define UVH_EVENT_OCCURRED0_XN_HCERR_SHFT 5 | 139 | #define UV1H_EVENT_OCCURRED0_XN_HCERR_SHFT 5 |
89 | #define UVH_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL | 140 | #define UV1H_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL |
90 | #define UVH_EVENT_OCCURRED0_SI_HCERR_SHFT 6 | 141 | #define UV1H_EVENT_OCCURRED0_SI_HCERR_SHFT 6 |
91 | #define UVH_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL | 142 | #define UV1H_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL |
92 | #define UVH_EVENT_OCCURRED0_LB_AOERR0_SHFT 7 | 143 | #define UV1H_EVENT_OCCURRED0_LB_AOERR0_SHFT 7 |
93 | #define UVH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL | 144 | #define UV1H_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL |
94 | #define UVH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8 | 145 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8 |
95 | #define UVH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL | 146 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL |
96 | #define UVH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9 | 147 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9 |
97 | #define UVH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL | 148 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL |
98 | #define UVH_EVENT_OCCURRED0_LH_AOERR0_SHFT 10 | 149 | #define UV1H_EVENT_OCCURRED0_LH_AOERR0_SHFT 10 |
99 | #define UVH_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL | 150 | #define UV1H_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL |
100 | #define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 | 151 | #define UV1H_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 |
101 | #define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL | 152 | #define UV1H_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL |
102 | #define UVH_EVENT_OCCURRED0_XN_AOERR0_SHFT 12 | 153 | #define UV1H_EVENT_OCCURRED0_XN_AOERR0_SHFT 12 |
103 | #define UVH_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL | 154 | #define UV1H_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL |
104 | #define UVH_EVENT_OCCURRED0_SI_AOERR0_SHFT 13 | 155 | #define UV1H_EVENT_OCCURRED0_SI_AOERR0_SHFT 13 |
105 | #define UVH_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL | 156 | #define UV1H_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL |
106 | #define UVH_EVENT_OCCURRED0_LB_AOERR1_SHFT 14 | 157 | #define UV1H_EVENT_OCCURRED0_LB_AOERR1_SHFT 14 |
107 | #define UVH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL | 158 | #define UV1H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL |
108 | #define UVH_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15 | 159 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15 |
109 | #define UVH_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL | 160 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL |
110 | #define UVH_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16 | 161 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16 |
111 | #define UVH_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL | 162 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL |
112 | #define UVH_EVENT_OCCURRED0_LH_AOERR1_SHFT 17 | 163 | #define UV1H_EVENT_OCCURRED0_LH_AOERR1_SHFT 17 |
113 | #define UVH_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL | 164 | #define UV1H_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL |
114 | #define UVH_EVENT_OCCURRED0_RH_AOERR1_SHFT 18 | 165 | #define UV1H_EVENT_OCCURRED0_RH_AOERR1_SHFT 18 |
115 | #define UVH_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL | 166 | #define UV1H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL |
116 | #define UVH_EVENT_OCCURRED0_XN_AOERR1_SHFT 19 | 167 | #define UV1H_EVENT_OCCURRED0_XN_AOERR1_SHFT 19 |
117 | #define UVH_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL | 168 | #define UV1H_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL |
118 | #define UVH_EVENT_OCCURRED0_SI_AOERR1_SHFT 20 | 169 | #define UV1H_EVENT_OCCURRED0_SI_AOERR1_SHFT 20 |
119 | #define UVH_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL | 170 | #define UV1H_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL |
120 | #define UVH_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21 | 171 | #define UV1H_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21 |
121 | #define UVH_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL | 172 | #define UV1H_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL |
122 | #define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22 | 173 | #define UV1H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22 |
123 | #define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL | 174 | #define UV1H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL |
124 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23 | 175 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23 |
125 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL | 176 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL |
126 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24 | 177 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24 |
127 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL | 178 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL |
128 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25 | 179 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25 |
129 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL | 180 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL |
130 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26 | 181 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26 |
131 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL | 182 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL |
132 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27 | 183 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27 |
133 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL | 184 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL |
134 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28 | 185 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28 |
135 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL | 186 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL |
136 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29 | 187 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29 |
137 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL | 188 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL |
138 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30 | 189 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30 |
139 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL | 190 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL |
140 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31 | 191 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31 |
141 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL | 192 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL |
142 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32 | 193 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32 |
143 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL | 194 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL |
144 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33 | 195 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33 |
145 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL | 196 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL |
146 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34 | 197 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34 |
147 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL | 198 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL |
148 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35 | 199 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35 |
149 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL | 200 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL |
150 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36 | 201 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36 |
151 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL | 202 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL |
152 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37 | 203 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37 |
153 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL | 204 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL |
154 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38 | 205 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38 |
155 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL | 206 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL |
156 | #define UVH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39 | 207 | #define UV1H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39 |
157 | #define UVH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL | 208 | #define UV1H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL |
158 | #define UVH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40 | 209 | #define UV1H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40 |
159 | #define UVH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL | 210 | #define UV1H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL |
160 | #define UVH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41 | 211 | #define UV1H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41 |
161 | #define UVH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL | 212 | #define UV1H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL |
162 | #define UVH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42 | 213 | #define UV1H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42 |
163 | #define UVH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL | 214 | #define UV1H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL |
164 | #define UVH_EVENT_OCCURRED0_LTC_INT_SHFT 43 | 215 | #define UV1H_EVENT_OCCURRED0_LTC_INT_SHFT 43 |
165 | #define UVH_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL | 216 | #define UV1H_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL |
166 | #define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44 | 217 | #define UV1H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44 |
167 | #define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL | 218 | #define UV1H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL |
168 | #define UVH_EVENT_OCCURRED0_IPI_INT_SHFT 45 | 219 | #define UV1H_EVENT_OCCURRED0_IPI_INT_SHFT 45 |
169 | #define UVH_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL | 220 | #define UV1H_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL |
170 | #define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46 | 221 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46 |
171 | #define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL | 222 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL |
172 | #define UVH_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47 | 223 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47 |
173 | #define UVH_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL | 224 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL |
174 | #define UVH_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48 | 225 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48 |
175 | #define UVH_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL | 226 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL |
176 | #define UVH_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49 | 227 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49 |
177 | #define UVH_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL | 228 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL |
178 | #define UVH_EVENT_OCCURRED0_PROFILE_INT_SHFT 50 | 229 | #define UV1H_EVENT_OCCURRED0_PROFILE_INT_SHFT 50 |
179 | #define UVH_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL | 230 | #define UV1H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL |
180 | #define UVH_EVENT_OCCURRED0_RTC0_SHFT 51 | 231 | #define UV1H_EVENT_OCCURRED0_RTC0_SHFT 51 |
181 | #define UVH_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL | 232 | #define UV1H_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL |
182 | #define UVH_EVENT_OCCURRED0_RTC1_SHFT 52 | 233 | #define UV1H_EVENT_OCCURRED0_RTC1_SHFT 52 |
183 | #define UVH_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL | 234 | #define UV1H_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL |
184 | #define UVH_EVENT_OCCURRED0_RTC2_SHFT 53 | 235 | #define UV1H_EVENT_OCCURRED0_RTC2_SHFT 53 |
185 | #define UVH_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL | 236 | #define UV1H_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL |
186 | #define UVH_EVENT_OCCURRED0_RTC3_SHFT 54 | 237 | #define UV1H_EVENT_OCCURRED0_RTC3_SHFT 54 |
187 | #define UVH_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL | 238 | #define UV1H_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL |
188 | #define UVH_EVENT_OCCURRED0_BAU_DATA_SHFT 55 | 239 | #define UV1H_EVENT_OCCURRED0_BAU_DATA_SHFT 55 |
189 | #define UVH_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL | 240 | #define UV1H_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL |
190 | #define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56 | 241 | #define UV1H_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56 |
191 | #define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL | 242 | #define UV1H_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL |
243 | |||
244 | #define UV2H_EVENT_OCCURRED0_LB_HCERR_SHFT 0 | ||
245 | #define UV2H_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL | ||
246 | #define UV2H_EVENT_OCCURRED0_QP_HCERR_SHFT 1 | ||
247 | #define UV2H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL | ||
248 | #define UV2H_EVENT_OCCURRED0_RH_HCERR_SHFT 2 | ||
249 | #define UV2H_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000004UL | ||
250 | #define UV2H_EVENT_OCCURRED0_LH0_HCERR_SHFT 3 | ||
251 | #define UV2H_EVENT_OCCURRED0_LH0_HCERR_MASK 0x0000000000000008UL | ||
252 | #define UV2H_EVENT_OCCURRED0_LH1_HCERR_SHFT 4 | ||
253 | #define UV2H_EVENT_OCCURRED0_LH1_HCERR_MASK 0x0000000000000010UL | ||
254 | #define UV2H_EVENT_OCCURRED0_GR0_HCERR_SHFT 5 | ||
255 | #define UV2H_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000020UL | ||
256 | #define UV2H_EVENT_OCCURRED0_GR1_HCERR_SHFT 6 | ||
257 | #define UV2H_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000040UL | ||
258 | #define UV2H_EVENT_OCCURRED0_NI0_HCERR_SHFT 7 | ||
259 | #define UV2H_EVENT_OCCURRED0_NI0_HCERR_MASK 0x0000000000000080UL | ||
260 | #define UV2H_EVENT_OCCURRED0_NI1_HCERR_SHFT 8 | ||
261 | #define UV2H_EVENT_OCCURRED0_NI1_HCERR_MASK 0x0000000000000100UL | ||
262 | #define UV2H_EVENT_OCCURRED0_LB_AOERR0_SHFT 9 | ||
263 | #define UV2H_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000200UL | ||
264 | #define UV2H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10 | ||
265 | #define UV2H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL | ||
266 | #define UV2H_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 | ||
267 | #define UV2H_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL | ||
268 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR0_SHFT 12 | ||
269 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR0_MASK 0x0000000000001000UL | ||
270 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR0_SHFT 13 | ||
271 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR0_MASK 0x0000000000002000UL | ||
272 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR0_SHFT 14 | ||
273 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000004000UL | ||
274 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR0_SHFT 15 | ||
275 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000008000UL | ||
276 | #define UV2H_EVENT_OCCURRED0_XB_AOERR0_SHFT 16 | ||
277 | #define UV2H_EVENT_OCCURRED0_XB_AOERR0_MASK 0x0000000000010000UL | ||
278 | #define UV2H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17 | ||
279 | #define UV2H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL | ||
280 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18 | ||
281 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL | ||
282 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19 | ||
283 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL | ||
284 | #define UV2H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20 | ||
285 | #define UV2H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL | ||
286 | #define UV2H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21 | ||
287 | #define UV2H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL | ||
288 | #define UV2H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22 | ||
289 | #define UV2H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL | ||
290 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23 | ||
291 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL | ||
292 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24 | ||
293 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL | ||
294 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25 | ||
295 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL | ||
296 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26 | ||
297 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL | ||
298 | #define UV2H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27 | ||
299 | #define UV2H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL | ||
300 | #define UV2H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28 | ||
301 | #define UV2H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL | ||
302 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29 | ||
303 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL | ||
304 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30 | ||
305 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL | ||
306 | #define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31 | ||
307 | #define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL | ||
308 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32 | ||
309 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL | ||
310 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33 | ||
311 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL | ||
312 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34 | ||
313 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL | ||
314 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35 | ||
315 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL | ||
316 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36 | ||
317 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL | ||
318 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37 | ||
319 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL | ||
320 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38 | ||
321 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL | ||
322 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39 | ||
323 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL | ||
324 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40 | ||
325 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL | ||
326 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41 | ||
327 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL | ||
328 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42 | ||
329 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL | ||
330 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43 | ||
331 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL | ||
332 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44 | ||
333 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL | ||
334 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45 | ||
335 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL | ||
336 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46 | ||
337 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL | ||
338 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47 | ||
339 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL | ||
340 | #define UV2H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48 | ||
341 | #define UV2H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL | ||
342 | #define UV2H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49 | ||
343 | #define UV2H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL | ||
344 | #define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50 | ||
345 | #define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL | ||
346 | #define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51 | ||
347 | #define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL | ||
348 | #define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52 | ||
349 | #define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL | ||
350 | #define UV2H_EVENT_OCCURRED0_IPI_INT_SHFT 53 | ||
351 | #define UV2H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL | ||
352 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54 | ||
353 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL | ||
354 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55 | ||
355 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL | ||
356 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56 | ||
357 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL | ||
358 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57 | ||
359 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL | ||
360 | #define UV2H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58 | ||
361 | #define UV2H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL | ||
362 | |||
192 | union uvh_event_occurred0_u { | 363 | union uvh_event_occurred0_u { |
193 | unsigned long v; | 364 | unsigned long v; |
194 | struct uvh_event_occurred0_s { | 365 | struct uv1h_event_occurred0_s { |
195 | unsigned long lb_hcerr : 1; /* RW, W1C */ | 366 | unsigned long lb_hcerr : 1; /* RW, W1C */ |
196 | unsigned long gr0_hcerr : 1; /* RW, W1C */ | 367 | unsigned long gr0_hcerr : 1; /* RW, W1C */ |
197 | unsigned long gr1_hcerr : 1; /* RW, W1C */ | 368 | unsigned long gr1_hcerr : 1; /* RW, W1C */ |
@@ -250,14 +421,76 @@ union uvh_event_occurred0_u { | |||
250 | unsigned long bau_data : 1; /* RW, W1C */ | 421 | unsigned long bau_data : 1; /* RW, W1C */ |
251 | unsigned long power_management_req : 1; /* RW, W1C */ | 422 | unsigned long power_management_req : 1; /* RW, W1C */ |
252 | unsigned long rsvd_57_63 : 7; /* */ | 423 | unsigned long rsvd_57_63 : 7; /* */ |
253 | } s; | 424 | } s1; |
425 | struct uv2h_event_occurred0_s { | ||
426 | unsigned long lb_hcerr : 1; /* RW */ | ||
427 | unsigned long qp_hcerr : 1; /* RW */ | ||
428 | unsigned long rh_hcerr : 1; /* RW */ | ||
429 | unsigned long lh0_hcerr : 1; /* RW */ | ||
430 | unsigned long lh1_hcerr : 1; /* RW */ | ||
431 | unsigned long gr0_hcerr : 1; /* RW */ | ||
432 | unsigned long gr1_hcerr : 1; /* RW */ | ||
433 | unsigned long ni0_hcerr : 1; /* RW */ | ||
434 | unsigned long ni1_hcerr : 1; /* RW */ | ||
435 | unsigned long lb_aoerr0 : 1; /* RW */ | ||
436 | unsigned long qp_aoerr0 : 1; /* RW */ | ||
437 | unsigned long rh_aoerr0 : 1; /* RW */ | ||
438 | unsigned long lh0_aoerr0 : 1; /* RW */ | ||
439 | unsigned long lh1_aoerr0 : 1; /* RW */ | ||
440 | unsigned long gr0_aoerr0 : 1; /* RW */ | ||
441 | unsigned long gr1_aoerr0 : 1; /* RW */ | ||
442 | unsigned long xb_aoerr0 : 1; /* RW */ | ||
443 | unsigned long rt_aoerr0 : 1; /* RW */ | ||
444 | unsigned long ni0_aoerr0 : 1; /* RW */ | ||
445 | unsigned long ni1_aoerr0 : 1; /* RW */ | ||
446 | unsigned long lb_aoerr1 : 1; /* RW */ | ||
447 | unsigned long qp_aoerr1 : 1; /* RW */ | ||
448 | unsigned long rh_aoerr1 : 1; /* RW */ | ||
449 | unsigned long lh0_aoerr1 : 1; /* RW */ | ||
450 | unsigned long lh1_aoerr1 : 1; /* RW */ | ||
451 | unsigned long gr0_aoerr1 : 1; /* RW */ | ||
452 | unsigned long gr1_aoerr1 : 1; /* RW */ | ||
453 | unsigned long xb_aoerr1 : 1; /* RW */ | ||
454 | unsigned long rt_aoerr1 : 1; /* RW */ | ||
455 | unsigned long ni0_aoerr1 : 1; /* RW */ | ||
456 | unsigned long ni1_aoerr1 : 1; /* RW */ | ||
457 | unsigned long system_shutdown_int : 1; /* RW */ | ||
458 | unsigned long lb_irq_int_0 : 1; /* RW */ | ||
459 | unsigned long lb_irq_int_1 : 1; /* RW */ | ||
460 | unsigned long lb_irq_int_2 : 1; /* RW */ | ||
461 | unsigned long lb_irq_int_3 : 1; /* RW */ | ||
462 | unsigned long lb_irq_int_4 : 1; /* RW */ | ||
463 | unsigned long lb_irq_int_5 : 1; /* RW */ | ||
464 | unsigned long lb_irq_int_6 : 1; /* RW */ | ||
465 | unsigned long lb_irq_int_7 : 1; /* RW */ | ||
466 | unsigned long lb_irq_int_8 : 1; /* RW */ | ||
467 | unsigned long lb_irq_int_9 : 1; /* RW */ | ||
468 | unsigned long lb_irq_int_10 : 1; /* RW */ | ||
469 | unsigned long lb_irq_int_11 : 1; /* RW */ | ||
470 | unsigned long lb_irq_int_12 : 1; /* RW */ | ||
471 | unsigned long lb_irq_int_13 : 1; /* RW */ | ||
472 | unsigned long lb_irq_int_14 : 1; /* RW */ | ||
473 | unsigned long lb_irq_int_15 : 1; /* RW */ | ||
474 | unsigned long l1_nmi_int : 1; /* RW */ | ||
475 | unsigned long stop_clock : 1; /* RW */ | ||
476 | unsigned long asic_to_l1 : 1; /* RW */ | ||
477 | unsigned long l1_to_asic : 1; /* RW */ | ||
478 | unsigned long la_seq_trigger : 1; /* RW */ | ||
479 | unsigned long ipi_int : 1; /* RW */ | ||
480 | unsigned long extio_int0 : 1; /* RW */ | ||
481 | unsigned long extio_int1 : 1; /* RW */ | ||
482 | unsigned long extio_int2 : 1; /* RW */ | ||
483 | unsigned long extio_int3 : 1; /* RW */ | ||
484 | unsigned long profile_int : 1; /* RW */ | ||
485 | unsigned long rsvd_59_63 : 5; /* */ | ||
486 | } s2; | ||
254 | }; | 487 | }; |
255 | 488 | ||
256 | /* ========================================================================= */ | 489 | /* ========================================================================= */ |
257 | /* UVH_EVENT_OCCURRED0_ALIAS */ | 490 | /* UVH_EVENT_OCCURRED0_ALIAS */ |
258 | /* ========================================================================= */ | 491 | /* ========================================================================= */ |
259 | #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL | 492 | #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL |
260 | #define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0 | 493 | #define UVH_EVENT_OCCURRED0_ALIAS_32 0x5f0 |
261 | 494 | ||
262 | /* ========================================================================= */ | 495 | /* ========================================================================= */ |
263 | /* UVH_GR0_TLB_INT0_CONFIG */ | 496 | /* UVH_GR0_TLB_INT0_CONFIG */ |
@@ -432,8 +665,16 @@ union uvh_int_cmpb_u { | |||
432 | /* ========================================================================= */ | 665 | /* ========================================================================= */ |
433 | #define UVH_INT_CMPC 0x22100UL | 666 | #define UVH_INT_CMPC 0x22100UL |
434 | 667 | ||
435 | #define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 | 668 | #define UV1H_INT_CMPC_REAL_TIME_CMPC_SHFT 0 |
436 | #define UVH_INT_CMPC_REAL_TIME_CMPC_MASK 0x00ffffffffffffffUL | 669 | #define UV2H_INT_CMPC_REAL_TIME_CMPC_SHFT 0 |
670 | #define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT (is_uv1_hub() ? \ | ||
671 | UV1H_INT_CMPC_REAL_TIME_CMPC_SHFT : \ | ||
672 | UV2H_INT_CMPC_REAL_TIME_CMPC_SHFT) | ||
673 | #define UV1H_INT_CMPC_REAL_TIME_CMPC_MASK 0xffffffffffffffUL | ||
674 | #define UV2H_INT_CMPC_REAL_TIME_CMPC_MASK 0xffffffffffffffUL | ||
675 | #define UVH_INT_CMPC_REAL_TIME_CMPC_MASK (is_uv1_hub() ? \ | ||
676 | UV1H_INT_CMPC_REAL_TIME_CMPC_MASK : \ | ||
677 | UV2H_INT_CMPC_REAL_TIME_CMPC_MASK) | ||
437 | 678 | ||
438 | union uvh_int_cmpc_u { | 679 | union uvh_int_cmpc_u { |
439 | unsigned long v; | 680 | unsigned long v; |
@@ -448,8 +689,16 @@ union uvh_int_cmpc_u { | |||
448 | /* ========================================================================= */ | 689 | /* ========================================================================= */ |
449 | #define UVH_INT_CMPD 0x22180UL | 690 | #define UVH_INT_CMPD 0x22180UL |
450 | 691 | ||
451 | #define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 | 692 | #define UV1H_INT_CMPD_REAL_TIME_CMPD_SHFT 0 |
452 | #define UVH_INT_CMPD_REAL_TIME_CMPD_MASK 0x00ffffffffffffffUL | 693 | #define UV2H_INT_CMPD_REAL_TIME_CMPD_SHFT 0 |
694 | #define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT (is_uv1_hub() ? \ | ||
695 | UV1H_INT_CMPD_REAL_TIME_CMPD_SHFT : \ | ||
696 | UV2H_INT_CMPD_REAL_TIME_CMPD_SHFT) | ||
697 | #define UV1H_INT_CMPD_REAL_TIME_CMPD_MASK 0xffffffffffffffUL | ||
698 | #define UV2H_INT_CMPD_REAL_TIME_CMPD_MASK 0xffffffffffffffUL | ||
699 | #define UVH_INT_CMPD_REAL_TIME_CMPD_MASK (is_uv1_hub() ? \ | ||
700 | UV1H_INT_CMPD_REAL_TIME_CMPD_MASK : \ | ||
701 | UV2H_INT_CMPD_REAL_TIME_CMPD_MASK) | ||
453 | 702 | ||
454 | union uvh_int_cmpd_u { | 703 | union uvh_int_cmpd_u { |
455 | unsigned long v; | 704 | unsigned long v; |
@@ -463,7 +712,7 @@ union uvh_int_cmpd_u { | |||
463 | /* UVH_IPI_INT */ | 712 | /* UVH_IPI_INT */ |
464 | /* ========================================================================= */ | 713 | /* ========================================================================= */ |
465 | #define UVH_IPI_INT 0x60500UL | 714 | #define UVH_IPI_INT 0x60500UL |
466 | #define UVH_IPI_INT_32 0x0348 | 715 | #define UVH_IPI_INT_32 0x348 |
467 | 716 | ||
468 | #define UVH_IPI_INT_VECTOR_SHFT 0 | 717 | #define UVH_IPI_INT_VECTOR_SHFT 0 |
469 | #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL | 718 | #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL |
@@ -493,7 +742,7 @@ union uvh_ipi_int_u { | |||
493 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST */ | 742 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST */ |
494 | /* ========================================================================= */ | 743 | /* ========================================================================= */ |
495 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL | 744 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL |
496 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x009c0 | 745 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x9c0 |
497 | 746 | ||
498 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 | 747 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 |
499 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL | 748 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL |
@@ -515,7 +764,7 @@ union uvh_lb_bau_intd_payload_queue_first_u { | |||
515 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST */ | 764 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST */ |
516 | /* ========================================================================= */ | 765 | /* ========================================================================= */ |
517 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL | 766 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL |
518 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x009c8 | 767 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x9c8 |
519 | 768 | ||
520 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 | 769 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 |
521 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL | 770 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL |
@@ -533,7 +782,7 @@ union uvh_lb_bau_intd_payload_queue_last_u { | |||
533 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL */ | 782 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL */ |
534 | /* ========================================================================= */ | 783 | /* ========================================================================= */ |
535 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL | 784 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL |
536 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x009d0 | 785 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x9d0 |
537 | 786 | ||
538 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 | 787 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 |
539 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL | 788 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL |
@@ -551,7 +800,7 @@ union uvh_lb_bau_intd_payload_queue_tail_u { | |||
551 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE */ | 800 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE */ |
552 | /* ========================================================================= */ | 801 | /* ========================================================================= */ |
553 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL | 802 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL |
554 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0x0a68 | 803 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0xa68 |
555 | 804 | ||
556 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 | 805 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 |
557 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL | 806 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL |
@@ -585,6 +834,7 @@ union uvh_lb_bau_intd_payload_queue_tail_u { | |||
585 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL | 834 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL |
586 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15 | 835 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15 |
587 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL | 836 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL |
837 | |||
588 | union uvh_lb_bau_intd_software_acknowledge_u { | 838 | union uvh_lb_bau_intd_software_acknowledge_u { |
589 | unsigned long v; | 839 | unsigned long v; |
590 | struct uvh_lb_bau_intd_software_acknowledge_s { | 840 | struct uvh_lb_bau_intd_software_acknowledge_s { |
@@ -612,13 +862,13 @@ union uvh_lb_bau_intd_software_acknowledge_u { | |||
612 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS */ | 862 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS */ |
613 | /* ========================================================================= */ | 863 | /* ========================================================================= */ |
614 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL | 864 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL |
615 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70 | 865 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0xa70 |
616 | 866 | ||
617 | /* ========================================================================= */ | 867 | /* ========================================================================= */ |
618 | /* UVH_LB_BAU_MISC_CONTROL */ | 868 | /* UVH_LB_BAU_MISC_CONTROL */ |
619 | /* ========================================================================= */ | 869 | /* ========================================================================= */ |
620 | #define UVH_LB_BAU_MISC_CONTROL 0x320170UL | 870 | #define UVH_LB_BAU_MISC_CONTROL 0x320170UL |
621 | #define UVH_LB_BAU_MISC_CONTROL_32 0x00a10 | 871 | #define UVH_LB_BAU_MISC_CONTROL_32 0xa10 |
622 | 872 | ||
623 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 | 873 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 |
624 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL | 874 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL |
@@ -628,8 +878,8 @@ union uvh_lb_bau_intd_software_acknowledge_u { | |||
628 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL | 878 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL |
629 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 | 879 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 |
630 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL | 880 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL |
631 | #define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_SHFT 11 | 881 | #define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 |
632 | #define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL | 882 | #define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL |
633 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 | 883 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 |
634 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL | 884 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL |
635 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 | 885 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 |
@@ -650,8 +900,86 @@ union uvh_lb_bau_intd_software_acknowledge_u { | |||
650 | #define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL | 900 | #define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL |
651 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 | 901 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 |
652 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL | 902 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL |
653 | #define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48 | 903 | |
654 | #define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL | 904 | #define UV1H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 |
905 | #define UV1H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL | ||
906 | #define UV1H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 | ||
907 | #define UV1H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL | ||
908 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 | ||
909 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL | ||
910 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 | ||
911 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL | ||
912 | #define UV1H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 | ||
913 | #define UV1H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL | ||
914 | #define UV1H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 | ||
915 | #define UV1H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL | ||
916 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 | ||
917 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL | ||
918 | #define UV1H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 | ||
919 | #define UV1H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL | ||
920 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 | ||
921 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL | ||
922 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 | ||
923 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL | ||
924 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 | ||
925 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL | ||
926 | #define UV1H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 | ||
927 | #define UV1H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL | ||
928 | #define UV1H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 | ||
929 | #define UV1H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL | ||
930 | #define UV1H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 | ||
931 | #define UV1H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL | ||
932 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 | ||
933 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL | ||
934 | #define UV1H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 | ||
935 | #define UV1H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL | ||
936 | |||
937 | #define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 | ||
938 | #define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL | ||
939 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 | ||
940 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL | ||
941 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 | ||
942 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL | ||
943 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 | ||
944 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL | ||
945 | #define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 | ||
946 | #define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL | ||
947 | #define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 | ||
948 | #define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL | ||
949 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 | ||
950 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL | ||
951 | #define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 | ||
952 | #define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL | ||
953 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 | ||
954 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL | ||
955 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 | ||
956 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL | ||
957 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 | ||
958 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL | ||
959 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 | ||
960 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL | ||
961 | #define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 | ||
962 | #define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL | ||
963 | #define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 | ||
964 | #define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL | ||
965 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 | ||
966 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL | ||
967 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29 | ||
968 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL | ||
969 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30 | ||
970 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL | ||
971 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31 | ||
972 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL | ||
973 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32 | ||
974 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL | ||
975 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33 | ||
976 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL | ||
977 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34 | ||
978 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL | ||
979 | #define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35 | ||
980 | #define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL | ||
981 | #define UV2H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 | ||
982 | #define UV2H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL | ||
655 | 983 | ||
656 | union uvh_lb_bau_misc_control_u { | 984 | union uvh_lb_bau_misc_control_u { |
657 | unsigned long v; | 985 | unsigned long v; |
@@ -660,7 +988,25 @@ union uvh_lb_bau_misc_control_u { | |||
660 | unsigned long apic_mode : 1; /* RW */ | 988 | unsigned long apic_mode : 1; /* RW */ |
661 | unsigned long force_broadcast : 1; /* RW */ | 989 | unsigned long force_broadcast : 1; /* RW */ |
662 | unsigned long force_lock_nop : 1; /* RW */ | 990 | unsigned long force_lock_nop : 1; /* RW */ |
663 | unsigned long csi_agent_presence_vector : 3; /* RW */ | 991 | unsigned long qpi_agent_presence_vector : 3; /* RW */ |
992 | unsigned long descriptor_fetch_mode : 1; /* RW */ | ||
993 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ | ||
994 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ | ||
995 | unsigned long enable_dual_mapping_mode : 1; /* RW */ | ||
996 | unsigned long vga_io_port_decode_enable : 1; /* RW */ | ||
997 | unsigned long vga_io_port_16_bit_decode : 1; /* RW */ | ||
998 | unsigned long suppress_dest_registration : 1; /* RW */ | ||
999 | unsigned long programmed_initial_priority : 3; /* RW */ | ||
1000 | unsigned long use_incoming_priority : 1; /* RW */ | ||
1001 | unsigned long enable_programmed_initial_priority : 1; /* RW */ | ||
1002 | unsigned long rsvd_29_63 : 35; | ||
1003 | } s; | ||
1004 | struct uv1h_lb_bau_misc_control_s { | ||
1005 | unsigned long rejection_delay : 8; /* RW */ | ||
1006 | unsigned long apic_mode : 1; /* RW */ | ||
1007 | unsigned long force_broadcast : 1; /* RW */ | ||
1008 | unsigned long force_lock_nop : 1; /* RW */ | ||
1009 | unsigned long qpi_agent_presence_vector : 3; /* RW */ | ||
664 | unsigned long descriptor_fetch_mode : 1; /* RW */ | 1010 | unsigned long descriptor_fetch_mode : 1; /* RW */ |
665 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ | 1011 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ |
666 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ | 1012 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ |
@@ -673,14 +1019,40 @@ union uvh_lb_bau_misc_control_u { | |||
673 | unsigned long enable_programmed_initial_priority : 1; /* RW */ | 1019 | unsigned long enable_programmed_initial_priority : 1; /* RW */ |
674 | unsigned long rsvd_29_47 : 19; /* */ | 1020 | unsigned long rsvd_29_47 : 19; /* */ |
675 | unsigned long fun : 16; /* RW */ | 1021 | unsigned long fun : 16; /* RW */ |
676 | } s; | 1022 | } s1; |
1023 | struct uv2h_lb_bau_misc_control_s { | ||
1024 | unsigned long rejection_delay : 8; /* RW */ | ||
1025 | unsigned long apic_mode : 1; /* RW */ | ||
1026 | unsigned long force_broadcast : 1; /* RW */ | ||
1027 | unsigned long force_lock_nop : 1; /* RW */ | ||
1028 | unsigned long qpi_agent_presence_vector : 3; /* RW */ | ||
1029 | unsigned long descriptor_fetch_mode : 1; /* RW */ | ||
1030 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ | ||
1031 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ | ||
1032 | unsigned long enable_dual_mapping_mode : 1; /* RW */ | ||
1033 | unsigned long vga_io_port_decode_enable : 1; /* RW */ | ||
1034 | unsigned long vga_io_port_16_bit_decode : 1; /* RW */ | ||
1035 | unsigned long suppress_dest_registration : 1; /* RW */ | ||
1036 | unsigned long programmed_initial_priority : 3; /* RW */ | ||
1037 | unsigned long use_incoming_priority : 1; /* RW */ | ||
1038 | unsigned long enable_programmed_initial_priority : 1; /* RW */ | ||
1039 | unsigned long enable_automatic_apic_mode_selection : 1; /* RW */ | ||
1040 | unsigned long apic_mode_status : 1; /* RO */ | ||
1041 | unsigned long suppress_interrupts_to_self : 1; /* RW */ | ||
1042 | unsigned long enable_lock_based_system_flush : 1; /* RW */ | ||
1043 | unsigned long enable_extended_sb_status : 1; /* RW */ | ||
1044 | unsigned long suppress_int_prio_udt_to_self : 1; /* RW */ | ||
1045 | unsigned long use_legacy_descriptor_formats : 1; /* RW */ | ||
1046 | unsigned long rsvd_36_47 : 12; /* */ | ||
1047 | unsigned long fun : 16; /* RW */ | ||
1048 | } s2; | ||
677 | }; | 1049 | }; |
678 | 1050 | ||
679 | /* ========================================================================= */ | 1051 | /* ========================================================================= */ |
680 | /* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ | 1052 | /* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ |
681 | /* ========================================================================= */ | 1053 | /* ========================================================================= */ |
682 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL | 1054 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL |
683 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x009a8 | 1055 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x9a8 |
684 | 1056 | ||
685 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0 | 1057 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0 |
686 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL | 1058 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL |
@@ -703,7 +1075,7 @@ union uvh_lb_bau_sb_activation_control_u { | |||
703 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_0 */ | 1075 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_0 */ |
704 | /* ========================================================================= */ | 1076 | /* ========================================================================= */ |
705 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL | 1077 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL |
706 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x009b0 | 1078 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x9b0 |
707 | 1079 | ||
708 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0 | 1080 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0 |
709 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL | 1081 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL |
@@ -719,7 +1091,7 @@ union uvh_lb_bau_sb_activation_status_0_u { | |||
719 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_1 */ | 1091 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_1 */ |
720 | /* ========================================================================= */ | 1092 | /* ========================================================================= */ |
721 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL | 1093 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL |
722 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x009b8 | 1094 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x9b8 |
723 | 1095 | ||
724 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0 | 1096 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0 |
725 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL | 1097 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL |
@@ -735,7 +1107,7 @@ union uvh_lb_bau_sb_activation_status_1_u { | |||
735 | /* UVH_LB_BAU_SB_DESCRIPTOR_BASE */ | 1107 | /* UVH_LB_BAU_SB_DESCRIPTOR_BASE */ |
736 | /* ========================================================================= */ | 1108 | /* ========================================================================= */ |
737 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL | 1109 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL |
738 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x009a0 | 1110 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x9a0 |
739 | 1111 | ||
740 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12 | 1112 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12 |
741 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL | 1113 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL |
@@ -754,23 +1126,6 @@ union uvh_lb_bau_sb_descriptor_base_u { | |||
754 | }; | 1126 | }; |
755 | 1127 | ||
756 | /* ========================================================================= */ | 1128 | /* ========================================================================= */ |
757 | /* UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK */ | ||
758 | /* ========================================================================= */ | ||
759 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL | ||
760 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x009f0 | ||
761 | |||
762 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0 | ||
763 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL | ||
764 | |||
765 | union uvh_lb_target_physical_apic_id_mask_u { | ||
766 | unsigned long v; | ||
767 | struct uvh_lb_target_physical_apic_id_mask_s { | ||
768 | unsigned long bit_enables : 32; /* RW */ | ||
769 | unsigned long rsvd_32_63 : 32; /* */ | ||
770 | } s; | ||
771 | }; | ||
772 | |||
773 | /* ========================================================================= */ | ||
774 | /* UVH_NODE_ID */ | 1129 | /* UVH_NODE_ID */ |
775 | /* ========================================================================= */ | 1130 | /* ========================================================================= */ |
776 | #define UVH_NODE_ID 0x0UL | 1131 | #define UVH_NODE_ID 0x0UL |
@@ -785,10 +1140,36 @@ union uvh_lb_target_physical_apic_id_mask_u { | |||
785 | #define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL | 1140 | #define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL |
786 | #define UVH_NODE_ID_NODE_ID_SHFT 32 | 1141 | #define UVH_NODE_ID_NODE_ID_SHFT 32 |
787 | #define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL | 1142 | #define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL |
788 | #define UVH_NODE_ID_NODES_PER_BIT_SHFT 48 | 1143 | |
789 | #define UVH_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL | 1144 | #define UV1H_NODE_ID_FORCE1_SHFT 0 |
790 | #define UVH_NODE_ID_NI_PORT_SHFT 56 | 1145 | #define UV1H_NODE_ID_FORCE1_MASK 0x0000000000000001UL |
791 | #define UVH_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL | 1146 | #define UV1H_NODE_ID_MANUFACTURER_SHFT 1 |
1147 | #define UV1H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL | ||
1148 | #define UV1H_NODE_ID_PART_NUMBER_SHFT 12 | ||
1149 | #define UV1H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL | ||
1150 | #define UV1H_NODE_ID_REVISION_SHFT 28 | ||
1151 | #define UV1H_NODE_ID_REVISION_MASK 0x00000000f0000000UL | ||
1152 | #define UV1H_NODE_ID_NODE_ID_SHFT 32 | ||
1153 | #define UV1H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL | ||
1154 | #define UV1H_NODE_ID_NODES_PER_BIT_SHFT 48 | ||
1155 | #define UV1H_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL | ||
1156 | #define UV1H_NODE_ID_NI_PORT_SHFT 56 | ||
1157 | #define UV1H_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL | ||
1158 | |||
1159 | #define UV2H_NODE_ID_FORCE1_SHFT 0 | ||
1160 | #define UV2H_NODE_ID_FORCE1_MASK 0x0000000000000001UL | ||
1161 | #define UV2H_NODE_ID_MANUFACTURER_SHFT 1 | ||
1162 | #define UV2H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL | ||
1163 | #define UV2H_NODE_ID_PART_NUMBER_SHFT 12 | ||
1164 | #define UV2H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL | ||
1165 | #define UV2H_NODE_ID_REVISION_SHFT 28 | ||
1166 | #define UV2H_NODE_ID_REVISION_MASK 0x00000000f0000000UL | ||
1167 | #define UV2H_NODE_ID_NODE_ID_SHFT 32 | ||
1168 | #define UV2H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL | ||
1169 | #define UV2H_NODE_ID_NODES_PER_BIT_SHFT 50 | ||
1170 | #define UV2H_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL | ||
1171 | #define UV2H_NODE_ID_NI_PORT_SHFT 57 | ||
1172 | #define UV2H_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL | ||
792 | 1173 | ||
793 | union uvh_node_id_u { | 1174 | union uvh_node_id_u { |
794 | unsigned long v; | 1175 | unsigned long v; |
@@ -798,12 +1179,31 @@ union uvh_node_id_u { | |||
798 | unsigned long part_number : 16; /* RO */ | 1179 | unsigned long part_number : 16; /* RO */ |
799 | unsigned long revision : 4; /* RO */ | 1180 | unsigned long revision : 4; /* RO */ |
800 | unsigned long node_id : 15; /* RW */ | 1181 | unsigned long node_id : 15; /* RW */ |
1182 | unsigned long rsvd_47_63 : 17; | ||
1183 | } s; | ||
1184 | struct uv1h_node_id_s { | ||
1185 | unsigned long force1 : 1; /* RO */ | ||
1186 | unsigned long manufacturer : 11; /* RO */ | ||
1187 | unsigned long part_number : 16; /* RO */ | ||
1188 | unsigned long revision : 4; /* RO */ | ||
1189 | unsigned long node_id : 15; /* RW */ | ||
801 | unsigned long rsvd_47 : 1; /* */ | 1190 | unsigned long rsvd_47 : 1; /* */ |
802 | unsigned long nodes_per_bit : 7; /* RW */ | 1191 | unsigned long nodes_per_bit : 7; /* RW */ |
803 | unsigned long rsvd_55 : 1; /* */ | 1192 | unsigned long rsvd_55 : 1; /* */ |
804 | unsigned long ni_port : 4; /* RO */ | 1193 | unsigned long ni_port : 4; /* RO */ |
805 | unsigned long rsvd_60_63 : 4; /* */ | 1194 | unsigned long rsvd_60_63 : 4; /* */ |
806 | } s; | 1195 | } s1; |
1196 | struct uv2h_node_id_s { | ||
1197 | unsigned long force1 : 1; /* RO */ | ||
1198 | unsigned long manufacturer : 11; /* RO */ | ||
1199 | unsigned long part_number : 16; /* RO */ | ||
1200 | unsigned long revision : 4; /* RO */ | ||
1201 | unsigned long node_id : 15; /* RW */ | ||
1202 | unsigned long rsvd_47_49 : 3; /* */ | ||
1203 | unsigned long nodes_per_bit : 7; /* RO */ | ||
1204 | unsigned long ni_port : 5; /* RO */ | ||
1205 | unsigned long rsvd_62_63 : 2; /* */ | ||
1206 | } s2; | ||
807 | }; | 1207 | }; |
808 | 1208 | ||
809 | /* ========================================================================= */ | 1209 | /* ========================================================================= */ |
@@ -954,18 +1354,38 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { | |||
954 | #define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | 1354 | #define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL |
955 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | 1355 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 |
956 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | 1356 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL |
957 | #define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 | 1357 | |
958 | #define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL | 1358 | #define UV1H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 |
1359 | #define UV1H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | ||
1360 | #define UV1H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | ||
1361 | #define UV1H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | ||
1362 | #define UV1H_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 | ||
1363 | #define UV1H_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL | ||
1364 | |||
1365 | #define UV2H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 | ||
1366 | #define UV2H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | ||
1367 | #define UV2H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | ||
1368 | #define UV2H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | ||
959 | 1369 | ||
960 | union uvh_rh_gam_config_mmr_u { | 1370 | union uvh_rh_gam_config_mmr_u { |
961 | unsigned long v; | 1371 | unsigned long v; |
962 | struct uvh_rh_gam_config_mmr_s { | 1372 | struct uvh_rh_gam_config_mmr_s { |
963 | unsigned long m_skt : 6; /* RW */ | 1373 | unsigned long m_skt : 6; /* RW */ |
964 | unsigned long n_skt : 4; /* RW */ | 1374 | unsigned long n_skt : 4; /* RW */ |
1375 | unsigned long rsvd_10_63 : 54; | ||
1376 | } s; | ||
1377 | struct uv1h_rh_gam_config_mmr_s { | ||
1378 | unsigned long m_skt : 6; /* RW */ | ||
1379 | unsigned long n_skt : 4; /* RW */ | ||
965 | unsigned long rsvd_10_11: 2; /* */ | 1380 | unsigned long rsvd_10_11: 2; /* */ |
966 | unsigned long mmiol_cfg : 1; /* RW */ | 1381 | unsigned long mmiol_cfg : 1; /* RW */ |
967 | unsigned long rsvd_13_63: 51; /* */ | 1382 | unsigned long rsvd_13_63: 51; /* */ |
968 | } s; | 1383 | } s1; |
1384 | struct uv2h_rh_gam_config_mmr_s { | ||
1385 | unsigned long m_skt : 6; /* RW */ | ||
1386 | unsigned long n_skt : 4; /* RW */ | ||
1387 | unsigned long rsvd_10_63: 54; /* */ | ||
1388 | } s2; | ||
969 | }; | 1389 | }; |
970 | 1390 | ||
971 | /* ========================================================================= */ | 1391 | /* ========================================================================= */ |
@@ -975,25 +1395,49 @@ union uvh_rh_gam_config_mmr_u { | |||
975 | 1395 | ||
976 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 | 1396 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 |
977 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL | 1397 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL |
978 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48 | 1398 | |
979 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL | 1399 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 |
980 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 | 1400 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL |
981 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL | 1401 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48 |
982 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | 1402 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL |
983 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | 1403 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 |
1404 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL | ||
1405 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1406 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1407 | |||
1408 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 | ||
1409 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL | ||
1410 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 | ||
1411 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL | ||
1412 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1413 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
984 | 1414 | ||
985 | union uvh_rh_gam_gru_overlay_config_mmr_u { | 1415 | union uvh_rh_gam_gru_overlay_config_mmr_u { |
986 | unsigned long v; | 1416 | unsigned long v; |
987 | struct uvh_rh_gam_gru_overlay_config_mmr_s { | 1417 | struct uvh_rh_gam_gru_overlay_config_mmr_s { |
988 | unsigned long rsvd_0_27: 28; /* */ | 1418 | unsigned long rsvd_0_27: 28; /* */ |
989 | unsigned long base : 18; /* RW */ | 1419 | unsigned long base : 18; /* RW */ |
1420 | unsigned long rsvd_46_62 : 17; | ||
1421 | unsigned long enable : 1; /* RW */ | ||
1422 | } s; | ||
1423 | struct uv1h_rh_gam_gru_overlay_config_mmr_s { | ||
1424 | unsigned long rsvd_0_27: 28; /* */ | ||
1425 | unsigned long base : 18; /* RW */ | ||
990 | unsigned long rsvd_46_47: 2; /* */ | 1426 | unsigned long rsvd_46_47: 2; /* */ |
991 | unsigned long gr4 : 1; /* RW */ | 1427 | unsigned long gr4 : 1; /* RW */ |
992 | unsigned long rsvd_49_51: 3; /* */ | 1428 | unsigned long rsvd_49_51: 3; /* */ |
993 | unsigned long n_gru : 4; /* RW */ | 1429 | unsigned long n_gru : 4; /* RW */ |
994 | unsigned long rsvd_56_62: 7; /* */ | 1430 | unsigned long rsvd_56_62: 7; /* */ |
995 | unsigned long enable : 1; /* RW */ | 1431 | unsigned long enable : 1; /* RW */ |
996 | } s; | 1432 | } s1; |
1433 | struct uv2h_rh_gam_gru_overlay_config_mmr_s { | ||
1434 | unsigned long rsvd_0_27: 28; /* */ | ||
1435 | unsigned long base : 18; /* RW */ | ||
1436 | unsigned long rsvd_46_51: 6; /* */ | ||
1437 | unsigned long n_gru : 4; /* RW */ | ||
1438 | unsigned long rsvd_56_62: 7; /* */ | ||
1439 | unsigned long enable : 1; /* RW */ | ||
1440 | } s2; | ||
997 | }; | 1441 | }; |
998 | 1442 | ||
999 | /* ========================================================================= */ | 1443 | /* ========================================================================= */ |
@@ -1001,25 +1445,42 @@ union uvh_rh_gam_gru_overlay_config_mmr_u { | |||
1001 | /* ========================================================================= */ | 1445 | /* ========================================================================= */ |
1002 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL | 1446 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL |
1003 | 1447 | ||
1004 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 | 1448 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 |
1005 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL | 1449 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL |
1006 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 | 1450 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 |
1007 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL | 1451 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL |
1008 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 | 1452 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 |
1009 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL | 1453 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL |
1010 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | 1454 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 |
1011 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | 1455 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL |
1456 | |||
1457 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 27 | ||
1458 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff8000000UL | ||
1459 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 | ||
1460 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL | ||
1461 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 | ||
1462 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL | ||
1463 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1464 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1012 | 1465 | ||
1013 | union uvh_rh_gam_mmioh_overlay_config_mmr_u { | 1466 | union uvh_rh_gam_mmioh_overlay_config_mmr_u { |
1014 | unsigned long v; | 1467 | unsigned long v; |
1015 | struct uvh_rh_gam_mmioh_overlay_config_mmr_s { | 1468 | struct uv1h_rh_gam_mmioh_overlay_config_mmr_s { |
1016 | unsigned long rsvd_0_29: 30; /* */ | 1469 | unsigned long rsvd_0_29: 30; /* */ |
1017 | unsigned long base : 16; /* RW */ | 1470 | unsigned long base : 16; /* RW */ |
1018 | unsigned long m_io : 6; /* RW */ | 1471 | unsigned long m_io : 6; /* RW */ |
1019 | unsigned long n_io : 4; /* RW */ | 1472 | unsigned long n_io : 4; /* RW */ |
1020 | unsigned long rsvd_56_62: 7; /* */ | 1473 | unsigned long rsvd_56_62: 7; /* */ |
1021 | unsigned long enable : 1; /* RW */ | 1474 | unsigned long enable : 1; /* RW */ |
1022 | } s; | 1475 | } s1; |
1476 | struct uv2h_rh_gam_mmioh_overlay_config_mmr_s { | ||
1477 | unsigned long rsvd_0_26: 27; /* */ | ||
1478 | unsigned long base : 19; /* RW */ | ||
1479 | unsigned long m_io : 6; /* RW */ | ||
1480 | unsigned long n_io : 4; /* RW */ | ||
1481 | unsigned long rsvd_56_62: 7; /* */ | ||
1482 | unsigned long enable : 1; /* RW */ | ||
1483 | } s2; | ||
1023 | }; | 1484 | }; |
1024 | 1485 | ||
1025 | /* ========================================================================= */ | 1486 | /* ========================================================================= */ |
@@ -1029,20 +1490,40 @@ union uvh_rh_gam_mmioh_overlay_config_mmr_u { | |||
1029 | 1490 | ||
1030 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 | 1491 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 |
1031 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL | 1492 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL |
1032 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46 | 1493 | |
1033 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL | 1494 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 |
1034 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | 1495 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL |
1035 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | 1496 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46 |
1497 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL | ||
1498 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1499 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1500 | |||
1501 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 | ||
1502 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL | ||
1503 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1504 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1036 | 1505 | ||
1037 | union uvh_rh_gam_mmr_overlay_config_mmr_u { | 1506 | union uvh_rh_gam_mmr_overlay_config_mmr_u { |
1038 | unsigned long v; | 1507 | unsigned long v; |
1039 | struct uvh_rh_gam_mmr_overlay_config_mmr_s { | 1508 | struct uvh_rh_gam_mmr_overlay_config_mmr_s { |
1040 | unsigned long rsvd_0_25: 26; /* */ | 1509 | unsigned long rsvd_0_25: 26; /* */ |
1041 | unsigned long base : 20; /* RW */ | 1510 | unsigned long base : 20; /* RW */ |
1511 | unsigned long rsvd_46_62 : 17; | ||
1512 | unsigned long enable : 1; /* RW */ | ||
1513 | } s; | ||
1514 | struct uv1h_rh_gam_mmr_overlay_config_mmr_s { | ||
1515 | unsigned long rsvd_0_25: 26; /* */ | ||
1516 | unsigned long base : 20; /* RW */ | ||
1042 | unsigned long dual_hub : 1; /* RW */ | 1517 | unsigned long dual_hub : 1; /* RW */ |
1043 | unsigned long rsvd_47_62: 16; /* */ | 1518 | unsigned long rsvd_47_62: 16; /* */ |
1044 | unsigned long enable : 1; /* RW */ | 1519 | unsigned long enable : 1; /* RW */ |
1045 | } s; | 1520 | } s1; |
1521 | struct uv2h_rh_gam_mmr_overlay_config_mmr_s { | ||
1522 | unsigned long rsvd_0_25: 26; /* */ | ||
1523 | unsigned long base : 20; /* RW */ | ||
1524 | unsigned long rsvd_46_62: 17; /* */ | ||
1525 | unsigned long enable : 1; /* RW */ | ||
1526 | } s2; | ||
1046 | }; | 1527 | }; |
1047 | 1528 | ||
1048 | /* ========================================================================= */ | 1529 | /* ========================================================================= */ |
@@ -1103,10 +1584,11 @@ union uvh_rtc1_int_config_u { | |||
1103 | /* UVH_SCRATCH5 */ | 1584 | /* UVH_SCRATCH5 */ |
1104 | /* ========================================================================= */ | 1585 | /* ========================================================================= */ |
1105 | #define UVH_SCRATCH5 0x2d0200UL | 1586 | #define UVH_SCRATCH5 0x2d0200UL |
1106 | #define UVH_SCRATCH5_32 0x00778 | 1587 | #define UVH_SCRATCH5_32 0x778 |
1107 | 1588 | ||
1108 | #define UVH_SCRATCH5_SCRATCH5_SHFT 0 | 1589 | #define UVH_SCRATCH5_SCRATCH5_SHFT 0 |
1109 | #define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL | 1590 | #define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL |
1591 | |||
1110 | union uvh_scratch5_u { | 1592 | union uvh_scratch5_u { |
1111 | unsigned long v; | 1593 | unsigned long v; |
1112 | struct uvh_scratch5_s { | 1594 | struct uvh_scratch5_s { |
@@ -1114,4 +1596,154 @@ union uvh_scratch5_u { | |||
1114 | } s; | 1596 | } s; |
1115 | }; | 1597 | }; |
1116 | 1598 | ||
1599 | /* ========================================================================= */ | ||
1600 | /* UV2H_EVENT_OCCURRED2 */ | ||
1601 | /* ========================================================================= */ | ||
1602 | #define UV2H_EVENT_OCCURRED2 0x70100UL | ||
1603 | #define UV2H_EVENT_OCCURRED2_32 0xb68 | ||
1604 | |||
1605 | #define UV2H_EVENT_OCCURRED2_RTC_0_SHFT 0 | ||
1606 | #define UV2H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL | ||
1607 | #define UV2H_EVENT_OCCURRED2_RTC_1_SHFT 1 | ||
1608 | #define UV2H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL | ||
1609 | #define UV2H_EVENT_OCCURRED2_RTC_2_SHFT 2 | ||
1610 | #define UV2H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL | ||
1611 | #define UV2H_EVENT_OCCURRED2_RTC_3_SHFT 3 | ||
1612 | #define UV2H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL | ||
1613 | #define UV2H_EVENT_OCCURRED2_RTC_4_SHFT 4 | ||
1614 | #define UV2H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL | ||
1615 | #define UV2H_EVENT_OCCURRED2_RTC_5_SHFT 5 | ||
1616 | #define UV2H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL | ||
1617 | #define UV2H_EVENT_OCCURRED2_RTC_6_SHFT 6 | ||
1618 | #define UV2H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL | ||
1619 | #define UV2H_EVENT_OCCURRED2_RTC_7_SHFT 7 | ||
1620 | #define UV2H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL | ||
1621 | #define UV2H_EVENT_OCCURRED2_RTC_8_SHFT 8 | ||
1622 | #define UV2H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL | ||
1623 | #define UV2H_EVENT_OCCURRED2_RTC_9_SHFT 9 | ||
1624 | #define UV2H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL | ||
1625 | #define UV2H_EVENT_OCCURRED2_RTC_10_SHFT 10 | ||
1626 | #define UV2H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL | ||
1627 | #define UV2H_EVENT_OCCURRED2_RTC_11_SHFT 11 | ||
1628 | #define UV2H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL | ||
1629 | #define UV2H_EVENT_OCCURRED2_RTC_12_SHFT 12 | ||
1630 | #define UV2H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL | ||
1631 | #define UV2H_EVENT_OCCURRED2_RTC_13_SHFT 13 | ||
1632 | #define UV2H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL | ||
1633 | #define UV2H_EVENT_OCCURRED2_RTC_14_SHFT 14 | ||
1634 | #define UV2H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL | ||
1635 | #define UV2H_EVENT_OCCURRED2_RTC_15_SHFT 15 | ||
1636 | #define UV2H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL | ||
1637 | #define UV2H_EVENT_OCCURRED2_RTC_16_SHFT 16 | ||
1638 | #define UV2H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL | ||
1639 | #define UV2H_EVENT_OCCURRED2_RTC_17_SHFT 17 | ||
1640 | #define UV2H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL | ||
1641 | #define UV2H_EVENT_OCCURRED2_RTC_18_SHFT 18 | ||
1642 | #define UV2H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL | ||
1643 | #define UV2H_EVENT_OCCURRED2_RTC_19_SHFT 19 | ||
1644 | #define UV2H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL | ||
1645 | #define UV2H_EVENT_OCCURRED2_RTC_20_SHFT 20 | ||
1646 | #define UV2H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL | ||
1647 | #define UV2H_EVENT_OCCURRED2_RTC_21_SHFT 21 | ||
1648 | #define UV2H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL | ||
1649 | #define UV2H_EVENT_OCCURRED2_RTC_22_SHFT 22 | ||
1650 | #define UV2H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL | ||
1651 | #define UV2H_EVENT_OCCURRED2_RTC_23_SHFT 23 | ||
1652 | #define UV2H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL | ||
1653 | #define UV2H_EVENT_OCCURRED2_RTC_24_SHFT 24 | ||
1654 | #define UV2H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL | ||
1655 | #define UV2H_EVENT_OCCURRED2_RTC_25_SHFT 25 | ||
1656 | #define UV2H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL | ||
1657 | #define UV2H_EVENT_OCCURRED2_RTC_26_SHFT 26 | ||
1658 | #define UV2H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL | ||
1659 | #define UV2H_EVENT_OCCURRED2_RTC_27_SHFT 27 | ||
1660 | #define UV2H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL | ||
1661 | #define UV2H_EVENT_OCCURRED2_RTC_28_SHFT 28 | ||
1662 | #define UV2H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL | ||
1663 | #define UV2H_EVENT_OCCURRED2_RTC_29_SHFT 29 | ||
1664 | #define UV2H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL | ||
1665 | #define UV2H_EVENT_OCCURRED2_RTC_30_SHFT 30 | ||
1666 | #define UV2H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL | ||
1667 | #define UV2H_EVENT_OCCURRED2_RTC_31_SHFT 31 | ||
1668 | #define UV2H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL | ||
1669 | |||
1670 | union uv2h_event_occurred2_u { | ||
1671 | unsigned long v; | ||
1672 | struct uv2h_event_occurred2_s { | ||
1673 | unsigned long rtc_0 : 1; /* RW */ | ||
1674 | unsigned long rtc_1 : 1; /* RW */ | ||
1675 | unsigned long rtc_2 : 1; /* RW */ | ||
1676 | unsigned long rtc_3 : 1; /* RW */ | ||
1677 | unsigned long rtc_4 : 1; /* RW */ | ||
1678 | unsigned long rtc_5 : 1; /* RW */ | ||
1679 | unsigned long rtc_6 : 1; /* RW */ | ||
1680 | unsigned long rtc_7 : 1; /* RW */ | ||
1681 | unsigned long rtc_8 : 1; /* RW */ | ||
1682 | unsigned long rtc_9 : 1; /* RW */ | ||
1683 | unsigned long rtc_10 : 1; /* RW */ | ||
1684 | unsigned long rtc_11 : 1; /* RW */ | ||
1685 | unsigned long rtc_12 : 1; /* RW */ | ||
1686 | unsigned long rtc_13 : 1; /* RW */ | ||
1687 | unsigned long rtc_14 : 1; /* RW */ | ||
1688 | unsigned long rtc_15 : 1; /* RW */ | ||
1689 | unsigned long rtc_16 : 1; /* RW */ | ||
1690 | unsigned long rtc_17 : 1; /* RW */ | ||
1691 | unsigned long rtc_18 : 1; /* RW */ | ||
1692 | unsigned long rtc_19 : 1; /* RW */ | ||
1693 | unsigned long rtc_20 : 1; /* RW */ | ||
1694 | unsigned long rtc_21 : 1; /* RW */ | ||
1695 | unsigned long rtc_22 : 1; /* RW */ | ||
1696 | unsigned long rtc_23 : 1; /* RW */ | ||
1697 | unsigned long rtc_24 : 1; /* RW */ | ||
1698 | unsigned long rtc_25 : 1; /* RW */ | ||
1699 | unsigned long rtc_26 : 1; /* RW */ | ||
1700 | unsigned long rtc_27 : 1; /* RW */ | ||
1701 | unsigned long rtc_28 : 1; /* RW */ | ||
1702 | unsigned long rtc_29 : 1; /* RW */ | ||
1703 | unsigned long rtc_30 : 1; /* RW */ | ||
1704 | unsigned long rtc_31 : 1; /* RW */ | ||
1705 | unsigned long rsvd_32_63: 32; /* */ | ||
1706 | } s1; | ||
1707 | }; | ||
1708 | |||
1709 | /* ========================================================================= */ | ||
1710 | /* UV2H_EVENT_OCCURRED2_ALIAS */ | ||
1711 | /* ========================================================================= */ | ||
1712 | #define UV2H_EVENT_OCCURRED2_ALIAS 0x70108UL | ||
1713 | #define UV2H_EVENT_OCCURRED2_ALIAS_32 0xb70 | ||
1714 | |||
1715 | /* ========================================================================= */ | ||
1716 | /* UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 */ | ||
1717 | /* ========================================================================= */ | ||
1718 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 0x320130UL | ||
1719 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_32 0x9f0 | ||
1720 | |||
1721 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0 | ||
1722 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL | ||
1723 | |||
1724 | union uv2h_lb_bau_sb_activation_status_2_u { | ||
1725 | unsigned long v; | ||
1726 | struct uv2h_lb_bau_sb_activation_status_2_s { | ||
1727 | unsigned long aux_error : 64; /* RW */ | ||
1728 | } s1; | ||
1729 | }; | ||
1730 | |||
1731 | /* ========================================================================= */ | ||
1732 | /* UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK */ | ||
1733 | /* ========================================================================= */ | ||
1734 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL | ||
1735 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x9f0 | ||
1736 | |||
1737 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0 | ||
1738 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL | ||
1739 | |||
1740 | union uv1h_lb_target_physical_apic_id_mask_u { | ||
1741 | unsigned long v; | ||
1742 | struct uv1h_lb_target_physical_apic_id_mask_s { | ||
1743 | unsigned long bit_enables : 32; /* RW */ | ||
1744 | unsigned long rsvd_32_63 : 32; /* */ | ||
1745 | } s1; | ||
1746 | }; | ||
1747 | |||
1748 | |||
1117 | #endif /* __ASM_UV_MMRS_X86_H__ */ | 1749 | #endif /* __ASM_UV_MMRS_X86_H__ */ |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index f450b683dfcf..b511a011b7d0 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -91,6 +91,10 @@ static int __init early_get_pnodeid(void) | |||
91 | m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR); | 91 | m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR); |
92 | uv_min_hub_revision_id = node_id.s.revision; | 92 | uv_min_hub_revision_id = node_id.s.revision; |
93 | 93 | ||
94 | if (node_id.s.part_number == UV2_HUB_PART_NUMBER) | ||
95 | uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1; | ||
96 | |||
97 | uv_hub_info->hub_revision = uv_min_hub_revision_id; | ||
94 | pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1); | 98 | pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1); |
95 | return pnode; | 99 | return pnode; |
96 | } | 100 | } |
@@ -112,17 +116,25 @@ static void __init early_get_apic_pnode_shift(void) | |||
112 | */ | 116 | */ |
113 | static void __init uv_set_apicid_hibit(void) | 117 | static void __init uv_set_apicid_hibit(void) |
114 | { | 118 | { |
115 | union uvh_lb_target_physical_apic_id_mask_u apicid_mask; | 119 | union uv1h_lb_target_physical_apic_id_mask_u apicid_mask; |
116 | 120 | ||
117 | apicid_mask.v = uv_early_read_mmr(UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK); | 121 | if (is_uv1_hub()) { |
118 | uv_apicid_hibits = apicid_mask.s.bit_enables & UV_APICID_HIBIT_MASK; | 122 | apicid_mask.v = |
123 | uv_early_read_mmr(UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK); | ||
124 | uv_apicid_hibits = | ||
125 | apicid_mask.s1.bit_enables & UV_APICID_HIBIT_MASK; | ||
126 | } | ||
119 | } | 127 | } |
120 | 128 | ||
121 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 129 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
122 | { | 130 | { |
123 | int pnodeid; | 131 | int pnodeid, is_uv1, is_uv2; |
124 | 132 | ||
125 | if (!strcmp(oem_id, "SGI")) { | 133 | is_uv1 = !strcmp(oem_id, "SGI"); |
134 | is_uv2 = !strcmp(oem_id, "SGI2"); | ||
135 | if (is_uv1 || is_uv2) { | ||
136 | uv_hub_info->hub_revision = | ||
137 | is_uv1 ? UV1_HUB_REVISION_BASE : UV2_HUB_REVISION_BASE; | ||
126 | pnodeid = early_get_pnodeid(); | 138 | pnodeid = early_get_pnodeid(); |
127 | early_get_apic_pnode_shift(); | 139 | early_get_apic_pnode_shift(); |
128 | x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; | 140 | x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; |
@@ -484,12 +496,19 @@ static __init void map_mmr_high(int max_pnode) | |||
484 | static __init void map_mmioh_high(int max_pnode) | 496 | static __init void map_mmioh_high(int max_pnode) |
485 | { | 497 | { |
486 | union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; | 498 | union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; |
487 | int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; | 499 | int shift; |
488 | 500 | ||
489 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); | 501 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); |
490 | if (mmioh.s.enable) | 502 | if (is_uv1_hub() && mmioh.s1.enable) { |
491 | map_high("MMIOH", mmioh.s.base, shift, mmioh.s.m_io, | 503 | shift = UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; |
504 | map_high("MMIOH", mmioh.s1.base, shift, mmioh.s1.m_io, | ||
505 | max_pnode, map_uc); | ||
506 | } | ||
507 | if (is_uv2_hub() && mmioh.s2.enable) { | ||
508 | shift = UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; | ||
509 | map_high("MMIOH", mmioh.s2.base, shift, mmioh.s2.m_io, | ||
492 | max_pnode, map_uc); | 510 | max_pnode, map_uc); |
511 | } | ||
493 | } | 512 | } |
494 | 513 | ||
495 | static __init void map_low_mmrs(void) | 514 | static __init void map_low_mmrs(void) |
@@ -736,13 +755,14 @@ void __init uv_system_init(void) | |||
736 | unsigned long mmr_base, present, paddr; | 755 | unsigned long mmr_base, present, paddr; |
737 | unsigned short pnode_mask, pnode_io_mask; | 756 | unsigned short pnode_mask, pnode_io_mask; |
738 | 757 | ||
758 | printk(KERN_INFO "UV: Found %s hub\n", is_uv1_hub() ? "UV1" : "UV2"); | ||
739 | map_low_mmrs(); | 759 | map_low_mmrs(); |
740 | 760 | ||
741 | m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); | 761 | m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); |
742 | m_val = m_n_config.s.m_skt; | 762 | m_val = m_n_config.s.m_skt; |
743 | n_val = m_n_config.s.n_skt; | 763 | n_val = m_n_config.s.n_skt; |
744 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); | 764 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); |
745 | n_io = mmioh.s.n_io; | 765 | n_io = is_uv1_hub() ? mmioh.s1.n_io : mmioh.s2.n_io; |
746 | mmr_base = | 766 | mmr_base = |
747 | uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & | 767 | uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & |
748 | ~UV_MMR_ENABLE; | 768 | ~UV_MMR_ENABLE; |
@@ -811,6 +831,8 @@ void __init uv_system_init(void) | |||
811 | */ | 831 | */ |
812 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; | 832 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; |
813 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; | 833 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; |
834 | uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision; | ||
835 | |||
814 | pnode = uv_apicid_to_pnode(apicid); | 836 | pnode = uv_apicid_to_pnode(apicid); |
815 | blade = boot_pnode_to_blade(pnode); | 837 | blade = boot_pnode_to_blade(pnode); |
816 | lcpu = uv_blade_info[blade].nr_possible_cpus; | 838 | lcpu = uv_blade_info[blade].nr_possible_cpus; |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 3bfa02235965..965a7666c283 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -361,6 +361,7 @@ struct apm_user { | |||
361 | * idle percentage above which bios idle calls are done | 361 | * idle percentage above which bios idle calls are done |
362 | */ | 362 | */ |
363 | #ifdef CONFIG_APM_CPU_IDLE | 363 | #ifdef CONFIG_APM_CPU_IDLE |
364 | #warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012 | ||
364 | #define DEFAULT_IDLE_THRESHOLD 95 | 365 | #define DEFAULT_IDLE_THRESHOLD 95 |
365 | #else | 366 | #else |
366 | #define DEFAULT_IDLE_THRESHOLD 100 | 367 | #define DEFAULT_IDLE_THRESHOLD 100 |
@@ -904,6 +905,7 @@ static void apm_cpu_idle(void) | |||
904 | unsigned int jiffies_since_last_check = jiffies - last_jiffies; | 905 | unsigned int jiffies_since_last_check = jiffies - last_jiffies; |
905 | unsigned int bucket; | 906 | unsigned int bucket; |
906 | 907 | ||
908 | WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012"); | ||
907 | recalc: | 909 | recalc: |
908 | if (jiffies_since_last_check > IDLE_CALC_LIMIT) { | 910 | if (jiffies_since_last_check > IDLE_CALC_LIMIT) { |
909 | use_apm_idle = 0; | 911 | use_apm_idle = 0; |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 8f5cabb3c5b0..b13ed393dfce 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -612,8 +612,11 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
612 | } | 612 | } |
613 | #endif | 613 | #endif |
614 | 614 | ||
615 | /* As a rule processors have APIC timer running in deep C states */ | 615 | /* |
616 | if (c->x86 > 0xf && !cpu_has_amd_erratum(amd_erratum_400)) | 616 | * Family 0x12 and above processors have APIC timer |
617 | * running in deep C states. | ||
618 | */ | ||
619 | if (c->x86 > 0x11) | ||
617 | set_cpu_cap(c, X86_FEATURE_ARAT); | 620 | set_cpu_cap(c, X86_FEATURE_ARAT); |
618 | 621 | ||
619 | /* | 622 | /* |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c39576cb3018..525514cf33c3 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | static int __init no_halt(char *s) | 20 | static int __init no_halt(char *s) |
21 | { | 21 | { |
22 | WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n"); | ||
22 | boot_cpu_data.hlt_works_ok = 0; | 23 | boot_cpu_data.hlt_works_ok = 0; |
23 | return 1; | 24 | return 1; |
24 | } | 25 | } |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c8b41623377f..22a073d7fbff 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -477,13 +477,6 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) | |||
477 | if (smp_num_siblings <= 1) | 477 | if (smp_num_siblings <= 1) |
478 | goto out; | 478 | goto out; |
479 | 479 | ||
480 | if (smp_num_siblings > nr_cpu_ids) { | ||
481 | pr_warning("CPU: Unsupported number of siblings %d", | ||
482 | smp_num_siblings); | ||
483 | smp_num_siblings = 1; | ||
484 | return; | ||
485 | } | ||
486 | |||
487 | index_msb = get_count_order(smp_num_siblings); | 480 | index_msb = get_count_order(smp_num_siblings); |
488 | c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb); | 481 | c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb); |
489 | 482 | ||
@@ -909,7 +902,7 @@ static void vgetcpu_set_mode(void) | |||
909 | void __init identify_boot_cpu(void) | 902 | void __init identify_boot_cpu(void) |
910 | { | 903 | { |
911 | identify_cpu(&boot_cpu_data); | 904 | identify_cpu(&boot_cpu_data); |
912 | init_c1e_mask(); | 905 | init_amd_e400_c1e_mask(); |
913 | #ifdef CONFIG_X86_32 | 906 | #ifdef CONFIG_X86_32 |
914 | sysenter_setup(); | 907 | sysenter_setup(); |
915 | enable_sep_cpu(); | 908 | enable_sep_cpu(); |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 0ba15a6cc57e..c9a281f272fd 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -123,7 +123,7 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | |||
123 | static atomic_t nmi_running = ATOMIC_INIT(0); | 123 | static atomic_t nmi_running = ATOMIC_INIT(0); |
124 | static int mod_code_status; /* holds return value of text write */ | 124 | static int mod_code_status; /* holds return value of text write */ |
125 | static void *mod_code_ip; /* holds the IP to write to */ | 125 | static void *mod_code_ip; /* holds the IP to write to */ |
126 | static void *mod_code_newcode; /* holds the text to write to the IP */ | 126 | static const void *mod_code_newcode; /* holds the text to write to the IP */ |
127 | 127 | ||
128 | static unsigned nmi_wait_count; | 128 | static unsigned nmi_wait_count; |
129 | static atomic_t nmi_update_count = ATOMIC_INIT(0); | 129 | static atomic_t nmi_update_count = ATOMIC_INIT(0); |
@@ -225,7 +225,7 @@ within(unsigned long addr, unsigned long start, unsigned long end) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | static int | 227 | static int |
228 | do_ftrace_mod_code(unsigned long ip, void *new_code) | 228 | do_ftrace_mod_code(unsigned long ip, const void *new_code) |
229 | { | 229 | { |
230 | /* | 230 | /* |
231 | * On x86_64, kernel text mappings are mapped read-only with | 231 | * On x86_64, kernel text mappings are mapped read-only with |
@@ -266,8 +266,8 @@ static const unsigned char *ftrace_nop_replace(void) | |||
266 | } | 266 | } |
267 | 267 | ||
268 | static int | 268 | static int |
269 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 269 | ftrace_modify_code(unsigned long ip, unsigned const char *old_code, |
270 | unsigned char *new_code) | 270 | unsigned const char *new_code) |
271 | { | 271 | { |
272 | unsigned char replaced[MCOUNT_INSN_SIZE]; | 272 | unsigned char replaced[MCOUNT_INSN_SIZE]; |
273 | 273 | ||
@@ -301,7 +301,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
301 | int ftrace_make_nop(struct module *mod, | 301 | int ftrace_make_nop(struct module *mod, |
302 | struct dyn_ftrace *rec, unsigned long addr) | 302 | struct dyn_ftrace *rec, unsigned long addr) |
303 | { | 303 | { |
304 | unsigned char *new, *old; | 304 | unsigned const char *new, *old; |
305 | unsigned long ip = rec->ip; | 305 | unsigned long ip = rec->ip; |
306 | 306 | ||
307 | old = ftrace_call_replace(ip, addr); | 307 | old = ftrace_call_replace(ip, addr); |
@@ -312,7 +312,7 @@ int ftrace_make_nop(struct module *mod, | |||
312 | 312 | ||
313 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 313 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
314 | { | 314 | { |
315 | unsigned char *new, *old; | 315 | unsigned const char *new, *old; |
316 | unsigned long ip = rec->ip; | 316 | unsigned long ip = rec->ip; |
317 | 317 | ||
318 | old = ftrace_nop_replace(); | 318 | old = ftrace_nop_replace(); |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 88a90a977f8e..2e4928d45a2d 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -337,7 +337,9 @@ EXPORT_SYMBOL(boot_option_idle_override); | |||
337 | * Powermanagement idle function, if any.. | 337 | * Powermanagement idle function, if any.. |
338 | */ | 338 | */ |
339 | void (*pm_idle)(void); | 339 | void (*pm_idle)(void); |
340 | #if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE) | ||
340 | EXPORT_SYMBOL(pm_idle); | 341 | EXPORT_SYMBOL(pm_idle); |
342 | #endif | ||
341 | 343 | ||
342 | #ifdef CONFIG_X86_32 | 344 | #ifdef CONFIG_X86_32 |
343 | /* | 345 | /* |
@@ -397,7 +399,7 @@ void default_idle(void) | |||
397 | cpu_relax(); | 399 | cpu_relax(); |
398 | } | 400 | } |
399 | } | 401 | } |
400 | #ifdef CONFIG_APM_MODULE | 402 | #if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE) |
401 | EXPORT_SYMBOL(default_idle); | 403 | EXPORT_SYMBOL(default_idle); |
402 | #endif | 404 | #endif |
403 | 405 | ||
@@ -535,45 +537,45 @@ int mwait_usable(const struct cpuinfo_x86 *c) | |||
535 | return (edx & MWAIT_EDX_C1); | 537 | return (edx & MWAIT_EDX_C1); |
536 | } | 538 | } |
537 | 539 | ||
538 | bool c1e_detected; | 540 | bool amd_e400_c1e_detected; |
539 | EXPORT_SYMBOL(c1e_detected); | 541 | EXPORT_SYMBOL(amd_e400_c1e_detected); |
540 | 542 | ||
541 | static cpumask_var_t c1e_mask; | 543 | static cpumask_var_t amd_e400_c1e_mask; |
542 | 544 | ||
543 | void c1e_remove_cpu(int cpu) | 545 | void amd_e400_remove_cpu(int cpu) |
544 | { | 546 | { |
545 | if (c1e_mask != NULL) | 547 | if (amd_e400_c1e_mask != NULL) |
546 | cpumask_clear_cpu(cpu, c1e_mask); | 548 | cpumask_clear_cpu(cpu, amd_e400_c1e_mask); |
547 | } | 549 | } |
548 | 550 | ||
549 | /* | 551 | /* |
550 | * C1E aware idle routine. We check for C1E active in the interrupt | 552 | * AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt |
551 | * pending message MSR. If we detect C1E, then we handle it the same | 553 | * pending message MSR. If we detect C1E, then we handle it the same |
552 | * way as C3 power states (local apic timer and TSC stop) | 554 | * way as C3 power states (local apic timer and TSC stop) |
553 | */ | 555 | */ |
554 | static void c1e_idle(void) | 556 | static void amd_e400_idle(void) |
555 | { | 557 | { |
556 | if (need_resched()) | 558 | if (need_resched()) |
557 | return; | 559 | return; |
558 | 560 | ||
559 | if (!c1e_detected) { | 561 | if (!amd_e400_c1e_detected) { |
560 | u32 lo, hi; | 562 | u32 lo, hi; |
561 | 563 | ||
562 | rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); | 564 | rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); |
563 | 565 | ||
564 | if (lo & K8_INTP_C1E_ACTIVE_MASK) { | 566 | if (lo & K8_INTP_C1E_ACTIVE_MASK) { |
565 | c1e_detected = true; | 567 | amd_e400_c1e_detected = true; |
566 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 568 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
567 | mark_tsc_unstable("TSC halt in AMD C1E"); | 569 | mark_tsc_unstable("TSC halt in AMD C1E"); |
568 | printk(KERN_INFO "System has AMD C1E enabled\n"); | 570 | printk(KERN_INFO "System has AMD C1E enabled\n"); |
569 | } | 571 | } |
570 | } | 572 | } |
571 | 573 | ||
572 | if (c1e_detected) { | 574 | if (amd_e400_c1e_detected) { |
573 | int cpu = smp_processor_id(); | 575 | int cpu = smp_processor_id(); |
574 | 576 | ||
575 | if (!cpumask_test_cpu(cpu, c1e_mask)) { | 577 | if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) { |
576 | cpumask_set_cpu(cpu, c1e_mask); | 578 | cpumask_set_cpu(cpu, amd_e400_c1e_mask); |
577 | /* | 579 | /* |
578 | * Force broadcast so ACPI can not interfere. | 580 | * Force broadcast so ACPI can not interfere. |
579 | */ | 581 | */ |
@@ -616,17 +618,17 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | |||
616 | pm_idle = mwait_idle; | 618 | pm_idle = mwait_idle; |
617 | } else if (cpu_has_amd_erratum(amd_erratum_400)) { | 619 | } else if (cpu_has_amd_erratum(amd_erratum_400)) { |
618 | /* E400: APIC timer interrupt does not wake up CPU from C1e */ | 620 | /* E400: APIC timer interrupt does not wake up CPU from C1e */ |
619 | printk(KERN_INFO "using C1E aware idle routine\n"); | 621 | printk(KERN_INFO "using AMD E400 aware idle routine\n"); |
620 | pm_idle = c1e_idle; | 622 | pm_idle = amd_e400_idle; |
621 | } else | 623 | } else |
622 | pm_idle = default_idle; | 624 | pm_idle = default_idle; |
623 | } | 625 | } |
624 | 626 | ||
625 | void __init init_c1e_mask(void) | 627 | void __init init_amd_e400_c1e_mask(void) |
626 | { | 628 | { |
627 | /* If we're using c1e_idle, we need to allocate c1e_mask. */ | 629 | /* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */ |
628 | if (pm_idle == c1e_idle) | 630 | if (pm_idle == amd_e400_idle) |
629 | zalloc_cpumask_var(&c1e_mask, GFP_KERNEL); | 631 | zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL); |
630 | } | 632 | } |
631 | 633 | ||
632 | static int __init idle_setup(char *str) | 634 | static int __init idle_setup(char *str) |
@@ -640,6 +642,7 @@ static int __init idle_setup(char *str) | |||
640 | boot_option_idle_override = IDLE_POLL; | 642 | boot_option_idle_override = IDLE_POLL; |
641 | } else if (!strcmp(str, "mwait")) { | 643 | } else if (!strcmp(str, "mwait")) { |
642 | boot_option_idle_override = IDLE_FORCE_MWAIT; | 644 | boot_option_idle_override = IDLE_FORCE_MWAIT; |
645 | WARN_ONCE(1, "\"idle=mwait\" will be removed in 2012\n"); | ||
643 | } else if (!strcmp(str, "halt")) { | 646 | } else if (!strcmp(str, "halt")) { |
644 | /* | 647 | /* |
645 | * When the boot option of idle=halt is added, halt is | 648 | * When the boot option of idle=halt is added, halt is |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a3e5948670c2..afaf38447ef5 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -910,6 +910,13 @@ void __init setup_arch(char **cmdline_p) | |||
910 | memblock.current_limit = get_max_mapped(); | 910 | memblock.current_limit = get_max_mapped(); |
911 | memblock_x86_fill(); | 911 | memblock_x86_fill(); |
912 | 912 | ||
913 | /* | ||
914 | * The EFI specification says that boot service code won't be called | ||
915 | * after ExitBootServices(). This is, in fact, a lie. | ||
916 | */ | ||
917 | if (efi_enabled) | ||
918 | efi_reserve_boot_services(); | ||
919 | |||
913 | /* preallocate 4k for mptable mpc */ | 920 | /* preallocate 4k for mptable mpc */ |
914 | early_reserve_e820_mpc_new(); | 921 | early_reserve_e820_mpc_new(); |
915 | 922 | ||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a3c430bdfb60..33a0c11797de 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1307,7 +1307,7 @@ void play_dead_common(void) | |||
1307 | { | 1307 | { |
1308 | idle_task_exit(); | 1308 | idle_task_exit(); |
1309 | reset_lazy_tlbstate(); | 1309 | reset_lazy_tlbstate(); |
1310 | c1e_remove_cpu(raw_smp_processor_id()); | 1310 | amd_e400_remove_cpu(raw_smp_processor_id()); |
1311 | 1311 | ||
1312 | mb(); | 1312 | mb(); |
1313 | /* Ack it */ | 1313 | /* Ack it */ |
@@ -1332,7 +1332,7 @@ static inline void mwait_play_dead(void) | |||
1332 | void *mwait_ptr; | 1332 | void *mwait_ptr; |
1333 | struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); | 1333 | struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); |
1334 | 1334 | ||
1335 | if (!this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c)) | 1335 | if (!(this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c))) |
1336 | return; | 1336 | return; |
1337 | if (!this_cpu_has(X86_FEATURE_CLFLSH)) | 1337 | if (!this_cpu_has(X86_FEATURE_CLFLSH)) |
1338 | return; | 1338 | return; |
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index 32cbffb0c494..fbb0a045a1a2 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S | |||
@@ -345,3 +345,4 @@ ENTRY(sys_call_table) | |||
345 | .long sys_clock_adjtime | 345 | .long sys_clock_adjtime |
346 | .long sys_syncfs | 346 | .long sys_syncfs |
347 | .long sys_sendmmsg /* 345 */ | 347 | .long sys_sendmmsg /* 345 */ |
348 | .long sys_setns | ||
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index e191c096ab90..db832fd65ecb 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -993,6 +993,7 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc) | |||
993 | static void lguest_time_init(void) | 993 | static void lguest_time_init(void) |
994 | { | 994 | { |
995 | /* Set up the timer interrupt (0) to go to our simple timer routine */ | 995 | /* Set up the timer interrupt (0) to go to our simple timer routine */ |
996 | lguest_setup_irq(0); | ||
996 | irq_set_handler(0, lguest_time_irq); | 997 | irq_set_handler(0, lguest_time_irq); |
997 | 998 | ||
998 | clocksource_register_hz(&lguest_clock, NSEC_PER_SEC); | 999 | clocksource_register_hz(&lguest_clock, NSEC_PER_SEC); |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f7a2a054a3c0..2dbf6bf4c7e5 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -823,16 +823,30 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | |||
823 | force_sig_info_fault(SIGBUS, code, address, tsk, fault); | 823 | force_sig_info_fault(SIGBUS, code, address, tsk, fault); |
824 | } | 824 | } |
825 | 825 | ||
826 | static noinline void | 826 | static noinline int |
827 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, | 827 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, |
828 | unsigned long address, unsigned int fault) | 828 | unsigned long address, unsigned int fault) |
829 | { | 829 | { |
830 | /* | ||
831 | * Pagefault was interrupted by SIGKILL. We have no reason to | ||
832 | * continue pagefault. | ||
833 | */ | ||
834 | if (fatal_signal_pending(current)) { | ||
835 | if (!(fault & VM_FAULT_RETRY)) | ||
836 | up_read(¤t->mm->mmap_sem); | ||
837 | if (!(error_code & PF_USER)) | ||
838 | no_context(regs, error_code, address); | ||
839 | return 1; | ||
840 | } | ||
841 | if (!(fault & VM_FAULT_ERROR)) | ||
842 | return 0; | ||
843 | |||
830 | if (fault & VM_FAULT_OOM) { | 844 | if (fault & VM_FAULT_OOM) { |
831 | /* Kernel mode? Handle exceptions or die: */ | 845 | /* Kernel mode? Handle exceptions or die: */ |
832 | if (!(error_code & PF_USER)) { | 846 | if (!(error_code & PF_USER)) { |
833 | up_read(¤t->mm->mmap_sem); | 847 | up_read(¤t->mm->mmap_sem); |
834 | no_context(regs, error_code, address); | 848 | no_context(regs, error_code, address); |
835 | return; | 849 | return 1; |
836 | } | 850 | } |
837 | 851 | ||
838 | out_of_memory(regs, error_code, address); | 852 | out_of_memory(regs, error_code, address); |
@@ -843,6 +857,7 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, | |||
843 | else | 857 | else |
844 | BUG(); | 858 | BUG(); |
845 | } | 859 | } |
860 | return 1; | ||
846 | } | 861 | } |
847 | 862 | ||
848 | static int spurious_fault_check(unsigned long error_code, pte_t *pte) | 863 | static int spurious_fault_check(unsigned long error_code, pte_t *pte) |
@@ -1133,19 +1148,9 @@ good_area: | |||
1133 | */ | 1148 | */ |
1134 | fault = handle_mm_fault(mm, vma, address, flags); | 1149 | fault = handle_mm_fault(mm, vma, address, flags); |
1135 | 1150 | ||
1136 | if (unlikely(fault & VM_FAULT_ERROR)) { | 1151 | if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { |
1137 | mm_fault_error(regs, error_code, address, fault); | 1152 | if (mm_fault_error(regs, error_code, address, fault)) |
1138 | return; | 1153 | return; |
1139 | } | ||
1140 | |||
1141 | /* | ||
1142 | * Pagefault was interrupted by SIGKILL. We have no reason to | ||
1143 | * continue pagefault. | ||
1144 | */ | ||
1145 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { | ||
1146 | if (!(error_code & PF_USER)) | ||
1147 | no_context(regs, error_code, address); | ||
1148 | return; | ||
1149 | } | 1154 | } |
1150 | 1155 | ||
1151 | /* | 1156 | /* |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index c3b8e24f2b16..9fd8a567fe1e 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -316,16 +316,23 @@ static void op_amd_stop_ibs(void) | |||
316 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); | 316 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); |
317 | } | 317 | } |
318 | 318 | ||
319 | static inline int eilvt_is_available(int offset) | 319 | static inline int get_eilvt(int offset) |
320 | { | 320 | { |
321 | /* check if we may assign a vector */ | ||
322 | return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); | 321 | return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); |
323 | } | 322 | } |
324 | 323 | ||
324 | static inline int put_eilvt(int offset) | ||
325 | { | ||
326 | return !setup_APIC_eilvt(offset, 0, 0, 1); | ||
327 | } | ||
328 | |||
325 | static inline int ibs_eilvt_valid(void) | 329 | static inline int ibs_eilvt_valid(void) |
326 | { | 330 | { |
327 | int offset; | 331 | int offset; |
328 | u64 val; | 332 | u64 val; |
333 | int valid = 0; | ||
334 | |||
335 | preempt_disable(); | ||
329 | 336 | ||
330 | rdmsrl(MSR_AMD64_IBSCTL, val); | 337 | rdmsrl(MSR_AMD64_IBSCTL, val); |
331 | offset = val & IBSCTL_LVT_OFFSET_MASK; | 338 | offset = val & IBSCTL_LVT_OFFSET_MASK; |
@@ -333,16 +340,20 @@ static inline int ibs_eilvt_valid(void) | |||
333 | if (!(val & IBSCTL_LVT_OFFSET_VALID)) { | 340 | if (!(val & IBSCTL_LVT_OFFSET_VALID)) { |
334 | pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", | 341 | pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", |
335 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); | 342 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); |
336 | return 0; | 343 | goto out; |
337 | } | 344 | } |
338 | 345 | ||
339 | if (!eilvt_is_available(offset)) { | 346 | if (!get_eilvt(offset)) { |
340 | pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", | 347 | pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", |
341 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); | 348 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); |
342 | return 0; | 349 | goto out; |
343 | } | 350 | } |
344 | 351 | ||
345 | return 1; | 352 | valid = 1; |
353 | out: | ||
354 | preempt_enable(); | ||
355 | |||
356 | return valid; | ||
346 | } | 357 | } |
347 | 358 | ||
348 | static inline int get_ibs_offset(void) | 359 | static inline int get_ibs_offset(void) |
@@ -600,67 +611,69 @@ static int setup_ibs_ctl(int ibs_eilvt_off) | |||
600 | 611 | ||
601 | static int force_ibs_eilvt_setup(void) | 612 | static int force_ibs_eilvt_setup(void) |
602 | { | 613 | { |
603 | int i; | 614 | int offset; |
604 | int ret; | 615 | int ret; |
605 | 616 | ||
606 | /* find the next free available EILVT entry */ | 617 | /* |
607 | for (i = 1; i < 4; i++) { | 618 | * find the next free available EILVT entry, skip offset 0, |
608 | if (!eilvt_is_available(i)) | 619 | * pin search to this cpu |
609 | continue; | 620 | */ |
610 | ret = setup_ibs_ctl(i); | 621 | preempt_disable(); |
611 | if (ret) | 622 | for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) { |
612 | return ret; | 623 | if (get_eilvt(offset)) |
613 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); | 624 | break; |
614 | return 0; | ||
615 | } | 625 | } |
626 | preempt_enable(); | ||
616 | 627 | ||
617 | printk(KERN_DEBUG "No EILVT entry available\n"); | 628 | if (offset == APIC_EILVT_NR_MAX) { |
618 | 629 | printk(KERN_DEBUG "No EILVT entry available\n"); | |
619 | return -EBUSY; | 630 | return -EBUSY; |
620 | } | 631 | } |
621 | |||
622 | static int __init_ibs_nmi(void) | ||
623 | { | ||
624 | int ret; | ||
625 | |||
626 | if (ibs_eilvt_valid()) | ||
627 | return 0; | ||
628 | 632 | ||
629 | ret = force_ibs_eilvt_setup(); | 633 | ret = setup_ibs_ctl(offset); |
630 | if (ret) | 634 | if (ret) |
631 | return ret; | 635 | goto out; |
632 | 636 | ||
633 | if (!ibs_eilvt_valid()) | 637 | if (!ibs_eilvt_valid()) { |
634 | return -EFAULT; | 638 | ret = -EFAULT; |
639 | goto out; | ||
640 | } | ||
635 | 641 | ||
642 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); | ||
636 | pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); | 643 | pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); |
637 | 644 | ||
638 | return 0; | 645 | return 0; |
646 | out: | ||
647 | preempt_disable(); | ||
648 | put_eilvt(offset); | ||
649 | preempt_enable(); | ||
650 | return ret; | ||
639 | } | 651 | } |
640 | 652 | ||
641 | /* | 653 | /* |
642 | * check and reserve APIC extended interrupt LVT offset for IBS if | 654 | * check and reserve APIC extended interrupt LVT offset for IBS if |
643 | * available | 655 | * available |
644 | * | ||
645 | * init_ibs() preforms implicitly cpu-local operations, so pin this | ||
646 | * thread to its current CPU | ||
647 | */ | 656 | */ |
648 | 657 | ||
649 | static void init_ibs(void) | 658 | static void init_ibs(void) |
650 | { | 659 | { |
651 | preempt_disable(); | ||
652 | |||
653 | ibs_caps = get_ibs_caps(); | 660 | ibs_caps = get_ibs_caps(); |
661 | |||
654 | if (!ibs_caps) | 662 | if (!ibs_caps) |
663 | return; | ||
664 | |||
665 | if (ibs_eilvt_valid()) | ||
655 | goto out; | 666 | goto out; |
656 | 667 | ||
657 | if (__init_ibs_nmi() < 0) | 668 | if (!force_ibs_eilvt_setup()) |
658 | ibs_caps = 0; | 669 | goto out; |
659 | else | 670 | |
660 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); | 671 | /* Failed to setup ibs */ |
672 | ibs_caps = 0; | ||
673 | return; | ||
661 | 674 | ||
662 | out: | 675 | out: |
663 | preempt_enable(); | 676 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); |
664 | } | 677 | } |
665 | 678 | ||
666 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); | 679 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index b30aa26a8df2..0d3a4fa34560 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -304,6 +304,40 @@ static void __init print_efi_memmap(void) | |||
304 | } | 304 | } |
305 | #endif /* EFI_DEBUG */ | 305 | #endif /* EFI_DEBUG */ |
306 | 306 | ||
307 | void __init efi_reserve_boot_services(void) | ||
308 | { | ||
309 | void *p; | ||
310 | |||
311 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
312 | efi_memory_desc_t *md = p; | ||
313 | unsigned long long start = md->phys_addr; | ||
314 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
315 | |||
316 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
317 | md->type != EFI_BOOT_SERVICES_DATA) | ||
318 | continue; | ||
319 | |||
320 | memblock_x86_reserve_range(start, start + size, "EFI Boot"); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | static void __init efi_free_boot_services(void) | ||
325 | { | ||
326 | void *p; | ||
327 | |||
328 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
329 | efi_memory_desc_t *md = p; | ||
330 | unsigned long long start = md->phys_addr; | ||
331 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
332 | |||
333 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
334 | md->type != EFI_BOOT_SERVICES_DATA) | ||
335 | continue; | ||
336 | |||
337 | free_bootmem_late(start, size); | ||
338 | } | ||
339 | } | ||
340 | |||
307 | void __init efi_init(void) | 341 | void __init efi_init(void) |
308 | { | 342 | { |
309 | efi_config_table_t *config_tables; | 343 | efi_config_table_t *config_tables; |
@@ -536,7 +570,9 @@ void __init efi_enter_virtual_mode(void) | |||
536 | 570 | ||
537 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 571 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
538 | md = p; | 572 | md = p; |
539 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | 573 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && |
574 | md->type != EFI_BOOT_SERVICES_CODE && | ||
575 | md->type != EFI_BOOT_SERVICES_DATA) | ||
540 | continue; | 576 | continue; |
541 | 577 | ||
542 | size = md->num_pages << EFI_PAGE_SHIFT; | 578 | size = md->num_pages << EFI_PAGE_SHIFT; |
@@ -593,6 +629,13 @@ void __init efi_enter_virtual_mode(void) | |||
593 | } | 629 | } |
594 | 630 | ||
595 | /* | 631 | /* |
632 | * Thankfully, it does seem that no runtime services other than | ||
633 | * SetVirtualAddressMap() will touch boot services code, so we can | ||
634 | * get rid of it all at this point | ||
635 | */ | ||
636 | efi_free_boot_services(); | ||
637 | |||
638 | /* | ||
596 | * Now that EFI is in virtual mode, update the function | 639 | * Now that EFI is in virtual mode, update the function |
597 | * pointers in the runtime service table to the new virtual addresses. | 640 | * pointers in the runtime service table to the new virtual addresses. |
598 | * | 641 | * |
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 2649426a7905..ac3aa54e2654 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -49,10 +49,11 @@ static void __init early_code_mapping_set_exec(int executable) | |||
49 | if (!(__supported_pte_mask & _PAGE_NX)) | 49 | if (!(__supported_pte_mask & _PAGE_NX)) |
50 | return; | 50 | return; |
51 | 51 | ||
52 | /* Make EFI runtime service code area executable */ | 52 | /* Make EFI service code area executable */ |
53 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 53 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
54 | md = p; | 54 | md = p; |
55 | if (md->type == EFI_RUNTIME_SERVICES_CODE) | 55 | if (md->type == EFI_RUNTIME_SERVICES_CODE || |
56 | md->type == EFI_BOOT_SERVICES_CODE) | ||
56 | efi_set_executable(md, executable); | 57 | efi_set_executable(md, executable); |
57 | } | 58 | } |
58 | } | 59 | } |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index c58e0ea39ef5..68e467f69fec 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SGI UltraViolet TLB flush routines. | 2 | * SGI UltraViolet TLB flush routines. |
3 | * | 3 | * |
4 | * (c) 2008-2010 Cliff Wickman <cpw@sgi.com>, SGI. | 4 | * (c) 2008-2011 Cliff Wickman <cpw@sgi.com>, SGI. |
5 | * | 5 | * |
6 | * This code is released under the GNU General Public License version 2 or | 6 | * This code is released under the GNU General Public License version 2 or |
7 | * later. | 7 | * later. |
@@ -35,6 +35,7 @@ static int timeout_base_ns[] = { | |||
35 | 5242880, | 35 | 5242880, |
36 | 167772160 | 36 | 167772160 |
37 | }; | 37 | }; |
38 | |||
38 | static int timeout_us; | 39 | static int timeout_us; |
39 | static int nobau; | 40 | static int nobau; |
40 | static int baudisabled; | 41 | static int baudisabled; |
@@ -42,20 +43,70 @@ static spinlock_t disable_lock; | |||
42 | static cycles_t congested_cycles; | 43 | static cycles_t congested_cycles; |
43 | 44 | ||
44 | /* tunables: */ | 45 | /* tunables: */ |
45 | static int max_bau_concurrent = MAX_BAU_CONCURRENT; | 46 | static int max_concurr = MAX_BAU_CONCURRENT; |
46 | static int max_bau_concurrent_constant = MAX_BAU_CONCURRENT; | 47 | static int max_concurr_const = MAX_BAU_CONCURRENT; |
47 | static int plugged_delay = PLUGGED_DELAY; | 48 | static int plugged_delay = PLUGGED_DELAY; |
48 | static int plugsb4reset = PLUGSB4RESET; | 49 | static int plugsb4reset = PLUGSB4RESET; |
49 | static int timeoutsb4reset = TIMEOUTSB4RESET; | 50 | static int timeoutsb4reset = TIMEOUTSB4RESET; |
50 | static int ipi_reset_limit = IPI_RESET_LIMIT; | 51 | static int ipi_reset_limit = IPI_RESET_LIMIT; |
51 | static int complete_threshold = COMPLETE_THRESHOLD; | 52 | static int complete_threshold = COMPLETE_THRESHOLD; |
52 | static int congested_response_us = CONGESTED_RESPONSE_US; | 53 | static int congested_respns_us = CONGESTED_RESPONSE_US; |
53 | static int congested_reps = CONGESTED_REPS; | 54 | static int congested_reps = CONGESTED_REPS; |
54 | static int congested_period = CONGESTED_PERIOD; | 55 | static int congested_period = CONGESTED_PERIOD; |
56 | |||
57 | static struct tunables tunables[] = { | ||
58 | {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ | ||
59 | {&plugged_delay, PLUGGED_DELAY}, | ||
60 | {&plugsb4reset, PLUGSB4RESET}, | ||
61 | {&timeoutsb4reset, TIMEOUTSB4RESET}, | ||
62 | {&ipi_reset_limit, IPI_RESET_LIMIT}, | ||
63 | {&complete_threshold, COMPLETE_THRESHOLD}, | ||
64 | {&congested_respns_us, CONGESTED_RESPONSE_US}, | ||
65 | {&congested_reps, CONGESTED_REPS}, | ||
66 | {&congested_period, CONGESTED_PERIOD} | ||
67 | }; | ||
68 | |||
55 | static struct dentry *tunables_dir; | 69 | static struct dentry *tunables_dir; |
56 | static struct dentry *tunables_file; | 70 | static struct dentry *tunables_file; |
57 | 71 | ||
58 | static int __init setup_nobau(char *arg) | 72 | /* these correspond to the statistics printed by ptc_seq_show() */ |
73 | static char *stat_description[] = { | ||
74 | "sent: number of shootdown messages sent", | ||
75 | "stime: time spent sending messages", | ||
76 | "numuvhubs: number of hubs targeted with shootdown", | ||
77 | "numuvhubs16: number times 16 or more hubs targeted", | ||
78 | "numuvhubs8: number times 8 or more hubs targeted", | ||
79 | "numuvhubs4: number times 4 or more hubs targeted", | ||
80 | "numuvhubs2: number times 2 or more hubs targeted", | ||
81 | "numuvhubs1: number times 1 hub targeted", | ||
82 | "numcpus: number of cpus targeted with shootdown", | ||
83 | "dto: number of destination timeouts", | ||
84 | "retries: destination timeout retries sent", | ||
85 | "rok: : destination timeouts successfully retried", | ||
86 | "resetp: ipi-style resource resets for plugs", | ||
87 | "resett: ipi-style resource resets for timeouts", | ||
88 | "giveup: fall-backs to ipi-style shootdowns", | ||
89 | "sto: number of source timeouts", | ||
90 | "bz: number of stay-busy's", | ||
91 | "throt: number times spun in throttle", | ||
92 | "swack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE", | ||
93 | "recv: shootdown messages received", | ||
94 | "rtime: time spent processing messages", | ||
95 | "all: shootdown all-tlb messages", | ||
96 | "one: shootdown one-tlb messages", | ||
97 | "mult: interrupts that found multiple messages", | ||
98 | "none: interrupts that found no messages", | ||
99 | "retry: number of retry messages processed", | ||
100 | "canc: number messages canceled by retries", | ||
101 | "nocan: number retries that found nothing to cancel", | ||
102 | "reset: number of ipi-style reset requests processed", | ||
103 | "rcan: number messages canceled by reset requests", | ||
104 | "disable: number times use of the BAU was disabled", | ||
105 | "enable: number times use of the BAU was re-enabled" | ||
106 | }; | ||
107 | |||
108 | static int __init | ||
109 | setup_nobau(char *arg) | ||
59 | { | 110 | { |
60 | nobau = 1; | 111 | nobau = 1; |
61 | return 0; | 112 | return 0; |
@@ -63,7 +114,7 @@ static int __init setup_nobau(char *arg) | |||
63 | early_param("nobau", setup_nobau); | 114 | early_param("nobau", setup_nobau); |
64 | 115 | ||
65 | /* base pnode in this partition */ | 116 | /* base pnode in this partition */ |
66 | static int uv_partition_base_pnode __read_mostly; | 117 | static int uv_base_pnode __read_mostly; |
67 | /* position of pnode (which is nasid>>1): */ | 118 | /* position of pnode (which is nasid>>1): */ |
68 | static int uv_nshift __read_mostly; | 119 | static int uv_nshift __read_mostly; |
69 | static unsigned long uv_mmask __read_mostly; | 120 | static unsigned long uv_mmask __read_mostly; |
@@ -109,60 +160,52 @@ static int __init uvhub_to_first_apicid(int uvhub) | |||
109 | * clear of the Timeout bit (as well) will free the resource. No reply will | 160 | * clear of the Timeout bit (as well) will free the resource. No reply will |
110 | * be sent (the hardware will only do one reply per message). | 161 | * be sent (the hardware will only do one reply per message). |
111 | */ | 162 | */ |
112 | static inline void uv_reply_to_message(struct msg_desc *mdp, | 163 | static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp) |
113 | struct bau_control *bcp) | ||
114 | { | 164 | { |
115 | unsigned long dw; | 165 | unsigned long dw; |
116 | struct bau_payload_queue_entry *msg; | 166 | struct bau_pq_entry *msg; |
117 | 167 | ||
118 | msg = mdp->msg; | 168 | msg = mdp->msg; |
119 | if (!msg->canceled) { | 169 | if (!msg->canceled) { |
120 | dw = (msg->sw_ack_vector << UV_SW_ACK_NPENDING) | | 170 | dw = (msg->swack_vec << UV_SW_ACK_NPENDING) | msg->swack_vec; |
121 | msg->sw_ack_vector; | 171 | write_mmr_sw_ack(dw); |
122 | uv_write_local_mmr( | ||
123 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw); | ||
124 | } | 172 | } |
125 | msg->replied_to = 1; | 173 | msg->replied_to = 1; |
126 | msg->sw_ack_vector = 0; | 174 | msg->swack_vec = 0; |
127 | } | 175 | } |
128 | 176 | ||
129 | /* | 177 | /* |
130 | * Process the receipt of a RETRY message | 178 | * Process the receipt of a RETRY message |
131 | */ | 179 | */ |
132 | static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | 180 | static void bau_process_retry_msg(struct msg_desc *mdp, |
133 | struct bau_control *bcp) | 181 | struct bau_control *bcp) |
134 | { | 182 | { |
135 | int i; | 183 | int i; |
136 | int cancel_count = 0; | 184 | int cancel_count = 0; |
137 | int slot2; | ||
138 | unsigned long msg_res; | 185 | unsigned long msg_res; |
139 | unsigned long mmr = 0; | 186 | unsigned long mmr = 0; |
140 | struct bau_payload_queue_entry *msg; | 187 | struct bau_pq_entry *msg = mdp->msg; |
141 | struct bau_payload_queue_entry *msg2; | 188 | struct bau_pq_entry *msg2; |
142 | struct ptc_stats *stat; | 189 | struct ptc_stats *stat = bcp->statp; |
143 | 190 | ||
144 | msg = mdp->msg; | ||
145 | stat = bcp->statp; | ||
146 | stat->d_retries++; | 191 | stat->d_retries++; |
147 | /* | 192 | /* |
148 | * cancel any message from msg+1 to the retry itself | 193 | * cancel any message from msg+1 to the retry itself |
149 | */ | 194 | */ |
150 | for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) { | 195 | for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) { |
151 | if (msg2 > mdp->va_queue_last) | 196 | if (msg2 > mdp->queue_last) |
152 | msg2 = mdp->va_queue_first; | 197 | msg2 = mdp->queue_first; |
153 | if (msg2 == msg) | 198 | if (msg2 == msg) |
154 | break; | 199 | break; |
155 | 200 | ||
156 | /* same conditions for cancellation as uv_do_reset */ | 201 | /* same conditions for cancellation as do_reset */ |
157 | if ((msg2->replied_to == 0) && (msg2->canceled == 0) && | 202 | if ((msg2->replied_to == 0) && (msg2->canceled == 0) && |
158 | (msg2->sw_ack_vector) && ((msg2->sw_ack_vector & | 203 | (msg2->swack_vec) && ((msg2->swack_vec & |
159 | msg->sw_ack_vector) == 0) && | 204 | msg->swack_vec) == 0) && |
160 | (msg2->sending_cpu == msg->sending_cpu) && | 205 | (msg2->sending_cpu == msg->sending_cpu) && |
161 | (msg2->msg_type != MSG_NOOP)) { | 206 | (msg2->msg_type != MSG_NOOP)) { |
162 | slot2 = msg2 - mdp->va_queue_first; | 207 | mmr = read_mmr_sw_ack(); |
163 | mmr = uv_read_local_mmr | 208 | msg_res = msg2->swack_vec; |
164 | (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
165 | msg_res = msg2->sw_ack_vector; | ||
166 | /* | 209 | /* |
167 | * This is a message retry; clear the resources held | 210 | * This is a message retry; clear the resources held |
168 | * by the previous message only if they timed out. | 211 | * by the previous message only if they timed out. |
@@ -170,6 +213,7 @@ static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | |||
170 | * situation to report. | 213 | * situation to report. |
171 | */ | 214 | */ |
172 | if (mmr & (msg_res << UV_SW_ACK_NPENDING)) { | 215 | if (mmr & (msg_res << UV_SW_ACK_NPENDING)) { |
216 | unsigned long mr; | ||
173 | /* | 217 | /* |
174 | * is the resource timed out? | 218 | * is the resource timed out? |
175 | * make everyone ignore the cancelled message. | 219 | * make everyone ignore the cancelled message. |
@@ -177,10 +221,8 @@ static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | |||
177 | msg2->canceled = 1; | 221 | msg2->canceled = 1; |
178 | stat->d_canceled++; | 222 | stat->d_canceled++; |
179 | cancel_count++; | 223 | cancel_count++; |
180 | uv_write_local_mmr( | 224 | mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res; |
181 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, | 225 | write_mmr_sw_ack(mr); |
182 | (msg_res << UV_SW_ACK_NPENDING) | | ||
183 | msg_res); | ||
184 | } | 226 | } |
185 | } | 227 | } |
186 | } | 228 | } |
@@ -192,20 +234,19 @@ static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | |||
192 | * Do all the things a cpu should do for a TLB shootdown message. | 234 | * Do all the things a cpu should do for a TLB shootdown message. |
193 | * Other cpu's may come here at the same time for this message. | 235 | * Other cpu's may come here at the same time for this message. |
194 | */ | 236 | */ |
195 | static void uv_bau_process_message(struct msg_desc *mdp, | 237 | static void bau_process_message(struct msg_desc *mdp, |
196 | struct bau_control *bcp) | 238 | struct bau_control *bcp) |
197 | { | 239 | { |
198 | int msg_ack_count; | ||
199 | short socket_ack_count = 0; | 240 | short socket_ack_count = 0; |
200 | struct ptc_stats *stat; | 241 | short *sp; |
201 | struct bau_payload_queue_entry *msg; | 242 | struct atomic_short *asp; |
243 | struct ptc_stats *stat = bcp->statp; | ||
244 | struct bau_pq_entry *msg = mdp->msg; | ||
202 | struct bau_control *smaster = bcp->socket_master; | 245 | struct bau_control *smaster = bcp->socket_master; |
203 | 246 | ||
204 | /* | 247 | /* |
205 | * This must be a normal message, or retry of a normal message | 248 | * This must be a normal message, or retry of a normal message |
206 | */ | 249 | */ |
207 | msg = mdp->msg; | ||
208 | stat = bcp->statp; | ||
209 | if (msg->address == TLB_FLUSH_ALL) { | 250 | if (msg->address == TLB_FLUSH_ALL) { |
210 | local_flush_tlb(); | 251 | local_flush_tlb(); |
211 | stat->d_alltlb++; | 252 | stat->d_alltlb++; |
@@ -222,30 +263,32 @@ static void uv_bau_process_message(struct msg_desc *mdp, | |||
222 | * cpu number. | 263 | * cpu number. |
223 | */ | 264 | */ |
224 | if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master) | 265 | if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master) |
225 | uv_bau_process_retry_msg(mdp, bcp); | 266 | bau_process_retry_msg(mdp, bcp); |
226 | 267 | ||
227 | /* | 268 | /* |
228 | * This is a sw_ack message, so we have to reply to it. | 269 | * This is a swack message, so we have to reply to it. |
229 | * Count each responding cpu on the socket. This avoids | 270 | * Count each responding cpu on the socket. This avoids |
230 | * pinging the count's cache line back and forth between | 271 | * pinging the count's cache line back and forth between |
231 | * the sockets. | 272 | * the sockets. |
232 | */ | 273 | */ |
233 | socket_ack_count = atomic_add_short_return(1, (struct atomic_short *) | 274 | sp = &smaster->socket_acknowledge_count[mdp->msg_slot]; |
234 | &smaster->socket_acknowledge_count[mdp->msg_slot]); | 275 | asp = (struct atomic_short *)sp; |
276 | socket_ack_count = atom_asr(1, asp); | ||
235 | if (socket_ack_count == bcp->cpus_in_socket) { | 277 | if (socket_ack_count == bcp->cpus_in_socket) { |
278 | int msg_ack_count; | ||
236 | /* | 279 | /* |
237 | * Both sockets dump their completed count total into | 280 | * Both sockets dump their completed count total into |
238 | * the message's count. | 281 | * the message's count. |
239 | */ | 282 | */ |
240 | smaster->socket_acknowledge_count[mdp->msg_slot] = 0; | 283 | smaster->socket_acknowledge_count[mdp->msg_slot] = 0; |
241 | msg_ack_count = atomic_add_short_return(socket_ack_count, | 284 | asp = (struct atomic_short *)&msg->acknowledge_count; |
242 | (struct atomic_short *)&msg->acknowledge_count); | 285 | msg_ack_count = atom_asr(socket_ack_count, asp); |
243 | 286 | ||
244 | if (msg_ack_count == bcp->cpus_in_uvhub) { | 287 | if (msg_ack_count == bcp->cpus_in_uvhub) { |
245 | /* | 288 | /* |
246 | * All cpus in uvhub saw it; reply | 289 | * All cpus in uvhub saw it; reply |
247 | */ | 290 | */ |
248 | uv_reply_to_message(mdp, bcp); | 291 | reply_to_message(mdp, bcp); |
249 | } | 292 | } |
250 | } | 293 | } |
251 | 294 | ||
@@ -268,62 +311,51 @@ static int uvhub_to_first_cpu(int uvhub) | |||
268 | * Last resort when we get a large number of destination timeouts is | 311 | * Last resort when we get a large number of destination timeouts is |
269 | * to clear resources held by a given cpu. | 312 | * to clear resources held by a given cpu. |
270 | * Do this with IPI so that all messages in the BAU message queue | 313 | * Do this with IPI so that all messages in the BAU message queue |
271 | * can be identified by their nonzero sw_ack_vector field. | 314 | * can be identified by their nonzero swack_vec field. |
272 | * | 315 | * |
273 | * This is entered for a single cpu on the uvhub. | 316 | * This is entered for a single cpu on the uvhub. |
274 | * The sender want's this uvhub to free a specific message's | 317 | * The sender want's this uvhub to free a specific message's |
275 | * sw_ack resources. | 318 | * swack resources. |
276 | */ | 319 | */ |
277 | static void | 320 | static void do_reset(void *ptr) |
278 | uv_do_reset(void *ptr) | ||
279 | { | 321 | { |
280 | int i; | 322 | int i; |
281 | int slot; | 323 | struct bau_control *bcp = &per_cpu(bau_control, smp_processor_id()); |
282 | int count = 0; | 324 | struct reset_args *rap = (struct reset_args *)ptr; |
283 | unsigned long mmr; | 325 | struct bau_pq_entry *msg; |
284 | unsigned long msg_res; | 326 | struct ptc_stats *stat = bcp->statp; |
285 | struct bau_control *bcp; | ||
286 | struct reset_args *rap; | ||
287 | struct bau_payload_queue_entry *msg; | ||
288 | struct ptc_stats *stat; | ||
289 | 327 | ||
290 | bcp = &per_cpu(bau_control, smp_processor_id()); | ||
291 | rap = (struct reset_args *)ptr; | ||
292 | stat = bcp->statp; | ||
293 | stat->d_resets++; | 328 | stat->d_resets++; |
294 | |||
295 | /* | 329 | /* |
296 | * We're looking for the given sender, and | 330 | * We're looking for the given sender, and |
297 | * will free its sw_ack resource. | 331 | * will free its swack resource. |
298 | * If all cpu's finally responded after the timeout, its | 332 | * If all cpu's finally responded after the timeout, its |
299 | * message 'replied_to' was set. | 333 | * message 'replied_to' was set. |
300 | */ | 334 | */ |
301 | for (msg = bcp->va_queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) { | 335 | for (msg = bcp->queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) { |
302 | /* uv_do_reset: same conditions for cancellation as | 336 | unsigned long msg_res; |
303 | uv_bau_process_retry_msg() */ | 337 | /* do_reset: same conditions for cancellation as |
338 | bau_process_retry_msg() */ | ||
304 | if ((msg->replied_to == 0) && | 339 | if ((msg->replied_to == 0) && |
305 | (msg->canceled == 0) && | 340 | (msg->canceled == 0) && |
306 | (msg->sending_cpu == rap->sender) && | 341 | (msg->sending_cpu == rap->sender) && |
307 | (msg->sw_ack_vector) && | 342 | (msg->swack_vec) && |
308 | (msg->msg_type != MSG_NOOP)) { | 343 | (msg->msg_type != MSG_NOOP)) { |
344 | unsigned long mmr; | ||
345 | unsigned long mr; | ||
309 | /* | 346 | /* |
310 | * make everyone else ignore this message | 347 | * make everyone else ignore this message |
311 | */ | 348 | */ |
312 | msg->canceled = 1; | 349 | msg->canceled = 1; |
313 | slot = msg - bcp->va_queue_first; | ||
314 | count++; | ||
315 | /* | 350 | /* |
316 | * only reset the resource if it is still pending | 351 | * only reset the resource if it is still pending |
317 | */ | 352 | */ |
318 | mmr = uv_read_local_mmr | 353 | mmr = read_mmr_sw_ack(); |
319 | (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | 354 | msg_res = msg->swack_vec; |
320 | msg_res = msg->sw_ack_vector; | 355 | mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res; |
321 | if (mmr & msg_res) { | 356 | if (mmr & msg_res) { |
322 | stat->d_rcanceled++; | 357 | stat->d_rcanceled++; |
323 | uv_write_local_mmr( | 358 | write_mmr_sw_ack(mr); |
324 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, | ||
325 | (msg_res << UV_SW_ACK_NPENDING) | | ||
326 | msg_res); | ||
327 | } | 359 | } |
328 | } | 360 | } |
329 | } | 361 | } |
@@ -334,39 +366,38 @@ uv_do_reset(void *ptr) | |||
334 | * Use IPI to get all target uvhubs to release resources held by | 366 | * Use IPI to get all target uvhubs to release resources held by |
335 | * a given sending cpu number. | 367 | * a given sending cpu number. |
336 | */ | 368 | */ |
337 | static void uv_reset_with_ipi(struct bau_target_uvhubmask *distribution, | 369 | static void reset_with_ipi(struct bau_targ_hubmask *distribution, int sender) |
338 | int sender) | ||
339 | { | 370 | { |
340 | int uvhub; | 371 | int uvhub; |
341 | int cpu; | 372 | int maskbits; |
342 | cpumask_t mask; | 373 | cpumask_t mask; |
343 | struct reset_args reset_args; | 374 | struct reset_args reset_args; |
344 | 375 | ||
345 | reset_args.sender = sender; | 376 | reset_args.sender = sender; |
346 | |||
347 | cpus_clear(mask); | 377 | cpus_clear(mask); |
348 | /* find a single cpu for each uvhub in this distribution mask */ | 378 | /* find a single cpu for each uvhub in this distribution mask */ |
349 | for (uvhub = 0; | 379 | maskbits = sizeof(struct bau_targ_hubmask) * BITSPERBYTE; |
350 | uvhub < sizeof(struct bau_target_uvhubmask) * BITSPERBYTE; | 380 | for (uvhub = 0; uvhub < maskbits; uvhub++) { |
351 | uvhub++) { | 381 | int cpu; |
352 | if (!bau_uvhub_isset(uvhub, distribution)) | 382 | if (!bau_uvhub_isset(uvhub, distribution)) |
353 | continue; | 383 | continue; |
354 | /* find a cpu for this uvhub */ | 384 | /* find a cpu for this uvhub */ |
355 | cpu = uvhub_to_first_cpu(uvhub); | 385 | cpu = uvhub_to_first_cpu(uvhub); |
356 | cpu_set(cpu, mask); | 386 | cpu_set(cpu, mask); |
357 | } | 387 | } |
358 | /* IPI all cpus; Preemption is already disabled */ | 388 | |
359 | smp_call_function_many(&mask, uv_do_reset, (void *)&reset_args, 1); | 389 | /* IPI all cpus; preemption is already disabled */ |
390 | smp_call_function_many(&mask, do_reset, (void *)&reset_args, 1); | ||
360 | return; | 391 | return; |
361 | } | 392 | } |
362 | 393 | ||
363 | static inline unsigned long | 394 | static inline unsigned long cycles_2_us(unsigned long long cyc) |
364 | cycles_2_us(unsigned long long cyc) | ||
365 | { | 395 | { |
366 | unsigned long long ns; | 396 | unsigned long long ns; |
367 | unsigned long us; | 397 | unsigned long us; |
368 | ns = (cyc * per_cpu(cyc2ns, smp_processor_id())) | 398 | int cpu = smp_processor_id(); |
369 | >> CYC2NS_SCALE_FACTOR; | 399 | |
400 | ns = (cyc * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR; | ||
370 | us = ns / 1000; | 401 | us = ns / 1000; |
371 | return us; | 402 | return us; |
372 | } | 403 | } |
@@ -376,56 +407,56 @@ cycles_2_us(unsigned long long cyc) | |||
376 | * leaves uvhub_quiesce set so that no new broadcasts are started by | 407 | * leaves uvhub_quiesce set so that no new broadcasts are started by |
377 | * bau_flush_send_and_wait() | 408 | * bau_flush_send_and_wait() |
378 | */ | 409 | */ |
379 | static inline void | 410 | static inline void quiesce_local_uvhub(struct bau_control *hmaster) |
380 | quiesce_local_uvhub(struct bau_control *hmaster) | ||
381 | { | 411 | { |
382 | atomic_add_short_return(1, (struct atomic_short *) | 412 | atom_asr(1, (struct atomic_short *)&hmaster->uvhub_quiesce); |
383 | &hmaster->uvhub_quiesce); | ||
384 | } | 413 | } |
385 | 414 | ||
386 | /* | 415 | /* |
387 | * mark this quiet-requestor as done | 416 | * mark this quiet-requestor as done |
388 | */ | 417 | */ |
389 | static inline void | 418 | static inline void end_uvhub_quiesce(struct bau_control *hmaster) |
390 | end_uvhub_quiesce(struct bau_control *hmaster) | ||
391 | { | 419 | { |
392 | atomic_add_short_return(-1, (struct atomic_short *) | 420 | atom_asr(-1, (struct atomic_short *)&hmaster->uvhub_quiesce); |
393 | &hmaster->uvhub_quiesce); | 421 | } |
422 | |||
423 | static unsigned long uv1_read_status(unsigned long mmr_offset, int right_shift) | ||
424 | { | ||
425 | unsigned long descriptor_status; | ||
426 | |||
427 | descriptor_status = uv_read_local_mmr(mmr_offset); | ||
428 | descriptor_status >>= right_shift; | ||
429 | descriptor_status &= UV_ACT_STATUS_MASK; | ||
430 | return descriptor_status; | ||
394 | } | 431 | } |
395 | 432 | ||
396 | /* | 433 | /* |
397 | * Wait for completion of a broadcast software ack message | 434 | * Wait for completion of a broadcast software ack message |
398 | * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP | 435 | * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP |
399 | */ | 436 | */ |
400 | static int uv_wait_completion(struct bau_desc *bau_desc, | 437 | static int uv1_wait_completion(struct bau_desc *bau_desc, |
401 | unsigned long mmr_offset, int right_shift, int this_cpu, | 438 | unsigned long mmr_offset, int right_shift, |
402 | struct bau_control *bcp, struct bau_control *smaster, long try) | 439 | struct bau_control *bcp, long try) |
403 | { | 440 | { |
404 | unsigned long descriptor_status; | 441 | unsigned long descriptor_status; |
405 | cycles_t ttime; | 442 | cycles_t ttm; |
406 | struct ptc_stats *stat = bcp->statp; | 443 | struct ptc_stats *stat = bcp->statp; |
407 | struct bau_control *hmaster; | ||
408 | |||
409 | hmaster = bcp->uvhub_master; | ||
410 | 444 | ||
445 | descriptor_status = uv1_read_status(mmr_offset, right_shift); | ||
411 | /* spin on the status MMR, waiting for it to go idle */ | 446 | /* spin on the status MMR, waiting for it to go idle */ |
412 | while ((descriptor_status = (((unsigned long) | 447 | while ((descriptor_status != DS_IDLE)) { |
413 | uv_read_local_mmr(mmr_offset) >> | ||
414 | right_shift) & UV_ACT_STATUS_MASK)) != | ||
415 | DESC_STATUS_IDLE) { | ||
416 | /* | 448 | /* |
417 | * Our software ack messages may be blocked because there are | 449 | * Our software ack messages may be blocked because |
418 | * no swack resources available. As long as none of them | 450 | * there are no swack resources available. As long |
419 | * has timed out hardware will NACK our message and its | 451 | * as none of them has timed out hardware will NACK |
420 | * state will stay IDLE. | 452 | * our message and its state will stay IDLE. |
421 | */ | 453 | */ |
422 | if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) { | 454 | if (descriptor_status == DS_SOURCE_TIMEOUT) { |
423 | stat->s_stimeout++; | 455 | stat->s_stimeout++; |
424 | return FLUSH_GIVEUP; | 456 | return FLUSH_GIVEUP; |
425 | } else if (descriptor_status == | 457 | } else if (descriptor_status == DS_DESTINATION_TIMEOUT) { |
426 | DESC_STATUS_DESTINATION_TIMEOUT) { | ||
427 | stat->s_dtimeout++; | 458 | stat->s_dtimeout++; |
428 | ttime = get_cycles(); | 459 | ttm = get_cycles(); |
429 | 460 | ||
430 | /* | 461 | /* |
431 | * Our retries may be blocked by all destination | 462 | * Our retries may be blocked by all destination |
@@ -433,8 +464,7 @@ static int uv_wait_completion(struct bau_desc *bau_desc, | |||
433 | * pending. In that case hardware returns the | 464 | * pending. In that case hardware returns the |
434 | * ERROR that looks like a destination timeout. | 465 | * ERROR that looks like a destination timeout. |
435 | */ | 466 | */ |
436 | if (cycles_2_us(ttime - bcp->send_message) < | 467 | if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { |
437 | timeout_us) { | ||
438 | bcp->conseccompletes = 0; | 468 | bcp->conseccompletes = 0; |
439 | return FLUSH_RETRY_PLUGGED; | 469 | return FLUSH_RETRY_PLUGGED; |
440 | } | 470 | } |
@@ -447,80 +477,160 @@ static int uv_wait_completion(struct bau_desc *bau_desc, | |||
447 | */ | 477 | */ |
448 | cpu_relax(); | 478 | cpu_relax(); |
449 | } | 479 | } |
480 | descriptor_status = uv1_read_status(mmr_offset, right_shift); | ||
450 | } | 481 | } |
451 | bcp->conseccompletes++; | 482 | bcp->conseccompletes++; |
452 | return FLUSH_COMPLETE; | 483 | return FLUSH_COMPLETE; |
453 | } | 484 | } |
454 | 485 | ||
455 | static inline cycles_t | 486 | /* |
456 | sec_2_cycles(unsigned long sec) | 487 | * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register. |
488 | */ | ||
489 | static unsigned long uv2_read_status(unsigned long offset, int rshft, int cpu) | ||
457 | { | 490 | { |
458 | unsigned long ns; | 491 | unsigned long descriptor_status; |
459 | cycles_t cyc; | 492 | unsigned long descriptor_status2; |
460 | 493 | ||
461 | ns = sec * 1000000000; | 494 | descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK); |
462 | cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); | 495 | descriptor_status2 = (read_mmr_uv2_status() >> cpu) & 0x1UL; |
463 | return cyc; | 496 | descriptor_status = (descriptor_status << 1) | descriptor_status2; |
497 | return descriptor_status; | ||
498 | } | ||
499 | |||
500 | static int uv2_wait_completion(struct bau_desc *bau_desc, | ||
501 | unsigned long mmr_offset, int right_shift, | ||
502 | struct bau_control *bcp, long try) | ||
503 | { | ||
504 | unsigned long descriptor_stat; | ||
505 | cycles_t ttm; | ||
506 | int cpu = bcp->uvhub_cpu; | ||
507 | struct ptc_stats *stat = bcp->statp; | ||
508 | |||
509 | descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu); | ||
510 | |||
511 | /* spin on the status MMR, waiting for it to go idle */ | ||
512 | while (descriptor_stat != UV2H_DESC_IDLE) { | ||
513 | /* | ||
514 | * Our software ack messages may be blocked because | ||
515 | * there are no swack resources available. As long | ||
516 | * as none of them has timed out hardware will NACK | ||
517 | * our message and its state will stay IDLE. | ||
518 | */ | ||
519 | if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) || | ||
520 | (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) || | ||
521 | (descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) { | ||
522 | stat->s_stimeout++; | ||
523 | return FLUSH_GIVEUP; | ||
524 | } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { | ||
525 | stat->s_dtimeout++; | ||
526 | ttm = get_cycles(); | ||
527 | /* | ||
528 | * Our retries may be blocked by all destination | ||
529 | * swack resources being consumed, and a timeout | ||
530 | * pending. In that case hardware returns the | ||
531 | * ERROR that looks like a destination timeout. | ||
532 | */ | ||
533 | if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { | ||
534 | bcp->conseccompletes = 0; | ||
535 | return FLUSH_RETRY_PLUGGED; | ||
536 | } | ||
537 | bcp->conseccompletes = 0; | ||
538 | return FLUSH_RETRY_TIMEOUT; | ||
539 | } else { | ||
540 | /* | ||
541 | * descriptor_stat is still BUSY | ||
542 | */ | ||
543 | cpu_relax(); | ||
544 | } | ||
545 | descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu); | ||
546 | } | ||
547 | bcp->conseccompletes++; | ||
548 | return FLUSH_COMPLETE; | ||
464 | } | 549 | } |
465 | 550 | ||
466 | /* | 551 | /* |
467 | * conditionally add 1 to *v, unless *v is >= u | 552 | * There are 2 status registers; each and array[32] of 2 bits. Set up for |
468 | * return 0 if we cannot add 1 to *v because it is >= u | 553 | * which register to read and position in that register based on cpu in |
469 | * return 1 if we can add 1 to *v because it is < u | 554 | * current hub. |
470 | * the add is atomic | ||
471 | * | ||
472 | * This is close to atomic_add_unless(), but this allows the 'u' value | ||
473 | * to be lowered below the current 'v'. atomic_add_unless can only stop | ||
474 | * on equal. | ||
475 | */ | 555 | */ |
476 | static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) | 556 | static int wait_completion(struct bau_desc *bau_desc, |
557 | struct bau_control *bcp, long try) | ||
477 | { | 558 | { |
478 | spin_lock(lock); | 559 | int right_shift; |
479 | if (atomic_read(v) >= u) { | 560 | unsigned long mmr_offset; |
480 | spin_unlock(lock); | 561 | int cpu = bcp->uvhub_cpu; |
481 | return 0; | 562 | |
563 | if (cpu < UV_CPUS_PER_AS) { | ||
564 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; | ||
565 | right_shift = cpu * UV_ACT_STATUS_SIZE; | ||
566 | } else { | ||
567 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; | ||
568 | right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE); | ||
482 | } | 569 | } |
483 | atomic_inc(v); | 570 | |
484 | spin_unlock(lock); | 571 | if (is_uv1_hub()) |
485 | return 1; | 572 | return uv1_wait_completion(bau_desc, mmr_offset, right_shift, |
573 | bcp, try); | ||
574 | else | ||
575 | return uv2_wait_completion(bau_desc, mmr_offset, right_shift, | ||
576 | bcp, try); | ||
577 | } | ||
578 | |||
579 | static inline cycles_t sec_2_cycles(unsigned long sec) | ||
580 | { | ||
581 | unsigned long ns; | ||
582 | cycles_t cyc; | ||
583 | |||
584 | ns = sec * 1000000000; | ||
585 | cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); | ||
586 | return cyc; | ||
486 | } | 587 | } |
487 | 588 | ||
488 | /* | 589 | /* |
489 | * Our retries are blocked by all destination swack resources being | 590 | * Our retries are blocked by all destination sw ack resources being |
490 | * in use, and a timeout is pending. In that case hardware immediately | 591 | * in use, and a timeout is pending. In that case hardware immediately |
491 | * returns the ERROR that looks like a destination timeout. | 592 | * returns the ERROR that looks like a destination timeout. |
492 | */ | 593 | */ |
493 | static void | 594 | static void destination_plugged(struct bau_desc *bau_desc, |
494 | destination_plugged(struct bau_desc *bau_desc, struct bau_control *bcp, | 595 | struct bau_control *bcp, |
495 | struct bau_control *hmaster, struct ptc_stats *stat) | 596 | struct bau_control *hmaster, struct ptc_stats *stat) |
496 | { | 597 | { |
497 | udelay(bcp->plugged_delay); | 598 | udelay(bcp->plugged_delay); |
498 | bcp->plugged_tries++; | 599 | bcp->plugged_tries++; |
600 | |||
499 | if (bcp->plugged_tries >= bcp->plugsb4reset) { | 601 | if (bcp->plugged_tries >= bcp->plugsb4reset) { |
500 | bcp->plugged_tries = 0; | 602 | bcp->plugged_tries = 0; |
603 | |||
501 | quiesce_local_uvhub(hmaster); | 604 | quiesce_local_uvhub(hmaster); |
605 | |||
502 | spin_lock(&hmaster->queue_lock); | 606 | spin_lock(&hmaster->queue_lock); |
503 | uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu); | 607 | reset_with_ipi(&bau_desc->distribution, bcp->cpu); |
504 | spin_unlock(&hmaster->queue_lock); | 608 | spin_unlock(&hmaster->queue_lock); |
609 | |||
505 | end_uvhub_quiesce(hmaster); | 610 | end_uvhub_quiesce(hmaster); |
611 | |||
506 | bcp->ipi_attempts++; | 612 | bcp->ipi_attempts++; |
507 | stat->s_resets_plug++; | 613 | stat->s_resets_plug++; |
508 | } | 614 | } |
509 | } | 615 | } |
510 | 616 | ||
511 | static void | 617 | static void destination_timeout(struct bau_desc *bau_desc, |
512 | destination_timeout(struct bau_desc *bau_desc, struct bau_control *bcp, | 618 | struct bau_control *bcp, struct bau_control *hmaster, |
513 | struct bau_control *hmaster, struct ptc_stats *stat) | 619 | struct ptc_stats *stat) |
514 | { | 620 | { |
515 | hmaster->max_bau_concurrent = 1; | 621 | hmaster->max_concurr = 1; |
516 | bcp->timeout_tries++; | 622 | bcp->timeout_tries++; |
517 | if (bcp->timeout_tries >= bcp->timeoutsb4reset) { | 623 | if (bcp->timeout_tries >= bcp->timeoutsb4reset) { |
518 | bcp->timeout_tries = 0; | 624 | bcp->timeout_tries = 0; |
625 | |||
519 | quiesce_local_uvhub(hmaster); | 626 | quiesce_local_uvhub(hmaster); |
627 | |||
520 | spin_lock(&hmaster->queue_lock); | 628 | spin_lock(&hmaster->queue_lock); |
521 | uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu); | 629 | reset_with_ipi(&bau_desc->distribution, bcp->cpu); |
522 | spin_unlock(&hmaster->queue_lock); | 630 | spin_unlock(&hmaster->queue_lock); |
631 | |||
523 | end_uvhub_quiesce(hmaster); | 632 | end_uvhub_quiesce(hmaster); |
633 | |||
524 | bcp->ipi_attempts++; | 634 | bcp->ipi_attempts++; |
525 | stat->s_resets_timeout++; | 635 | stat->s_resets_timeout++; |
526 | } | 636 | } |
@@ -530,34 +640,104 @@ destination_timeout(struct bau_desc *bau_desc, struct bau_control *bcp, | |||
530 | * Completions are taking a very long time due to a congested numalink | 640 | * Completions are taking a very long time due to a congested numalink |
531 | * network. | 641 | * network. |
532 | */ | 642 | */ |
533 | static void | 643 | static void disable_for_congestion(struct bau_control *bcp, |
534 | disable_for_congestion(struct bau_control *bcp, struct ptc_stats *stat) | 644 | struct ptc_stats *stat) |
535 | { | 645 | { |
536 | int tcpu; | ||
537 | struct bau_control *tbcp; | ||
538 | |||
539 | /* let only one cpu do this disabling */ | 646 | /* let only one cpu do this disabling */ |
540 | spin_lock(&disable_lock); | 647 | spin_lock(&disable_lock); |
648 | |||
541 | if (!baudisabled && bcp->period_requests && | 649 | if (!baudisabled && bcp->period_requests && |
542 | ((bcp->period_time / bcp->period_requests) > congested_cycles)) { | 650 | ((bcp->period_time / bcp->period_requests) > congested_cycles)) { |
651 | int tcpu; | ||
652 | struct bau_control *tbcp; | ||
543 | /* it becomes this cpu's job to turn on the use of the | 653 | /* it becomes this cpu's job to turn on the use of the |
544 | BAU again */ | 654 | BAU again */ |
545 | baudisabled = 1; | 655 | baudisabled = 1; |
546 | bcp->set_bau_off = 1; | 656 | bcp->set_bau_off = 1; |
547 | bcp->set_bau_on_time = get_cycles() + | 657 | bcp->set_bau_on_time = get_cycles(); |
548 | sec_2_cycles(bcp->congested_period); | 658 | bcp->set_bau_on_time += sec_2_cycles(bcp->cong_period); |
549 | stat->s_bau_disabled++; | 659 | stat->s_bau_disabled++; |
550 | for_each_present_cpu(tcpu) { | 660 | for_each_present_cpu(tcpu) { |
551 | tbcp = &per_cpu(bau_control, tcpu); | 661 | tbcp = &per_cpu(bau_control, tcpu); |
552 | tbcp->baudisabled = 1; | 662 | tbcp->baudisabled = 1; |
553 | } | 663 | } |
554 | } | 664 | } |
665 | |||
555 | spin_unlock(&disable_lock); | 666 | spin_unlock(&disable_lock); |
556 | } | 667 | } |
557 | 668 | ||
558 | /** | 669 | static void count_max_concurr(int stat, struct bau_control *bcp, |
559 | * uv_flush_send_and_wait | 670 | struct bau_control *hmaster) |
560 | * | 671 | { |
672 | bcp->plugged_tries = 0; | ||
673 | bcp->timeout_tries = 0; | ||
674 | if (stat != FLUSH_COMPLETE) | ||
675 | return; | ||
676 | if (bcp->conseccompletes <= bcp->complete_threshold) | ||
677 | return; | ||
678 | if (hmaster->max_concurr >= hmaster->max_concurr_const) | ||
679 | return; | ||
680 | hmaster->max_concurr++; | ||
681 | } | ||
682 | |||
683 | static void record_send_stats(cycles_t time1, cycles_t time2, | ||
684 | struct bau_control *bcp, struct ptc_stats *stat, | ||
685 | int completion_status, int try) | ||
686 | { | ||
687 | cycles_t elapsed; | ||
688 | |||
689 | if (time2 > time1) { | ||
690 | elapsed = time2 - time1; | ||
691 | stat->s_time += elapsed; | ||
692 | |||
693 | if ((completion_status == FLUSH_COMPLETE) && (try == 1)) { | ||
694 | bcp->period_requests++; | ||
695 | bcp->period_time += elapsed; | ||
696 | if ((elapsed > congested_cycles) && | ||
697 | (bcp->period_requests > bcp->cong_reps)) | ||
698 | disable_for_congestion(bcp, stat); | ||
699 | } | ||
700 | } else | ||
701 | stat->s_requestor--; | ||
702 | |||
703 | if (completion_status == FLUSH_COMPLETE && try > 1) | ||
704 | stat->s_retriesok++; | ||
705 | else if (completion_status == FLUSH_GIVEUP) | ||
706 | stat->s_giveup++; | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * Because of a uv1 hardware bug only a limited number of concurrent | ||
711 | * requests can be made. | ||
712 | */ | ||
713 | static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat) | ||
714 | { | ||
715 | spinlock_t *lock = &hmaster->uvhub_lock; | ||
716 | atomic_t *v; | ||
717 | |||
718 | v = &hmaster->active_descriptor_count; | ||
719 | if (!atomic_inc_unless_ge(lock, v, hmaster->max_concurr)) { | ||
720 | stat->s_throttles++; | ||
721 | do { | ||
722 | cpu_relax(); | ||
723 | } while (!atomic_inc_unless_ge(lock, v, hmaster->max_concurr)); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | * Handle the completion status of a message send. | ||
729 | */ | ||
730 | static void handle_cmplt(int completion_status, struct bau_desc *bau_desc, | ||
731 | struct bau_control *bcp, struct bau_control *hmaster, | ||
732 | struct ptc_stats *stat) | ||
733 | { | ||
734 | if (completion_status == FLUSH_RETRY_PLUGGED) | ||
735 | destination_plugged(bau_desc, bcp, hmaster, stat); | ||
736 | else if (completion_status == FLUSH_RETRY_TIMEOUT) | ||
737 | destination_timeout(bau_desc, bcp, hmaster, stat); | ||
738 | } | ||
739 | |||
740 | /* | ||
561 | * Send a broadcast and wait for it to complete. | 741 | * Send a broadcast and wait for it to complete. |
562 | * | 742 | * |
563 | * The flush_mask contains the cpus the broadcast is to be sent to including | 743 | * The flush_mask contains the cpus the broadcast is to be sent to including |
@@ -568,44 +748,23 @@ disable_for_congestion(struct bau_control *bcp, struct ptc_stats *stat) | |||
568 | * returned to the kernel. | 748 | * returned to the kernel. |
569 | */ | 749 | */ |
570 | int uv_flush_send_and_wait(struct bau_desc *bau_desc, | 750 | int uv_flush_send_and_wait(struct bau_desc *bau_desc, |
571 | struct cpumask *flush_mask, struct bau_control *bcp) | 751 | struct cpumask *flush_mask, struct bau_control *bcp) |
572 | { | 752 | { |
573 | int right_shift; | ||
574 | int completion_status = 0; | ||
575 | int seq_number = 0; | 753 | int seq_number = 0; |
754 | int completion_stat = 0; | ||
576 | long try = 0; | 755 | long try = 0; |
577 | int cpu = bcp->uvhub_cpu; | ||
578 | int this_cpu = bcp->cpu; | ||
579 | unsigned long mmr_offset; | ||
580 | unsigned long index; | 756 | unsigned long index; |
581 | cycles_t time1; | 757 | cycles_t time1; |
582 | cycles_t time2; | 758 | cycles_t time2; |
583 | cycles_t elapsed; | ||
584 | struct ptc_stats *stat = bcp->statp; | 759 | struct ptc_stats *stat = bcp->statp; |
585 | struct bau_control *smaster = bcp->socket_master; | ||
586 | struct bau_control *hmaster = bcp->uvhub_master; | 760 | struct bau_control *hmaster = bcp->uvhub_master; |
587 | 761 | ||
588 | if (!atomic_inc_unless_ge(&hmaster->uvhub_lock, | 762 | if (is_uv1_hub()) |
589 | &hmaster->active_descriptor_count, | 763 | uv1_throttle(hmaster, stat); |
590 | hmaster->max_bau_concurrent)) { | 764 | |
591 | stat->s_throttles++; | ||
592 | do { | ||
593 | cpu_relax(); | ||
594 | } while (!atomic_inc_unless_ge(&hmaster->uvhub_lock, | ||
595 | &hmaster->active_descriptor_count, | ||
596 | hmaster->max_bau_concurrent)); | ||
597 | } | ||
598 | while (hmaster->uvhub_quiesce) | 765 | while (hmaster->uvhub_quiesce) |
599 | cpu_relax(); | 766 | cpu_relax(); |
600 | 767 | ||
601 | if (cpu < UV_CPUS_PER_ACT_STATUS) { | ||
602 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; | ||
603 | right_shift = cpu * UV_ACT_STATUS_SIZE; | ||
604 | } else { | ||
605 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; | ||
606 | right_shift = | ||
607 | ((cpu - UV_CPUS_PER_ACT_STATUS) * UV_ACT_STATUS_SIZE); | ||
608 | } | ||
609 | time1 = get_cycles(); | 768 | time1 = get_cycles(); |
610 | do { | 769 | do { |
611 | if (try == 0) { | 770 | if (try == 0) { |
@@ -615,64 +774,134 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc, | |||
615 | bau_desc->header.msg_type = MSG_RETRY; | 774 | bau_desc->header.msg_type = MSG_RETRY; |
616 | stat->s_retry_messages++; | 775 | stat->s_retry_messages++; |
617 | } | 776 | } |
777 | |||
618 | bau_desc->header.sequence = seq_number; | 778 | bau_desc->header.sequence = seq_number; |
619 | index = (1UL << UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT) | | 779 | index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; |
620 | bcp->uvhub_cpu; | ||
621 | bcp->send_message = get_cycles(); | 780 | bcp->send_message = get_cycles(); |
622 | uv_write_local_mmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); | 781 | |
782 | write_mmr_activation(index); | ||
783 | |||
623 | try++; | 784 | try++; |
624 | completion_status = uv_wait_completion(bau_desc, mmr_offset, | 785 | completion_stat = wait_completion(bau_desc, bcp, try); |
625 | right_shift, this_cpu, bcp, smaster, try); | 786 | |
787 | handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); | ||
626 | 788 | ||
627 | if (completion_status == FLUSH_RETRY_PLUGGED) { | ||
628 | destination_plugged(bau_desc, bcp, hmaster, stat); | ||
629 | } else if (completion_status == FLUSH_RETRY_TIMEOUT) { | ||
630 | destination_timeout(bau_desc, bcp, hmaster, stat); | ||
631 | } | ||
632 | if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { | 789 | if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { |
633 | bcp->ipi_attempts = 0; | 790 | bcp->ipi_attempts = 0; |
634 | completion_status = FLUSH_GIVEUP; | 791 | completion_stat = FLUSH_GIVEUP; |
635 | break; | 792 | break; |
636 | } | 793 | } |
637 | cpu_relax(); | 794 | cpu_relax(); |
638 | } while ((completion_status == FLUSH_RETRY_PLUGGED) || | 795 | } while ((completion_stat == FLUSH_RETRY_PLUGGED) || |
639 | (completion_status == FLUSH_RETRY_TIMEOUT)); | 796 | (completion_stat == FLUSH_RETRY_TIMEOUT)); |
797 | |||
640 | time2 = get_cycles(); | 798 | time2 = get_cycles(); |
641 | bcp->plugged_tries = 0; | 799 | |
642 | bcp->timeout_tries = 0; | 800 | count_max_concurr(completion_stat, bcp, hmaster); |
643 | if ((completion_status == FLUSH_COMPLETE) && | 801 | |
644 | (bcp->conseccompletes > bcp->complete_threshold) && | ||
645 | (hmaster->max_bau_concurrent < | ||
646 | hmaster->max_bau_concurrent_constant)) | ||
647 | hmaster->max_bau_concurrent++; | ||
648 | while (hmaster->uvhub_quiesce) | 802 | while (hmaster->uvhub_quiesce) |
649 | cpu_relax(); | 803 | cpu_relax(); |
804 | |||
650 | atomic_dec(&hmaster->active_descriptor_count); | 805 | atomic_dec(&hmaster->active_descriptor_count); |
651 | if (time2 > time1) { | 806 | |
652 | elapsed = time2 - time1; | 807 | record_send_stats(time1, time2, bcp, stat, completion_stat, try); |
653 | stat->s_time += elapsed; | 808 | |
654 | if ((completion_status == FLUSH_COMPLETE) && (try == 1)) { | 809 | if (completion_stat == FLUSH_GIVEUP) |
655 | bcp->period_requests++; | 810 | return 1; |
656 | bcp->period_time += elapsed; | 811 | return 0; |
657 | if ((elapsed > congested_cycles) && | 812 | } |
658 | (bcp->period_requests > bcp->congested_reps)) { | 813 | |
659 | disable_for_congestion(bcp, stat); | 814 | /* |
815 | * The BAU is disabled. When the disabled time period has expired, the cpu | ||
816 | * that disabled it must re-enable it. | ||
817 | * Return 0 if it is re-enabled for all cpus. | ||
818 | */ | ||
819 | static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) | ||
820 | { | ||
821 | int tcpu; | ||
822 | struct bau_control *tbcp; | ||
823 | |||
824 | if (bcp->set_bau_off) { | ||
825 | if (get_cycles() >= bcp->set_bau_on_time) { | ||
826 | stat->s_bau_reenabled++; | ||
827 | baudisabled = 0; | ||
828 | for_each_present_cpu(tcpu) { | ||
829 | tbcp = &per_cpu(bau_control, tcpu); | ||
830 | tbcp->baudisabled = 0; | ||
831 | tbcp->period_requests = 0; | ||
832 | tbcp->period_time = 0; | ||
660 | } | 833 | } |
834 | return 0; | ||
661 | } | 835 | } |
836 | } | ||
837 | return -1; | ||
838 | } | ||
839 | |||
840 | static void record_send_statistics(struct ptc_stats *stat, int locals, int hubs, | ||
841 | int remotes, struct bau_desc *bau_desc) | ||
842 | { | ||
843 | stat->s_requestor++; | ||
844 | stat->s_ntargcpu += remotes + locals; | ||
845 | stat->s_ntargremotes += remotes; | ||
846 | stat->s_ntarglocals += locals; | ||
847 | |||
848 | /* uvhub statistics */ | ||
849 | hubs = bau_uvhub_weight(&bau_desc->distribution); | ||
850 | if (locals) { | ||
851 | stat->s_ntarglocaluvhub++; | ||
852 | stat->s_ntargremoteuvhub += (hubs - 1); | ||
662 | } else | 853 | } else |
663 | stat->s_requestor--; | 854 | stat->s_ntargremoteuvhub += hubs; |
664 | if (completion_status == FLUSH_COMPLETE && try > 1) | 855 | |
665 | stat->s_retriesok++; | 856 | stat->s_ntarguvhub += hubs; |
666 | else if (completion_status == FLUSH_GIVEUP) { | 857 | |
667 | stat->s_giveup++; | 858 | if (hubs >= 16) |
668 | return 1; | 859 | stat->s_ntarguvhub16++; |
860 | else if (hubs >= 8) | ||
861 | stat->s_ntarguvhub8++; | ||
862 | else if (hubs >= 4) | ||
863 | stat->s_ntarguvhub4++; | ||
864 | else if (hubs >= 2) | ||
865 | stat->s_ntarguvhub2++; | ||
866 | else | ||
867 | stat->s_ntarguvhub1++; | ||
868 | } | ||
869 | |||
870 | /* | ||
871 | * Translate a cpu mask to the uvhub distribution mask in the BAU | ||
872 | * activation descriptor. | ||
873 | */ | ||
874 | static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp, | ||
875 | struct bau_desc *bau_desc, int *localsp, int *remotesp) | ||
876 | { | ||
877 | int cpu; | ||
878 | int pnode; | ||
879 | int cnt = 0; | ||
880 | struct hub_and_pnode *hpp; | ||
881 | |||
882 | for_each_cpu(cpu, flush_mask) { | ||
883 | /* | ||
884 | * The distribution vector is a bit map of pnodes, relative | ||
885 | * to the partition base pnode (and the partition base nasid | ||
886 | * in the header). | ||
887 | * Translate cpu to pnode and hub using a local memory array. | ||
888 | */ | ||
889 | hpp = &bcp->socket_master->thp[cpu]; | ||
890 | pnode = hpp->pnode - bcp->partition_base_pnode; | ||
891 | bau_uvhub_set(pnode, &bau_desc->distribution); | ||
892 | cnt++; | ||
893 | if (hpp->uvhub == bcp->uvhub) | ||
894 | (*localsp)++; | ||
895 | else | ||
896 | (*remotesp)++; | ||
669 | } | 897 | } |
898 | if (!cnt) | ||
899 | return 1; | ||
670 | return 0; | 900 | return 0; |
671 | } | 901 | } |
672 | 902 | ||
673 | /** | 903 | /* |
674 | * uv_flush_tlb_others - globally purge translation cache of a virtual | 904 | * globally purge translation cache of a virtual address or all TLB's |
675 | * address or all TLB's | ||
676 | * @cpumask: mask of all cpu's in which the address is to be removed | 905 | * @cpumask: mask of all cpu's in which the address is to be removed |
677 | * @mm: mm_struct containing virtual address range | 906 | * @mm: mm_struct containing virtual address range |
678 | * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu) | 907 | * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu) |
@@ -696,20 +925,16 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc, | |||
696 | * done. The returned pointer is valid till preemption is re-enabled. | 925 | * done. The returned pointer is valid till preemption is re-enabled. |
697 | */ | 926 | */ |
698 | const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | 927 | const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, |
699 | struct mm_struct *mm, | 928 | struct mm_struct *mm, unsigned long va, |
700 | unsigned long va, unsigned int cpu) | 929 | unsigned int cpu) |
701 | { | 930 | { |
702 | int locals = 0; | 931 | int locals = 0; |
703 | int remotes = 0; | 932 | int remotes = 0; |
704 | int hubs = 0; | 933 | int hubs = 0; |
705 | int tcpu; | ||
706 | int tpnode; | ||
707 | struct bau_desc *bau_desc; | 934 | struct bau_desc *bau_desc; |
708 | struct cpumask *flush_mask; | 935 | struct cpumask *flush_mask; |
709 | struct ptc_stats *stat; | 936 | struct ptc_stats *stat; |
710 | struct bau_control *bcp; | 937 | struct bau_control *bcp; |
711 | struct bau_control *tbcp; | ||
712 | struct hub_and_pnode *hpp; | ||
713 | 938 | ||
714 | /* kernel was booted 'nobau' */ | 939 | /* kernel was booted 'nobau' */ |
715 | if (nobau) | 940 | if (nobau) |
@@ -720,20 +945,8 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
720 | 945 | ||
721 | /* bau was disabled due to slow response */ | 946 | /* bau was disabled due to slow response */ |
722 | if (bcp->baudisabled) { | 947 | if (bcp->baudisabled) { |
723 | /* the cpu that disabled it must re-enable it */ | 948 | if (check_enable(bcp, stat)) |
724 | if (bcp->set_bau_off) { | 949 | return cpumask; |
725 | if (get_cycles() >= bcp->set_bau_on_time) { | ||
726 | stat->s_bau_reenabled++; | ||
727 | baudisabled = 0; | ||
728 | for_each_present_cpu(tcpu) { | ||
729 | tbcp = &per_cpu(bau_control, tcpu); | ||
730 | tbcp->baudisabled = 0; | ||
731 | tbcp->period_requests = 0; | ||
732 | tbcp->period_time = 0; | ||
733 | } | ||
734 | } | ||
735 | } | ||
736 | return cpumask; | ||
737 | } | 950 | } |
738 | 951 | ||
739 | /* | 952 | /* |
@@ -744,59 +957,20 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
744 | flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu); | 957 | flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu); |
745 | /* don't actually do a shootdown of the local cpu */ | 958 | /* don't actually do a shootdown of the local cpu */ |
746 | cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); | 959 | cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); |
960 | |||
747 | if (cpu_isset(cpu, *cpumask)) | 961 | if (cpu_isset(cpu, *cpumask)) |
748 | stat->s_ntargself++; | 962 | stat->s_ntargself++; |
749 | 963 | ||
750 | bau_desc = bcp->descriptor_base; | 964 | bau_desc = bcp->descriptor_base; |
751 | bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu; | 965 | bau_desc += ITEMS_PER_DESC * bcp->uvhub_cpu; |
752 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); | 966 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); |
753 | 967 | if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) | |
754 | for_each_cpu(tcpu, flush_mask) { | ||
755 | /* | ||
756 | * The distribution vector is a bit map of pnodes, relative | ||
757 | * to the partition base pnode (and the partition base nasid | ||
758 | * in the header). | ||
759 | * Translate cpu to pnode and hub using an array stored | ||
760 | * in local memory. | ||
761 | */ | ||
762 | hpp = &bcp->socket_master->target_hub_and_pnode[tcpu]; | ||
763 | tpnode = hpp->pnode - bcp->partition_base_pnode; | ||
764 | bau_uvhub_set(tpnode, &bau_desc->distribution); | ||
765 | if (hpp->uvhub == bcp->uvhub) | ||
766 | locals++; | ||
767 | else | ||
768 | remotes++; | ||
769 | } | ||
770 | if ((locals + remotes) == 0) | ||
771 | return NULL; | 968 | return NULL; |
772 | stat->s_requestor++; | ||
773 | stat->s_ntargcpu += remotes + locals; | ||
774 | stat->s_ntargremotes += remotes; | ||
775 | stat->s_ntarglocals += locals; | ||
776 | remotes = bau_uvhub_weight(&bau_desc->distribution); | ||
777 | 969 | ||
778 | /* uvhub statistics */ | 970 | record_send_statistics(stat, locals, hubs, remotes, bau_desc); |
779 | hubs = bau_uvhub_weight(&bau_desc->distribution); | ||
780 | if (locals) { | ||
781 | stat->s_ntarglocaluvhub++; | ||
782 | stat->s_ntargremoteuvhub += (hubs - 1); | ||
783 | } else | ||
784 | stat->s_ntargremoteuvhub += hubs; | ||
785 | stat->s_ntarguvhub += hubs; | ||
786 | if (hubs >= 16) | ||
787 | stat->s_ntarguvhub16++; | ||
788 | else if (hubs >= 8) | ||
789 | stat->s_ntarguvhub8++; | ||
790 | else if (hubs >= 4) | ||
791 | stat->s_ntarguvhub4++; | ||
792 | else if (hubs >= 2) | ||
793 | stat->s_ntarguvhub2++; | ||
794 | else | ||
795 | stat->s_ntarguvhub1++; | ||
796 | 971 | ||
797 | bau_desc->payload.address = va; | 972 | bau_desc->payload.address = va; |
798 | bau_desc->payload.sending_cpu = cpu; | 973 | bau_desc->payload.sending_cpu = cpu; |
799 | |||
800 | /* | 974 | /* |
801 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, | 975 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, |
802 | * or 1 if it gave up and the original cpumask should be returned. | 976 | * or 1 if it gave up and the original cpumask should be returned. |
@@ -825,26 +999,31 @@ void uv_bau_message_interrupt(struct pt_regs *regs) | |||
825 | { | 999 | { |
826 | int count = 0; | 1000 | int count = 0; |
827 | cycles_t time_start; | 1001 | cycles_t time_start; |
828 | struct bau_payload_queue_entry *msg; | 1002 | struct bau_pq_entry *msg; |
829 | struct bau_control *bcp; | 1003 | struct bau_control *bcp; |
830 | struct ptc_stats *stat; | 1004 | struct ptc_stats *stat; |
831 | struct msg_desc msgdesc; | 1005 | struct msg_desc msgdesc; |
832 | 1006 | ||
833 | time_start = get_cycles(); | 1007 | time_start = get_cycles(); |
1008 | |||
834 | bcp = &per_cpu(bau_control, smp_processor_id()); | 1009 | bcp = &per_cpu(bau_control, smp_processor_id()); |
835 | stat = bcp->statp; | 1010 | stat = bcp->statp; |
836 | msgdesc.va_queue_first = bcp->va_queue_first; | 1011 | |
837 | msgdesc.va_queue_last = bcp->va_queue_last; | 1012 | msgdesc.queue_first = bcp->queue_first; |
1013 | msgdesc.queue_last = bcp->queue_last; | ||
1014 | |||
838 | msg = bcp->bau_msg_head; | 1015 | msg = bcp->bau_msg_head; |
839 | while (msg->sw_ack_vector) { | 1016 | while (msg->swack_vec) { |
840 | count++; | 1017 | count++; |
841 | msgdesc.msg_slot = msg - msgdesc.va_queue_first; | 1018 | |
842 | msgdesc.sw_ack_slot = ffs(msg->sw_ack_vector) - 1; | 1019 | msgdesc.msg_slot = msg - msgdesc.queue_first; |
1020 | msgdesc.swack_slot = ffs(msg->swack_vec) - 1; | ||
843 | msgdesc.msg = msg; | 1021 | msgdesc.msg = msg; |
844 | uv_bau_process_message(&msgdesc, bcp); | 1022 | bau_process_message(&msgdesc, bcp); |
1023 | |||
845 | msg++; | 1024 | msg++; |
846 | if (msg > msgdesc.va_queue_last) | 1025 | if (msg > msgdesc.queue_last) |
847 | msg = msgdesc.va_queue_first; | 1026 | msg = msgdesc.queue_first; |
848 | bcp->bau_msg_head = msg; | 1027 | bcp->bau_msg_head = msg; |
849 | } | 1028 | } |
850 | stat->d_time += (get_cycles() - time_start); | 1029 | stat->d_time += (get_cycles() - time_start); |
@@ -852,18 +1031,17 @@ void uv_bau_message_interrupt(struct pt_regs *regs) | |||
852 | stat->d_nomsg++; | 1031 | stat->d_nomsg++; |
853 | else if (count > 1) | 1032 | else if (count > 1) |
854 | stat->d_multmsg++; | 1033 | stat->d_multmsg++; |
1034 | |||
855 | ack_APIC_irq(); | 1035 | ack_APIC_irq(); |
856 | } | 1036 | } |
857 | 1037 | ||
858 | /* | 1038 | /* |
859 | * uv_enable_timeouts | 1039 | * Each target uvhub (i.e. a uvhub that has cpu's) needs to have |
860 | * | ||
861 | * Each target uvhub (i.e. a uvhub that has no cpu's) needs to have | ||
862 | * shootdown message timeouts enabled. The timeout does not cause | 1040 | * shootdown message timeouts enabled. The timeout does not cause |
863 | * an interrupt, but causes an error message to be returned to | 1041 | * an interrupt, but causes an error message to be returned to |
864 | * the sender. | 1042 | * the sender. |
865 | */ | 1043 | */ |
866 | static void __init uv_enable_timeouts(void) | 1044 | static void __init enable_timeouts(void) |
867 | { | 1045 | { |
868 | int uvhub; | 1046 | int uvhub; |
869 | int nuvhubs; | 1047 | int nuvhubs; |
@@ -877,47 +1055,44 @@ static void __init uv_enable_timeouts(void) | |||
877 | continue; | 1055 | continue; |
878 | 1056 | ||
879 | pnode = uv_blade_to_pnode(uvhub); | 1057 | pnode = uv_blade_to_pnode(uvhub); |
880 | mmr_image = | 1058 | mmr_image = read_mmr_misc_control(pnode); |
881 | uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL); | ||
882 | /* | 1059 | /* |
883 | * Set the timeout period and then lock it in, in three | 1060 | * Set the timeout period and then lock it in, in three |
884 | * steps; captures and locks in the period. | 1061 | * steps; captures and locks in the period. |
885 | * | 1062 | * |
886 | * To program the period, the SOFT_ACK_MODE must be off. | 1063 | * To program the period, the SOFT_ACK_MODE must be off. |
887 | */ | 1064 | */ |
888 | mmr_image &= ~((unsigned long)1 << | 1065 | mmr_image &= ~(1L << SOFTACK_MSHIFT); |
889 | UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT); | 1066 | write_mmr_misc_control(pnode, mmr_image); |
890 | uv_write_global_mmr64 | ||
891 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
892 | /* | 1067 | /* |
893 | * Set the 4-bit period. | 1068 | * Set the 4-bit period. |
894 | */ | 1069 | */ |
895 | mmr_image &= ~((unsigned long)0xf << | 1070 | mmr_image &= ~((unsigned long)0xf << SOFTACK_PSHIFT); |
896 | UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT); | 1071 | mmr_image |= (SOFTACK_TIMEOUT_PERIOD << SOFTACK_PSHIFT); |
897 | mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD << | 1072 | write_mmr_misc_control(pnode, mmr_image); |
898 | UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT); | ||
899 | uv_write_global_mmr64 | ||
900 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
901 | /* | 1073 | /* |
1074 | * UV1: | ||
902 | * Subsequent reversals of the timebase bit (3) cause an | 1075 | * Subsequent reversals of the timebase bit (3) cause an |
903 | * immediate timeout of one or all INTD resources as | 1076 | * immediate timeout of one or all INTD resources as |
904 | * indicated in bits 2:0 (7 causes all of them to timeout). | 1077 | * indicated in bits 2:0 (7 causes all of them to timeout). |
905 | */ | 1078 | */ |
906 | mmr_image |= ((unsigned long)1 << | 1079 | mmr_image |= (1L << SOFTACK_MSHIFT); |
907 | UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT); | 1080 | if (is_uv2_hub()) { |
908 | uv_write_global_mmr64 | 1081 | mmr_image |= (1L << UV2_LEG_SHFT); |
909 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | 1082 | mmr_image |= (1L << UV2_EXT_SHFT); |
1083 | } | ||
1084 | write_mmr_misc_control(pnode, mmr_image); | ||
910 | } | 1085 | } |
911 | } | 1086 | } |
912 | 1087 | ||
913 | static void *uv_ptc_seq_start(struct seq_file *file, loff_t *offset) | 1088 | static void *ptc_seq_start(struct seq_file *file, loff_t *offset) |
914 | { | 1089 | { |
915 | if (*offset < num_possible_cpus()) | 1090 | if (*offset < num_possible_cpus()) |
916 | return offset; | 1091 | return offset; |
917 | return NULL; | 1092 | return NULL; |
918 | } | 1093 | } |
919 | 1094 | ||
920 | static void *uv_ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) | 1095 | static void *ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) |
921 | { | 1096 | { |
922 | (*offset)++; | 1097 | (*offset)++; |
923 | if (*offset < num_possible_cpus()) | 1098 | if (*offset < num_possible_cpus()) |
@@ -925,12 +1100,11 @@ static void *uv_ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) | |||
925 | return NULL; | 1100 | return NULL; |
926 | } | 1101 | } |
927 | 1102 | ||
928 | static void uv_ptc_seq_stop(struct seq_file *file, void *data) | 1103 | static void ptc_seq_stop(struct seq_file *file, void *data) |
929 | { | 1104 | { |
930 | } | 1105 | } |
931 | 1106 | ||
932 | static inline unsigned long long | 1107 | static inline unsigned long long usec_2_cycles(unsigned long microsec) |
933 | microsec_2_cycles(unsigned long microsec) | ||
934 | { | 1108 | { |
935 | unsigned long ns; | 1109 | unsigned long ns; |
936 | unsigned long long cyc; | 1110 | unsigned long long cyc; |
@@ -941,29 +1115,27 @@ microsec_2_cycles(unsigned long microsec) | |||
941 | } | 1115 | } |
942 | 1116 | ||
943 | /* | 1117 | /* |
944 | * Display the statistics thru /proc. | 1118 | * Display the statistics thru /proc/sgi_uv/ptc_statistics |
945 | * 'data' points to the cpu number | 1119 | * 'data' points to the cpu number |
1120 | * Note: see the descriptions in stat_description[]. | ||
946 | */ | 1121 | */ |
947 | static int uv_ptc_seq_show(struct seq_file *file, void *data) | 1122 | static int ptc_seq_show(struct seq_file *file, void *data) |
948 | { | 1123 | { |
949 | struct ptc_stats *stat; | 1124 | struct ptc_stats *stat; |
950 | int cpu; | 1125 | int cpu; |
951 | 1126 | ||
952 | cpu = *(loff_t *)data; | 1127 | cpu = *(loff_t *)data; |
953 | |||
954 | if (!cpu) { | 1128 | if (!cpu) { |
955 | seq_printf(file, | 1129 | seq_printf(file, |
956 | "# cpu sent stime self locals remotes ncpus localhub "); | 1130 | "# cpu sent stime self locals remotes ncpus localhub "); |
957 | seq_printf(file, | 1131 | seq_printf(file, |
958 | "remotehub numuvhubs numuvhubs16 numuvhubs8 "); | 1132 | "remotehub numuvhubs numuvhubs16 numuvhubs8 "); |
959 | seq_printf(file, | 1133 | seq_printf(file, |
960 | "numuvhubs4 numuvhubs2 numuvhubs1 dto "); | 1134 | "numuvhubs4 numuvhubs2 numuvhubs1 dto retries rok "); |
961 | seq_printf(file, | ||
962 | "retries rok resetp resett giveup sto bz throt "); | ||
963 | seq_printf(file, | 1135 | seq_printf(file, |
964 | "sw_ack recv rtime all "); | 1136 | "resetp resett giveup sto bz throt swack recv rtime "); |
965 | seq_printf(file, | 1137 | seq_printf(file, |
966 | "one mult none retry canc nocan reset rcan "); | 1138 | "all one mult none retry canc nocan reset rcan "); |
967 | seq_printf(file, | 1139 | seq_printf(file, |
968 | "disable enable\n"); | 1140 | "disable enable\n"); |
969 | } | 1141 | } |
@@ -990,8 +1162,7 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
990 | /* destination side statistics */ | 1162 | /* destination side statistics */ |
991 | seq_printf(file, | 1163 | seq_printf(file, |
992 | "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", | 1164 | "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", |
993 | uv_read_global_mmr64(uv_cpu_to_pnode(cpu), | 1165 | read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)), |
994 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE), | ||
995 | stat->d_requestee, cycles_2_us(stat->d_time), | 1166 | stat->d_requestee, cycles_2_us(stat->d_time), |
996 | stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, | 1167 | stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, |
997 | stat->d_nomsg, stat->d_retries, stat->d_canceled, | 1168 | stat->d_nomsg, stat->d_retries, stat->d_canceled, |
@@ -1000,7 +1171,6 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
1000 | seq_printf(file, "%ld %ld\n", | 1171 | seq_printf(file, "%ld %ld\n", |
1001 | stat->s_bau_disabled, stat->s_bau_reenabled); | 1172 | stat->s_bau_disabled, stat->s_bau_reenabled); |
1002 | } | 1173 | } |
1003 | |||
1004 | return 0; | 1174 | return 0; |
1005 | } | 1175 | } |
1006 | 1176 | ||
@@ -1008,18 +1178,18 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
1008 | * Display the tunables thru debugfs | 1178 | * Display the tunables thru debugfs |
1009 | */ | 1179 | */ |
1010 | static ssize_t tunables_read(struct file *file, char __user *userbuf, | 1180 | static ssize_t tunables_read(struct file *file, char __user *userbuf, |
1011 | size_t count, loff_t *ppos) | 1181 | size_t count, loff_t *ppos) |
1012 | { | 1182 | { |
1013 | char *buf; | 1183 | char *buf; |
1014 | int ret; | 1184 | int ret; |
1015 | 1185 | ||
1016 | buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", | 1186 | buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", |
1017 | "max_bau_concurrent plugged_delay plugsb4reset", | 1187 | "max_concur plugged_delay plugsb4reset", |
1018 | "timeoutsb4reset ipi_reset_limit complete_threshold", | 1188 | "timeoutsb4reset ipi_reset_limit complete_threshold", |
1019 | "congested_response_us congested_reps congested_period", | 1189 | "congested_response_us congested_reps congested_period", |
1020 | max_bau_concurrent, plugged_delay, plugsb4reset, | 1190 | max_concurr, plugged_delay, plugsb4reset, |
1021 | timeoutsb4reset, ipi_reset_limit, complete_threshold, | 1191 | timeoutsb4reset, ipi_reset_limit, complete_threshold, |
1022 | congested_response_us, congested_reps, congested_period); | 1192 | congested_respns_us, congested_reps, congested_period); |
1023 | 1193 | ||
1024 | if (!buf) | 1194 | if (!buf) |
1025 | return -ENOMEM; | 1195 | return -ENOMEM; |
@@ -1030,13 +1200,16 @@ static ssize_t tunables_read(struct file *file, char __user *userbuf, | |||
1030 | } | 1200 | } |
1031 | 1201 | ||
1032 | /* | 1202 | /* |
1033 | * -1: resetf the statistics | 1203 | * handle a write to /proc/sgi_uv/ptc_statistics |
1204 | * -1: reset the statistics | ||
1034 | * 0: display meaning of the statistics | 1205 | * 0: display meaning of the statistics |
1035 | */ | 1206 | */ |
1036 | static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user, | 1207 | static ssize_t ptc_proc_write(struct file *file, const char __user *user, |
1037 | size_t count, loff_t *data) | 1208 | size_t count, loff_t *data) |
1038 | { | 1209 | { |
1039 | int cpu; | 1210 | int cpu; |
1211 | int i; | ||
1212 | int elements; | ||
1040 | long input_arg; | 1213 | long input_arg; |
1041 | char optstr[64]; | 1214 | char optstr[64]; |
1042 | struct ptc_stats *stat; | 1215 | struct ptc_stats *stat; |
@@ -1046,79 +1219,18 @@ static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user, | |||
1046 | if (copy_from_user(optstr, user, count)) | 1219 | if (copy_from_user(optstr, user, count)) |
1047 | return -EFAULT; | 1220 | return -EFAULT; |
1048 | optstr[count - 1] = '\0'; | 1221 | optstr[count - 1] = '\0'; |
1222 | |||
1049 | if (strict_strtol(optstr, 10, &input_arg) < 0) { | 1223 | if (strict_strtol(optstr, 10, &input_arg) < 0) { |
1050 | printk(KERN_DEBUG "%s is invalid\n", optstr); | 1224 | printk(KERN_DEBUG "%s is invalid\n", optstr); |
1051 | return -EINVAL; | 1225 | return -EINVAL; |
1052 | } | 1226 | } |
1053 | 1227 | ||
1054 | if (input_arg == 0) { | 1228 | if (input_arg == 0) { |
1229 | elements = sizeof(stat_description)/sizeof(*stat_description); | ||
1055 | printk(KERN_DEBUG "# cpu: cpu number\n"); | 1230 | printk(KERN_DEBUG "# cpu: cpu number\n"); |
1056 | printk(KERN_DEBUG "Sender statistics:\n"); | 1231 | printk(KERN_DEBUG "Sender statistics:\n"); |
1057 | printk(KERN_DEBUG | 1232 | for (i = 0; i < elements; i++) |
1058 | "sent: number of shootdown messages sent\n"); | 1233 | printk(KERN_DEBUG "%s\n", stat_description[i]); |
1059 | printk(KERN_DEBUG | ||
1060 | "stime: time spent sending messages\n"); | ||
1061 | printk(KERN_DEBUG | ||
1062 | "numuvhubs: number of hubs targeted with shootdown\n"); | ||
1063 | printk(KERN_DEBUG | ||
1064 | "numuvhubs16: number times 16 or more hubs targeted\n"); | ||
1065 | printk(KERN_DEBUG | ||
1066 | "numuvhubs8: number times 8 or more hubs targeted\n"); | ||
1067 | printk(KERN_DEBUG | ||
1068 | "numuvhubs4: number times 4 or more hubs targeted\n"); | ||
1069 | printk(KERN_DEBUG | ||
1070 | "numuvhubs2: number times 2 or more hubs targeted\n"); | ||
1071 | printk(KERN_DEBUG | ||
1072 | "numuvhubs1: number times 1 hub targeted\n"); | ||
1073 | printk(KERN_DEBUG | ||
1074 | "numcpus: number of cpus targeted with shootdown\n"); | ||
1075 | printk(KERN_DEBUG | ||
1076 | "dto: number of destination timeouts\n"); | ||
1077 | printk(KERN_DEBUG | ||
1078 | "retries: destination timeout retries sent\n"); | ||
1079 | printk(KERN_DEBUG | ||
1080 | "rok: : destination timeouts successfully retried\n"); | ||
1081 | printk(KERN_DEBUG | ||
1082 | "resetp: ipi-style resource resets for plugs\n"); | ||
1083 | printk(KERN_DEBUG | ||
1084 | "resett: ipi-style resource resets for timeouts\n"); | ||
1085 | printk(KERN_DEBUG | ||
1086 | "giveup: fall-backs to ipi-style shootdowns\n"); | ||
1087 | printk(KERN_DEBUG | ||
1088 | "sto: number of source timeouts\n"); | ||
1089 | printk(KERN_DEBUG | ||
1090 | "bz: number of stay-busy's\n"); | ||
1091 | printk(KERN_DEBUG | ||
1092 | "throt: number times spun in throttle\n"); | ||
1093 | printk(KERN_DEBUG "Destination side statistics:\n"); | ||
1094 | printk(KERN_DEBUG | ||
1095 | "sw_ack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n"); | ||
1096 | printk(KERN_DEBUG | ||
1097 | "recv: shootdown messages received\n"); | ||
1098 | printk(KERN_DEBUG | ||
1099 | "rtime: time spent processing messages\n"); | ||
1100 | printk(KERN_DEBUG | ||
1101 | "all: shootdown all-tlb messages\n"); | ||
1102 | printk(KERN_DEBUG | ||
1103 | "one: shootdown one-tlb messages\n"); | ||
1104 | printk(KERN_DEBUG | ||
1105 | "mult: interrupts that found multiple messages\n"); | ||
1106 | printk(KERN_DEBUG | ||
1107 | "none: interrupts that found no messages\n"); | ||
1108 | printk(KERN_DEBUG | ||
1109 | "retry: number of retry messages processed\n"); | ||
1110 | printk(KERN_DEBUG | ||
1111 | "canc: number messages canceled by retries\n"); | ||
1112 | printk(KERN_DEBUG | ||
1113 | "nocan: number retries that found nothing to cancel\n"); | ||
1114 | printk(KERN_DEBUG | ||
1115 | "reset: number of ipi-style reset requests processed\n"); | ||
1116 | printk(KERN_DEBUG | ||
1117 | "rcan: number messages canceled by reset requests\n"); | ||
1118 | printk(KERN_DEBUG | ||
1119 | "disable: number times use of the BAU was disabled\n"); | ||
1120 | printk(KERN_DEBUG | ||
1121 | "enable: number times use of the BAU was re-enabled\n"); | ||
1122 | } else if (input_arg == -1) { | 1234 | } else if (input_arg == -1) { |
1123 | for_each_present_cpu(cpu) { | 1235 | for_each_present_cpu(cpu) { |
1124 | stat = &per_cpu(ptcstats, cpu); | 1236 | stat = &per_cpu(ptcstats, cpu); |
@@ -1145,27 +1257,18 @@ static int local_atoi(const char *name) | |||
1145 | } | 1257 | } |
1146 | 1258 | ||
1147 | /* | 1259 | /* |
1148 | * set the tunables | 1260 | * Parse the values written to /sys/kernel/debug/sgi_uv/bau_tunables. |
1149 | * 0 values reset them to defaults | 1261 | * Zero values reset them to defaults. |
1150 | */ | 1262 | */ |
1151 | static ssize_t tunables_write(struct file *file, const char __user *user, | 1263 | static int parse_tunables_write(struct bau_control *bcp, char *instr, |
1152 | size_t count, loff_t *data) | 1264 | int count) |
1153 | { | 1265 | { |
1154 | int cpu; | ||
1155 | int cnt = 0; | ||
1156 | int val; | ||
1157 | char *p; | 1266 | char *p; |
1158 | char *q; | 1267 | char *q; |
1159 | char instr[64]; | 1268 | int cnt = 0; |
1160 | struct bau_control *bcp; | 1269 | int val; |
1161 | 1270 | int e = sizeof(tunables) / sizeof(*tunables); | |
1162 | if (count == 0 || count > sizeof(instr)-1) | ||
1163 | return -EINVAL; | ||
1164 | if (copy_from_user(instr, user, count)) | ||
1165 | return -EFAULT; | ||
1166 | 1271 | ||
1167 | instr[count] = '\0'; | ||
1168 | /* count the fields */ | ||
1169 | p = instr + strspn(instr, WHITESPACE); | 1272 | p = instr + strspn(instr, WHITESPACE); |
1170 | q = p; | 1273 | q = p; |
1171 | for (; *p; p = q + strspn(q, WHITESPACE)) { | 1274 | for (; *p; p = q + strspn(q, WHITESPACE)) { |
@@ -1174,8 +1277,8 @@ static ssize_t tunables_write(struct file *file, const char __user *user, | |||
1174 | if (q == p) | 1277 | if (q == p) |
1175 | break; | 1278 | break; |
1176 | } | 1279 | } |
1177 | if (cnt != 9) { | 1280 | if (cnt != e) { |
1178 | printk(KERN_INFO "bau tunable error: should be 9 numbers\n"); | 1281 | printk(KERN_INFO "bau tunable error: should be %d values\n", e); |
1179 | return -EINVAL; | 1282 | return -EINVAL; |
1180 | } | 1283 | } |
1181 | 1284 | ||
@@ -1187,97 +1290,80 @@ static ssize_t tunables_write(struct file *file, const char __user *user, | |||
1187 | switch (cnt) { | 1290 | switch (cnt) { |
1188 | case 0: | 1291 | case 0: |
1189 | if (val == 0) { | 1292 | if (val == 0) { |
1190 | max_bau_concurrent = MAX_BAU_CONCURRENT; | 1293 | max_concurr = MAX_BAU_CONCURRENT; |
1191 | max_bau_concurrent_constant = | 1294 | max_concurr_const = MAX_BAU_CONCURRENT; |
1192 | MAX_BAU_CONCURRENT; | ||
1193 | continue; | 1295 | continue; |
1194 | } | 1296 | } |
1195 | bcp = &per_cpu(bau_control, smp_processor_id()); | ||
1196 | if (val < 1 || val > bcp->cpus_in_uvhub) { | 1297 | if (val < 1 || val > bcp->cpus_in_uvhub) { |
1197 | printk(KERN_DEBUG | 1298 | printk(KERN_DEBUG |
1198 | "Error: BAU max concurrent %d is invalid\n", | 1299 | "Error: BAU max concurrent %d is invalid\n", |
1199 | val); | 1300 | val); |
1200 | return -EINVAL; | 1301 | return -EINVAL; |
1201 | } | 1302 | } |
1202 | max_bau_concurrent = val; | 1303 | max_concurr = val; |
1203 | max_bau_concurrent_constant = val; | 1304 | max_concurr_const = val; |
1204 | continue; | ||
1205 | case 1: | ||
1206 | if (val == 0) | ||
1207 | plugged_delay = PLUGGED_DELAY; | ||
1208 | else | ||
1209 | plugged_delay = val; | ||
1210 | continue; | ||
1211 | case 2: | ||
1212 | if (val == 0) | ||
1213 | plugsb4reset = PLUGSB4RESET; | ||
1214 | else | ||
1215 | plugsb4reset = val; | ||
1216 | continue; | ||
1217 | case 3: | ||
1218 | if (val == 0) | ||
1219 | timeoutsb4reset = TIMEOUTSB4RESET; | ||
1220 | else | ||
1221 | timeoutsb4reset = val; | ||
1222 | continue; | ||
1223 | case 4: | ||
1224 | if (val == 0) | ||
1225 | ipi_reset_limit = IPI_RESET_LIMIT; | ||
1226 | else | ||
1227 | ipi_reset_limit = val; | ||
1228 | continue; | ||
1229 | case 5: | ||
1230 | if (val == 0) | ||
1231 | complete_threshold = COMPLETE_THRESHOLD; | ||
1232 | else | ||
1233 | complete_threshold = val; | ||
1234 | continue; | ||
1235 | case 6: | ||
1236 | if (val == 0) | ||
1237 | congested_response_us = CONGESTED_RESPONSE_US; | ||
1238 | else | ||
1239 | congested_response_us = val; | ||
1240 | continue; | ||
1241 | case 7: | ||
1242 | if (val == 0) | ||
1243 | congested_reps = CONGESTED_REPS; | ||
1244 | else | ||
1245 | congested_reps = val; | ||
1246 | continue; | 1305 | continue; |
1247 | case 8: | 1306 | default: |
1248 | if (val == 0) | 1307 | if (val == 0) |
1249 | congested_period = CONGESTED_PERIOD; | 1308 | *tunables[cnt].tunp = tunables[cnt].deflt; |
1250 | else | 1309 | else |
1251 | congested_period = val; | 1310 | *tunables[cnt].tunp = val; |
1252 | continue; | 1311 | continue; |
1253 | } | 1312 | } |
1254 | if (q == p) | 1313 | if (q == p) |
1255 | break; | 1314 | break; |
1256 | } | 1315 | } |
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | /* | ||
1320 | * Handle a write to debugfs. (/sys/kernel/debug/sgi_uv/bau_tunables) | ||
1321 | */ | ||
1322 | static ssize_t tunables_write(struct file *file, const char __user *user, | ||
1323 | size_t count, loff_t *data) | ||
1324 | { | ||
1325 | int cpu; | ||
1326 | int ret; | ||
1327 | char instr[100]; | ||
1328 | struct bau_control *bcp; | ||
1329 | |||
1330 | if (count == 0 || count > sizeof(instr)-1) | ||
1331 | return -EINVAL; | ||
1332 | if (copy_from_user(instr, user, count)) | ||
1333 | return -EFAULT; | ||
1334 | |||
1335 | instr[count] = '\0'; | ||
1336 | |||
1337 | bcp = &per_cpu(bau_control, smp_processor_id()); | ||
1338 | |||
1339 | ret = parse_tunables_write(bcp, instr, count); | ||
1340 | if (ret) | ||
1341 | return ret; | ||
1342 | |||
1257 | for_each_present_cpu(cpu) { | 1343 | for_each_present_cpu(cpu) { |
1258 | bcp = &per_cpu(bau_control, cpu); | 1344 | bcp = &per_cpu(bau_control, cpu); |
1259 | bcp->max_bau_concurrent = max_bau_concurrent; | 1345 | bcp->max_concurr = max_concurr; |
1260 | bcp->max_bau_concurrent_constant = max_bau_concurrent; | 1346 | bcp->max_concurr_const = max_concurr; |
1261 | bcp->plugged_delay = plugged_delay; | 1347 | bcp->plugged_delay = plugged_delay; |
1262 | bcp->plugsb4reset = plugsb4reset; | 1348 | bcp->plugsb4reset = plugsb4reset; |
1263 | bcp->timeoutsb4reset = timeoutsb4reset; | 1349 | bcp->timeoutsb4reset = timeoutsb4reset; |
1264 | bcp->ipi_reset_limit = ipi_reset_limit; | 1350 | bcp->ipi_reset_limit = ipi_reset_limit; |
1265 | bcp->complete_threshold = complete_threshold; | 1351 | bcp->complete_threshold = complete_threshold; |
1266 | bcp->congested_response_us = congested_response_us; | 1352 | bcp->cong_response_us = congested_respns_us; |
1267 | bcp->congested_reps = congested_reps; | 1353 | bcp->cong_reps = congested_reps; |
1268 | bcp->congested_period = congested_period; | 1354 | bcp->cong_period = congested_period; |
1269 | } | 1355 | } |
1270 | return count; | 1356 | return count; |
1271 | } | 1357 | } |
1272 | 1358 | ||
1273 | static const struct seq_operations uv_ptc_seq_ops = { | 1359 | static const struct seq_operations uv_ptc_seq_ops = { |
1274 | .start = uv_ptc_seq_start, | 1360 | .start = ptc_seq_start, |
1275 | .next = uv_ptc_seq_next, | 1361 | .next = ptc_seq_next, |
1276 | .stop = uv_ptc_seq_stop, | 1362 | .stop = ptc_seq_stop, |
1277 | .show = uv_ptc_seq_show | 1363 | .show = ptc_seq_show |
1278 | }; | 1364 | }; |
1279 | 1365 | ||
1280 | static int uv_ptc_proc_open(struct inode *inode, struct file *file) | 1366 | static int ptc_proc_open(struct inode *inode, struct file *file) |
1281 | { | 1367 | { |
1282 | return seq_open(file, &uv_ptc_seq_ops); | 1368 | return seq_open(file, &uv_ptc_seq_ops); |
1283 | } | 1369 | } |
@@ -1288,9 +1374,9 @@ static int tunables_open(struct inode *inode, struct file *file) | |||
1288 | } | 1374 | } |
1289 | 1375 | ||
1290 | static const struct file_operations proc_uv_ptc_operations = { | 1376 | static const struct file_operations proc_uv_ptc_operations = { |
1291 | .open = uv_ptc_proc_open, | 1377 | .open = ptc_proc_open, |
1292 | .read = seq_read, | 1378 | .read = seq_read, |
1293 | .write = uv_ptc_proc_write, | 1379 | .write = ptc_proc_write, |
1294 | .llseek = seq_lseek, | 1380 | .llseek = seq_lseek, |
1295 | .release = seq_release, | 1381 | .release = seq_release, |
1296 | }; | 1382 | }; |
@@ -1324,7 +1410,7 @@ static int __init uv_ptc_init(void) | |||
1324 | return -EINVAL; | 1410 | return -EINVAL; |
1325 | } | 1411 | } |
1326 | tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, | 1412 | tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, |
1327 | tunables_dir, NULL, &tunables_fops); | 1413 | tunables_dir, NULL, &tunables_fops); |
1328 | if (!tunables_file) { | 1414 | if (!tunables_file) { |
1329 | printk(KERN_ERR "unable to create debugfs file %s\n", | 1415 | printk(KERN_ERR "unable to create debugfs file %s\n", |
1330 | UV_BAU_TUNABLES_FILE); | 1416 | UV_BAU_TUNABLES_FILE); |
@@ -1336,24 +1422,24 @@ static int __init uv_ptc_init(void) | |||
1336 | /* | 1422 | /* |
1337 | * Initialize the sending side's sending buffers. | 1423 | * Initialize the sending side's sending buffers. |
1338 | */ | 1424 | */ |
1339 | static void | 1425 | static void activation_descriptor_init(int node, int pnode, int base_pnode) |
1340 | uv_activation_descriptor_init(int node, int pnode, int base_pnode) | ||
1341 | { | 1426 | { |
1342 | int i; | 1427 | int i; |
1343 | int cpu; | 1428 | int cpu; |
1344 | unsigned long pa; | 1429 | unsigned long pa; |
1345 | unsigned long m; | 1430 | unsigned long m; |
1346 | unsigned long n; | 1431 | unsigned long n; |
1432 | size_t dsize; | ||
1347 | struct bau_desc *bau_desc; | 1433 | struct bau_desc *bau_desc; |
1348 | struct bau_desc *bd2; | 1434 | struct bau_desc *bd2; |
1349 | struct bau_control *bcp; | 1435 | struct bau_control *bcp; |
1350 | 1436 | ||
1351 | /* | 1437 | /* |
1352 | * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) | 1438 | * each bau_desc is 64 bytes; there are 8 (ITEMS_PER_DESC) |
1353 | * per cpu; and one per cpu on the uvhub (UV_ADP_SIZE) | 1439 | * per cpu; and one per cpu on the uvhub (ADP_SZ) |
1354 | */ | 1440 | */ |
1355 | bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE | 1441 | dsize = sizeof(struct bau_desc) * ADP_SZ * ITEMS_PER_DESC; |
1356 | * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); | 1442 | bau_desc = kmalloc_node(dsize, GFP_KERNEL, node); |
1357 | BUG_ON(!bau_desc); | 1443 | BUG_ON(!bau_desc); |
1358 | 1444 | ||
1359 | pa = uv_gpa(bau_desc); /* need the real nasid*/ | 1445 | pa = uv_gpa(bau_desc); /* need the real nasid*/ |
@@ -1361,27 +1447,25 @@ uv_activation_descriptor_init(int node, int pnode, int base_pnode) | |||
1361 | m = pa & uv_mmask; | 1447 | m = pa & uv_mmask; |
1362 | 1448 | ||
1363 | /* the 14-bit pnode */ | 1449 | /* the 14-bit pnode */ |
1364 | uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, | 1450 | write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m)); |
1365 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); | ||
1366 | /* | 1451 | /* |
1367 | * Initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each | 1452 | * Initializing all 8 (ITEMS_PER_DESC) descriptors for each |
1368 | * cpu even though we only use the first one; one descriptor can | 1453 | * cpu even though we only use the first one; one descriptor can |
1369 | * describe a broadcast to 256 uv hubs. | 1454 | * describe a broadcast to 256 uv hubs. |
1370 | */ | 1455 | */ |
1371 | for (i = 0, bd2 = bau_desc; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR); | 1456 | for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) { |
1372 | i++, bd2++) { | ||
1373 | memset(bd2, 0, sizeof(struct bau_desc)); | 1457 | memset(bd2, 0, sizeof(struct bau_desc)); |
1374 | bd2->header.sw_ack_flag = 1; | 1458 | bd2->header.swack_flag = 1; |
1375 | /* | 1459 | /* |
1376 | * The base_dest_nasid set in the message header is the nasid | 1460 | * The base_dest_nasid set in the message header is the nasid |
1377 | * of the first uvhub in the partition. The bit map will | 1461 | * of the first uvhub in the partition. The bit map will |
1378 | * indicate destination pnode numbers relative to that base. | 1462 | * indicate destination pnode numbers relative to that base. |
1379 | * They may not be consecutive if nasid striding is being used. | 1463 | * They may not be consecutive if nasid striding is being used. |
1380 | */ | 1464 | */ |
1381 | bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); | 1465 | bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); |
1382 | bd2->header.dest_subnodeid = UV_LB_SUBNODEID; | 1466 | bd2->header.dest_subnodeid = UV_LB_SUBNODEID; |
1383 | bd2->header.command = UV_NET_ENDPOINT_INTD; | 1467 | bd2->header.command = UV_NET_ENDPOINT_INTD; |
1384 | bd2->header.int_both = 1; | 1468 | bd2->header.int_both = 1; |
1385 | /* | 1469 | /* |
1386 | * all others need to be set to zero: | 1470 | * all others need to be set to zero: |
1387 | * fairness chaining multilevel count replied_to | 1471 | * fairness chaining multilevel count replied_to |
@@ -1401,57 +1485,55 @@ uv_activation_descriptor_init(int node, int pnode, int base_pnode) | |||
1401 | * - node is first node (kernel memory notion) on the uvhub | 1485 | * - node is first node (kernel memory notion) on the uvhub |
1402 | * - pnode is the uvhub's physical identifier | 1486 | * - pnode is the uvhub's physical identifier |
1403 | */ | 1487 | */ |
1404 | static void | 1488 | static void pq_init(int node, int pnode) |
1405 | uv_payload_queue_init(int node, int pnode) | ||
1406 | { | 1489 | { |
1407 | int pn; | ||
1408 | int cpu; | 1490 | int cpu; |
1491 | size_t plsize; | ||
1409 | char *cp; | 1492 | char *cp; |
1410 | unsigned long pa; | 1493 | void *vp; |
1411 | struct bau_payload_queue_entry *pqp; | 1494 | unsigned long pn; |
1412 | struct bau_payload_queue_entry *pqp_malloc; | 1495 | unsigned long first; |
1496 | unsigned long pn_first; | ||
1497 | unsigned long last; | ||
1498 | struct bau_pq_entry *pqp; | ||
1413 | struct bau_control *bcp; | 1499 | struct bau_control *bcp; |
1414 | 1500 | ||
1415 | pqp = kmalloc_node((DEST_Q_SIZE + 1) | 1501 | plsize = (DEST_Q_SIZE + 1) * sizeof(struct bau_pq_entry); |
1416 | * sizeof(struct bau_payload_queue_entry), | 1502 | vp = kmalloc_node(plsize, GFP_KERNEL, node); |
1417 | GFP_KERNEL, node); | 1503 | pqp = (struct bau_pq_entry *)vp; |
1418 | BUG_ON(!pqp); | 1504 | BUG_ON(!pqp); |
1419 | pqp_malloc = pqp; | ||
1420 | 1505 | ||
1421 | cp = (char *)pqp + 31; | 1506 | cp = (char *)pqp + 31; |
1422 | pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5); | 1507 | pqp = (struct bau_pq_entry *)(((unsigned long)cp >> 5) << 5); |
1423 | 1508 | ||
1424 | for_each_present_cpu(cpu) { | 1509 | for_each_present_cpu(cpu) { |
1425 | if (pnode != uv_cpu_to_pnode(cpu)) | 1510 | if (pnode != uv_cpu_to_pnode(cpu)) |
1426 | continue; | 1511 | continue; |
1427 | /* for every cpu on this pnode: */ | 1512 | /* for every cpu on this pnode: */ |
1428 | bcp = &per_cpu(bau_control, cpu); | 1513 | bcp = &per_cpu(bau_control, cpu); |
1429 | bcp->va_queue_first = pqp; | 1514 | bcp->queue_first = pqp; |
1430 | bcp->bau_msg_head = pqp; | 1515 | bcp->bau_msg_head = pqp; |
1431 | bcp->va_queue_last = pqp + (DEST_Q_SIZE - 1); | 1516 | bcp->queue_last = pqp + (DEST_Q_SIZE - 1); |
1432 | } | 1517 | } |
1433 | /* | 1518 | /* |
1434 | * need the pnode of where the memory was really allocated | 1519 | * need the pnode of where the memory was really allocated |
1435 | */ | 1520 | */ |
1436 | pa = uv_gpa(pqp); | 1521 | pn = uv_gpa(pqp) >> uv_nshift; |
1437 | pn = pa >> uv_nshift; | 1522 | first = uv_physnodeaddr(pqp); |
1438 | uv_write_global_mmr64(pnode, | 1523 | pn_first = ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | first; |
1439 | UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, | 1524 | last = uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)); |
1440 | ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | | 1525 | write_mmr_payload_first(pnode, pn_first); |
1441 | uv_physnodeaddr(pqp)); | 1526 | write_mmr_payload_tail(pnode, first); |
1442 | uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, | 1527 | write_mmr_payload_last(pnode, last); |
1443 | uv_physnodeaddr(pqp)); | 1528 | |
1444 | uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, | ||
1445 | (unsigned long) | ||
1446 | uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1))); | ||
1447 | /* in effect, all msg_type's are set to MSG_NOOP */ | 1529 | /* in effect, all msg_type's are set to MSG_NOOP */ |
1448 | memset(pqp, 0, sizeof(struct bau_payload_queue_entry) * DEST_Q_SIZE); | 1530 | memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE); |
1449 | } | 1531 | } |
1450 | 1532 | ||
1451 | /* | 1533 | /* |
1452 | * Initialization of each UV hub's structures | 1534 | * Initialization of each UV hub's structures |
1453 | */ | 1535 | */ |
1454 | static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode) | 1536 | static void __init init_uvhub(int uvhub, int vector, int base_pnode) |
1455 | { | 1537 | { |
1456 | int node; | 1538 | int node; |
1457 | int pnode; | 1539 | int pnode; |
@@ -1459,24 +1541,24 @@ static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode) | |||
1459 | 1541 | ||
1460 | node = uvhub_to_first_node(uvhub); | 1542 | node = uvhub_to_first_node(uvhub); |
1461 | pnode = uv_blade_to_pnode(uvhub); | 1543 | pnode = uv_blade_to_pnode(uvhub); |
1462 | uv_activation_descriptor_init(node, pnode, base_pnode); | 1544 | |
1463 | uv_payload_queue_init(node, pnode); | 1545 | activation_descriptor_init(node, pnode, base_pnode); |
1546 | |||
1547 | pq_init(node, pnode); | ||
1464 | /* | 1548 | /* |
1465 | * The below initialization can't be in firmware because the | 1549 | * The below initialization can't be in firmware because the |
1466 | * messaging IRQ will be determined by the OS. | 1550 | * messaging IRQ will be determined by the OS. |
1467 | */ | 1551 | */ |
1468 | apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits; | 1552 | apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits; |
1469 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, | 1553 | write_mmr_data_config(pnode, ((apicid << 32) | vector)); |
1470 | ((apicid << 32) | vector)); | ||
1471 | } | 1554 | } |
1472 | 1555 | ||
1473 | /* | 1556 | /* |
1474 | * We will set BAU_MISC_CONTROL with a timeout period. | 1557 | * We will set BAU_MISC_CONTROL with a timeout period. |
1475 | * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT. | 1558 | * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT. |
1476 | * So the destination timeout period has be be calculated from them. | 1559 | * So the destination timeout period has to be calculated from them. |
1477 | */ | 1560 | */ |
1478 | static int | 1561 | static int calculate_destination_timeout(void) |
1479 | calculate_destination_timeout(void) | ||
1480 | { | 1562 | { |
1481 | unsigned long mmr_image; | 1563 | unsigned long mmr_image; |
1482 | int mult1; | 1564 | int mult1; |
@@ -1486,73 +1568,92 @@ calculate_destination_timeout(void) | |||
1486 | int ret; | 1568 | int ret; |
1487 | unsigned long ts_ns; | 1569 | unsigned long ts_ns; |
1488 | 1570 | ||
1489 | mult1 = UV_INTD_SOFT_ACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK; | 1571 | if (is_uv1_hub()) { |
1490 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); | 1572 | mult1 = SOFTACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK; |
1491 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; | 1573 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); |
1492 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); | 1574 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; |
1493 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; | 1575 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); |
1494 | base = timeout_base_ns[index]; | 1576 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; |
1495 | ts_ns = base * mult1 * mult2; | 1577 | base = timeout_base_ns[index]; |
1496 | ret = ts_ns / 1000; | 1578 | ts_ns = base * mult1 * mult2; |
1579 | ret = ts_ns / 1000; | ||
1580 | } else { | ||
1581 | /* 4 bits 0/1 for 10/80us, 3 bits of multiplier */ | ||
1582 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); | ||
1583 | mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT; | ||
1584 | if (mmr_image & (1L << UV2_ACK_UNITS_SHFT)) | ||
1585 | mult1 = 80; | ||
1586 | else | ||
1587 | mult1 = 10; | ||
1588 | base = mmr_image & UV2_ACK_MASK; | ||
1589 | ret = mult1 * base; | ||
1590 | } | ||
1497 | return ret; | 1591 | return ret; |
1498 | } | 1592 | } |
1499 | 1593 | ||
1594 | static void __init init_per_cpu_tunables(void) | ||
1595 | { | ||
1596 | int cpu; | ||
1597 | struct bau_control *bcp; | ||
1598 | |||
1599 | for_each_present_cpu(cpu) { | ||
1600 | bcp = &per_cpu(bau_control, cpu); | ||
1601 | bcp->baudisabled = 0; | ||
1602 | bcp->statp = &per_cpu(ptcstats, cpu); | ||
1603 | /* time interval to catch a hardware stay-busy bug */ | ||
1604 | bcp->timeout_interval = usec_2_cycles(2*timeout_us); | ||
1605 | bcp->max_concurr = max_concurr; | ||
1606 | bcp->max_concurr_const = max_concurr; | ||
1607 | bcp->plugged_delay = plugged_delay; | ||
1608 | bcp->plugsb4reset = plugsb4reset; | ||
1609 | bcp->timeoutsb4reset = timeoutsb4reset; | ||
1610 | bcp->ipi_reset_limit = ipi_reset_limit; | ||
1611 | bcp->complete_threshold = complete_threshold; | ||
1612 | bcp->cong_response_us = congested_respns_us; | ||
1613 | bcp->cong_reps = congested_reps; | ||
1614 | bcp->cong_period = congested_period; | ||
1615 | } | ||
1616 | } | ||
1617 | |||
1500 | /* | 1618 | /* |
1501 | * initialize the bau_control structure for each cpu | 1619 | * Scan all cpus to collect blade and socket summaries. |
1502 | */ | 1620 | */ |
1503 | static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode) | 1621 | static int __init get_cpu_topology(int base_pnode, |
1622 | struct uvhub_desc *uvhub_descs, | ||
1623 | unsigned char *uvhub_mask) | ||
1504 | { | 1624 | { |
1505 | int i; | ||
1506 | int cpu; | 1625 | int cpu; |
1507 | int tcpu; | ||
1508 | int pnode; | 1626 | int pnode; |
1509 | int uvhub; | 1627 | int uvhub; |
1510 | int have_hmaster; | 1628 | int socket; |
1511 | short socket = 0; | ||
1512 | unsigned short socket_mask; | ||
1513 | unsigned char *uvhub_mask; | ||
1514 | struct bau_control *bcp; | 1629 | struct bau_control *bcp; |
1515 | struct uvhub_desc *bdp; | 1630 | struct uvhub_desc *bdp; |
1516 | struct socket_desc *sdp; | 1631 | struct socket_desc *sdp; |
1517 | struct bau_control *hmaster = NULL; | ||
1518 | struct bau_control *smaster = NULL; | ||
1519 | struct socket_desc { | ||
1520 | short num_cpus; | ||
1521 | short cpu_number[MAX_CPUS_PER_SOCKET]; | ||
1522 | }; | ||
1523 | struct uvhub_desc { | ||
1524 | unsigned short socket_mask; | ||
1525 | short num_cpus; | ||
1526 | short uvhub; | ||
1527 | short pnode; | ||
1528 | struct socket_desc socket[2]; | ||
1529 | }; | ||
1530 | struct uvhub_desc *uvhub_descs; | ||
1531 | |||
1532 | timeout_us = calculate_destination_timeout(); | ||
1533 | 1632 | ||
1534 | uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); | ||
1535 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); | ||
1536 | uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); | ||
1537 | for_each_present_cpu(cpu) { | 1633 | for_each_present_cpu(cpu) { |
1538 | bcp = &per_cpu(bau_control, cpu); | 1634 | bcp = &per_cpu(bau_control, cpu); |
1635 | |||
1539 | memset(bcp, 0, sizeof(struct bau_control)); | 1636 | memset(bcp, 0, sizeof(struct bau_control)); |
1637 | |||
1540 | pnode = uv_cpu_hub_info(cpu)->pnode; | 1638 | pnode = uv_cpu_hub_info(cpu)->pnode; |
1541 | if ((pnode - base_part_pnode) >= UV_DISTRIBUTION_SIZE) { | 1639 | if ((pnode - base_pnode) >= UV_DISTRIBUTION_SIZE) { |
1542 | printk(KERN_EMERG | 1640 | printk(KERN_EMERG |
1543 | "cpu %d pnode %d-%d beyond %d; BAU disabled\n", | 1641 | "cpu %d pnode %d-%d beyond %d; BAU disabled\n", |
1544 | cpu, pnode, base_part_pnode, | 1642 | cpu, pnode, base_pnode, UV_DISTRIBUTION_SIZE); |
1545 | UV_DISTRIBUTION_SIZE); | ||
1546 | return 1; | 1643 | return 1; |
1547 | } | 1644 | } |
1645 | |||
1548 | bcp->osnode = cpu_to_node(cpu); | 1646 | bcp->osnode = cpu_to_node(cpu); |
1549 | bcp->partition_base_pnode = uv_partition_base_pnode; | 1647 | bcp->partition_base_pnode = base_pnode; |
1648 | |||
1550 | uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; | 1649 | uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; |
1551 | *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); | 1650 | *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); |
1552 | bdp = &uvhub_descs[uvhub]; | 1651 | bdp = &uvhub_descs[uvhub]; |
1652 | |||
1553 | bdp->num_cpus++; | 1653 | bdp->num_cpus++; |
1554 | bdp->uvhub = uvhub; | 1654 | bdp->uvhub = uvhub; |
1555 | bdp->pnode = pnode; | 1655 | bdp->pnode = pnode; |
1656 | |||
1556 | /* kludge: 'assuming' one node per socket, and assuming that | 1657 | /* kludge: 'assuming' one node per socket, and assuming that |
1557 | disabling a socket just leaves a gap in node numbers */ | 1658 | disabling a socket just leaves a gap in node numbers */ |
1558 | socket = bcp->osnode & 1; | 1659 | socket = bcp->osnode & 1; |
@@ -1561,84 +1662,129 @@ static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode) | |||
1561 | sdp->cpu_number[sdp->num_cpus] = cpu; | 1662 | sdp->cpu_number[sdp->num_cpus] = cpu; |
1562 | sdp->num_cpus++; | 1663 | sdp->num_cpus++; |
1563 | if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) { | 1664 | if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) { |
1564 | printk(KERN_EMERG "%d cpus per socket invalid\n", sdp->num_cpus); | 1665 | printk(KERN_EMERG "%d cpus per socket invalid\n", |
1666 | sdp->num_cpus); | ||
1565 | return 1; | 1667 | return 1; |
1566 | } | 1668 | } |
1567 | } | 1669 | } |
1670 | return 0; | ||
1671 | } | ||
1672 | |||
1673 | /* | ||
1674 | * Each socket is to get a local array of pnodes/hubs. | ||
1675 | */ | ||
1676 | static void make_per_cpu_thp(struct bau_control *smaster) | ||
1677 | { | ||
1678 | int cpu; | ||
1679 | size_t hpsz = sizeof(struct hub_and_pnode) * num_possible_cpus(); | ||
1680 | |||
1681 | smaster->thp = kmalloc_node(hpsz, GFP_KERNEL, smaster->osnode); | ||
1682 | memset(smaster->thp, 0, hpsz); | ||
1683 | for_each_present_cpu(cpu) { | ||
1684 | smaster->thp[cpu].pnode = uv_cpu_hub_info(cpu)->pnode; | ||
1685 | smaster->thp[cpu].uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; | ||
1686 | } | ||
1687 | } | ||
1688 | |||
1689 | /* | ||
1690 | * Initialize all the per_cpu information for the cpu's on a given socket, | ||
1691 | * given what has been gathered into the socket_desc struct. | ||
1692 | * And reports the chosen hub and socket masters back to the caller. | ||
1693 | */ | ||
1694 | static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp, | ||
1695 | struct bau_control **smasterp, | ||
1696 | struct bau_control **hmasterp) | ||
1697 | { | ||
1698 | int i; | ||
1699 | int cpu; | ||
1700 | struct bau_control *bcp; | ||
1701 | |||
1702 | for (i = 0; i < sdp->num_cpus; i++) { | ||
1703 | cpu = sdp->cpu_number[i]; | ||
1704 | bcp = &per_cpu(bau_control, cpu); | ||
1705 | bcp->cpu = cpu; | ||
1706 | if (i == 0) { | ||
1707 | *smasterp = bcp; | ||
1708 | if (!(*hmasterp)) | ||
1709 | *hmasterp = bcp; | ||
1710 | } | ||
1711 | bcp->cpus_in_uvhub = bdp->num_cpus; | ||
1712 | bcp->cpus_in_socket = sdp->num_cpus; | ||
1713 | bcp->socket_master = *smasterp; | ||
1714 | bcp->uvhub = bdp->uvhub; | ||
1715 | bcp->uvhub_master = *hmasterp; | ||
1716 | bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; | ||
1717 | if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { | ||
1718 | printk(KERN_EMERG "%d cpus per uvhub invalid\n", | ||
1719 | bcp->uvhub_cpu); | ||
1720 | return 1; | ||
1721 | } | ||
1722 | } | ||
1723 | return 0; | ||
1724 | } | ||
1725 | |||
1726 | /* | ||
1727 | * Summarize the blade and socket topology into the per_cpu structures. | ||
1728 | */ | ||
1729 | static int __init summarize_uvhub_sockets(int nuvhubs, | ||
1730 | struct uvhub_desc *uvhub_descs, | ||
1731 | unsigned char *uvhub_mask) | ||
1732 | { | ||
1733 | int socket; | ||
1734 | int uvhub; | ||
1735 | unsigned short socket_mask; | ||
1736 | |||
1568 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { | 1737 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { |
1738 | struct uvhub_desc *bdp; | ||
1739 | struct bau_control *smaster = NULL; | ||
1740 | struct bau_control *hmaster = NULL; | ||
1741 | |||
1569 | if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) | 1742 | if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) |
1570 | continue; | 1743 | continue; |
1571 | have_hmaster = 0; | 1744 | |
1572 | bdp = &uvhub_descs[uvhub]; | 1745 | bdp = &uvhub_descs[uvhub]; |
1573 | socket_mask = bdp->socket_mask; | 1746 | socket_mask = bdp->socket_mask; |
1574 | socket = 0; | 1747 | socket = 0; |
1575 | while (socket_mask) { | 1748 | while (socket_mask) { |
1576 | if (!(socket_mask & 1)) | 1749 | struct socket_desc *sdp; |
1577 | goto nextsocket; | 1750 | if ((socket_mask & 1)) { |
1578 | sdp = &bdp->socket[socket]; | 1751 | sdp = &bdp->socket[socket]; |
1579 | for (i = 0; i < sdp->num_cpus; i++) { | 1752 | if (scan_sock(sdp, bdp, &smaster, &hmaster)) |
1580 | cpu = sdp->cpu_number[i]; | ||
1581 | bcp = &per_cpu(bau_control, cpu); | ||
1582 | bcp->cpu = cpu; | ||
1583 | if (i == 0) { | ||
1584 | smaster = bcp; | ||
1585 | if (!have_hmaster) { | ||
1586 | have_hmaster++; | ||
1587 | hmaster = bcp; | ||
1588 | } | ||
1589 | } | ||
1590 | bcp->cpus_in_uvhub = bdp->num_cpus; | ||
1591 | bcp->cpus_in_socket = sdp->num_cpus; | ||
1592 | bcp->socket_master = smaster; | ||
1593 | bcp->uvhub = bdp->uvhub; | ||
1594 | bcp->uvhub_master = hmaster; | ||
1595 | bcp->uvhub_cpu = uv_cpu_hub_info(cpu)-> | ||
1596 | blade_processor_id; | ||
1597 | if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { | ||
1598 | printk(KERN_EMERG | ||
1599 | "%d cpus per uvhub invalid\n", | ||
1600 | bcp->uvhub_cpu); | ||
1601 | return 1; | 1753 | return 1; |
1602 | } | ||
1603 | } | 1754 | } |
1604 | nextsocket: | ||
1605 | socket++; | 1755 | socket++; |
1606 | socket_mask = (socket_mask >> 1); | 1756 | socket_mask = (socket_mask >> 1); |
1607 | /* each socket gets a local array of pnodes/hubs */ | 1757 | make_per_cpu_thp(smaster); |
1608 | bcp = smaster; | ||
1609 | bcp->target_hub_and_pnode = kmalloc_node( | ||
1610 | sizeof(struct hub_and_pnode) * | ||
1611 | num_possible_cpus(), GFP_KERNEL, bcp->osnode); | ||
1612 | memset(bcp->target_hub_and_pnode, 0, | ||
1613 | sizeof(struct hub_and_pnode) * | ||
1614 | num_possible_cpus()); | ||
1615 | for_each_present_cpu(tcpu) { | ||
1616 | bcp->target_hub_and_pnode[tcpu].pnode = | ||
1617 | uv_cpu_hub_info(tcpu)->pnode; | ||
1618 | bcp->target_hub_and_pnode[tcpu].uvhub = | ||
1619 | uv_cpu_hub_info(tcpu)->numa_blade_id; | ||
1620 | } | ||
1621 | } | 1758 | } |
1622 | } | 1759 | } |
1760 | return 0; | ||
1761 | } | ||
1762 | |||
1763 | /* | ||
1764 | * initialize the bau_control structure for each cpu | ||
1765 | */ | ||
1766 | static int __init init_per_cpu(int nuvhubs, int base_part_pnode) | ||
1767 | { | ||
1768 | unsigned char *uvhub_mask; | ||
1769 | void *vp; | ||
1770 | struct uvhub_desc *uvhub_descs; | ||
1771 | |||
1772 | timeout_us = calculate_destination_timeout(); | ||
1773 | |||
1774 | vp = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); | ||
1775 | uvhub_descs = (struct uvhub_desc *)vp; | ||
1776 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); | ||
1777 | uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); | ||
1778 | |||
1779 | if (get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask)) | ||
1780 | return 1; | ||
1781 | |||
1782 | if (summarize_uvhub_sockets(nuvhubs, uvhub_descs, uvhub_mask)) | ||
1783 | return 1; | ||
1784 | |||
1623 | kfree(uvhub_descs); | 1785 | kfree(uvhub_descs); |
1624 | kfree(uvhub_mask); | 1786 | kfree(uvhub_mask); |
1625 | for_each_present_cpu(cpu) { | 1787 | init_per_cpu_tunables(); |
1626 | bcp = &per_cpu(bau_control, cpu); | ||
1627 | bcp->baudisabled = 0; | ||
1628 | bcp->statp = &per_cpu(ptcstats, cpu); | ||
1629 | /* time interval to catch a hardware stay-busy bug */ | ||
1630 | bcp->timeout_interval = microsec_2_cycles(2*timeout_us); | ||
1631 | bcp->max_bau_concurrent = max_bau_concurrent; | ||
1632 | bcp->max_bau_concurrent_constant = max_bau_concurrent; | ||
1633 | bcp->plugged_delay = plugged_delay; | ||
1634 | bcp->plugsb4reset = plugsb4reset; | ||
1635 | bcp->timeoutsb4reset = timeoutsb4reset; | ||
1636 | bcp->ipi_reset_limit = ipi_reset_limit; | ||
1637 | bcp->complete_threshold = complete_threshold; | ||
1638 | bcp->congested_response_us = congested_response_us; | ||
1639 | bcp->congested_reps = congested_reps; | ||
1640 | bcp->congested_period = congested_period; | ||
1641 | } | ||
1642 | return 0; | 1788 | return 0; |
1643 | } | 1789 | } |
1644 | 1790 | ||
@@ -1651,8 +1797,9 @@ static int __init uv_bau_init(void) | |||
1651 | int pnode; | 1797 | int pnode; |
1652 | int nuvhubs; | 1798 | int nuvhubs; |
1653 | int cur_cpu; | 1799 | int cur_cpu; |
1800 | int cpus; | ||
1654 | int vector; | 1801 | int vector; |
1655 | unsigned long mmr; | 1802 | cpumask_var_t *mask; |
1656 | 1803 | ||
1657 | if (!is_uv_system()) | 1804 | if (!is_uv_system()) |
1658 | return 0; | 1805 | return 0; |
@@ -1660,24 +1807,25 @@ static int __init uv_bau_init(void) | |||
1660 | if (nobau) | 1807 | if (nobau) |
1661 | return 0; | 1808 | return 0; |
1662 | 1809 | ||
1663 | for_each_possible_cpu(cur_cpu) | 1810 | for_each_possible_cpu(cur_cpu) { |
1664 | zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu), | 1811 | mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); |
1665 | GFP_KERNEL, cpu_to_node(cur_cpu)); | 1812 | zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); |
1813 | } | ||
1666 | 1814 | ||
1667 | uv_nshift = uv_hub_info->m_val; | 1815 | uv_nshift = uv_hub_info->m_val; |
1668 | uv_mmask = (1UL << uv_hub_info->m_val) - 1; | 1816 | uv_mmask = (1UL << uv_hub_info->m_val) - 1; |
1669 | nuvhubs = uv_num_possible_blades(); | 1817 | nuvhubs = uv_num_possible_blades(); |
1670 | spin_lock_init(&disable_lock); | 1818 | spin_lock_init(&disable_lock); |
1671 | congested_cycles = microsec_2_cycles(congested_response_us); | 1819 | congested_cycles = usec_2_cycles(congested_respns_us); |
1672 | 1820 | ||
1673 | uv_partition_base_pnode = 0x7fffffff; | 1821 | uv_base_pnode = 0x7fffffff; |
1674 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { | 1822 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { |
1675 | if (uv_blade_nr_possible_cpus(uvhub) && | 1823 | cpus = uv_blade_nr_possible_cpus(uvhub); |
1676 | (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode)) | 1824 | if (cpus && (uv_blade_to_pnode(uvhub) < uv_base_pnode)) |
1677 | uv_partition_base_pnode = uv_blade_to_pnode(uvhub); | 1825 | uv_base_pnode = uv_blade_to_pnode(uvhub); |
1678 | } | 1826 | } |
1679 | 1827 | ||
1680 | if (uv_init_per_cpu(nuvhubs, uv_partition_base_pnode)) { | 1828 | if (init_per_cpu(nuvhubs, uv_base_pnode)) { |
1681 | nobau = 1; | 1829 | nobau = 1; |
1682 | return 0; | 1830 | return 0; |
1683 | } | 1831 | } |
@@ -1685,21 +1833,21 @@ static int __init uv_bau_init(void) | |||
1685 | vector = UV_BAU_MESSAGE; | 1833 | vector = UV_BAU_MESSAGE; |
1686 | for_each_possible_blade(uvhub) | 1834 | for_each_possible_blade(uvhub) |
1687 | if (uv_blade_nr_possible_cpus(uvhub)) | 1835 | if (uv_blade_nr_possible_cpus(uvhub)) |
1688 | uv_init_uvhub(uvhub, vector, uv_partition_base_pnode); | 1836 | init_uvhub(uvhub, vector, uv_base_pnode); |
1689 | 1837 | ||
1690 | uv_enable_timeouts(); | 1838 | enable_timeouts(); |
1691 | alloc_intr_gate(vector, uv_bau_message_intr1); | 1839 | alloc_intr_gate(vector, uv_bau_message_intr1); |
1692 | 1840 | ||
1693 | for_each_possible_blade(uvhub) { | 1841 | for_each_possible_blade(uvhub) { |
1694 | if (uv_blade_nr_possible_cpus(uvhub)) { | 1842 | if (uv_blade_nr_possible_cpus(uvhub)) { |
1843 | unsigned long val; | ||
1844 | unsigned long mmr; | ||
1695 | pnode = uv_blade_to_pnode(uvhub); | 1845 | pnode = uv_blade_to_pnode(uvhub); |
1696 | /* INIT the bau */ | 1846 | /* INIT the bau */ |
1697 | uv_write_global_mmr64(pnode, | 1847 | val = 1L << 63; |
1698 | UVH_LB_BAU_SB_ACTIVATION_CONTROL, | 1848 | write_gmmr_activation(pnode, val); |
1699 | ((unsigned long)1 << 63)); | ||
1700 | mmr = 1; /* should be 1 to broadcast to both sockets */ | 1849 | mmr = 1; /* should be 1 to broadcast to both sockets */ |
1701 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST, | 1850 | write_mmr_data_broadcast(pnode, mmr); |
1702 | mmr); | ||
1703 | } | 1851 | } |
1704 | } | 1852 | } |
1705 | 1853 | ||
diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c index 0eb90184515f..9f29a01ee1b3 100644 --- a/arch/x86/platform/uv/uv_time.c +++ b/arch/x86/platform/uv/uv_time.c | |||
@@ -99,8 +99,12 @@ static void uv_rtc_send_IPI(int cpu) | |||
99 | /* Check for an RTC interrupt pending */ | 99 | /* Check for an RTC interrupt pending */ |
100 | static int uv_intr_pending(int pnode) | 100 | static int uv_intr_pending(int pnode) |
101 | { | 101 | { |
102 | return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) & | 102 | if (is_uv1_hub()) |
103 | UVH_EVENT_OCCURRED0_RTC1_MASK; | 103 | return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) & |
104 | UV1H_EVENT_OCCURRED0_RTC1_MASK; | ||
105 | else | ||
106 | return uv_read_global_mmr64(pnode, UV2H_EVENT_OCCURRED2) & | ||
107 | UV2H_EVENT_OCCURRED2_RTC_1_MASK; | ||
104 | } | 108 | } |
105 | 109 | ||
106 | /* Setup interrupt and return non-zero if early expiration occurred. */ | 110 | /* Setup interrupt and return non-zero if early expiration occurred. */ |
@@ -114,8 +118,12 @@ static int uv_setup_intr(int cpu, u64 expires) | |||
114 | UVH_RTC1_INT_CONFIG_M_MASK); | 118 | UVH_RTC1_INT_CONFIG_M_MASK); |
115 | uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L); | 119 | uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L); |
116 | 120 | ||
117 | uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS, | 121 | if (is_uv1_hub()) |
118 | UVH_EVENT_OCCURRED0_RTC1_MASK); | 122 | uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS, |
123 | UV1H_EVENT_OCCURRED0_RTC1_MASK); | ||
124 | else | ||
125 | uv_write_global_mmr64(pnode, UV2H_EVENT_OCCURRED2_ALIAS, | ||
126 | UV2H_EVENT_OCCURRED2_RTC_1_MASK); | ||
119 | 127 | ||
120 | val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) | | 128 | val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) | |
121 | ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT); | 129 | ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT); |
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index 528042c2951e..a6f934f37f1a 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h | |||
@@ -683,8 +683,10 @@ __SYSCALL(305, sys_ni_syscall, 0) | |||
683 | __SYSCALL(306, sys_eventfd, 1) | 683 | __SYSCALL(306, sys_eventfd, 1) |
684 | #define __NR_recvmmsg 307 | 684 | #define __NR_recvmmsg 307 |
685 | __SYSCALL(307, sys_recvmmsg, 5) | 685 | __SYSCALL(307, sys_recvmmsg, 5) |
686 | #define __NR_setns 308 | ||
687 | __SYSCALL(308, sys_setns, 2) | ||
686 | 688 | ||
687 | #define __NR_syscall_count 308 | 689 | #define __NR_syscall_count 309 |
688 | 690 | ||
689 | /* | 691 | /* |
690 | * sysxtensa syscall handler | 692 | * sysxtensa syscall handler |
diff --git a/drivers/Makefile b/drivers/Makefile index 6b17f5864340..09f3232bcdcd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -17,6 +17,9 @@ obj-$(CONFIG_SFI) += sfi/ | |||
17 | # was used and do nothing if so | 17 | # was used and do nothing if so |
18 | obj-$(CONFIG_PNP) += pnp/ | 18 | obj-$(CONFIG_PNP) += pnp/ |
19 | obj-$(CONFIG_ARM_AMBA) += amba/ | 19 | obj-$(CONFIG_ARM_AMBA) += amba/ |
20 | # Many drivers will want to use DMA so this has to be made available | ||
21 | # really early. | ||
22 | obj-$(CONFIG_DMA_ENGINE) += dma/ | ||
20 | 23 | ||
21 | obj-$(CONFIG_VIRTIO) += virtio/ | 24 | obj-$(CONFIG_VIRTIO) += virtio/ |
22 | obj-$(CONFIG_XEN) += xen/ | 25 | obj-$(CONFIG_XEN) += xen/ |
@@ -92,7 +95,6 @@ obj-$(CONFIG_EISA) += eisa/ | |||
92 | obj-y += lguest/ | 95 | obj-y += lguest/ |
93 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 96 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
94 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 97 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
95 | obj-$(CONFIG_DMA_ENGINE) += dma/ | ||
96 | obj-$(CONFIG_MMC) += mmc/ | 98 | obj-$(CONFIG_MMC) += mmc/ |
97 | obj-$(CONFIG_MEMSTICK) += memstick/ | 99 | obj-$(CONFIG_MEMSTICK) += memstick/ |
98 | obj-y += leds/ | 100 | obj-y += leds/ |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index bc2218db5ba9..de0e3df76776 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -369,6 +369,21 @@ config ACPI_HED | |||
369 | which is used to report some hardware errors notified via | 369 | which is used to report some hardware errors notified via |
370 | SCI, mainly the corrected errors. | 370 | SCI, mainly the corrected errors. |
371 | 371 | ||
372 | config ACPI_CUSTOM_METHOD | ||
373 | tristate "Allow ACPI methods to be inserted/replaced at run time" | ||
374 | depends on DEBUG_FS | ||
375 | default n | ||
376 | help | ||
377 | This debug facility allows ACPI AML methods to me inserted and/or | ||
378 | replaced without rebooting the system. For details refer to: | ||
379 | Documentation/acpi/method-customizing.txt. | ||
380 | |||
381 | NOTE: This option is security sensitive, because it allows arbitrary | ||
382 | kernel memory to be written to by root (uid=0) users, allowing them | ||
383 | to bypass certain security measures (e.g. if root is not allowed to | ||
384 | load additional kernel modules after boot, this feature may be used | ||
385 | to override that restriction). | ||
386 | |||
372 | source "drivers/acpi/apei/Kconfig" | 387 | source "drivers/acpi/apei/Kconfig" |
373 | 388 | ||
374 | endif # ACPI | 389 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index b66fbb2fc85f..ecb26b4f29a0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -61,6 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o | |||
61 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 61 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
62 | obj-$(CONFIG_ACPI_HED) += hed.o | 62 | obj-$(CONFIG_ACPI_HED) += hed.o |
63 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | 63 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o |
64 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o | ||
64 | 65 | ||
65 | # processor has its own "processor." module_param namespace | 66 | # processor has its own "processor." module_param namespace |
66 | processor-y := processor_driver.o processor_throttling.o | 67 | processor-y := processor_driver.o processor_throttling.o |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index a1224712fd0c..301bd2d388ad 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -14,7 +14,7 @@ acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ | |||
14 | 14 | ||
15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ | 15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ |
16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ | 16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ |
17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o | 17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o evglock.o |
18 | 18 | ||
19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | 19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ |
20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ | 20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index ab87396c2c07..bc533dde16c4 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -187,7 +187,6 @@ | |||
187 | 187 | ||
188 | /* Operation regions */ | 188 | /* Operation regions */ |
189 | 189 | ||
190 | #define ACPI_NUM_PREDEFINED_REGIONS 9 | ||
191 | #define ACPI_USER_REGION_BEGIN 0x80 | 190 | #define ACPI_USER_REGION_BEGIN 0x80 |
192 | 191 | ||
193 | /* Maximum space_ids for Operation Regions */ | 192 | /* Maximum space_ids for Operation Regions */ |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 41d247daf461..bea3b4899183 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -58,12 +58,6 @@ u32 acpi_ev_fixed_event_detect(void); | |||
58 | */ | 58 | */ |
59 | u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node); | 59 | u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node); |
60 | 60 | ||
61 | acpi_status acpi_ev_acquire_global_lock(u16 timeout); | ||
62 | |||
63 | acpi_status acpi_ev_release_global_lock(void); | ||
64 | |||
65 | acpi_status acpi_ev_init_global_lock_handler(void); | ||
66 | |||
67 | u32 acpi_ev_get_gpe_number_index(u32 gpe_number); | 61 | u32 acpi_ev_get_gpe_number_index(u32 gpe_number); |
68 | 62 | ||
69 | acpi_status | 63 | acpi_status |
@@ -71,6 +65,17 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, | |||
71 | u32 notify_value); | 65 | u32 notify_value); |
72 | 66 | ||
73 | /* | 67 | /* |
68 | * evglock - Global Lock support | ||
69 | */ | ||
70 | acpi_status acpi_ev_init_global_lock_handler(void); | ||
71 | |||
72 | acpi_status acpi_ev_acquire_global_lock(u16 timeout); | ||
73 | |||
74 | acpi_status acpi_ev_release_global_lock(void); | ||
75 | |||
76 | acpi_status acpi_ev_remove_global_lock_handler(void); | ||
77 | |||
78 | /* | ||
74 | * evgpe - Low-level GPE support | 79 | * evgpe - Low-level GPE support |
75 | */ | 80 | */ |
76 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); | 81 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index d69750b83b36..73863d86f022 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -214,24 +214,23 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; | |||
214 | 214 | ||
215 | /* | 215 | /* |
216 | * Global lock mutex is an actual AML mutex object | 216 | * Global lock mutex is an actual AML mutex object |
217 | * Global lock semaphore works in conjunction with the HW global lock | 217 | * Global lock semaphore works in conjunction with the actual global lock |
218 | * Global lock spinlock is used for "pending" handshake | ||
218 | */ | 219 | */ |
219 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; | 220 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; |
220 | ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; | 221 | ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; |
222 | ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock; | ||
221 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; | 223 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; |
222 | ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; | 224 | ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; |
223 | ACPI_EXTERN u8 acpi_gbl_global_lock_present; | 225 | ACPI_EXTERN u8 acpi_gbl_global_lock_present; |
226 | ACPI_EXTERN u8 acpi_gbl_global_lock_pending; | ||
224 | 227 | ||
225 | /* | 228 | /* |
226 | * Spinlocks are used for interfaces that can be possibly called at | 229 | * Spinlocks are used for interfaces that can be possibly called at |
227 | * interrupt level | 230 | * interrupt level |
228 | */ | 231 | */ |
229 | ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */ | 232 | ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */ |
230 | ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ | 233 | ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ |
231 | ACPI_EXTERN spinlock_t _acpi_ev_global_lock_pending_lock; /* For global lock */ | ||
232 | #define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock | ||
233 | #define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock | ||
234 | #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock | ||
235 | 234 | ||
236 | /***************************************************************************** | 235 | /***************************************************************************** |
237 | * | 236 | * |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index f4f0998d3967..1077f17859ed 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -394,21 +394,6 @@ | |||
394 | #define AML_CLASS_METHOD_CALL 0x09 | 394 | #define AML_CLASS_METHOD_CALL 0x09 |
395 | #define AML_CLASS_UNKNOWN 0x0A | 395 | #define AML_CLASS_UNKNOWN 0x0A |
396 | 396 | ||
397 | /* Predefined Operation Region space_iDs */ | ||
398 | |||
399 | typedef enum { | ||
400 | REGION_MEMORY = 0, | ||
401 | REGION_IO, | ||
402 | REGION_PCI_CONFIG, | ||
403 | REGION_EC, | ||
404 | REGION_SMBUS, | ||
405 | REGION_CMOS, | ||
406 | REGION_PCI_BAR, | ||
407 | REGION_IPMI, | ||
408 | REGION_DATA_TABLE, /* Internal use only */ | ||
409 | REGION_FIXED_HW = 0x7F | ||
410 | } AML_REGION_TYPES; | ||
411 | |||
412 | /* Comparison operation codes for match_op operator */ | 397 | /* Comparison operation codes for match_op operator */ |
413 | 398 | ||
414 | typedef enum { | 399 | typedef enum { |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 23a3b1ab20c1..324acec1179a 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -450,7 +450,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) | |||
450 | status = | 450 | status = |
451 | acpi_ex_create_region(op->named.data, | 451 | acpi_ex_create_region(op->named.data, |
452 | op->named.length, | 452 | op->named.length, |
453 | REGION_DATA_TABLE, | 453 | ACPI_ADR_SPACE_DATA_TABLE, |
454 | walk_state); | 454 | walk_state); |
455 | if (ACPI_FAILURE(status)) { | 455 | if (ACPI_FAILURE(status)) { |
456 | return_ACPI_STATUS(status); | 456 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 4be4e921dfe1..976318138c56 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -562,7 +562,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
562 | ((op->common.value.arg)->common.value. | 562 | ((op->common.value.arg)->common.value. |
563 | integer); | 563 | integer); |
564 | } else { | 564 | } else { |
565 | region_space = REGION_DATA_TABLE; | 565 | region_space = ACPI_ADR_SPACE_DATA_TABLE; |
566 | } | 566 | } |
567 | 567 | ||
568 | /* | 568 | /* |
diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c new file mode 100644 index 000000000000..56a562a1e5d7 --- /dev/null +++ b/drivers/acpi/acpica/evglock.c | |||
@@ -0,0 +1,335 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: evglock - Global Lock support | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acevents.h" | ||
47 | #include "acinterp.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_EVENTS | ||
50 | ACPI_MODULE_NAME("evglock") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static u32 acpi_ev_global_lock_handler(void *context); | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_ev_init_global_lock_handler | ||
58 | * | ||
59 | * PARAMETERS: None | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Install a handler for the global lock release event | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | acpi_status acpi_ev_init_global_lock_handler(void) | ||
68 | { | ||
69 | acpi_status status; | ||
70 | |||
71 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | ||
72 | |||
73 | /* Attempt installation of the global lock handler */ | ||
74 | |||
75 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
76 | acpi_ev_global_lock_handler, | ||
77 | NULL); | ||
78 | |||
79 | /* | ||
80 | * If the global lock does not exist on this platform, the attempt to | ||
81 | * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). | ||
82 | * Map to AE_OK, but mark global lock as not present. Any attempt to | ||
83 | * actually use the global lock will be flagged with an error. | ||
84 | */ | ||
85 | acpi_gbl_global_lock_present = FALSE; | ||
86 | if (status == AE_NO_HARDWARE_RESPONSE) { | ||
87 | ACPI_ERROR((AE_INFO, | ||
88 | "No response from Global Lock hardware, disabling lock")); | ||
89 | |||
90 | return_ACPI_STATUS(AE_OK); | ||
91 | } | ||
92 | |||
93 | status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | return_ACPI_STATUS(status); | ||
96 | } | ||
97 | |||
98 | acpi_gbl_global_lock_pending = FALSE; | ||
99 | acpi_gbl_global_lock_present = TRUE; | ||
100 | return_ACPI_STATUS(status); | ||
101 | } | ||
102 | |||
103 | /******************************************************************************* | ||
104 | * | ||
105 | * FUNCTION: acpi_ev_remove_global_lock_handler | ||
106 | * | ||
107 | * PARAMETERS: None | ||
108 | * | ||
109 | * RETURN: Status | ||
110 | * | ||
111 | * DESCRIPTION: Remove the handler for the Global Lock | ||
112 | * | ||
113 | ******************************************************************************/ | ||
114 | |||
115 | acpi_status acpi_ev_remove_global_lock_handler(void) | ||
116 | { | ||
117 | acpi_status status; | ||
118 | |||
119 | ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); | ||
120 | |||
121 | acpi_gbl_global_lock_present = FALSE; | ||
122 | status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
123 | acpi_ev_global_lock_handler); | ||
124 | |||
125 | return_ACPI_STATUS(status); | ||
126 | } | ||
127 | |||
128 | /******************************************************************************* | ||
129 | * | ||
130 | * FUNCTION: acpi_ev_global_lock_handler | ||
131 | * | ||
132 | * PARAMETERS: Context - From thread interface, not used | ||
133 | * | ||
134 | * RETURN: ACPI_INTERRUPT_HANDLED | ||
135 | * | ||
136 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | ||
137 | * release interrupt occurs. If there is actually a pending | ||
138 | * request for the lock, signal the waiting thread. | ||
139 | * | ||
140 | ******************************************************************************/ | ||
141 | |||
142 | static u32 acpi_ev_global_lock_handler(void *context) | ||
143 | { | ||
144 | acpi_status status; | ||
145 | acpi_cpu_flags flags; | ||
146 | |||
147 | flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); | ||
148 | |||
149 | /* | ||
150 | * If a request for the global lock is not actually pending, | ||
151 | * we are done. This handles "spurious" global lock interrupts | ||
152 | * which are possible (and have been seen) with bad BIOSs. | ||
153 | */ | ||
154 | if (!acpi_gbl_global_lock_pending) { | ||
155 | goto cleanup_and_exit; | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Send a unit to the global lock semaphore. The actual acquisition | ||
160 | * of the global lock will be performed by the waiting thread. | ||
161 | */ | ||
162 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); | ||
163 | if (ACPI_FAILURE(status)) { | ||
164 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); | ||
165 | } | ||
166 | |||
167 | acpi_gbl_global_lock_pending = FALSE; | ||
168 | |||
169 | cleanup_and_exit: | ||
170 | |||
171 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | ||
172 | return (ACPI_INTERRUPT_HANDLED); | ||
173 | } | ||
174 | |||
175 | /****************************************************************************** | ||
176 | * | ||
177 | * FUNCTION: acpi_ev_acquire_global_lock | ||
178 | * | ||
179 | * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. | ||
180 | * | ||
181 | * RETURN: Status | ||
182 | * | ||
183 | * DESCRIPTION: Attempt to gain ownership of the Global Lock. | ||
184 | * | ||
185 | * MUTEX: Interpreter must be locked | ||
186 | * | ||
187 | * Note: The original implementation allowed multiple threads to "acquire" the | ||
188 | * Global Lock, and the OS would hold the lock until the last thread had | ||
189 | * released it. However, this could potentially starve the BIOS out of the | ||
190 | * lock, especially in the case where there is a tight handshake between the | ||
191 | * Embedded Controller driver and the BIOS. Therefore, this implementation | ||
192 | * allows only one thread to acquire the HW Global Lock at a time, and makes | ||
193 | * the global lock appear as a standard mutex on the OS side. | ||
194 | * | ||
195 | *****************************************************************************/ | ||
196 | |||
197 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | ||
198 | { | ||
199 | acpi_cpu_flags flags; | ||
200 | acpi_status status; | ||
201 | u8 acquired = FALSE; | ||
202 | |||
203 | ACPI_FUNCTION_TRACE(ev_acquire_global_lock); | ||
204 | |||
205 | /* | ||
206 | * Only one thread can acquire the GL at a time, the global_lock_mutex | ||
207 | * enforces this. This interface releases the interpreter if we must wait. | ||
208 | */ | ||
209 | status = | ||
210 | acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex. | ||
211 | os_mutex, timeout); | ||
212 | if (ACPI_FAILURE(status)) { | ||
213 | return_ACPI_STATUS(status); | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Update the global lock handle and check for wraparound. The handle is | ||
218 | * only used for the external global lock interfaces, but it is updated | ||
219 | * here to properly handle the case where a single thread may acquire the | ||
220 | * lock via both the AML and the acpi_acquire_global_lock interfaces. The | ||
221 | * handle is therefore updated on the first acquire from a given thread | ||
222 | * regardless of where the acquisition request originated. | ||
223 | */ | ||
224 | acpi_gbl_global_lock_handle++; | ||
225 | if (acpi_gbl_global_lock_handle == 0) { | ||
226 | acpi_gbl_global_lock_handle = 1; | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Make sure that a global lock actually exists. If not, just | ||
231 | * treat the lock as a standard mutex. | ||
232 | */ | ||
233 | if (!acpi_gbl_global_lock_present) { | ||
234 | acpi_gbl_global_lock_acquired = TRUE; | ||
235 | return_ACPI_STATUS(AE_OK); | ||
236 | } | ||
237 | |||
238 | flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); | ||
239 | |||
240 | do { | ||
241 | |||
242 | /* Attempt to acquire the actual hardware lock */ | ||
243 | |||
244 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
245 | if (acquired) { | ||
246 | acpi_gbl_global_lock_acquired = TRUE; | ||
247 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
248 | "Acquired hardware Global Lock\n")); | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Did not get the lock. The pending bit was set above, and | ||
254 | * we must now wait until we receive the global lock | ||
255 | * released interrupt. | ||
256 | */ | ||
257 | acpi_gbl_global_lock_pending = TRUE; | ||
258 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | ||
259 | |||
260 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
261 | "Waiting for hardware Global Lock\n")); | ||
262 | |||
263 | /* | ||
264 | * Wait for handshake with the global lock interrupt handler. | ||
265 | * This interface releases the interpreter if we must wait. | ||
266 | */ | ||
267 | status = | ||
268 | acpi_ex_system_wait_semaphore | ||
269 | (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); | ||
270 | |||
271 | flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); | ||
272 | |||
273 | } while (ACPI_SUCCESS(status)); | ||
274 | |||
275 | acpi_gbl_global_lock_pending = FALSE; | ||
276 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | ||
277 | |||
278 | return_ACPI_STATUS(status); | ||
279 | } | ||
280 | |||
281 | /******************************************************************************* | ||
282 | * | ||
283 | * FUNCTION: acpi_ev_release_global_lock | ||
284 | * | ||
285 | * PARAMETERS: None | ||
286 | * | ||
287 | * RETURN: Status | ||
288 | * | ||
289 | * DESCRIPTION: Releases ownership of the Global Lock. | ||
290 | * | ||
291 | ******************************************************************************/ | ||
292 | |||
293 | acpi_status acpi_ev_release_global_lock(void) | ||
294 | { | ||
295 | u8 pending = FALSE; | ||
296 | acpi_status status = AE_OK; | ||
297 | |||
298 | ACPI_FUNCTION_TRACE(ev_release_global_lock); | ||
299 | |||
300 | /* Lock must be already acquired */ | ||
301 | |||
302 | if (!acpi_gbl_global_lock_acquired) { | ||
303 | ACPI_WARNING((AE_INFO, | ||
304 | "Cannot release the ACPI Global Lock, it has not been acquired")); | ||
305 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | ||
306 | } | ||
307 | |||
308 | if (acpi_gbl_global_lock_present) { | ||
309 | |||
310 | /* Allow any thread to release the lock */ | ||
311 | |||
312 | ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending); | ||
313 | |||
314 | /* | ||
315 | * If the pending bit was set, we must write GBL_RLS to the control | ||
316 | * register | ||
317 | */ | ||
318 | if (pending) { | ||
319 | status = | ||
320 | acpi_write_bit_register | ||
321 | (ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
322 | ACPI_ENABLE_EVENT); | ||
323 | } | ||
324 | |||
325 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
326 | "Released hardware Global Lock\n")); | ||
327 | } | ||
328 | |||
329 | acpi_gbl_global_lock_acquired = FALSE; | ||
330 | |||
331 | /* Release the local GL mutex */ | ||
332 | |||
333 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); | ||
334 | return_ACPI_STATUS(status); | ||
335 | } | ||
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 7dc80946f7bd..d0b331844427 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acevents.h" | 46 | #include "acevents.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acinterp.h" | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evmisc") | 50 | ACPI_MODULE_NAME("evmisc") |
@@ -53,10 +52,6 @@ ACPI_MODULE_NAME("evmisc") | |||
53 | /* Local prototypes */ | 52 | /* Local prototypes */ |
54 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); | 53 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); |
55 | 54 | ||
56 | static u32 acpi_ev_global_lock_handler(void *context); | ||
57 | |||
58 | static acpi_status acpi_ev_remove_global_lock_handler(void); | ||
59 | |||
60 | /******************************************************************************* | 55 | /******************************************************************************* |
61 | * | 56 | * |
62 | * FUNCTION: acpi_ev_is_notify_object | 57 | * FUNCTION: acpi_ev_is_notify_object |
@@ -275,304 +270,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
275 | acpi_ut_delete_generic_state(notify_info); | 270 | acpi_ut_delete_generic_state(notify_info); |
276 | } | 271 | } |
277 | 272 | ||
278 | /******************************************************************************* | ||
279 | * | ||
280 | * FUNCTION: acpi_ev_global_lock_handler | ||
281 | * | ||
282 | * PARAMETERS: Context - From thread interface, not used | ||
283 | * | ||
284 | * RETURN: ACPI_INTERRUPT_HANDLED | ||
285 | * | ||
286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | ||
287 | * release interrupt occurs. If there's a thread waiting for | ||
288 | * the global lock, signal it. | ||
289 | * | ||
290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | ||
291 | * this is not possible for some reason, a separate thread will have to be | ||
292 | * scheduled to do this. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | static u8 acpi_ev_global_lock_pending; | ||
296 | |||
297 | static u32 acpi_ev_global_lock_handler(void *context) | ||
298 | { | ||
299 | acpi_status status; | ||
300 | acpi_cpu_flags flags; | ||
301 | |||
302 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); | ||
303 | |||
304 | if (!acpi_ev_global_lock_pending) { | ||
305 | goto out; | ||
306 | } | ||
307 | |||
308 | /* Send a unit to the semaphore */ | ||
309 | |||
310 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); | ||
311 | if (ACPI_FAILURE(status)) { | ||
312 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); | ||
313 | } | ||
314 | |||
315 | acpi_ev_global_lock_pending = FALSE; | ||
316 | |||
317 | out: | ||
318 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
319 | |||
320 | return (ACPI_INTERRUPT_HANDLED); | ||
321 | } | ||
322 | |||
323 | /******************************************************************************* | ||
324 | * | ||
325 | * FUNCTION: acpi_ev_init_global_lock_handler | ||
326 | * | ||
327 | * PARAMETERS: None | ||
328 | * | ||
329 | * RETURN: Status | ||
330 | * | ||
331 | * DESCRIPTION: Install a handler for the global lock release event | ||
332 | * | ||
333 | ******************************************************************************/ | ||
334 | |||
335 | acpi_status acpi_ev_init_global_lock_handler(void) | ||
336 | { | ||
337 | acpi_status status; | ||
338 | |||
339 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | ||
340 | |||
341 | /* Attempt installation of the global lock handler */ | ||
342 | |||
343 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
344 | acpi_ev_global_lock_handler, | ||
345 | NULL); | ||
346 | |||
347 | /* | ||
348 | * If the global lock does not exist on this platform, the attempt to | ||
349 | * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). | ||
350 | * Map to AE_OK, but mark global lock as not present. Any attempt to | ||
351 | * actually use the global lock will be flagged with an error. | ||
352 | */ | ||
353 | if (status == AE_NO_HARDWARE_RESPONSE) { | ||
354 | ACPI_ERROR((AE_INFO, | ||
355 | "No response from Global Lock hardware, disabling lock")); | ||
356 | |||
357 | acpi_gbl_global_lock_present = FALSE; | ||
358 | return_ACPI_STATUS(AE_OK); | ||
359 | } | ||
360 | |||
361 | acpi_gbl_global_lock_present = TRUE; | ||
362 | return_ACPI_STATUS(status); | ||
363 | } | ||
364 | |||
365 | /******************************************************************************* | ||
366 | * | ||
367 | * FUNCTION: acpi_ev_remove_global_lock_handler | ||
368 | * | ||
369 | * PARAMETERS: None | ||
370 | * | ||
371 | * RETURN: Status | ||
372 | * | ||
373 | * DESCRIPTION: Remove the handler for the Global Lock | ||
374 | * | ||
375 | ******************************************************************************/ | ||
376 | |||
377 | static acpi_status acpi_ev_remove_global_lock_handler(void) | ||
378 | { | ||
379 | acpi_status status; | ||
380 | |||
381 | ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); | ||
382 | |||
383 | acpi_gbl_global_lock_present = FALSE; | ||
384 | status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
385 | acpi_ev_global_lock_handler); | ||
386 | |||
387 | return_ACPI_STATUS(status); | ||
388 | } | ||
389 | |||
390 | /****************************************************************************** | ||
391 | * | ||
392 | * FUNCTION: acpi_ev_acquire_global_lock | ||
393 | * | ||
394 | * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. | ||
395 | * | ||
396 | * RETURN: Status | ||
397 | * | ||
398 | * DESCRIPTION: Attempt to gain ownership of the Global Lock. | ||
399 | * | ||
400 | * MUTEX: Interpreter must be locked | ||
401 | * | ||
402 | * Note: The original implementation allowed multiple threads to "acquire" the | ||
403 | * Global Lock, and the OS would hold the lock until the last thread had | ||
404 | * released it. However, this could potentially starve the BIOS out of the | ||
405 | * lock, especially in the case where there is a tight handshake between the | ||
406 | * Embedded Controller driver and the BIOS. Therefore, this implementation | ||
407 | * allows only one thread to acquire the HW Global Lock at a time, and makes | ||
408 | * the global lock appear as a standard mutex on the OS side. | ||
409 | * | ||
410 | *****************************************************************************/ | ||
411 | static acpi_thread_id acpi_ev_global_lock_thread_id; | ||
412 | static int acpi_ev_global_lock_acquired; | ||
413 | |||
414 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | ||
415 | { | ||
416 | acpi_cpu_flags flags; | ||
417 | acpi_status status = AE_OK; | ||
418 | u8 acquired = FALSE; | ||
419 | |||
420 | ACPI_FUNCTION_TRACE(ev_acquire_global_lock); | ||
421 | |||
422 | /* | ||
423 | * Only one thread can acquire the GL at a time, the global_lock_mutex | ||
424 | * enforces this. This interface releases the interpreter if we must wait. | ||
425 | */ | ||
426 | status = acpi_ex_system_wait_mutex( | ||
427 | acpi_gbl_global_lock_mutex->mutex.os_mutex, 0); | ||
428 | if (status == AE_TIME) { | ||
429 | if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { | ||
430 | acpi_ev_global_lock_acquired++; | ||
431 | return AE_OK; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | if (ACPI_FAILURE(status)) { | ||
436 | status = acpi_ex_system_wait_mutex( | ||
437 | acpi_gbl_global_lock_mutex->mutex.os_mutex, | ||
438 | timeout); | ||
439 | } | ||
440 | if (ACPI_FAILURE(status)) { | ||
441 | return_ACPI_STATUS(status); | ||
442 | } | ||
443 | |||
444 | acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); | ||
445 | acpi_ev_global_lock_acquired++; | ||
446 | |||
447 | /* | ||
448 | * Update the global lock handle and check for wraparound. The handle is | ||
449 | * only used for the external global lock interfaces, but it is updated | ||
450 | * here to properly handle the case where a single thread may acquire the | ||
451 | * lock via both the AML and the acpi_acquire_global_lock interfaces. The | ||
452 | * handle is therefore updated on the first acquire from a given thread | ||
453 | * regardless of where the acquisition request originated. | ||
454 | */ | ||
455 | acpi_gbl_global_lock_handle++; | ||
456 | if (acpi_gbl_global_lock_handle == 0) { | ||
457 | acpi_gbl_global_lock_handle = 1; | ||
458 | } | ||
459 | |||
460 | /* | ||
461 | * Make sure that a global lock actually exists. If not, just treat the | ||
462 | * lock as a standard mutex. | ||
463 | */ | ||
464 | if (!acpi_gbl_global_lock_present) { | ||
465 | acpi_gbl_global_lock_acquired = TRUE; | ||
466 | return_ACPI_STATUS(AE_OK); | ||
467 | } | ||
468 | |||
469 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); | ||
470 | |||
471 | do { | ||
472 | |||
473 | /* Attempt to acquire the actual hardware lock */ | ||
474 | |||
475 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
476 | if (acquired) { | ||
477 | acpi_gbl_global_lock_acquired = TRUE; | ||
478 | |||
479 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
480 | "Acquired hardware Global Lock\n")); | ||
481 | break; | ||
482 | } | ||
483 | |||
484 | acpi_ev_global_lock_pending = TRUE; | ||
485 | |||
486 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
487 | |||
488 | /* | ||
489 | * Did not get the lock. The pending bit was set above, and we | ||
490 | * must wait until we get the global lock released interrupt. | ||
491 | */ | ||
492 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
493 | "Waiting for hardware Global Lock\n")); | ||
494 | |||
495 | /* | ||
496 | * Wait for handshake with the global lock interrupt handler. | ||
497 | * This interface releases the interpreter if we must wait. | ||
498 | */ | ||
499 | status = acpi_ex_system_wait_semaphore( | ||
500 | acpi_gbl_global_lock_semaphore, | ||
501 | ACPI_WAIT_FOREVER); | ||
502 | |||
503 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); | ||
504 | |||
505 | } while (ACPI_SUCCESS(status)); | ||
506 | |||
507 | acpi_ev_global_lock_pending = FALSE; | ||
508 | |||
509 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
510 | |||
511 | return_ACPI_STATUS(status); | ||
512 | } | ||
513 | |||
514 | /******************************************************************************* | ||
515 | * | ||
516 | * FUNCTION: acpi_ev_release_global_lock | ||
517 | * | ||
518 | * PARAMETERS: None | ||
519 | * | ||
520 | * RETURN: Status | ||
521 | * | ||
522 | * DESCRIPTION: Releases ownership of the Global Lock. | ||
523 | * | ||
524 | ******************************************************************************/ | ||
525 | |||
526 | acpi_status acpi_ev_release_global_lock(void) | ||
527 | { | ||
528 | u8 pending = FALSE; | ||
529 | acpi_status status = AE_OK; | ||
530 | |||
531 | ACPI_FUNCTION_TRACE(ev_release_global_lock); | ||
532 | |||
533 | /* Lock must be already acquired */ | ||
534 | |||
535 | if (!acpi_gbl_global_lock_acquired) { | ||
536 | ACPI_WARNING((AE_INFO, | ||
537 | "Cannot release the ACPI Global Lock, it has not been acquired")); | ||
538 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | ||
539 | } | ||
540 | |||
541 | acpi_ev_global_lock_acquired--; | ||
542 | if (acpi_ev_global_lock_acquired > 0) { | ||
543 | return AE_OK; | ||
544 | } | ||
545 | |||
546 | if (acpi_gbl_global_lock_present) { | ||
547 | |||
548 | /* Allow any thread to release the lock */ | ||
549 | |||
550 | ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending); | ||
551 | |||
552 | /* | ||
553 | * If the pending bit was set, we must write GBL_RLS to the control | ||
554 | * register | ||
555 | */ | ||
556 | if (pending) { | ||
557 | status = | ||
558 | acpi_write_bit_register | ||
559 | (ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
560 | ACPI_ENABLE_EVENT); | ||
561 | } | ||
562 | |||
563 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
564 | "Released hardware Global Lock\n")); | ||
565 | } | ||
566 | |||
567 | acpi_gbl_global_lock_acquired = FALSE; | ||
568 | |||
569 | /* Release the local GL mutex */ | ||
570 | acpi_ev_global_lock_thread_id = 0; | ||
571 | acpi_ev_global_lock_acquired = 0; | ||
572 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); | ||
573 | return_ACPI_STATUS(status); | ||
574 | } | ||
575 | |||
576 | /****************************************************************************** | 273 | /****************************************************************************** |
577 | * | 274 | * |
578 | * FUNCTION: acpi_ev_terminate | 275 | * FUNCTION: acpi_ev_terminate |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index bea7223d7a71..f0edf5c43c03 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -55,6 +55,8 @@ static u8 | |||
55 | acpi_ev_has_default_handler(struct acpi_namespace_node *node, | 55 | acpi_ev_has_default_handler(struct acpi_namespace_node *node, |
56 | acpi_adr_space_type space_id); | 56 | acpi_adr_space_type space_id); |
57 | 57 | ||
58 | static void acpi_ev_orphan_ec_reg_method(void); | ||
59 | |||
58 | static acpi_status | 60 | static acpi_status |
59 | acpi_ev_reg_run(acpi_handle obj_handle, | 61 | acpi_ev_reg_run(acpi_handle obj_handle, |
60 | u32 level, void *context, void **return_value); | 62 | u32 level, void *context, void **return_value); |
@@ -561,7 +563,9 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, | |||
561 | 563 | ||
562 | /* Now stop region accesses by executing the _REG method */ | 564 | /* Now stop region accesses by executing the _REG method */ |
563 | 565 | ||
564 | status = acpi_ev_execute_reg_method(region_obj, 0); | 566 | status = |
567 | acpi_ev_execute_reg_method(region_obj, | ||
568 | ACPI_REG_DISCONNECT); | ||
565 | if (ACPI_FAILURE(status)) { | 569 | if (ACPI_FAILURE(status)) { |
566 | ACPI_EXCEPTION((AE_INFO, status, | 570 | ACPI_EXCEPTION((AE_INFO, status, |
567 | "from region _REG, [%s]", | 571 | "from region _REG, [%s]", |
@@ -1062,6 +1066,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, | |||
1062 | ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, | 1066 | ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, |
1063 | NULL, &space_id, NULL); | 1067 | NULL, &space_id, NULL); |
1064 | 1068 | ||
1069 | /* Special case for EC: handle "orphan" _REG methods with no region */ | ||
1070 | |||
1071 | if (space_id == ACPI_ADR_SPACE_EC) { | ||
1072 | acpi_ev_orphan_ec_reg_method(); | ||
1073 | } | ||
1074 | |||
1065 | return_ACPI_STATUS(status); | 1075 | return_ACPI_STATUS(status); |
1066 | } | 1076 | } |
1067 | 1077 | ||
@@ -1120,6 +1130,113 @@ acpi_ev_reg_run(acpi_handle obj_handle, | |||
1120 | return (AE_OK); | 1130 | return (AE_OK); |
1121 | } | 1131 | } |
1122 | 1132 | ||
1123 | status = acpi_ev_execute_reg_method(obj_desc, 1); | 1133 | status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT); |
1124 | return (status); | 1134 | return (status); |
1125 | } | 1135 | } |
1136 | |||
1137 | /******************************************************************************* | ||
1138 | * | ||
1139 | * FUNCTION: acpi_ev_orphan_ec_reg_method | ||
1140 | * | ||
1141 | * PARAMETERS: None | ||
1142 | * | ||
1143 | * RETURN: None | ||
1144 | * | ||
1145 | * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC | ||
1146 | * device. This is a _REG method that has no corresponding region | ||
1147 | * within the EC device scope. The orphan _REG method appears to | ||
1148 | * have been enabled by the description of the ECDT in the ACPI | ||
1149 | * specification: "The availability of the region space can be | ||
1150 | * detected by providing a _REG method object underneath the | ||
1151 | * Embedded Controller device." | ||
1152 | * | ||
1153 | * To quickly access the EC device, we use the EC_ID that appears | ||
1154 | * within the ECDT. Otherwise, we would need to perform a time- | ||
1155 | * consuming namespace walk, executing _HID methods to find the | ||
1156 | * EC device. | ||
1157 | * | ||
1158 | ******************************************************************************/ | ||
1159 | |||
1160 | static void acpi_ev_orphan_ec_reg_method(void) | ||
1161 | { | ||
1162 | struct acpi_table_ecdt *table; | ||
1163 | acpi_status status; | ||
1164 | struct acpi_object_list args; | ||
1165 | union acpi_object objects[2]; | ||
1166 | struct acpi_namespace_node *ec_device_node; | ||
1167 | struct acpi_namespace_node *reg_method; | ||
1168 | struct acpi_namespace_node *next_node; | ||
1169 | |||
1170 | ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); | ||
1171 | |||
1172 | /* Get the ECDT (if present in system) */ | ||
1173 | |||
1174 | status = acpi_get_table(ACPI_SIG_ECDT, 0, | ||
1175 | ACPI_CAST_INDIRECT_PTR(struct acpi_table_header, | ||
1176 | &table)); | ||
1177 | if (ACPI_FAILURE(status)) { | ||
1178 | return_VOID; | ||
1179 | } | ||
1180 | |||
1181 | /* We need a valid EC_ID string */ | ||
1182 | |||
1183 | if (!(*table->id)) { | ||
1184 | return_VOID; | ||
1185 | } | ||
1186 | |||
1187 | /* Namespace is currently locked, must release */ | ||
1188 | |||
1189 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
1190 | |||
1191 | /* Get a handle to the EC device referenced in the ECDT */ | ||
1192 | |||
1193 | status = acpi_get_handle(NULL, | ||
1194 | ACPI_CAST_PTR(char, table->id), | ||
1195 | ACPI_CAST_PTR(acpi_handle, &ec_device_node)); | ||
1196 | if (ACPI_FAILURE(status)) { | ||
1197 | goto exit; | ||
1198 | } | ||
1199 | |||
1200 | /* Get a handle to a _REG method immediately under the EC device */ | ||
1201 | |||
1202 | status = acpi_get_handle(ec_device_node, | ||
1203 | METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle, | ||
1204 | ®_method)); | ||
1205 | if (ACPI_FAILURE(status)) { | ||
1206 | goto exit; | ||
1207 | } | ||
1208 | |||
1209 | /* | ||
1210 | * Execute the _REG method only if there is no Operation Region in | ||
1211 | * this scope with the Embedded Controller space ID. Otherwise, it | ||
1212 | * will already have been executed. Note, this allows for Regions | ||
1213 | * with other space IDs to be present; but the code below will then | ||
1214 | * execute the _REG method with the EC space ID argument. | ||
1215 | */ | ||
1216 | next_node = acpi_ns_get_next_node(ec_device_node, NULL); | ||
1217 | while (next_node) { | ||
1218 | if ((next_node->type == ACPI_TYPE_REGION) && | ||
1219 | (next_node->object) && | ||
1220 | (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { | ||
1221 | goto exit; /* Do not execute _REG */ | ||
1222 | } | ||
1223 | next_node = acpi_ns_get_next_node(ec_device_node, next_node); | ||
1224 | } | ||
1225 | |||
1226 | /* Evaluate the _REG(EC,Connect) method */ | ||
1227 | |||
1228 | args.count = 2; | ||
1229 | args.pointer = objects; | ||
1230 | objects[0].type = ACPI_TYPE_INTEGER; | ||
1231 | objects[0].integer.value = ACPI_ADR_SPACE_EC; | ||
1232 | objects[1].type = ACPI_TYPE_INTEGER; | ||
1233 | objects[1].integer.value = ACPI_REG_CONNECT; | ||
1234 | |||
1235 | status = acpi_evaluate_object(reg_method, NULL, &args, NULL); | ||
1236 | |||
1237 | exit: | ||
1238 | /* We ignore all errors from above, don't care */ | ||
1239 | |||
1240 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
1241 | return_VOID; | ||
1242 | } | ||
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 9659cee6093e..55a5d35ef34a 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -637,7 +637,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
637 | 637 | ||
638 | status = | 638 | status = |
639 | acpi_ev_execute_reg_method | 639 | acpi_ev_execute_reg_method |
640 | (region_obj, 1); | 640 | (region_obj, ACPI_REG_CONNECT); |
641 | 641 | ||
642 | if (acpi_ns_locked) { | 642 | if (acpi_ns_locked) { |
643 | status = | 643 | status = |
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index c85c8c45599d..00cd95692a91 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -130,20 +130,21 @@ acpi_install_address_space_handler(acpi_handle device, | |||
130 | case ACPI_ADR_SPACE_PCI_CONFIG: | 130 | case ACPI_ADR_SPACE_PCI_CONFIG: |
131 | case ACPI_ADR_SPACE_DATA_TABLE: | 131 | case ACPI_ADR_SPACE_DATA_TABLE: |
132 | 132 | ||
133 | if (acpi_gbl_reg_methods_executed) { | 133 | if (!acpi_gbl_reg_methods_executed) { |
134 | 134 | ||
135 | /* Run all _REG methods for this address space */ | 135 | /* We will defer execution of the _REG methods for this space */ |
136 | 136 | goto unlock_and_exit; | |
137 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
138 | } | 137 | } |
139 | break; | 138 | break; |
140 | 139 | ||
141 | default: | 140 | default: |
142 | |||
143 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
144 | break; | 141 | break; |
145 | } | 142 | } |
146 | 143 | ||
144 | /* Run all _REG methods for this address space */ | ||
145 | |||
146 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
147 | |||
147 | unlock_and_exit: | 148 | unlock_and_exit: |
148 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 149 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
149 | return_ACPI_STATUS(status); | 150 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index e7b372d17667..110711afada8 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -305,7 +305,8 @@ acpi_ex_create_region(u8 * aml_start, | |||
305 | * range | 305 | * range |
306 | */ | 306 | */ |
307 | if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && | 307 | if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && |
308 | (region_space < ACPI_USER_REGION_BEGIN)) { | 308 | (region_space < ACPI_USER_REGION_BEGIN) && |
309 | (region_space != ACPI_ADR_SPACE_DATA_TABLE)) { | ||
309 | ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X", | 310 | ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X", |
310 | region_space)); | 311 | region_space)); |
311 | return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); | 312 | return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 1d76ac85b5e7..ac7b854b0bd7 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -74,7 +74,6 @@ ACPI_MODULE_NAME("nsrepair") | |||
74 | * | 74 | * |
75 | * Additional possible repairs: | 75 | * Additional possible repairs: |
76 | * | 76 | * |
77 | * Optional/unnecessary NULL package elements removed | ||
78 | * Required package elements that are NULL replaced by Integer/String/Buffer | 77 | * Required package elements that are NULL replaced by Integer/String/Buffer |
79 | * Incorrect standalone package wrapped with required outer package | 78 | * Incorrect standalone package wrapped with required outer package |
80 | * | 79 | * |
@@ -623,16 +622,12 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, | |||
623 | ACPI_FUNCTION_NAME(ns_remove_null_elements); | 622 | ACPI_FUNCTION_NAME(ns_remove_null_elements); |
624 | 623 | ||
625 | /* | 624 | /* |
626 | * PTYPE1 packages contain no subpackages. | 625 | * We can safely remove all NULL elements from these package types: |
627 | * PTYPE2 packages contain a variable number of sub-packages. We can | 626 | * PTYPE1_VAR packages contain a variable number of simple data types. |
628 | * safely remove all NULL elements from the PTYPE2 packages. | 627 | * PTYPE2 packages contain a variable number of sub-packages. |
629 | */ | 628 | */ |
630 | switch (package_type) { | 629 | switch (package_type) { |
631 | case ACPI_PTYPE1_FIXED: | ||
632 | case ACPI_PTYPE1_VAR: | 630 | case ACPI_PTYPE1_VAR: |
633 | case ACPI_PTYPE1_OPTION: | ||
634 | return; | ||
635 | |||
636 | case ACPI_PTYPE2: | 631 | case ACPI_PTYPE2: |
637 | case ACPI_PTYPE2_COUNT: | 632 | case ACPI_PTYPE2_COUNT: |
638 | case ACPI_PTYPE2_PKG_COUNT: | 633 | case ACPI_PTYPE2_PKG_COUNT: |
@@ -642,6 +637,8 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, | |||
642 | break; | 637 | break; |
643 | 638 | ||
644 | default: | 639 | default: |
640 | case ACPI_PTYPE1_FIXED: | ||
641 | case ACPI_PTYPE1_OPTION: | ||
645 | return; | 642 | return; |
646 | } | 643 | } |
647 | 644 | ||
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 136a814cec69..97cb36f85ce9 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -170,8 +170,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { | |||
170 | "SMBus", | 170 | "SMBus", |
171 | "SystemCMOS", | 171 | "SystemCMOS", |
172 | "PCIBARTarget", | 172 | "PCIBARTarget", |
173 | "IPMI", | 173 | "IPMI" |
174 | "DataTable" | ||
175 | }; | 174 | }; |
176 | 175 | ||
177 | char *acpi_ut_get_region_name(u8 space_id) | 176 | char *acpi_ut_get_region_name(u8 space_id) |
@@ -179,6 +178,8 @@ char *acpi_ut_get_region_name(u8 space_id) | |||
179 | 178 | ||
180 | if (space_id >= ACPI_USER_REGION_BEGIN) { | 179 | if (space_id >= ACPI_USER_REGION_BEGIN) { |
181 | return ("UserDefinedRegion"); | 180 | return ("UserDefinedRegion"); |
181 | } else if (space_id == ACPI_ADR_SPACE_DATA_TABLE) { | ||
182 | return ("DataTable"); | ||
182 | } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { | 183 | } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { |
183 | return ("FunctionalFixedHW"); | 184 | return ("FunctionalFixedHW"); |
184 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { | 185 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index a946c689f03b..7d797e2baecd 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -83,9 +83,15 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
83 | 83 | ||
84 | /* Create the spinlocks for use at interrupt level */ | 84 | /* Create the spinlocks for use at interrupt level */ |
85 | 85 | ||
86 | spin_lock_init(acpi_gbl_gpe_lock); | 86 | status = acpi_os_create_lock (&acpi_gbl_gpe_lock); |
87 | spin_lock_init(acpi_gbl_hardware_lock); | 87 | if (ACPI_FAILURE (status)) { |
88 | spin_lock_init(acpi_ev_global_lock_pending_lock); | 88 | return_ACPI_STATUS (status); |
89 | } | ||
90 | |||
91 | status = acpi_os_create_lock (&acpi_gbl_hardware_lock); | ||
92 | if (ACPI_FAILURE (status)) { | ||
93 | return_ACPI_STATUS (status); | ||
94 | } | ||
89 | 95 | ||
90 | /* Mutex for _OSI support */ | 96 | /* Mutex for _OSI support */ |
91 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); | 97 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9749980ca6ca..d1e06c182cdb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -227,7 +227,7 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state) | |||
227 | acpi_status status = AE_OK; | 227 | acpi_status status = AE_OK; |
228 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; | 228 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; |
229 | 229 | ||
230 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 230 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) |
231 | return -EINVAL; | 231 | return -EINVAL; |
232 | 232 | ||
233 | /* Make sure this is a valid target state */ | 233 | /* Make sure this is a valid target state */ |
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c new file mode 100644 index 000000000000..5d42c2414ae5 --- /dev/null +++ b/drivers/acpi/custom_method.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * debugfs.c - ACPI debugfs interface to userspace. | ||
3 | */ | ||
4 | |||
5 | #include <linux/init.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | #include <linux/debugfs.h> | ||
10 | #include <acpi/acpi_drivers.h> | ||
11 | |||
12 | #include "internal.h" | ||
13 | |||
14 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | ||
15 | ACPI_MODULE_NAME("custom_method"); | ||
16 | MODULE_LICENSE("GPL"); | ||
17 | |||
18 | static struct dentry *cm_dentry; | ||
19 | |||
20 | /* /sys/kernel/debug/acpi/custom_method */ | ||
21 | |||
22 | static ssize_t cm_write(struct file *file, const char __user * user_buf, | ||
23 | size_t count, loff_t *ppos) | ||
24 | { | ||
25 | static char *buf; | ||
26 | static u32 max_size; | ||
27 | static u32 uncopied_bytes; | ||
28 | |||
29 | struct acpi_table_header table; | ||
30 | acpi_status status; | ||
31 | |||
32 | if (!(*ppos)) { | ||
33 | /* parse the table header to get the table length */ | ||
34 | if (count <= sizeof(struct acpi_table_header)) | ||
35 | return -EINVAL; | ||
36 | if (copy_from_user(&table, user_buf, | ||
37 | sizeof(struct acpi_table_header))) | ||
38 | return -EFAULT; | ||
39 | uncopied_bytes = max_size = table.length; | ||
40 | buf = kzalloc(max_size, GFP_KERNEL); | ||
41 | if (!buf) | ||
42 | return -ENOMEM; | ||
43 | } | ||
44 | |||
45 | if (buf == NULL) | ||
46 | return -EINVAL; | ||
47 | |||
48 | if ((*ppos > max_size) || | ||
49 | (*ppos + count > max_size) || | ||
50 | (*ppos + count < count) || | ||
51 | (count > uncopied_bytes)) | ||
52 | return -EINVAL; | ||
53 | |||
54 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
55 | kfree(buf); | ||
56 | buf = NULL; | ||
57 | return -EFAULT; | ||
58 | } | ||
59 | |||
60 | uncopied_bytes -= count; | ||
61 | *ppos += count; | ||
62 | |||
63 | if (!uncopied_bytes) { | ||
64 | status = acpi_install_method(buf); | ||
65 | kfree(buf); | ||
66 | buf = NULL; | ||
67 | if (ACPI_FAILURE(status)) | ||
68 | return -EINVAL; | ||
69 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
70 | } | ||
71 | |||
72 | return count; | ||
73 | } | ||
74 | |||
75 | static const struct file_operations cm_fops = { | ||
76 | .write = cm_write, | ||
77 | .llseek = default_llseek, | ||
78 | }; | ||
79 | |||
80 | static int __init acpi_custom_method_init(void) | ||
81 | { | ||
82 | if (acpi_debugfs_dir == NULL) | ||
83 | return -ENOENT; | ||
84 | |||
85 | cm_dentry = debugfs_create_file("custom_method", S_IWUSR, | ||
86 | acpi_debugfs_dir, NULL, &cm_fops); | ||
87 | if (cm_dentry == NULL) | ||
88 | return -ENODEV; | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void __exit acpi_custom_method_exit(void) | ||
94 | { | ||
95 | if (cm_dentry) | ||
96 | debugfs_remove(cm_dentry); | ||
97 | } | ||
98 | |||
99 | module_init(acpi_custom_method_init); | ||
100 | module_exit(acpi_custom_method_exit); | ||
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 384f7abcff77..182a9fc36355 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c | |||
@@ -3,100 +3,16 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | #include <linux/debugfs.h> | 6 | #include <linux/debugfs.h> |
10 | #include <acpi/acpi_drivers.h> | 7 | #include <acpi/acpi_drivers.h> |
11 | 8 | ||
12 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 9 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
13 | ACPI_MODULE_NAME("debugfs"); | 10 | ACPI_MODULE_NAME("debugfs"); |
14 | 11 | ||
12 | struct dentry *acpi_debugfs_dir; | ||
13 | EXPORT_SYMBOL_GPL(acpi_debugfs_dir); | ||
15 | 14 | ||
16 | /* /sys/modules/acpi/parameters/aml_debug_output */ | 15 | void __init acpi_debugfs_init(void) |
17 | |||
18 | module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, | ||
19 | bool, 0644); | ||
20 | MODULE_PARM_DESC(aml_debug_output, | ||
21 | "To enable/disable the ACPI Debug Object output."); | ||
22 | |||
23 | /* /sys/kernel/debug/acpi/custom_method */ | ||
24 | |||
25 | static ssize_t cm_write(struct file *file, const char __user * user_buf, | ||
26 | size_t count, loff_t *ppos) | ||
27 | { | 16 | { |
28 | static char *buf; | 17 | acpi_debugfs_dir = debugfs_create_dir("acpi", NULL); |
29 | static u32 max_size; | ||
30 | static u32 uncopied_bytes; | ||
31 | |||
32 | struct acpi_table_header table; | ||
33 | acpi_status status; | ||
34 | |||
35 | if (!(*ppos)) { | ||
36 | /* parse the table header to get the table length */ | ||
37 | if (count <= sizeof(struct acpi_table_header)) | ||
38 | return -EINVAL; | ||
39 | if (copy_from_user(&table, user_buf, | ||
40 | sizeof(struct acpi_table_header))) | ||
41 | return -EFAULT; | ||
42 | uncopied_bytes = max_size = table.length; | ||
43 | buf = kzalloc(max_size, GFP_KERNEL); | ||
44 | if (!buf) | ||
45 | return -ENOMEM; | ||
46 | } | ||
47 | |||
48 | if (buf == NULL) | ||
49 | return -EINVAL; | ||
50 | |||
51 | if ((*ppos > max_size) || | ||
52 | (*ppos + count > max_size) || | ||
53 | (*ppos + count < count) || | ||
54 | (count > uncopied_bytes)) | ||
55 | return -EINVAL; | ||
56 | |||
57 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
58 | kfree(buf); | ||
59 | buf = NULL; | ||
60 | return -EFAULT; | ||
61 | } | ||
62 | |||
63 | uncopied_bytes -= count; | ||
64 | *ppos += count; | ||
65 | |||
66 | if (!uncopied_bytes) { | ||
67 | status = acpi_install_method(buf); | ||
68 | kfree(buf); | ||
69 | buf = NULL; | ||
70 | if (ACPI_FAILURE(status)) | ||
71 | return -EINVAL; | ||
72 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
73 | } | ||
74 | |||
75 | return count; | ||
76 | } | ||
77 | |||
78 | static const struct file_operations cm_fops = { | ||
79 | .write = cm_write, | ||
80 | .llseek = default_llseek, | ||
81 | }; | ||
82 | |||
83 | int __init acpi_debugfs_init(void) | ||
84 | { | ||
85 | struct dentry *acpi_dir, *cm_dentry; | ||
86 | |||
87 | acpi_dir = debugfs_create_dir("acpi", NULL); | ||
88 | if (!acpi_dir) | ||
89 | goto err; | ||
90 | |||
91 | cm_dentry = debugfs_create_file("custom_method", S_IWUSR, | ||
92 | acpi_dir, NULL, &cm_fops); | ||
93 | if (!cm_dentry) | ||
94 | goto err; | ||
95 | |||
96 | return 0; | ||
97 | |||
98 | err: | ||
99 | if (acpi_dir) | ||
100 | debugfs_remove(acpi_dir); | ||
101 | return -EINVAL; | ||
102 | } | 18 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index fa848c4116a8..b19a18dd994f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -69,7 +69,6 @@ enum ec_command { | |||
69 | 69 | ||
70 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 70 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
71 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 71 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
72 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | ||
73 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | 72 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ |
74 | 73 | ||
75 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 74 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
@@ -433,8 +432,7 @@ EXPORT_SYMBOL(ec_write); | |||
433 | 432 | ||
434 | int ec_transaction(u8 command, | 433 | int ec_transaction(u8 command, |
435 | const u8 * wdata, unsigned wdata_len, | 434 | const u8 * wdata, unsigned wdata_len, |
436 | u8 * rdata, unsigned rdata_len, | 435 | u8 * rdata, unsigned rdata_len) |
437 | int force_poll) | ||
438 | { | 436 | { |
439 | struct transaction t = {.command = command, | 437 | struct transaction t = {.command = command, |
440 | .wdata = wdata, .rdata = rdata, | 438 | .wdata = wdata, .rdata = rdata, |
@@ -592,8 +590,6 @@ static void acpi_ec_gpe_query(void *ec_cxt) | |||
592 | mutex_unlock(&ec->lock); | 590 | mutex_unlock(&ec->lock); |
593 | } | 591 | } |
594 | 592 | ||
595 | static void acpi_ec_gpe_query(void *ec_cxt); | ||
596 | |||
597 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 593 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
598 | { | 594 | { |
599 | if (state & ACPI_EC_FLAG_SCI) { | 595 | if (state & ACPI_EC_FLAG_SCI) { |
@@ -808,8 +804,6 @@ static int acpi_ec_add(struct acpi_device *device) | |||
808 | return -EINVAL; | 804 | return -EINVAL; |
809 | } | 805 | } |
810 | 806 | ||
811 | ec->handle = device->handle; | ||
812 | |||
813 | /* Find and register all query methods */ | 807 | /* Find and register all query methods */ |
814 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, | 808 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, |
815 | acpi_ec_register_query_methods, NULL, ec, NULL); | 809 | acpi_ec_register_query_methods, NULL, ec, NULL); |
@@ -938,8 +932,19 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
938 | ec_flag_msi, "MSI hardware", { | 932 | ec_flag_msi, "MSI hardware", { |
939 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | 933 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, |
940 | { | 934 | { |
935 | ec_flag_msi, "Quanta hardware", { | ||
936 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | ||
937 | DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL}, | ||
938 | { | ||
939 | ec_flag_msi, "Quanta hardware", { | ||
940 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | ||
941 | DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL}, | ||
942 | { | ||
941 | ec_validate_ecdt, "ASUS hardware", { | 943 | ec_validate_ecdt, "ASUS hardware", { |
942 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 944 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
945 | { | ||
946 | ec_validate_ecdt, "ASUS hardware", { | ||
947 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL}, | ||
943 | {}, | 948 | {}, |
944 | }; | 949 | }; |
945 | 950 | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 4bfb759deb10..ca75b9ce0489 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -28,9 +28,10 @@ int acpi_scan_init(void); | |||
28 | int acpi_sysfs_init(void); | 28 | int acpi_sysfs_init(void); |
29 | 29 | ||
30 | #ifdef CONFIG_DEBUG_FS | 30 | #ifdef CONFIG_DEBUG_FS |
31 | extern struct dentry *acpi_debugfs_dir; | ||
31 | int acpi_debugfs_init(void); | 32 | int acpi_debugfs_init(void); |
32 | #else | 33 | #else |
33 | static inline int acpi_debugfs_init(void) { return 0; } | 34 | static inline void acpi_debugfs_init(void) { return; } |
34 | #endif | 35 | #endif |
35 | 36 | ||
36 | /* -------------------------------------------------------------------------- | 37 | /* -------------------------------------------------------------------------- |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 45ad4ffef533..52ca9649d769 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -902,14 +902,6 @@ void acpi_os_wait_events_complete(void *context) | |||
902 | 902 | ||
903 | EXPORT_SYMBOL(acpi_os_wait_events_complete); | 903 | EXPORT_SYMBOL(acpi_os_wait_events_complete); |
904 | 904 | ||
905 | /* | ||
906 | * Deallocate the memory for a spinlock. | ||
907 | */ | ||
908 | void acpi_os_delete_lock(acpi_spinlock handle) | ||
909 | { | ||
910 | return; | ||
911 | } | ||
912 | |||
913 | acpi_status | 905 | acpi_status |
914 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | 906 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) |
915 | { | 907 | { |
@@ -1341,6 +1333,31 @@ int acpi_resources_are_enforced(void) | |||
1341 | EXPORT_SYMBOL(acpi_resources_are_enforced); | 1333 | EXPORT_SYMBOL(acpi_resources_are_enforced); |
1342 | 1334 | ||
1343 | /* | 1335 | /* |
1336 | * Create and initialize a spinlock. | ||
1337 | */ | ||
1338 | acpi_status | ||
1339 | acpi_os_create_lock(acpi_spinlock *out_handle) | ||
1340 | { | ||
1341 | spinlock_t *lock; | ||
1342 | |||
1343 | lock = ACPI_ALLOCATE(sizeof(spinlock_t)); | ||
1344 | if (!lock) | ||
1345 | return AE_NO_MEMORY; | ||
1346 | spin_lock_init(lock); | ||
1347 | *out_handle = lock; | ||
1348 | |||
1349 | return AE_OK; | ||
1350 | } | ||
1351 | |||
1352 | /* | ||
1353 | * Deallocate the memory for a spinlock. | ||
1354 | */ | ||
1355 | void acpi_os_delete_lock(acpi_spinlock handle) | ||
1356 | { | ||
1357 | ACPI_FREE(handle); | ||
1358 | } | ||
1359 | |||
1360 | /* | ||
1344 | * Acquire a spinlock. | 1361 | * Acquire a spinlock. |
1345 | * | 1362 | * |
1346 | * handle is a pointer to the spinlock_t. | 1363 | * handle is a pointer to the spinlock_t. |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 25bf17da69fd..02d2a4c9084d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -37,7 +37,6 @@ static struct dmi_system_id __initdata processor_idle_dmi_table[] = { | |||
37 | {}, | 37 | {}, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #ifdef CONFIG_SMP | ||
41 | static int map_lapic_id(struct acpi_subtable_header *entry, | 40 | static int map_lapic_id(struct acpi_subtable_header *entry, |
42 | u32 acpi_id, int *apic_id) | 41 | u32 acpi_id, int *apic_id) |
43 | { | 42 | { |
@@ -165,7 +164,9 @@ exit: | |||
165 | 164 | ||
166 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | 165 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) |
167 | { | 166 | { |
167 | #ifdef CONFIG_SMP | ||
168 | int i; | 168 | int i; |
169 | #endif | ||
169 | int apic_id = -1; | 170 | int apic_id = -1; |
170 | 171 | ||
171 | apic_id = map_mat_entry(handle, type, acpi_id); | 172 | apic_id = map_mat_entry(handle, type, acpi_id); |
@@ -174,14 +175,19 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
174 | if (apic_id == -1) | 175 | if (apic_id == -1) |
175 | return apic_id; | 176 | return apic_id; |
176 | 177 | ||
178 | #ifdef CONFIG_SMP | ||
177 | for_each_possible_cpu(i) { | 179 | for_each_possible_cpu(i) { |
178 | if (cpu_physical_id(i) == apic_id) | 180 | if (cpu_physical_id(i) == apic_id) |
179 | return i; | 181 | return i; |
180 | } | 182 | } |
183 | #else | ||
184 | /* In UP kernel, only processor 0 is valid */ | ||
185 | if (apic_id == 0) | ||
186 | return apic_id; | ||
187 | #endif | ||
181 | return -1; | 188 | return -1; |
182 | } | 189 | } |
183 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 190 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
184 | #endif | ||
185 | 191 | ||
186 | static bool __init processor_physically_present(acpi_handle handle) | 192 | static bool __init processor_physically_present(acpi_handle handle) |
187 | { | 193 | { |
@@ -217,7 +223,7 @@ static bool __init processor_physically_present(acpi_handle handle) | |||
217 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | 223 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; |
218 | cpuid = acpi_get_cpuid(handle, type, acpi_id); | 224 | cpuid = acpi_get_cpuid(handle, type, acpi_id); |
219 | 225 | ||
220 | if ((cpuid == -1) && (num_possible_cpus() > 1)) | 226 | if (cpuid == -1) |
221 | return false; | 227 | return false; |
222 | 228 | ||
223 | return true; | 229 | return true; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d615b7d69bca..431ab11c8c1b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, | |||
161 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) | 161 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) |
162 | return; | 162 | return; |
163 | 163 | ||
164 | if (c1e_detected) | 164 | if (amd_e400_c1e_detected) |
165 | type = ACPI_STATE_C1; | 165 | type = ACPI_STATE_C1; |
166 | 166 | ||
167 | /* | 167 | /* |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 61891e75583d..77255f250dbb 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -220,6 +220,14 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | |||
220 | NULL, 0644); | 220 | NULL, 0644); |
221 | #endif /* CONFIG_ACPI_DEBUG */ | 221 | #endif /* CONFIG_ACPI_DEBUG */ |
222 | 222 | ||
223 | |||
224 | /* /sys/modules/acpi/parameters/aml_debug_output */ | ||
225 | |||
226 | module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, | ||
227 | bool, 0644); | ||
228 | MODULE_PARM_DESC(aml_debug_output, | ||
229 | "To enable/disable the ACPI Debug Object output."); | ||
230 | |||
223 | /* /sys/module/acpi/parameters/acpica_version */ | 231 | /* /sys/module/acpi/parameters/acpica_version */ |
224 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) | 232 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) |
225 | { | 233 | { |
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 7025593a58c8..d74926e0939e 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -603,6 +603,10 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
603 | if (ret) | 603 | if (ret) |
604 | goto err_out; | 604 | goto err_out; |
605 | 605 | ||
606 | /* Hard-coded primecell ID instead of plug-n-play */ | ||
607 | if (dev->periphid != 0) | ||
608 | goto skip_probe; | ||
609 | |||
606 | /* | 610 | /* |
607 | * Dynamically calculate the size of the resource | 611 | * Dynamically calculate the size of the resource |
608 | * and use this for iomap | 612 | * and use this for iomap |
@@ -643,6 +647,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
643 | if (ret) | 647 | if (ret) |
644 | goto err_release; | 648 | goto err_release; |
645 | 649 | ||
650 | skip_probe: | ||
646 | ret = device_add(&dev->dev); | 651 | ret = device_add(&dev->dev); |
647 | if (ret) | 652 | if (ret) |
648 | goto err_release; | 653 | goto err_release; |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index db8f88586c8d..98de8f418676 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -1038,6 +1038,7 @@ static void floppy_disable_hlt(void) | |||
1038 | { | 1038 | { |
1039 | unsigned long flags; | 1039 | unsigned long flags; |
1040 | 1040 | ||
1041 | WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012"); | ||
1041 | spin_lock_irqsave(&floppy_hlt_lock, flags); | 1042 | spin_lock_irqsave(&floppy_hlt_lock, flags); |
1042 | if (!hlt_disabled) { | 1043 | if (!hlt_disabled) { |
1043 | hlt_disabled = 1; | 1044 | hlt_disabled = 1; |
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index a0aabd904a51..46b8136c31bb 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c | |||
@@ -321,7 +321,6 @@ static void pcd_init_units(void) | |||
321 | strcpy(disk->disk_name, cd->name); /* umm... */ | 321 | strcpy(disk->disk_name, cd->name); /* umm... */ |
322 | disk->fops = &pcd_bdops; | 322 | disk->fops = &pcd_bdops; |
323 | disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; | 323 | disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
324 | disk->events = DISK_EVENT_MEDIA_CHANGE; | ||
325 | } | 324 | } |
326 | } | 325 | } |
327 | 326 | ||
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 6ecf89cdf006..079c08808d8a 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -6,10 +6,13 @@ | |||
6 | #include <linux/virtio.h> | 6 | #include <linux/virtio.h> |
7 | #include <linux/virtio_blk.h> | 7 | #include <linux/virtio_blk.h> |
8 | #include <linux/scatterlist.h> | 8 | #include <linux/scatterlist.h> |
9 | #include <linux/string_helpers.h> | ||
10 | #include <scsi/scsi_cmnd.h> | ||
9 | 11 | ||
10 | #define PART_BITS 4 | 12 | #define PART_BITS 4 |
11 | 13 | ||
12 | static int major, index; | 14 | static int major, index; |
15 | struct workqueue_struct *virtblk_wq; | ||
13 | 16 | ||
14 | struct virtio_blk | 17 | struct virtio_blk |
15 | { | 18 | { |
@@ -26,6 +29,9 @@ struct virtio_blk | |||
26 | 29 | ||
27 | mempool_t *pool; | 30 | mempool_t *pool; |
28 | 31 | ||
32 | /* Process context for config space updates */ | ||
33 | struct work_struct config_work; | ||
34 | |||
29 | /* What host tells us, plus 2 for header & tailer. */ | 35 | /* What host tells us, plus 2 for header & tailer. */ |
30 | unsigned int sg_elems; | 36 | unsigned int sg_elems; |
31 | 37 | ||
@@ -141,7 +147,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
141 | num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); | 147 | num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); |
142 | 148 | ||
143 | if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { | 149 | if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { |
144 | sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96); | 150 | sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE); |
145 | sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, | 151 | sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, |
146 | sizeof(vbr->in_hdr)); | 152 | sizeof(vbr->in_hdr)); |
147 | } | 153 | } |
@@ -291,6 +297,46 @@ static ssize_t virtblk_serial_show(struct device *dev, | |||
291 | } | 297 | } |
292 | DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); | 298 | DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); |
293 | 299 | ||
300 | static void virtblk_config_changed_work(struct work_struct *work) | ||
301 | { | ||
302 | struct virtio_blk *vblk = | ||
303 | container_of(work, struct virtio_blk, config_work); | ||
304 | struct virtio_device *vdev = vblk->vdev; | ||
305 | struct request_queue *q = vblk->disk->queue; | ||
306 | char cap_str_2[10], cap_str_10[10]; | ||
307 | u64 capacity, size; | ||
308 | |||
309 | /* Host must always specify the capacity. */ | ||
310 | vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), | ||
311 | &capacity, sizeof(capacity)); | ||
312 | |||
313 | /* If capacity is too big, truncate with warning. */ | ||
314 | if ((sector_t)capacity != capacity) { | ||
315 | dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n", | ||
316 | (unsigned long long)capacity); | ||
317 | capacity = (sector_t)-1; | ||
318 | } | ||
319 | |||
320 | size = capacity * queue_logical_block_size(q); | ||
321 | string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2)); | ||
322 | string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10)); | ||
323 | |||
324 | dev_notice(&vdev->dev, | ||
325 | "new size: %llu %d-byte logical blocks (%s/%s)\n", | ||
326 | (unsigned long long)capacity, | ||
327 | queue_logical_block_size(q), | ||
328 | cap_str_10, cap_str_2); | ||
329 | |||
330 | set_capacity(vblk->disk, capacity); | ||
331 | } | ||
332 | |||
333 | static void virtblk_config_changed(struct virtio_device *vdev) | ||
334 | { | ||
335 | struct virtio_blk *vblk = vdev->priv; | ||
336 | |||
337 | queue_work(virtblk_wq, &vblk->config_work); | ||
338 | } | ||
339 | |||
294 | static int __devinit virtblk_probe(struct virtio_device *vdev) | 340 | static int __devinit virtblk_probe(struct virtio_device *vdev) |
295 | { | 341 | { |
296 | struct virtio_blk *vblk; | 342 | struct virtio_blk *vblk; |
@@ -327,6 +373,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
327 | vblk->vdev = vdev; | 373 | vblk->vdev = vdev; |
328 | vblk->sg_elems = sg_elems; | 374 | vblk->sg_elems = sg_elems; |
329 | sg_init_table(vblk->sg, vblk->sg_elems); | 375 | sg_init_table(vblk->sg, vblk->sg_elems); |
376 | INIT_WORK(&vblk->config_work, virtblk_config_changed_work); | ||
330 | 377 | ||
331 | /* We expect one virtqueue, for output. */ | 378 | /* We expect one virtqueue, for output. */ |
332 | vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests"); | 379 | vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests"); |
@@ -477,6 +524,8 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) | |||
477 | { | 524 | { |
478 | struct virtio_blk *vblk = vdev->priv; | 525 | struct virtio_blk *vblk = vdev->priv; |
479 | 526 | ||
527 | flush_work(&vblk->config_work); | ||
528 | |||
480 | /* Nothing should be pending. */ | 529 | /* Nothing should be pending. */ |
481 | BUG_ON(!list_empty(&vblk->reqs)); | 530 | BUG_ON(!list_empty(&vblk->reqs)); |
482 | 531 | ||
@@ -508,27 +557,47 @@ static unsigned int features[] = { | |||
508 | * Use __refdata to avoid this warning. | 557 | * Use __refdata to avoid this warning. |
509 | */ | 558 | */ |
510 | static struct virtio_driver __refdata virtio_blk = { | 559 | static struct virtio_driver __refdata virtio_blk = { |
511 | .feature_table = features, | 560 | .feature_table = features, |
512 | .feature_table_size = ARRAY_SIZE(features), | 561 | .feature_table_size = ARRAY_SIZE(features), |
513 | .driver.name = KBUILD_MODNAME, | 562 | .driver.name = KBUILD_MODNAME, |
514 | .driver.owner = THIS_MODULE, | 563 | .driver.owner = THIS_MODULE, |
515 | .id_table = id_table, | 564 | .id_table = id_table, |
516 | .probe = virtblk_probe, | 565 | .probe = virtblk_probe, |
517 | .remove = __devexit_p(virtblk_remove), | 566 | .remove = __devexit_p(virtblk_remove), |
567 | .config_changed = virtblk_config_changed, | ||
518 | }; | 568 | }; |
519 | 569 | ||
520 | static int __init init(void) | 570 | static int __init init(void) |
521 | { | 571 | { |
572 | int error; | ||
573 | |||
574 | virtblk_wq = alloc_workqueue("virtio-blk", 0, 0); | ||
575 | if (!virtblk_wq) | ||
576 | return -ENOMEM; | ||
577 | |||
522 | major = register_blkdev(0, "virtblk"); | 578 | major = register_blkdev(0, "virtblk"); |
523 | if (major < 0) | 579 | if (major < 0) { |
524 | return major; | 580 | error = major; |
525 | return register_virtio_driver(&virtio_blk); | 581 | goto out_destroy_workqueue; |
582 | } | ||
583 | |||
584 | error = register_virtio_driver(&virtio_blk); | ||
585 | if (error) | ||
586 | goto out_unregister_blkdev; | ||
587 | return 0; | ||
588 | |||
589 | out_unregister_blkdev: | ||
590 | unregister_blkdev(major, "virtblk"); | ||
591 | out_destroy_workqueue: | ||
592 | destroy_workqueue(virtblk_wq); | ||
593 | return error; | ||
526 | } | 594 | } |
527 | 595 | ||
528 | static void __exit fini(void) | 596 | static void __exit fini(void) |
529 | { | 597 | { |
530 | unregister_blkdev(major, "virtblk"); | 598 | unregister_blkdev(major, "virtblk"); |
531 | unregister_virtio_driver(&virtio_blk); | 599 | unregister_virtio_driver(&virtio_blk); |
600 | destroy_workqueue(virtblk_wq); | ||
532 | } | 601 | } |
533 | module_init(init); | 602 | module_init(init); |
534 | module_exit(fini); | 603 | module_exit(fini); |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index ae15a4ddaa9b..7878da89d29e 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -627,7 +627,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
627 | gendisk->fops = &viocd_fops; | 627 | gendisk->fops = &viocd_fops; |
628 | gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | | 628 | gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | |
629 | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; | 629 | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
630 | gendisk->events = DISK_EVENT_MEDIA_CHANGE; | ||
631 | set_capacity(gendisk, 0); | 630 | set_capacity(gendisk, 0); |
632 | gendisk->private_data = d; | 631 | gendisk->private_data = d; |
633 | d->viocd_disk = gendisk; | 632 | d->viocd_disk = gendisk; |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 838568a7dbf5..fb68b1295373 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -1677,17 +1677,12 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) | |||
1677 | portdev->config.max_nr_ports = 1; | 1677 | portdev->config.max_nr_ports = 1; |
1678 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { | 1678 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { |
1679 | multiport = true; | 1679 | multiport = true; |
1680 | vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; | ||
1681 | |||
1682 | vdev->config->get(vdev, offsetof(struct virtio_console_config, | 1680 | vdev->config->get(vdev, offsetof(struct virtio_console_config, |
1683 | max_nr_ports), | 1681 | max_nr_ports), |
1684 | &portdev->config.max_nr_ports, | 1682 | &portdev->config.max_nr_ports, |
1685 | sizeof(portdev->config.max_nr_ports)); | 1683 | sizeof(portdev->config.max_nr_ports)); |
1686 | } | 1684 | } |
1687 | 1685 | ||
1688 | /* Let the Host know we support multiple ports.*/ | ||
1689 | vdev->config->finalize_features(vdev); | ||
1690 | |||
1691 | err = init_vqs(portdev); | 1686 | err = init_vqs(portdev); |
1692 | if (err < 0) { | 1687 | if (err < 0) { |
1693 | dev_err(&vdev->dev, "Error %d initializing vqs\n", err); | 1688 | dev_err(&vdev->dev, "Error %d initializing vqs\n", err); |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index f508690eb958..c47f3d09c1ee 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -237,6 +237,7 @@ static int menu_select(struct cpuidle_device *dev) | |||
237 | unsigned int power_usage = -1; | 237 | unsigned int power_usage = -1; |
238 | int i; | 238 | int i; |
239 | int multiplier; | 239 | int multiplier; |
240 | struct timespec t; | ||
240 | 241 | ||
241 | if (data->needs_update) { | 242 | if (data->needs_update) { |
242 | menu_update(dev); | 243 | menu_update(dev); |
@@ -251,8 +252,9 @@ static int menu_select(struct cpuidle_device *dev) | |||
251 | return 0; | 252 | return 0; |
252 | 253 | ||
253 | /* determine the expected residency time, round up */ | 254 | /* determine the expected residency time, round up */ |
255 | t = ktime_to_timespec(tick_nohz_get_sleep_length()); | ||
254 | data->expected_us = | 256 | data->expected_us = |
255 | DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000); | 257 | t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; |
256 | 258 | ||
257 | 259 | ||
258 | data->bucket = which_bucket(data->expected_us); | 260 | data->bucket = which_bucket(data->expected_us); |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a572600e44eb..25cf327cd1cb 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -200,16 +200,18 @@ config PL330_DMA | |||
200 | platform_data for a dma-pl330 device. | 200 | platform_data for a dma-pl330 device. |
201 | 201 | ||
202 | config PCH_DMA | 202 | config PCH_DMA |
203 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7213 IOH DMA support" | 203 | tristate "Intel EG20T PCH / OKI Semi IOH(ML7213/ML7223) DMA support" |
204 | depends on PCI && X86 | 204 | depends on PCI && X86 |
205 | select DMA_ENGINE | 205 | select DMA_ENGINE |
206 | help | 206 | help |
207 | Enable support for Intel EG20T PCH DMA engine. | 207 | Enable support for Intel EG20T PCH DMA engine. |
208 | 208 | ||
209 | This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/ | 209 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ |
210 | Output Hub) which is for IVI(In-Vehicle Infotainment) use. | 210 | Output Hub), ML7213 and ML7223. |
211 | ML7213 is companion chip for Intel Atom E6xx series. | 211 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is |
212 | ML7213 is completely compatible for Intel EG20T PCH. | 212 | for MP(Media Phone) use. |
213 | ML7213/ML7223 is companion chip for Intel Atom E6xx series. | ||
214 | ML7213/ML7223 is completely compatible for Intel EG20T PCH. | ||
213 | 215 | ||
214 | config IMX_SDMA | 216 | config IMX_SDMA |
215 | tristate "i.MX SDMA support" | 217 | tristate "i.MX SDMA support" |
diff --git a/drivers/dma/TODO b/drivers/dma/TODO new file mode 100644 index 000000000000..a4af8589330c --- /dev/null +++ b/drivers/dma/TODO | |||
@@ -0,0 +1,14 @@ | |||
1 | TODO for slave dma | ||
2 | |||
3 | 1. Move remaining drivers to use new slave interface | ||
4 | 2. Remove old slave pointer machansim | ||
5 | 3. Make issue_pending to start the transaction in below drivers | ||
6 | - mpc512x_dma | ||
7 | - imx-dma | ||
8 | - imx-sdma | ||
9 | - mxs-dma.c | ||
10 | - dw_dmac | ||
11 | - intel_mid_dma | ||
12 | - ste_dma40 | ||
13 | 4. Check other subsystems for dma drivers and merge/move to dmaengine | ||
14 | 5. Remove dma_slave_config's dma direction. | ||
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 235f53bf494e..36144f88d718 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -37,8 +37,8 @@ | |||
37 | 37 | ||
38 | #define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO) | 38 | #define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO) |
39 | #define ATC_DEFAULT_CTRLA (0) | 39 | #define ATC_DEFAULT_CTRLA (0) |
40 | #define ATC_DEFAULT_CTRLB (ATC_SIF(0) \ | 40 | #define ATC_DEFAULT_CTRLB (ATC_SIF(AT_DMA_MEM_IF) \ |
41 | |ATC_DIF(1)) | 41 | |ATC_DIF(AT_DMA_MEM_IF)) |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Initial number of descriptors to allocate for each channel. This could | 44 | * Initial number of descriptors to allocate for each channel. This could |
@@ -165,6 +165,29 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /** | 167 | /** |
168 | * atc_desc_chain - build chain adding a descripor | ||
169 | * @first: address of first descripor of the chain | ||
170 | * @prev: address of previous descripor of the chain | ||
171 | * @desc: descriptor to queue | ||
172 | * | ||
173 | * Called from prep_* functions | ||
174 | */ | ||
175 | static void atc_desc_chain(struct at_desc **first, struct at_desc **prev, | ||
176 | struct at_desc *desc) | ||
177 | { | ||
178 | if (!(*first)) { | ||
179 | *first = desc; | ||
180 | } else { | ||
181 | /* inform the HW lli about chaining */ | ||
182 | (*prev)->lli.dscr = desc->txd.phys; | ||
183 | /* insert the link descriptor to the LD ring */ | ||
184 | list_add_tail(&desc->desc_node, | ||
185 | &(*first)->tx_list); | ||
186 | } | ||
187 | *prev = desc; | ||
188 | } | ||
189 | |||
190 | /** | ||
168 | * atc_assign_cookie - compute and assign new cookie | 191 | * atc_assign_cookie - compute and assign new cookie |
169 | * @atchan: channel we work on | 192 | * @atchan: channel we work on |
170 | * @desc: descriptor to assign cookie for | 193 | * @desc: descriptor to assign cookie for |
@@ -237,16 +260,12 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) | |||
237 | static void | 260 | static void |
238 | atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) | 261 | atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) |
239 | { | 262 | { |
240 | dma_async_tx_callback callback; | ||
241 | void *param; | ||
242 | struct dma_async_tx_descriptor *txd = &desc->txd; | 263 | struct dma_async_tx_descriptor *txd = &desc->txd; |
243 | 264 | ||
244 | dev_vdbg(chan2dev(&atchan->chan_common), | 265 | dev_vdbg(chan2dev(&atchan->chan_common), |
245 | "descriptor %u complete\n", txd->cookie); | 266 | "descriptor %u complete\n", txd->cookie); |
246 | 267 | ||
247 | atchan->completed_cookie = txd->cookie; | 268 | atchan->completed_cookie = txd->cookie; |
248 | callback = txd->callback; | ||
249 | param = txd->callback_param; | ||
250 | 269 | ||
251 | /* move children to free_list */ | 270 | /* move children to free_list */ |
252 | list_splice_init(&desc->tx_list, &atchan->free_list); | 271 | list_splice_init(&desc->tx_list, &atchan->free_list); |
@@ -278,12 +297,19 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) | |||
278 | } | 297 | } |
279 | } | 298 | } |
280 | 299 | ||
281 | /* | 300 | /* for cyclic transfers, |
282 | * The API requires that no submissions are done from a | 301 | * no need to replay callback function while stopping */ |
283 | * callback, so we don't need to drop the lock here | 302 | if (!test_bit(ATC_IS_CYCLIC, &atchan->status)) { |
284 | */ | 303 | dma_async_tx_callback callback = txd->callback; |
285 | if (callback) | 304 | void *param = txd->callback_param; |
286 | callback(param); | 305 | |
306 | /* | ||
307 | * The API requires that no submissions are done from a | ||
308 | * callback, so we don't need to drop the lock here | ||
309 | */ | ||
310 | if (callback) | ||
311 | callback(param); | ||
312 | } | ||
287 | 313 | ||
288 | dma_run_dependencies(txd); | 314 | dma_run_dependencies(txd); |
289 | } | 315 | } |
@@ -419,6 +445,26 @@ static void atc_handle_error(struct at_dma_chan *atchan) | |||
419 | atc_chain_complete(atchan, bad_desc); | 445 | atc_chain_complete(atchan, bad_desc); |
420 | } | 446 | } |
421 | 447 | ||
448 | /** | ||
449 | * atc_handle_cyclic - at the end of a period, run callback function | ||
450 | * @atchan: channel used for cyclic operations | ||
451 | * | ||
452 | * Called with atchan->lock held and bh disabled | ||
453 | */ | ||
454 | static void atc_handle_cyclic(struct at_dma_chan *atchan) | ||
455 | { | ||
456 | struct at_desc *first = atc_first_active(atchan); | ||
457 | struct dma_async_tx_descriptor *txd = &first->txd; | ||
458 | dma_async_tx_callback callback = txd->callback; | ||
459 | void *param = txd->callback_param; | ||
460 | |||
461 | dev_vdbg(chan2dev(&atchan->chan_common), | ||
462 | "new cyclic period llp 0x%08x\n", | ||
463 | channel_readl(atchan, DSCR)); | ||
464 | |||
465 | if (callback) | ||
466 | callback(param); | ||
467 | } | ||
422 | 468 | ||
423 | /*-- IRQ & Tasklet ---------------------------------------------------*/ | 469 | /*-- IRQ & Tasklet ---------------------------------------------------*/ |
424 | 470 | ||
@@ -426,16 +472,11 @@ static void atc_tasklet(unsigned long data) | |||
426 | { | 472 | { |
427 | struct at_dma_chan *atchan = (struct at_dma_chan *)data; | 473 | struct at_dma_chan *atchan = (struct at_dma_chan *)data; |
428 | 474 | ||
429 | /* Channel cannot be enabled here */ | ||
430 | if (atc_chan_is_enabled(atchan)) { | ||
431 | dev_err(chan2dev(&atchan->chan_common), | ||
432 | "BUG: channel enabled in tasklet\n"); | ||
433 | return; | ||
434 | } | ||
435 | |||
436 | spin_lock(&atchan->lock); | 475 | spin_lock(&atchan->lock); |
437 | if (test_and_clear_bit(0, &atchan->error_status)) | 476 | if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status)) |
438 | atc_handle_error(atchan); | 477 | atc_handle_error(atchan); |
478 | else if (test_bit(ATC_IS_CYCLIC, &atchan->status)) | ||
479 | atc_handle_cyclic(atchan); | ||
439 | else | 480 | else |
440 | atc_advance_work(atchan); | 481 | atc_advance_work(atchan); |
441 | 482 | ||
@@ -464,12 +505,13 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id) | |||
464 | 505 | ||
465 | for (i = 0; i < atdma->dma_common.chancnt; i++) { | 506 | for (i = 0; i < atdma->dma_common.chancnt; i++) { |
466 | atchan = &atdma->chan[i]; | 507 | atchan = &atdma->chan[i]; |
467 | if (pending & (AT_DMA_CBTC(i) | AT_DMA_ERR(i))) { | 508 | if (pending & (AT_DMA_BTC(i) | AT_DMA_ERR(i))) { |
468 | if (pending & AT_DMA_ERR(i)) { | 509 | if (pending & AT_DMA_ERR(i)) { |
469 | /* Disable channel on AHB error */ | 510 | /* Disable channel on AHB error */ |
470 | dma_writel(atdma, CHDR, atchan->mask); | 511 | dma_writel(atdma, CHDR, |
512 | AT_DMA_RES(i) | atchan->mask); | ||
471 | /* Give information to tasklet */ | 513 | /* Give information to tasklet */ |
472 | set_bit(0, &atchan->error_status); | 514 | set_bit(ATC_IS_ERROR, &atchan->status); |
473 | } | 515 | } |
474 | tasklet_schedule(&atchan->tasklet); | 516 | tasklet_schedule(&atchan->tasklet); |
475 | ret = IRQ_HANDLED; | 517 | ret = IRQ_HANDLED; |
@@ -549,7 +591,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
549 | } | 591 | } |
550 | 592 | ||
551 | ctrla = ATC_DEFAULT_CTRLA; | 593 | ctrla = ATC_DEFAULT_CTRLA; |
552 | ctrlb = ATC_DEFAULT_CTRLB | 594 | ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN |
553 | | ATC_SRC_ADDR_MODE_INCR | 595 | | ATC_SRC_ADDR_MODE_INCR |
554 | | ATC_DST_ADDR_MODE_INCR | 596 | | ATC_DST_ADDR_MODE_INCR |
555 | | ATC_FC_MEM2MEM; | 597 | | ATC_FC_MEM2MEM; |
@@ -584,16 +626,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
584 | 626 | ||
585 | desc->txd.cookie = 0; | 627 | desc->txd.cookie = 0; |
586 | 628 | ||
587 | if (!first) { | 629 | atc_desc_chain(&first, &prev, desc); |
588 | first = desc; | ||
589 | } else { | ||
590 | /* inform the HW lli about chaining */ | ||
591 | prev->lli.dscr = desc->txd.phys; | ||
592 | /* insert the link descriptor to the LD ring */ | ||
593 | list_add_tail(&desc->desc_node, | ||
594 | &first->tx_list); | ||
595 | } | ||
596 | prev = desc; | ||
597 | } | 630 | } |
598 | 631 | ||
599 | /* First descriptor of the chain embedds additional information */ | 632 | /* First descriptor of the chain embedds additional information */ |
@@ -639,7 +672,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
639 | struct scatterlist *sg; | 672 | struct scatterlist *sg; |
640 | size_t total_len = 0; | 673 | size_t total_len = 0; |
641 | 674 | ||
642 | dev_vdbg(chan2dev(chan), "prep_slave_sg: %s f0x%lx\n", | 675 | dev_vdbg(chan2dev(chan), "prep_slave_sg (%d): %s f0x%lx\n", |
676 | sg_len, | ||
643 | direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE", | 677 | direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE", |
644 | flags); | 678 | flags); |
645 | 679 | ||
@@ -651,14 +685,15 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
651 | reg_width = atslave->reg_width; | 685 | reg_width = atslave->reg_width; |
652 | 686 | ||
653 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; | 687 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; |
654 | ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN; | 688 | ctrlb = ATC_IEN; |
655 | 689 | ||
656 | switch (direction) { | 690 | switch (direction) { |
657 | case DMA_TO_DEVICE: | 691 | case DMA_TO_DEVICE: |
658 | ctrla |= ATC_DST_WIDTH(reg_width); | 692 | ctrla |= ATC_DST_WIDTH(reg_width); |
659 | ctrlb |= ATC_DST_ADDR_MODE_FIXED | 693 | ctrlb |= ATC_DST_ADDR_MODE_FIXED |
660 | | ATC_SRC_ADDR_MODE_INCR | 694 | | ATC_SRC_ADDR_MODE_INCR |
661 | | ATC_FC_MEM2PER; | 695 | | ATC_FC_MEM2PER |
696 | | ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF); | ||
662 | reg = atslave->tx_reg; | 697 | reg = atslave->tx_reg; |
663 | for_each_sg(sgl, sg, sg_len, i) { | 698 | for_each_sg(sgl, sg, sg_len, i) { |
664 | struct at_desc *desc; | 699 | struct at_desc *desc; |
@@ -682,16 +717,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
682 | | len >> mem_width; | 717 | | len >> mem_width; |
683 | desc->lli.ctrlb = ctrlb; | 718 | desc->lli.ctrlb = ctrlb; |
684 | 719 | ||
685 | if (!first) { | 720 | atc_desc_chain(&first, &prev, desc); |
686 | first = desc; | ||
687 | } else { | ||
688 | /* inform the HW lli about chaining */ | ||
689 | prev->lli.dscr = desc->txd.phys; | ||
690 | /* insert the link descriptor to the LD ring */ | ||
691 | list_add_tail(&desc->desc_node, | ||
692 | &first->tx_list); | ||
693 | } | ||
694 | prev = desc; | ||
695 | total_len += len; | 721 | total_len += len; |
696 | } | 722 | } |
697 | break; | 723 | break; |
@@ -699,7 +725,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
699 | ctrla |= ATC_SRC_WIDTH(reg_width); | 725 | ctrla |= ATC_SRC_WIDTH(reg_width); |
700 | ctrlb |= ATC_DST_ADDR_MODE_INCR | 726 | ctrlb |= ATC_DST_ADDR_MODE_INCR |
701 | | ATC_SRC_ADDR_MODE_FIXED | 727 | | ATC_SRC_ADDR_MODE_FIXED |
702 | | ATC_FC_PER2MEM; | 728 | | ATC_FC_PER2MEM |
729 | | ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF); | ||
703 | 730 | ||
704 | reg = atslave->rx_reg; | 731 | reg = atslave->rx_reg; |
705 | for_each_sg(sgl, sg, sg_len, i) { | 732 | for_each_sg(sgl, sg, sg_len, i) { |
@@ -724,16 +751,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
724 | | len >> reg_width; | 751 | | len >> reg_width; |
725 | desc->lli.ctrlb = ctrlb; | 752 | desc->lli.ctrlb = ctrlb; |
726 | 753 | ||
727 | if (!first) { | 754 | atc_desc_chain(&first, &prev, desc); |
728 | first = desc; | ||
729 | } else { | ||
730 | /* inform the HW lli about chaining */ | ||
731 | prev->lli.dscr = desc->txd.phys; | ||
732 | /* insert the link descriptor to the LD ring */ | ||
733 | list_add_tail(&desc->desc_node, | ||
734 | &first->tx_list); | ||
735 | } | ||
736 | prev = desc; | ||
737 | total_len += len; | 755 | total_len += len; |
738 | } | 756 | } |
739 | break; | 757 | break; |
@@ -759,41 +777,211 @@ err_desc_get: | |||
759 | return NULL; | 777 | return NULL; |
760 | } | 778 | } |
761 | 779 | ||
780 | /** | ||
781 | * atc_dma_cyclic_check_values | ||
782 | * Check for too big/unaligned periods and unaligned DMA buffer | ||
783 | */ | ||
784 | static int | ||
785 | atc_dma_cyclic_check_values(unsigned int reg_width, dma_addr_t buf_addr, | ||
786 | size_t period_len, enum dma_data_direction direction) | ||
787 | { | ||
788 | if (period_len > (ATC_BTSIZE_MAX << reg_width)) | ||
789 | goto err_out; | ||
790 | if (unlikely(period_len & ((1 << reg_width) - 1))) | ||
791 | goto err_out; | ||
792 | if (unlikely(buf_addr & ((1 << reg_width) - 1))) | ||
793 | goto err_out; | ||
794 | if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE)))) | ||
795 | goto err_out; | ||
796 | |||
797 | return 0; | ||
798 | |||
799 | err_out: | ||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * atc_dma_cyclic_fill_desc - Fill one period decriptor | ||
805 | */ | ||
806 | static int | ||
807 | atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc, | ||
808 | unsigned int period_index, dma_addr_t buf_addr, | ||
809 | size_t period_len, enum dma_data_direction direction) | ||
810 | { | ||
811 | u32 ctrla; | ||
812 | unsigned int reg_width = atslave->reg_width; | ||
813 | |||
814 | /* prepare common CRTLA value */ | ||
815 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla | ||
816 | | ATC_DST_WIDTH(reg_width) | ||
817 | | ATC_SRC_WIDTH(reg_width) | ||
818 | | period_len >> reg_width; | ||
819 | |||
820 | switch (direction) { | ||
821 | case DMA_TO_DEVICE: | ||
822 | desc->lli.saddr = buf_addr + (period_len * period_index); | ||
823 | desc->lli.daddr = atslave->tx_reg; | ||
824 | desc->lli.ctrla = ctrla; | ||
825 | desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED | ||
826 | | ATC_SRC_ADDR_MODE_INCR | ||
827 | | ATC_FC_MEM2PER | ||
828 | | ATC_SIF(AT_DMA_MEM_IF) | ||
829 | | ATC_DIF(AT_DMA_PER_IF); | ||
830 | break; | ||
831 | |||
832 | case DMA_FROM_DEVICE: | ||
833 | desc->lli.saddr = atslave->rx_reg; | ||
834 | desc->lli.daddr = buf_addr + (period_len * period_index); | ||
835 | desc->lli.ctrla = ctrla; | ||
836 | desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR | ||
837 | | ATC_SRC_ADDR_MODE_FIXED | ||
838 | | ATC_FC_PER2MEM | ||
839 | | ATC_SIF(AT_DMA_PER_IF) | ||
840 | | ATC_DIF(AT_DMA_MEM_IF); | ||
841 | break; | ||
842 | |||
843 | default: | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /** | ||
851 | * atc_prep_dma_cyclic - prepare the cyclic DMA transfer | ||
852 | * @chan: the DMA channel to prepare | ||
853 | * @buf_addr: physical DMA address where the buffer starts | ||
854 | * @buf_len: total number of bytes for the entire buffer | ||
855 | * @period_len: number of bytes for each period | ||
856 | * @direction: transfer direction, to or from device | ||
857 | */ | ||
858 | static struct dma_async_tx_descriptor * | ||
859 | atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | ||
860 | size_t period_len, enum dma_data_direction direction) | ||
861 | { | ||
862 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | ||
863 | struct at_dma_slave *atslave = chan->private; | ||
864 | struct at_desc *first = NULL; | ||
865 | struct at_desc *prev = NULL; | ||
866 | unsigned long was_cyclic; | ||
867 | unsigned int periods = buf_len / period_len; | ||
868 | unsigned int i; | ||
869 | |||
870 | dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@0x%08x - %d (%d/%d)\n", | ||
871 | direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE", | ||
872 | buf_addr, | ||
873 | periods, buf_len, period_len); | ||
874 | |||
875 | if (unlikely(!atslave || !buf_len || !period_len)) { | ||
876 | dev_dbg(chan2dev(chan), "prep_dma_cyclic: length is zero!\n"); | ||
877 | return NULL; | ||
878 | } | ||
879 | |||
880 | was_cyclic = test_and_set_bit(ATC_IS_CYCLIC, &atchan->status); | ||
881 | if (was_cyclic) { | ||
882 | dev_dbg(chan2dev(chan), "prep_dma_cyclic: channel in use!\n"); | ||
883 | return NULL; | ||
884 | } | ||
885 | |||
886 | /* Check for too big/unaligned periods and unaligned DMA buffer */ | ||
887 | if (atc_dma_cyclic_check_values(atslave->reg_width, buf_addr, | ||
888 | period_len, direction)) | ||
889 | goto err_out; | ||
890 | |||
891 | /* build cyclic linked list */ | ||
892 | for (i = 0; i < periods; i++) { | ||
893 | struct at_desc *desc; | ||
894 | |||
895 | desc = atc_desc_get(atchan); | ||
896 | if (!desc) | ||
897 | goto err_desc_get; | ||
898 | |||
899 | if (atc_dma_cyclic_fill_desc(atslave, desc, i, buf_addr, | ||
900 | period_len, direction)) | ||
901 | goto err_desc_get; | ||
902 | |||
903 | atc_desc_chain(&first, &prev, desc); | ||
904 | } | ||
905 | |||
906 | /* lets make a cyclic list */ | ||
907 | prev->lli.dscr = first->txd.phys; | ||
908 | |||
909 | /* First descriptor of the chain embedds additional information */ | ||
910 | first->txd.cookie = -EBUSY; | ||
911 | first->len = buf_len; | ||
912 | |||
913 | return &first->txd; | ||
914 | |||
915 | err_desc_get: | ||
916 | dev_err(chan2dev(chan), "not enough descriptors available\n"); | ||
917 | atc_desc_put(atchan, first); | ||
918 | err_out: | ||
919 | clear_bit(ATC_IS_CYCLIC, &atchan->status); | ||
920 | return NULL; | ||
921 | } | ||
922 | |||
923 | |||
762 | static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 924 | static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, |
763 | unsigned long arg) | 925 | unsigned long arg) |
764 | { | 926 | { |
765 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | 927 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
766 | struct at_dma *atdma = to_at_dma(chan->device); | 928 | struct at_dma *atdma = to_at_dma(chan->device); |
767 | struct at_desc *desc, *_desc; | 929 | int chan_id = atchan->chan_common.chan_id; |
930 | |||
768 | LIST_HEAD(list); | 931 | LIST_HEAD(list); |
769 | 932 | ||
770 | /* Only supports DMA_TERMINATE_ALL */ | 933 | dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd); |
771 | if (cmd != DMA_TERMINATE_ALL) | ||
772 | return -ENXIO; | ||
773 | 934 | ||
774 | /* | 935 | if (cmd == DMA_PAUSE) { |
775 | * This is only called when something went wrong elsewhere, so | 936 | spin_lock_bh(&atchan->lock); |
776 | * we don't really care about the data. Just disable the | ||
777 | * channel. We still have to poll the channel enable bit due | ||
778 | * to AHB/HSB limitations. | ||
779 | */ | ||
780 | spin_lock_bh(&atchan->lock); | ||
781 | 937 | ||
782 | dma_writel(atdma, CHDR, atchan->mask); | 938 | dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id)); |
939 | set_bit(ATC_IS_PAUSED, &atchan->status); | ||
783 | 940 | ||
784 | /* confirm that this channel is disabled */ | 941 | spin_unlock_bh(&atchan->lock); |
785 | while (dma_readl(atdma, CHSR) & atchan->mask) | 942 | } else if (cmd == DMA_RESUME) { |
786 | cpu_relax(); | 943 | if (!test_bit(ATC_IS_PAUSED, &atchan->status)) |
944 | return 0; | ||
787 | 945 | ||
788 | /* active_list entries will end up before queued entries */ | 946 | spin_lock_bh(&atchan->lock); |
789 | list_splice_init(&atchan->queue, &list); | ||
790 | list_splice_init(&atchan->active_list, &list); | ||
791 | 947 | ||
792 | /* Flush all pending and queued descriptors */ | 948 | dma_writel(atdma, CHDR, AT_DMA_RES(chan_id)); |
793 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | 949 | clear_bit(ATC_IS_PAUSED, &atchan->status); |
794 | atc_chain_complete(atchan, desc); | ||
795 | 950 | ||
796 | spin_unlock_bh(&atchan->lock); | 951 | spin_unlock_bh(&atchan->lock); |
952 | } else if (cmd == DMA_TERMINATE_ALL) { | ||
953 | struct at_desc *desc, *_desc; | ||
954 | /* | ||
955 | * This is only called when something went wrong elsewhere, so | ||
956 | * we don't really care about the data. Just disable the | ||
957 | * channel. We still have to poll the channel enable bit due | ||
958 | * to AHB/HSB limitations. | ||
959 | */ | ||
960 | spin_lock_bh(&atchan->lock); | ||
961 | |||
962 | /* disabling channel: must also remove suspend state */ | ||
963 | dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask); | ||
964 | |||
965 | /* confirm that this channel is disabled */ | ||
966 | while (dma_readl(atdma, CHSR) & atchan->mask) | ||
967 | cpu_relax(); | ||
968 | |||
969 | /* active_list entries will end up before queued entries */ | ||
970 | list_splice_init(&atchan->queue, &list); | ||
971 | list_splice_init(&atchan->active_list, &list); | ||
972 | |||
973 | /* Flush all pending and queued descriptors */ | ||
974 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | ||
975 | atc_chain_complete(atchan, desc); | ||
976 | |||
977 | clear_bit(ATC_IS_PAUSED, &atchan->status); | ||
978 | /* if channel dedicated to cyclic operations, free it */ | ||
979 | clear_bit(ATC_IS_CYCLIC, &atchan->status); | ||
980 | |||
981 | spin_unlock_bh(&atchan->lock); | ||
982 | } else { | ||
983 | return -ENXIO; | ||
984 | } | ||
797 | 985 | ||
798 | return 0; | 986 | return 0; |
799 | } | 987 | } |
@@ -835,9 +1023,17 @@ atc_tx_status(struct dma_chan *chan, | |||
835 | 1023 | ||
836 | spin_unlock_bh(&atchan->lock); | 1024 | spin_unlock_bh(&atchan->lock); |
837 | 1025 | ||
838 | dma_set_tx_state(txstate, last_complete, last_used, 0); | 1026 | if (ret != DMA_SUCCESS) |
839 | dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", | 1027 | dma_set_tx_state(txstate, last_complete, last_used, |
840 | cookie, last_complete ? last_complete : 0, | 1028 | atc_first_active(atchan)->len); |
1029 | else | ||
1030 | dma_set_tx_state(txstate, last_complete, last_used, 0); | ||
1031 | |||
1032 | if (test_bit(ATC_IS_PAUSED, &atchan->status)) | ||
1033 | ret = DMA_PAUSED; | ||
1034 | |||
1035 | dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n", | ||
1036 | ret, cookie, last_complete ? last_complete : 0, | ||
841 | last_used ? last_used : 0); | 1037 | last_used ? last_used : 0); |
842 | 1038 | ||
843 | return ret; | 1039 | return ret; |
@@ -853,6 +1049,10 @@ static void atc_issue_pending(struct dma_chan *chan) | |||
853 | 1049 | ||
854 | dev_vdbg(chan2dev(chan), "issue_pending\n"); | 1050 | dev_vdbg(chan2dev(chan), "issue_pending\n"); |
855 | 1051 | ||
1052 | /* Not needed for cyclic transfers */ | ||
1053 | if (test_bit(ATC_IS_CYCLIC, &atchan->status)) | ||
1054 | return; | ||
1055 | |||
856 | spin_lock_bh(&atchan->lock); | 1056 | spin_lock_bh(&atchan->lock); |
857 | if (!atc_chan_is_enabled(atchan)) { | 1057 | if (!atc_chan_is_enabled(atchan)) { |
858 | atc_advance_work(atchan); | 1058 | atc_advance_work(atchan); |
@@ -959,6 +1159,7 @@ static void atc_free_chan_resources(struct dma_chan *chan) | |||
959 | } | 1159 | } |
960 | list_splice_init(&atchan->free_list, &list); | 1160 | list_splice_init(&atchan->free_list, &list); |
961 | atchan->descs_allocated = 0; | 1161 | atchan->descs_allocated = 0; |
1162 | atchan->status = 0; | ||
962 | 1163 | ||
963 | dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); | 1164 | dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); |
964 | } | 1165 | } |
@@ -1092,10 +1293,15 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1092 | if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask)) | 1293 | if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask)) |
1093 | atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy; | 1294 | atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy; |
1094 | 1295 | ||
1095 | if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) { | 1296 | if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) |
1096 | atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; | 1297 | atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; |
1298 | |||
1299 | if (dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask)) | ||
1300 | atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic; | ||
1301 | |||
1302 | if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) || | ||
1303 | dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask)) | ||
1097 | atdma->dma_common.device_control = atc_control; | 1304 | atdma->dma_common.device_control = atc_control; |
1098 | } | ||
1099 | 1305 | ||
1100 | dma_writel(atdma, EN, AT_DMA_ENABLE); | 1306 | dma_writel(atdma, EN, AT_DMA_ENABLE); |
1101 | 1307 | ||
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h index 495457e3dc4b..087dbf1dd39c 100644 --- a/drivers/dma/at_hdmac_regs.h +++ b/drivers/dma/at_hdmac_regs.h | |||
@@ -103,6 +103,10 @@ | |||
103 | /* Bitfields in CTRLB */ | 103 | /* Bitfields in CTRLB */ |
104 | #define ATC_SIF(i) (0x3 & (i)) /* Src tx done via AHB-Lite Interface i */ | 104 | #define ATC_SIF(i) (0x3 & (i)) /* Src tx done via AHB-Lite Interface i */ |
105 | #define ATC_DIF(i) ((0x3 & (i)) << 4) /* Dst tx done via AHB-Lite Interface i */ | 105 | #define ATC_DIF(i) ((0x3 & (i)) << 4) /* Dst tx done via AHB-Lite Interface i */ |
106 | /* Specify AHB interfaces */ | ||
107 | #define AT_DMA_MEM_IF 0 /* interface 0 as memory interface */ | ||
108 | #define AT_DMA_PER_IF 1 /* interface 1 as peripheral interface */ | ||
109 | |||
106 | #define ATC_SRC_PIP (0x1 << 8) /* Source Picture-in-Picture enabled */ | 110 | #define ATC_SRC_PIP (0x1 << 8) /* Source Picture-in-Picture enabled */ |
107 | #define ATC_DST_PIP (0x1 << 12) /* Destination Picture-in-Picture enabled */ | 111 | #define ATC_DST_PIP (0x1 << 12) /* Destination Picture-in-Picture enabled */ |
108 | #define ATC_SRC_DSCR_DIS (0x1 << 16) /* Src Descriptor fetch disable */ | 112 | #define ATC_SRC_DSCR_DIS (0x1 << 16) /* Src Descriptor fetch disable */ |
@@ -181,12 +185,23 @@ txd_to_at_desc(struct dma_async_tx_descriptor *txd) | |||
181 | /*-- Channels --------------------------------------------------------*/ | 185 | /*-- Channels --------------------------------------------------------*/ |
182 | 186 | ||
183 | /** | 187 | /** |
188 | * atc_status - information bits stored in channel status flag | ||
189 | * | ||
190 | * Manipulated with atomic operations. | ||
191 | */ | ||
192 | enum atc_status { | ||
193 | ATC_IS_ERROR = 0, | ||
194 | ATC_IS_PAUSED = 1, | ||
195 | ATC_IS_CYCLIC = 24, | ||
196 | }; | ||
197 | |||
198 | /** | ||
184 | * struct at_dma_chan - internal representation of an Atmel HDMAC channel | 199 | * struct at_dma_chan - internal representation of an Atmel HDMAC channel |
185 | * @chan_common: common dmaengine channel object members | 200 | * @chan_common: common dmaengine channel object members |
186 | * @device: parent device | 201 | * @device: parent device |
187 | * @ch_regs: memory mapped register base | 202 | * @ch_regs: memory mapped register base |
188 | * @mask: channel index in a mask | 203 | * @mask: channel index in a mask |
189 | * @error_status: transmit error status information from irq handler | 204 | * @status: transmit status information from irq/prep* functions |
190 | * to tasklet (use atomic operations) | 205 | * to tasklet (use atomic operations) |
191 | * @tasklet: bottom half to finish transaction work | 206 | * @tasklet: bottom half to finish transaction work |
192 | * @lock: serializes enqueue/dequeue operations to descriptors lists | 207 | * @lock: serializes enqueue/dequeue operations to descriptors lists |
@@ -201,7 +216,7 @@ struct at_dma_chan { | |||
201 | struct at_dma *device; | 216 | struct at_dma *device; |
202 | void __iomem *ch_regs; | 217 | void __iomem *ch_regs; |
203 | u8 mask; | 218 | u8 mask; |
204 | unsigned long error_status; | 219 | unsigned long status; |
205 | struct tasklet_struct tasklet; | 220 | struct tasklet_struct tasklet; |
206 | 221 | ||
207 | spinlock_t lock; | 222 | spinlock_t lock; |
@@ -309,8 +324,8 @@ static void atc_setup_irq(struct at_dma_chan *atchan, int on) | |||
309 | struct at_dma *atdma = to_at_dma(atchan->chan_common.device); | 324 | struct at_dma *atdma = to_at_dma(atchan->chan_common.device); |
310 | u32 ebci; | 325 | u32 ebci; |
311 | 326 | ||
312 | /* enable interrupts on buffer chain completion & error */ | 327 | /* enable interrupts on buffer transfer completion & error */ |
313 | ebci = AT_DMA_CBTC(atchan->chan_common.chan_id) | 328 | ebci = AT_DMA_BTC(atchan->chan_common.chan_id) |
314 | | AT_DMA_ERR(atchan->chan_common.chan_id); | 329 | | AT_DMA_ERR(atchan->chan_common.chan_id); |
315 | if (on) | 330 | if (on) |
316 | dma_writel(atdma, EBCIER, ebci); | 331 | dma_writel(atdma, EBCIER, ebci); |
@@ -347,7 +362,12 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan) | |||
347 | */ | 362 | */ |
348 | static void set_desc_eol(struct at_desc *desc) | 363 | static void set_desc_eol(struct at_desc *desc) |
349 | { | 364 | { |
350 | desc->lli.ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS; | 365 | u32 ctrlb = desc->lli.ctrlb; |
366 | |||
367 | ctrlb &= ~ATC_IEN; | ||
368 | ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS; | ||
369 | |||
370 | desc->lli.ctrlb = ctrlb; | ||
351 | desc->lli.dscr = 0; | 371 | desc->lli.dscr = 0; |
352 | } | 372 | } |
353 | 373 | ||
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index f48e54006518..af8c0b5ed70f 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c | |||
@@ -1610,7 +1610,7 @@ int __init coh901318_init(void) | |||
1610 | { | 1610 | { |
1611 | return platform_driver_probe(&coh901318_driver, coh901318_probe); | 1611 | return platform_driver_probe(&coh901318_driver, coh901318_probe); |
1612 | } | 1612 | } |
1613 | arch_initcall(coh901318_init); | 1613 | subsys_initcall(coh901318_init); |
1614 | 1614 | ||
1615 | void __exit coh901318_exit(void) | 1615 | void __exit coh901318_exit(void) |
1616 | { | 1616 | { |
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 2a2e2fa00e91..4d180ca9a1d8 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * AVR32 systems.) | 3 | * AVR32 systems.) |
4 | * | 4 | * |
5 | * Copyright (C) 2007-2008 Atmel Corporation | 5 | * Copyright (C) 2007-2008 Atmel Corporation |
6 | * Copyright (C) 2010-2011 ST Microelectronics | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -93,8 +94,9 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc) | |||
93 | struct dw_desc *desc, *_desc; | 94 | struct dw_desc *desc, *_desc; |
94 | struct dw_desc *ret = NULL; | 95 | struct dw_desc *ret = NULL; |
95 | unsigned int i = 0; | 96 | unsigned int i = 0; |
97 | unsigned long flags; | ||
96 | 98 | ||
97 | spin_lock_bh(&dwc->lock); | 99 | spin_lock_irqsave(&dwc->lock, flags); |
98 | list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) { | 100 | list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) { |
99 | if (async_tx_test_ack(&desc->txd)) { | 101 | if (async_tx_test_ack(&desc->txd)) { |
100 | list_del(&desc->desc_node); | 102 | list_del(&desc->desc_node); |
@@ -104,7 +106,7 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc) | |||
104 | dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc); | 106 | dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc); |
105 | i++; | 107 | i++; |
106 | } | 108 | } |
107 | spin_unlock_bh(&dwc->lock); | 109 | spin_unlock_irqrestore(&dwc->lock, flags); |
108 | 110 | ||
109 | dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i); | 111 | dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i); |
110 | 112 | ||
@@ -130,12 +132,14 @@ static void dwc_sync_desc_for_cpu(struct dw_dma_chan *dwc, struct dw_desc *desc) | |||
130 | */ | 132 | */ |
131 | static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) | 133 | static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) |
132 | { | 134 | { |
135 | unsigned long flags; | ||
136 | |||
133 | if (desc) { | 137 | if (desc) { |
134 | struct dw_desc *child; | 138 | struct dw_desc *child; |
135 | 139 | ||
136 | dwc_sync_desc_for_cpu(dwc, desc); | 140 | dwc_sync_desc_for_cpu(dwc, desc); |
137 | 141 | ||
138 | spin_lock_bh(&dwc->lock); | 142 | spin_lock_irqsave(&dwc->lock, flags); |
139 | list_for_each_entry(child, &desc->tx_list, desc_node) | 143 | list_for_each_entry(child, &desc->tx_list, desc_node) |
140 | dev_vdbg(chan2dev(&dwc->chan), | 144 | dev_vdbg(chan2dev(&dwc->chan), |
141 | "moving child desc %p to freelist\n", | 145 | "moving child desc %p to freelist\n", |
@@ -143,7 +147,7 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) | |||
143 | list_splice_init(&desc->tx_list, &dwc->free_list); | 147 | list_splice_init(&desc->tx_list, &dwc->free_list); |
144 | dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc); | 148 | dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc); |
145 | list_add(&desc->desc_node, &dwc->free_list); | 149 | list_add(&desc->desc_node, &dwc->free_list); |
146 | spin_unlock_bh(&dwc->lock); | 150 | spin_unlock_irqrestore(&dwc->lock, flags); |
147 | } | 151 | } |
148 | } | 152 | } |
149 | 153 | ||
@@ -195,18 +199,23 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) | |||
195 | /*----------------------------------------------------------------------*/ | 199 | /*----------------------------------------------------------------------*/ |
196 | 200 | ||
197 | static void | 201 | static void |
198 | dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc) | 202 | dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc, |
203 | bool callback_required) | ||
199 | { | 204 | { |
200 | dma_async_tx_callback callback; | 205 | dma_async_tx_callback callback = NULL; |
201 | void *param; | 206 | void *param = NULL; |
202 | struct dma_async_tx_descriptor *txd = &desc->txd; | 207 | struct dma_async_tx_descriptor *txd = &desc->txd; |
203 | struct dw_desc *child; | 208 | struct dw_desc *child; |
209 | unsigned long flags; | ||
204 | 210 | ||
205 | dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); | 211 | dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); |
206 | 212 | ||
213 | spin_lock_irqsave(&dwc->lock, flags); | ||
207 | dwc->completed = txd->cookie; | 214 | dwc->completed = txd->cookie; |
208 | callback = txd->callback; | 215 | if (callback_required) { |
209 | param = txd->callback_param; | 216 | callback = txd->callback; |
217 | param = txd->callback_param; | ||
218 | } | ||
210 | 219 | ||
211 | dwc_sync_desc_for_cpu(dwc, desc); | 220 | dwc_sync_desc_for_cpu(dwc, desc); |
212 | 221 | ||
@@ -238,11 +247,9 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc) | |||
238 | } | 247 | } |
239 | } | 248 | } |
240 | 249 | ||
241 | /* | 250 | spin_unlock_irqrestore(&dwc->lock, flags); |
242 | * The API requires that no submissions are done from a | 251 | |
243 | * callback, so we don't need to drop the lock here | 252 | if (callback_required && callback) |
244 | */ | ||
245 | if (callback) | ||
246 | callback(param); | 253 | callback(param); |
247 | } | 254 | } |
248 | 255 | ||
@@ -250,7 +257,9 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
250 | { | 257 | { |
251 | struct dw_desc *desc, *_desc; | 258 | struct dw_desc *desc, *_desc; |
252 | LIST_HEAD(list); | 259 | LIST_HEAD(list); |
260 | unsigned long flags; | ||
253 | 261 | ||
262 | spin_lock_irqsave(&dwc->lock, flags); | ||
254 | if (dma_readl(dw, CH_EN) & dwc->mask) { | 263 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
255 | dev_err(chan2dev(&dwc->chan), | 264 | dev_err(chan2dev(&dwc->chan), |
256 | "BUG: XFER bit set, but channel not idle!\n"); | 265 | "BUG: XFER bit set, but channel not idle!\n"); |
@@ -271,8 +280,10 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
271 | dwc_dostart(dwc, dwc_first_active(dwc)); | 280 | dwc_dostart(dwc, dwc_first_active(dwc)); |
272 | } | 281 | } |
273 | 282 | ||
283 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
284 | |||
274 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | 285 | list_for_each_entry_safe(desc, _desc, &list, desc_node) |
275 | dwc_descriptor_complete(dwc, desc); | 286 | dwc_descriptor_complete(dwc, desc, true); |
276 | } | 287 | } |
277 | 288 | ||
278 | static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | 289 | static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) |
@@ -281,7 +292,9 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
281 | struct dw_desc *desc, *_desc; | 292 | struct dw_desc *desc, *_desc; |
282 | struct dw_desc *child; | 293 | struct dw_desc *child; |
283 | u32 status_xfer; | 294 | u32 status_xfer; |
295 | unsigned long flags; | ||
284 | 296 | ||
297 | spin_lock_irqsave(&dwc->lock, flags); | ||
285 | /* | 298 | /* |
286 | * Clear block interrupt flag before scanning so that we don't | 299 | * Clear block interrupt flag before scanning so that we don't |
287 | * miss any, and read LLP before RAW_XFER to ensure it is | 300 | * miss any, and read LLP before RAW_XFER to ensure it is |
@@ -294,30 +307,47 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
294 | if (status_xfer & dwc->mask) { | 307 | if (status_xfer & dwc->mask) { |
295 | /* Everything we've submitted is done */ | 308 | /* Everything we've submitted is done */ |
296 | dma_writel(dw, CLEAR.XFER, dwc->mask); | 309 | dma_writel(dw, CLEAR.XFER, dwc->mask); |
310 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
311 | |||
297 | dwc_complete_all(dw, dwc); | 312 | dwc_complete_all(dw, dwc); |
298 | return; | 313 | return; |
299 | } | 314 | } |
300 | 315 | ||
301 | if (list_empty(&dwc->active_list)) | 316 | if (list_empty(&dwc->active_list)) { |
317 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
302 | return; | 318 | return; |
319 | } | ||
303 | 320 | ||
304 | dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); | 321 | dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); |
305 | 322 | ||
306 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { | 323 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { |
307 | if (desc->lli.llp == llp) | 324 | /* check first descriptors addr */ |
325 | if (desc->txd.phys == llp) { | ||
326 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
327 | return; | ||
328 | } | ||
329 | |||
330 | /* check first descriptors llp */ | ||
331 | if (desc->lli.llp == llp) { | ||
308 | /* This one is currently in progress */ | 332 | /* This one is currently in progress */ |
333 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
309 | return; | 334 | return; |
335 | } | ||
310 | 336 | ||
311 | list_for_each_entry(child, &desc->tx_list, desc_node) | 337 | list_for_each_entry(child, &desc->tx_list, desc_node) |
312 | if (child->lli.llp == llp) | 338 | if (child->lli.llp == llp) { |
313 | /* Currently in progress */ | 339 | /* Currently in progress */ |
340 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
314 | return; | 341 | return; |
342 | } | ||
315 | 343 | ||
316 | /* | 344 | /* |
317 | * No descriptors so far seem to be in progress, i.e. | 345 | * No descriptors so far seem to be in progress, i.e. |
318 | * this one must be done. | 346 | * this one must be done. |
319 | */ | 347 | */ |
320 | dwc_descriptor_complete(dwc, desc); | 348 | spin_unlock_irqrestore(&dwc->lock, flags); |
349 | dwc_descriptor_complete(dwc, desc, true); | ||
350 | spin_lock_irqsave(&dwc->lock, flags); | ||
321 | } | 351 | } |
322 | 352 | ||
323 | dev_err(chan2dev(&dwc->chan), | 353 | dev_err(chan2dev(&dwc->chan), |
@@ -332,6 +362,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
332 | list_move(dwc->queue.next, &dwc->active_list); | 362 | list_move(dwc->queue.next, &dwc->active_list); |
333 | dwc_dostart(dwc, dwc_first_active(dwc)); | 363 | dwc_dostart(dwc, dwc_first_active(dwc)); |
334 | } | 364 | } |
365 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
335 | } | 366 | } |
336 | 367 | ||
337 | static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli) | 368 | static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli) |
@@ -346,9 +377,12 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
346 | { | 377 | { |
347 | struct dw_desc *bad_desc; | 378 | struct dw_desc *bad_desc; |
348 | struct dw_desc *child; | 379 | struct dw_desc *child; |
380 | unsigned long flags; | ||
349 | 381 | ||
350 | dwc_scan_descriptors(dw, dwc); | 382 | dwc_scan_descriptors(dw, dwc); |
351 | 383 | ||
384 | spin_lock_irqsave(&dwc->lock, flags); | ||
385 | |||
352 | /* | 386 | /* |
353 | * The descriptor currently at the head of the active list is | 387 | * The descriptor currently at the head of the active list is |
354 | * borked. Since we don't have any way to report errors, we'll | 388 | * borked. Since we don't have any way to report errors, we'll |
@@ -378,8 +412,10 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
378 | list_for_each_entry(child, &bad_desc->tx_list, desc_node) | 412 | list_for_each_entry(child, &bad_desc->tx_list, desc_node) |
379 | dwc_dump_lli(dwc, &child->lli); | 413 | dwc_dump_lli(dwc, &child->lli); |
380 | 414 | ||
415 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
416 | |||
381 | /* Pretend the descriptor completed successfully */ | 417 | /* Pretend the descriptor completed successfully */ |
382 | dwc_descriptor_complete(dwc, bad_desc); | 418 | dwc_descriptor_complete(dwc, bad_desc, true); |
383 | } | 419 | } |
384 | 420 | ||
385 | /* --------------------- Cyclic DMA API extensions -------------------- */ | 421 | /* --------------------- Cyclic DMA API extensions -------------------- */ |
@@ -402,6 +438,8 @@ EXPORT_SYMBOL(dw_dma_get_dst_addr); | |||
402 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | 438 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, |
403 | u32 status_block, u32 status_err, u32 status_xfer) | 439 | u32 status_block, u32 status_err, u32 status_xfer) |
404 | { | 440 | { |
441 | unsigned long flags; | ||
442 | |||
405 | if (status_block & dwc->mask) { | 443 | if (status_block & dwc->mask) { |
406 | void (*callback)(void *param); | 444 | void (*callback)(void *param); |
407 | void *callback_param; | 445 | void *callback_param; |
@@ -412,11 +450,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
412 | 450 | ||
413 | callback = dwc->cdesc->period_callback; | 451 | callback = dwc->cdesc->period_callback; |
414 | callback_param = dwc->cdesc->period_callback_param; | 452 | callback_param = dwc->cdesc->period_callback_param; |
415 | if (callback) { | 453 | |
416 | spin_unlock(&dwc->lock); | 454 | if (callback) |
417 | callback(callback_param); | 455 | callback(callback_param); |
418 | spin_lock(&dwc->lock); | ||
419 | } | ||
420 | } | 456 | } |
421 | 457 | ||
422 | /* | 458 | /* |
@@ -430,6 +466,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
430 | dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s " | 466 | dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s " |
431 | "interrupt, stopping DMA transfer\n", | 467 | "interrupt, stopping DMA transfer\n", |
432 | status_xfer ? "xfer" : "error"); | 468 | status_xfer ? "xfer" : "error"); |
469 | |||
470 | spin_lock_irqsave(&dwc->lock, flags); | ||
471 | |||
433 | dev_err(chan2dev(&dwc->chan), | 472 | dev_err(chan2dev(&dwc->chan), |
434 | " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", | 473 | " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", |
435 | channel_readl(dwc, SAR), | 474 | channel_readl(dwc, SAR), |
@@ -453,6 +492,8 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
453 | 492 | ||
454 | for (i = 0; i < dwc->cdesc->periods; i++) | 493 | for (i = 0; i < dwc->cdesc->periods; i++) |
455 | dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli); | 494 | dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli); |
495 | |||
496 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
456 | } | 497 | } |
457 | } | 498 | } |
458 | 499 | ||
@@ -476,7 +517,6 @@ static void dw_dma_tasklet(unsigned long data) | |||
476 | 517 | ||
477 | for (i = 0; i < dw->dma.chancnt; i++) { | 518 | for (i = 0; i < dw->dma.chancnt; i++) { |
478 | dwc = &dw->chan[i]; | 519 | dwc = &dw->chan[i]; |
479 | spin_lock(&dwc->lock); | ||
480 | if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) | 520 | if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) |
481 | dwc_handle_cyclic(dw, dwc, status_block, status_err, | 521 | dwc_handle_cyclic(dw, dwc, status_block, status_err, |
482 | status_xfer); | 522 | status_xfer); |
@@ -484,7 +524,6 @@ static void dw_dma_tasklet(unsigned long data) | |||
484 | dwc_handle_error(dw, dwc); | 524 | dwc_handle_error(dw, dwc); |
485 | else if ((status_block | status_xfer) & (1 << i)) | 525 | else if ((status_block | status_xfer) & (1 << i)) |
486 | dwc_scan_descriptors(dw, dwc); | 526 | dwc_scan_descriptors(dw, dwc); |
487 | spin_unlock(&dwc->lock); | ||
488 | } | 527 | } |
489 | 528 | ||
490 | /* | 529 | /* |
@@ -539,8 +578,9 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx) | |||
539 | struct dw_desc *desc = txd_to_dw_desc(tx); | 578 | struct dw_desc *desc = txd_to_dw_desc(tx); |
540 | struct dw_dma_chan *dwc = to_dw_dma_chan(tx->chan); | 579 | struct dw_dma_chan *dwc = to_dw_dma_chan(tx->chan); |
541 | dma_cookie_t cookie; | 580 | dma_cookie_t cookie; |
581 | unsigned long flags; | ||
542 | 582 | ||
543 | spin_lock_bh(&dwc->lock); | 583 | spin_lock_irqsave(&dwc->lock, flags); |
544 | cookie = dwc_assign_cookie(dwc, desc); | 584 | cookie = dwc_assign_cookie(dwc, desc); |
545 | 585 | ||
546 | /* | 586 | /* |
@@ -560,7 +600,7 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx) | |||
560 | list_add_tail(&desc->desc_node, &dwc->queue); | 600 | list_add_tail(&desc->desc_node, &dwc->queue); |
561 | } | 601 | } |
562 | 602 | ||
563 | spin_unlock_bh(&dwc->lock); | 603 | spin_unlock_irqrestore(&dwc->lock, flags); |
564 | 604 | ||
565 | return cookie; | 605 | return cookie; |
566 | } | 606 | } |
@@ -689,9 +729,15 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
689 | reg = dws->tx_reg; | 729 | reg = dws->tx_reg; |
690 | for_each_sg(sgl, sg, sg_len, i) { | 730 | for_each_sg(sgl, sg, sg_len, i) { |
691 | struct dw_desc *desc; | 731 | struct dw_desc *desc; |
692 | u32 len; | 732 | u32 len, dlen, mem; |
693 | u32 mem; | 733 | |
734 | mem = sg_phys(sg); | ||
735 | len = sg_dma_len(sg); | ||
736 | mem_width = 2; | ||
737 | if (unlikely(mem & 3 || len & 3)) | ||
738 | mem_width = 0; | ||
694 | 739 | ||
740 | slave_sg_todev_fill_desc: | ||
695 | desc = dwc_desc_get(dwc); | 741 | desc = dwc_desc_get(dwc); |
696 | if (!desc) { | 742 | if (!desc) { |
697 | dev_err(chan2dev(chan), | 743 | dev_err(chan2dev(chan), |
@@ -699,16 +745,19 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
699 | goto err_desc_get; | 745 | goto err_desc_get; |
700 | } | 746 | } |
701 | 747 | ||
702 | mem = sg_phys(sg); | ||
703 | len = sg_dma_len(sg); | ||
704 | mem_width = 2; | ||
705 | if (unlikely(mem & 3 || len & 3)) | ||
706 | mem_width = 0; | ||
707 | |||
708 | desc->lli.sar = mem; | 748 | desc->lli.sar = mem; |
709 | desc->lli.dar = reg; | 749 | desc->lli.dar = reg; |
710 | desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width); | 750 | desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width); |
711 | desc->lli.ctlhi = len >> mem_width; | 751 | if ((len >> mem_width) > DWC_MAX_COUNT) { |
752 | dlen = DWC_MAX_COUNT << mem_width; | ||
753 | mem += dlen; | ||
754 | len -= dlen; | ||
755 | } else { | ||
756 | dlen = len; | ||
757 | len = 0; | ||
758 | } | ||
759 | |||
760 | desc->lli.ctlhi = dlen >> mem_width; | ||
712 | 761 | ||
713 | if (!first) { | 762 | if (!first) { |
714 | first = desc; | 763 | first = desc; |
@@ -722,7 +771,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
722 | &first->tx_list); | 771 | &first->tx_list); |
723 | } | 772 | } |
724 | prev = desc; | 773 | prev = desc; |
725 | total_len += len; | 774 | total_len += dlen; |
775 | |||
776 | if (len) | ||
777 | goto slave_sg_todev_fill_desc; | ||
726 | } | 778 | } |
727 | break; | 779 | break; |
728 | case DMA_FROM_DEVICE: | 780 | case DMA_FROM_DEVICE: |
@@ -735,15 +787,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
735 | reg = dws->rx_reg; | 787 | reg = dws->rx_reg; |
736 | for_each_sg(sgl, sg, sg_len, i) { | 788 | for_each_sg(sgl, sg, sg_len, i) { |
737 | struct dw_desc *desc; | 789 | struct dw_desc *desc; |
738 | u32 len; | 790 | u32 len, dlen, mem; |
739 | u32 mem; | ||
740 | |||
741 | desc = dwc_desc_get(dwc); | ||
742 | if (!desc) { | ||
743 | dev_err(chan2dev(chan), | ||
744 | "not enough descriptors available\n"); | ||
745 | goto err_desc_get; | ||
746 | } | ||
747 | 791 | ||
748 | mem = sg_phys(sg); | 792 | mem = sg_phys(sg); |
749 | len = sg_dma_len(sg); | 793 | len = sg_dma_len(sg); |
@@ -751,10 +795,26 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
751 | if (unlikely(mem & 3 || len & 3)) | 795 | if (unlikely(mem & 3 || len & 3)) |
752 | mem_width = 0; | 796 | mem_width = 0; |
753 | 797 | ||
798 | slave_sg_fromdev_fill_desc: | ||
799 | desc = dwc_desc_get(dwc); | ||
800 | if (!desc) { | ||
801 | dev_err(chan2dev(chan), | ||
802 | "not enough descriptors available\n"); | ||
803 | goto err_desc_get; | ||
804 | } | ||
805 | |||
754 | desc->lli.sar = reg; | 806 | desc->lli.sar = reg; |
755 | desc->lli.dar = mem; | 807 | desc->lli.dar = mem; |
756 | desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width); | 808 | desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width); |
757 | desc->lli.ctlhi = len >> reg_width; | 809 | if ((len >> reg_width) > DWC_MAX_COUNT) { |
810 | dlen = DWC_MAX_COUNT << reg_width; | ||
811 | mem += dlen; | ||
812 | len -= dlen; | ||
813 | } else { | ||
814 | dlen = len; | ||
815 | len = 0; | ||
816 | } | ||
817 | desc->lli.ctlhi = dlen >> reg_width; | ||
758 | 818 | ||
759 | if (!first) { | 819 | if (!first) { |
760 | first = desc; | 820 | first = desc; |
@@ -768,7 +828,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
768 | &first->tx_list); | 828 | &first->tx_list); |
769 | } | 829 | } |
770 | prev = desc; | 830 | prev = desc; |
771 | total_len += len; | 831 | total_len += dlen; |
832 | |||
833 | if (len) | ||
834 | goto slave_sg_fromdev_fill_desc; | ||
772 | } | 835 | } |
773 | break; | 836 | break; |
774 | default: | 837 | default: |
@@ -799,34 +862,51 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
799 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 862 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
800 | struct dw_dma *dw = to_dw_dma(chan->device); | 863 | struct dw_dma *dw = to_dw_dma(chan->device); |
801 | struct dw_desc *desc, *_desc; | 864 | struct dw_desc *desc, *_desc; |
865 | unsigned long flags; | ||
866 | u32 cfglo; | ||
802 | LIST_HEAD(list); | 867 | LIST_HEAD(list); |
803 | 868 | ||
804 | /* Only supports DMA_TERMINATE_ALL */ | 869 | if (cmd == DMA_PAUSE) { |
805 | if (cmd != DMA_TERMINATE_ALL) | 870 | spin_lock_irqsave(&dwc->lock, flags); |
806 | return -ENXIO; | ||
807 | 871 | ||
808 | /* | 872 | cfglo = channel_readl(dwc, CFG_LO); |
809 | * This is only called when something went wrong elsewhere, so | 873 | channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); |
810 | * we don't really care about the data. Just disable the | 874 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY)) |
811 | * channel. We still have to poll the channel enable bit due | 875 | cpu_relax(); |
812 | * to AHB/HSB limitations. | ||
813 | */ | ||
814 | spin_lock_bh(&dwc->lock); | ||
815 | 876 | ||
816 | channel_clear_bit(dw, CH_EN, dwc->mask); | 877 | dwc->paused = true; |
878 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
879 | } else if (cmd == DMA_RESUME) { | ||
880 | if (!dwc->paused) | ||
881 | return 0; | ||
817 | 882 | ||
818 | while (dma_readl(dw, CH_EN) & dwc->mask) | 883 | spin_lock_irqsave(&dwc->lock, flags); |
819 | cpu_relax(); | ||
820 | 884 | ||
821 | /* active_list entries will end up before queued entries */ | 885 | cfglo = channel_readl(dwc, CFG_LO); |
822 | list_splice_init(&dwc->queue, &list); | 886 | channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP); |
823 | list_splice_init(&dwc->active_list, &list); | 887 | dwc->paused = false; |
824 | 888 | ||
825 | spin_unlock_bh(&dwc->lock); | 889 | spin_unlock_irqrestore(&dwc->lock, flags); |
890 | } else if (cmd == DMA_TERMINATE_ALL) { | ||
891 | spin_lock_irqsave(&dwc->lock, flags); | ||
826 | 892 | ||
827 | /* Flush all pending and queued descriptors */ | 893 | channel_clear_bit(dw, CH_EN, dwc->mask); |
828 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | 894 | while (dma_readl(dw, CH_EN) & dwc->mask) |
829 | dwc_descriptor_complete(dwc, desc); | 895 | cpu_relax(); |
896 | |||
897 | dwc->paused = false; | ||
898 | |||
899 | /* active_list entries will end up before queued entries */ | ||
900 | list_splice_init(&dwc->queue, &list); | ||
901 | list_splice_init(&dwc->active_list, &list); | ||
902 | |||
903 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
904 | |||
905 | /* Flush all pending and queued descriptors */ | ||
906 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | ||
907 | dwc_descriptor_complete(dwc, desc, false); | ||
908 | } else | ||
909 | return -ENXIO; | ||
830 | 910 | ||
831 | return 0; | 911 | return 0; |
832 | } | 912 | } |
@@ -846,9 +926,7 @@ dwc_tx_status(struct dma_chan *chan, | |||
846 | 926 | ||
847 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 927 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
848 | if (ret != DMA_SUCCESS) { | 928 | if (ret != DMA_SUCCESS) { |
849 | spin_lock_bh(&dwc->lock); | ||
850 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); | 929 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); |
851 | spin_unlock_bh(&dwc->lock); | ||
852 | 930 | ||
853 | last_complete = dwc->completed; | 931 | last_complete = dwc->completed; |
854 | last_used = chan->cookie; | 932 | last_used = chan->cookie; |
@@ -856,7 +934,14 @@ dwc_tx_status(struct dma_chan *chan, | |||
856 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 934 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
857 | } | 935 | } |
858 | 936 | ||
859 | dma_set_tx_state(txstate, last_complete, last_used, 0); | 937 | if (ret != DMA_SUCCESS) |
938 | dma_set_tx_state(txstate, last_complete, last_used, | ||
939 | dwc_first_active(dwc)->len); | ||
940 | else | ||
941 | dma_set_tx_state(txstate, last_complete, last_used, 0); | ||
942 | |||
943 | if (dwc->paused) | ||
944 | return DMA_PAUSED; | ||
860 | 945 | ||
861 | return ret; | 946 | return ret; |
862 | } | 947 | } |
@@ -865,10 +950,8 @@ static void dwc_issue_pending(struct dma_chan *chan) | |||
865 | { | 950 | { |
866 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 951 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
867 | 952 | ||
868 | spin_lock_bh(&dwc->lock); | ||
869 | if (!list_empty(&dwc->queue)) | 953 | if (!list_empty(&dwc->queue)) |
870 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); | 954 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); |
871 | spin_unlock_bh(&dwc->lock); | ||
872 | } | 955 | } |
873 | 956 | ||
874 | static int dwc_alloc_chan_resources(struct dma_chan *chan) | 957 | static int dwc_alloc_chan_resources(struct dma_chan *chan) |
@@ -880,6 +963,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
880 | int i; | 963 | int i; |
881 | u32 cfghi; | 964 | u32 cfghi; |
882 | u32 cfglo; | 965 | u32 cfglo; |
966 | unsigned long flags; | ||
883 | 967 | ||
884 | dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); | 968 | dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); |
885 | 969 | ||
@@ -917,16 +1001,16 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
917 | * doesn't mean what you think it means), and status writeback. | 1001 | * doesn't mean what you think it means), and status writeback. |
918 | */ | 1002 | */ |
919 | 1003 | ||
920 | spin_lock_bh(&dwc->lock); | 1004 | spin_lock_irqsave(&dwc->lock, flags); |
921 | i = dwc->descs_allocated; | 1005 | i = dwc->descs_allocated; |
922 | while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) { | 1006 | while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) { |
923 | spin_unlock_bh(&dwc->lock); | 1007 | spin_unlock_irqrestore(&dwc->lock, flags); |
924 | 1008 | ||
925 | desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL); | 1009 | desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL); |
926 | if (!desc) { | 1010 | if (!desc) { |
927 | dev_info(chan2dev(chan), | 1011 | dev_info(chan2dev(chan), |
928 | "only allocated %d descriptors\n", i); | 1012 | "only allocated %d descriptors\n", i); |
929 | spin_lock_bh(&dwc->lock); | 1013 | spin_lock_irqsave(&dwc->lock, flags); |
930 | break; | 1014 | break; |
931 | } | 1015 | } |
932 | 1016 | ||
@@ -938,7 +1022,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
938 | sizeof(desc->lli), DMA_TO_DEVICE); | 1022 | sizeof(desc->lli), DMA_TO_DEVICE); |
939 | dwc_desc_put(dwc, desc); | 1023 | dwc_desc_put(dwc, desc); |
940 | 1024 | ||
941 | spin_lock_bh(&dwc->lock); | 1025 | spin_lock_irqsave(&dwc->lock, flags); |
942 | i = ++dwc->descs_allocated; | 1026 | i = ++dwc->descs_allocated; |
943 | } | 1027 | } |
944 | 1028 | ||
@@ -947,7 +1031,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
947 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | 1031 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); |
948 | channel_set_bit(dw, MASK.ERROR, dwc->mask); | 1032 | channel_set_bit(dw, MASK.ERROR, dwc->mask); |
949 | 1033 | ||
950 | spin_unlock_bh(&dwc->lock); | 1034 | spin_unlock_irqrestore(&dwc->lock, flags); |
951 | 1035 | ||
952 | dev_dbg(chan2dev(chan), | 1036 | dev_dbg(chan2dev(chan), |
953 | "alloc_chan_resources allocated %d descriptors\n", i); | 1037 | "alloc_chan_resources allocated %d descriptors\n", i); |
@@ -960,6 +1044,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
960 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1044 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
961 | struct dw_dma *dw = to_dw_dma(chan->device); | 1045 | struct dw_dma *dw = to_dw_dma(chan->device); |
962 | struct dw_desc *desc, *_desc; | 1046 | struct dw_desc *desc, *_desc; |
1047 | unsigned long flags; | ||
963 | LIST_HEAD(list); | 1048 | LIST_HEAD(list); |
964 | 1049 | ||
965 | dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n", | 1050 | dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n", |
@@ -970,7 +1055,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
970 | BUG_ON(!list_empty(&dwc->queue)); | 1055 | BUG_ON(!list_empty(&dwc->queue)); |
971 | BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask); | 1056 | BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask); |
972 | 1057 | ||
973 | spin_lock_bh(&dwc->lock); | 1058 | spin_lock_irqsave(&dwc->lock, flags); |
974 | list_splice_init(&dwc->free_list, &list); | 1059 | list_splice_init(&dwc->free_list, &list); |
975 | dwc->descs_allocated = 0; | 1060 | dwc->descs_allocated = 0; |
976 | 1061 | ||
@@ -979,7 +1064,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
979 | channel_clear_bit(dw, MASK.BLOCK, dwc->mask); | 1064 | channel_clear_bit(dw, MASK.BLOCK, dwc->mask); |
980 | channel_clear_bit(dw, MASK.ERROR, dwc->mask); | 1065 | channel_clear_bit(dw, MASK.ERROR, dwc->mask); |
981 | 1066 | ||
982 | spin_unlock_bh(&dwc->lock); | 1067 | spin_unlock_irqrestore(&dwc->lock, flags); |
983 | 1068 | ||
984 | list_for_each_entry_safe(desc, _desc, &list, desc_node) { | 1069 | list_for_each_entry_safe(desc, _desc, &list, desc_node) { |
985 | dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc); | 1070 | dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc); |
@@ -1004,13 +1089,14 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1004 | { | 1089 | { |
1005 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1090 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
1006 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | 1091 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
1092 | unsigned long flags; | ||
1007 | 1093 | ||
1008 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { | 1094 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { |
1009 | dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n"); | 1095 | dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n"); |
1010 | return -ENODEV; | 1096 | return -ENODEV; |
1011 | } | 1097 | } |
1012 | 1098 | ||
1013 | spin_lock(&dwc->lock); | 1099 | spin_lock_irqsave(&dwc->lock, flags); |
1014 | 1100 | ||
1015 | /* assert channel is idle */ | 1101 | /* assert channel is idle */ |
1016 | if (dma_readl(dw, CH_EN) & dwc->mask) { | 1102 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
@@ -1023,7 +1109,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1023 | channel_readl(dwc, LLP), | 1109 | channel_readl(dwc, LLP), |
1024 | channel_readl(dwc, CTL_HI), | 1110 | channel_readl(dwc, CTL_HI), |
1025 | channel_readl(dwc, CTL_LO)); | 1111 | channel_readl(dwc, CTL_LO)); |
1026 | spin_unlock(&dwc->lock); | 1112 | spin_unlock_irqrestore(&dwc->lock, flags); |
1027 | return -EBUSY; | 1113 | return -EBUSY; |
1028 | } | 1114 | } |
1029 | 1115 | ||
@@ -1038,7 +1124,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1038 | 1124 | ||
1039 | channel_set_bit(dw, CH_EN, dwc->mask); | 1125 | channel_set_bit(dw, CH_EN, dwc->mask); |
1040 | 1126 | ||
1041 | spin_unlock(&dwc->lock); | 1127 | spin_unlock_irqrestore(&dwc->lock, flags); |
1042 | 1128 | ||
1043 | return 0; | 1129 | return 0; |
1044 | } | 1130 | } |
@@ -1054,14 +1140,15 @@ void dw_dma_cyclic_stop(struct dma_chan *chan) | |||
1054 | { | 1140 | { |
1055 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1141 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
1056 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | 1142 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
1143 | unsigned long flags; | ||
1057 | 1144 | ||
1058 | spin_lock(&dwc->lock); | 1145 | spin_lock_irqsave(&dwc->lock, flags); |
1059 | 1146 | ||
1060 | channel_clear_bit(dw, CH_EN, dwc->mask); | 1147 | channel_clear_bit(dw, CH_EN, dwc->mask); |
1061 | while (dma_readl(dw, CH_EN) & dwc->mask) | 1148 | while (dma_readl(dw, CH_EN) & dwc->mask) |
1062 | cpu_relax(); | 1149 | cpu_relax(); |
1063 | 1150 | ||
1064 | spin_unlock(&dwc->lock); | 1151 | spin_unlock_irqrestore(&dwc->lock, flags); |
1065 | } | 1152 | } |
1066 | EXPORT_SYMBOL(dw_dma_cyclic_stop); | 1153 | EXPORT_SYMBOL(dw_dma_cyclic_stop); |
1067 | 1154 | ||
@@ -1090,17 +1177,18 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | |||
1090 | unsigned int reg_width; | 1177 | unsigned int reg_width; |
1091 | unsigned int periods; | 1178 | unsigned int periods; |
1092 | unsigned int i; | 1179 | unsigned int i; |
1180 | unsigned long flags; | ||
1093 | 1181 | ||
1094 | spin_lock_bh(&dwc->lock); | 1182 | spin_lock_irqsave(&dwc->lock, flags); |
1095 | if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) { | 1183 | if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) { |
1096 | spin_unlock_bh(&dwc->lock); | 1184 | spin_unlock_irqrestore(&dwc->lock, flags); |
1097 | dev_dbg(chan2dev(&dwc->chan), | 1185 | dev_dbg(chan2dev(&dwc->chan), |
1098 | "queue and/or active list are not empty\n"); | 1186 | "queue and/or active list are not empty\n"); |
1099 | return ERR_PTR(-EBUSY); | 1187 | return ERR_PTR(-EBUSY); |
1100 | } | 1188 | } |
1101 | 1189 | ||
1102 | was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags); | 1190 | was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags); |
1103 | spin_unlock_bh(&dwc->lock); | 1191 | spin_unlock_irqrestore(&dwc->lock, flags); |
1104 | if (was_cyclic) { | 1192 | if (was_cyclic) { |
1105 | dev_dbg(chan2dev(&dwc->chan), | 1193 | dev_dbg(chan2dev(&dwc->chan), |
1106 | "channel already prepared for cyclic DMA\n"); | 1194 | "channel already prepared for cyclic DMA\n"); |
@@ -1214,13 +1302,14 @@ void dw_dma_cyclic_free(struct dma_chan *chan) | |||
1214 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | 1302 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
1215 | struct dw_cyclic_desc *cdesc = dwc->cdesc; | 1303 | struct dw_cyclic_desc *cdesc = dwc->cdesc; |
1216 | int i; | 1304 | int i; |
1305 | unsigned long flags; | ||
1217 | 1306 | ||
1218 | dev_dbg(chan2dev(&dwc->chan), "cyclic free\n"); | 1307 | dev_dbg(chan2dev(&dwc->chan), "cyclic free\n"); |
1219 | 1308 | ||
1220 | if (!cdesc) | 1309 | if (!cdesc) |
1221 | return; | 1310 | return; |
1222 | 1311 | ||
1223 | spin_lock_bh(&dwc->lock); | 1312 | spin_lock_irqsave(&dwc->lock, flags); |
1224 | 1313 | ||
1225 | channel_clear_bit(dw, CH_EN, dwc->mask); | 1314 | channel_clear_bit(dw, CH_EN, dwc->mask); |
1226 | while (dma_readl(dw, CH_EN) & dwc->mask) | 1315 | while (dma_readl(dw, CH_EN) & dwc->mask) |
@@ -1230,7 +1319,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan) | |||
1230 | dma_writel(dw, CLEAR.ERROR, dwc->mask); | 1319 | dma_writel(dw, CLEAR.ERROR, dwc->mask); |
1231 | dma_writel(dw, CLEAR.XFER, dwc->mask); | 1320 | dma_writel(dw, CLEAR.XFER, dwc->mask); |
1232 | 1321 | ||
1233 | spin_unlock_bh(&dwc->lock); | 1322 | spin_unlock_irqrestore(&dwc->lock, flags); |
1234 | 1323 | ||
1235 | for (i = 0; i < cdesc->periods; i++) | 1324 | for (i = 0; i < cdesc->periods; i++) |
1236 | dwc_desc_put(dwc, cdesc->desc[i]); | 1325 | dwc_desc_put(dwc, cdesc->desc[i]); |
@@ -1487,3 +1576,4 @@ module_exit(dw_exit); | |||
1487 | MODULE_LICENSE("GPL v2"); | 1576 | MODULE_LICENSE("GPL v2"); |
1488 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); | 1577 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); |
1489 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); | 1578 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
1579 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); | ||
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index 720f821527f8..c3419518d701 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * Driver for the Synopsys DesignWare AHB DMA Controller | 2 | * Driver for the Synopsys DesignWare AHB DMA Controller |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Atmel Corporation | 4 | * Copyright (C) 2005-2007 Atmel Corporation |
5 | * Copyright (C) 2010-2011 ST Microelectronics | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -138,6 +139,7 @@ struct dw_dma_chan { | |||
138 | void __iomem *ch_regs; | 139 | void __iomem *ch_regs; |
139 | u8 mask; | 140 | u8 mask; |
140 | u8 priority; | 141 | u8 priority; |
142 | bool paused; | ||
141 | 143 | ||
142 | spinlock_t lock; | 144 | spinlock_t lock; |
143 | 145 | ||
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 3d4ec38b9b62..f653517ef744 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
@@ -1292,8 +1292,7 @@ static int __devinit intel_mid_dma_probe(struct pci_dev *pdev, | |||
1292 | if (err) | 1292 | if (err) |
1293 | goto err_dma; | 1293 | goto err_dma; |
1294 | 1294 | ||
1295 | pm_runtime_set_active(&pdev->dev); | 1295 | pm_runtime_put_noidle(&pdev->dev); |
1296 | pm_runtime_enable(&pdev->dev); | ||
1297 | pm_runtime_allow(&pdev->dev); | 1296 | pm_runtime_allow(&pdev->dev); |
1298 | return 0; | 1297 | return 0; |
1299 | 1298 | ||
@@ -1322,6 +1321,9 @@ err_enable_device: | |||
1322 | static void __devexit intel_mid_dma_remove(struct pci_dev *pdev) | 1321 | static void __devexit intel_mid_dma_remove(struct pci_dev *pdev) |
1323 | { | 1322 | { |
1324 | struct middma_device *device = pci_get_drvdata(pdev); | 1323 | struct middma_device *device = pci_get_drvdata(pdev); |
1324 | |||
1325 | pm_runtime_get_noresume(&pdev->dev); | ||
1326 | pm_runtime_forbid(&pdev->dev); | ||
1325 | middma_shutdown(pdev); | 1327 | middma_shutdown(pdev); |
1326 | pci_dev_put(pdev); | 1328 | pci_dev_put(pdev); |
1327 | kfree(device); | 1329 | kfree(device); |
@@ -1385,13 +1387,20 @@ int dma_resume(struct pci_dev *pci) | |||
1385 | static int dma_runtime_suspend(struct device *dev) | 1387 | static int dma_runtime_suspend(struct device *dev) |
1386 | { | 1388 | { |
1387 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1389 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1388 | return dma_suspend(pci_dev, PMSG_SUSPEND); | 1390 | struct middma_device *device = pci_get_drvdata(pci_dev); |
1391 | |||
1392 | device->state = SUSPENDED; | ||
1393 | return 0; | ||
1389 | } | 1394 | } |
1390 | 1395 | ||
1391 | static int dma_runtime_resume(struct device *dev) | 1396 | static int dma_runtime_resume(struct device *dev) |
1392 | { | 1397 | { |
1393 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1398 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1394 | return dma_resume(pci_dev); | 1399 | struct middma_device *device = pci_get_drvdata(pci_dev); |
1400 | |||
1401 | device->state = RUNNING; | ||
1402 | iowrite32(REG_BIT0, device->dma_base + DMA_CFG); | ||
1403 | return 0; | ||
1395 | } | 1404 | } |
1396 | 1405 | ||
1397 | static int dma_runtime_idle(struct device *dev) | 1406 | static int dma_runtime_idle(struct device *dev) |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index f4a51d4d0349..5d65f8377971 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -508,6 +508,7 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
508 | struct ioat_ring_ent **ring; | 508 | struct ioat_ring_ent **ring; |
509 | u64 status; | 509 | u64 status; |
510 | int order; | 510 | int order; |
511 | int i = 0; | ||
511 | 512 | ||
512 | /* have we already been set up? */ | 513 | /* have we already been set up? */ |
513 | if (ioat->ring) | 514 | if (ioat->ring) |
@@ -548,8 +549,11 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
548 | ioat2_start_null_desc(ioat); | 549 | ioat2_start_null_desc(ioat); |
549 | 550 | ||
550 | /* check that we got off the ground */ | 551 | /* check that we got off the ground */ |
551 | udelay(5); | 552 | do { |
552 | status = ioat_chansts(chan); | 553 | udelay(1); |
554 | status = ioat_chansts(chan); | ||
555 | } while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status)); | ||
556 | |||
553 | if (is_ioat_active(status) || is_ioat_idle(status)) { | 557 | if (is_ioat_active(status) || is_ioat_idle(status)) { |
554 | set_bit(IOAT_RUN, &chan->state); | 558 | set_bit(IOAT_RUN, &chan->state); |
555 | return 1 << ioat->alloc_order; | 559 | return 1 << ioat->alloc_order; |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index c6b01f535b29..e03f811a83dd 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -619,7 +619,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, | |||
619 | 619 | ||
620 | if (unlikely(!len)) | 620 | if (unlikely(!len)) |
621 | return NULL; | 621 | return NULL; |
622 | BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT)); | 622 | BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT); |
623 | 623 | ||
624 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", | 624 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", |
625 | __func__, len); | 625 | __func__, len); |
@@ -652,7 +652,7 @@ iop_adma_prep_dma_memset(struct dma_chan *chan, dma_addr_t dma_dest, | |||
652 | 652 | ||
653 | if (unlikely(!len)) | 653 | if (unlikely(!len)) |
654 | return NULL; | 654 | return NULL; |
655 | BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT)); | 655 | BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT); |
656 | 656 | ||
657 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", | 657 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", |
658 | __func__, len); | 658 | __func__, len); |
@@ -686,7 +686,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest, | |||
686 | 686 | ||
687 | if (unlikely(!len)) | 687 | if (unlikely(!len)) |
688 | return NULL; | 688 | return NULL; |
689 | BUG_ON(unlikely(len > IOP_ADMA_XOR_MAX_BYTE_COUNT)); | 689 | BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT); |
690 | 690 | ||
691 | dev_dbg(iop_chan->device->common.dev, | 691 | dev_dbg(iop_chan->device->common.dev, |
692 | "%s src_cnt: %d len: %u flags: %lx\n", | 692 | "%s src_cnt: %d len: %u flags: %lx\n", |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a25f5f61e0e0..954e334e01bb 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -671,7 +671,7 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
671 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 671 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
672 | return NULL; | 672 | return NULL; |
673 | 673 | ||
674 | BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); | 674 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
675 | 675 | ||
676 | spin_lock_bh(&mv_chan->lock); | 676 | spin_lock_bh(&mv_chan->lock); |
677 | slot_cnt = mv_chan_memcpy_slot_count(len); | 677 | slot_cnt = mv_chan_memcpy_slot_count(len); |
@@ -710,7 +710,7 @@ mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, | |||
710 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 710 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
711 | return NULL; | 711 | return NULL; |
712 | 712 | ||
713 | BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); | 713 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
714 | 714 | ||
715 | spin_lock_bh(&mv_chan->lock); | 715 | spin_lock_bh(&mv_chan->lock); |
716 | slot_cnt = mv_chan_memset_slot_count(len); | 716 | slot_cnt = mv_chan_memset_slot_count(len); |
@@ -744,7 +744,7 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, | |||
744 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 744 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
745 | return NULL; | 745 | return NULL; |
746 | 746 | ||
747 | BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); | 747 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
748 | 748 | ||
749 | dev_dbg(mv_chan->device->common.dev, | 749 | dev_dbg(mv_chan->device->common.dev, |
750 | "%s src_cnt: %d len: dest %x %u flags: %ld\n", | 750 | "%s src_cnt: %d len: dest %x %u flags: %ld\n", |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 8d8fef1480a9..ff5b38f9d45b 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
@@ -77,10 +77,10 @@ struct pch_dma_regs { | |||
77 | u32 dma_ctl0; | 77 | u32 dma_ctl0; |
78 | u32 dma_ctl1; | 78 | u32 dma_ctl1; |
79 | u32 dma_ctl2; | 79 | u32 dma_ctl2; |
80 | u32 reserved1; | 80 | u32 dma_ctl3; |
81 | u32 dma_sts0; | 81 | u32 dma_sts0; |
82 | u32 dma_sts1; | 82 | u32 dma_sts1; |
83 | u32 reserved2; | 83 | u32 dma_sts2; |
84 | u32 reserved3; | 84 | u32 reserved3; |
85 | struct pch_dma_desc_regs desc[MAX_CHAN_NR]; | 85 | struct pch_dma_desc_regs desc[MAX_CHAN_NR]; |
86 | }; | 86 | }; |
@@ -130,6 +130,7 @@ struct pch_dma { | |||
130 | #define PCH_DMA_CTL0 0x00 | 130 | #define PCH_DMA_CTL0 0x00 |
131 | #define PCH_DMA_CTL1 0x04 | 131 | #define PCH_DMA_CTL1 0x04 |
132 | #define PCH_DMA_CTL2 0x08 | 132 | #define PCH_DMA_CTL2 0x08 |
133 | #define PCH_DMA_CTL3 0x0C | ||
133 | #define PCH_DMA_STS0 0x10 | 134 | #define PCH_DMA_STS0 0x10 |
134 | #define PCH_DMA_STS1 0x14 | 135 | #define PCH_DMA_STS1 0x14 |
135 | 136 | ||
@@ -138,7 +139,8 @@ struct pch_dma { | |||
138 | #define dma_writel(pd, name, val) \ | 139 | #define dma_writel(pd, name, val) \ |
139 | writel((val), (pd)->membase + PCH_DMA_##name) | 140 | writel((val), (pd)->membase + PCH_DMA_##name) |
140 | 141 | ||
141 | static inline struct pch_dma_desc *to_pd_desc(struct dma_async_tx_descriptor *txd) | 142 | static inline |
143 | struct pch_dma_desc *to_pd_desc(struct dma_async_tx_descriptor *txd) | ||
142 | { | 144 | { |
143 | return container_of(txd, struct pch_dma_desc, txd); | 145 | return container_of(txd, struct pch_dma_desc, txd); |
144 | } | 146 | } |
@@ -163,13 +165,15 @@ static inline struct device *chan2parent(struct dma_chan *chan) | |||
163 | return chan->dev->device.parent; | 165 | return chan->dev->device.parent; |
164 | } | 166 | } |
165 | 167 | ||
166 | static inline struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan) | 168 | static inline |
169 | struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan) | ||
167 | { | 170 | { |
168 | return list_first_entry(&pd_chan->active_list, | 171 | return list_first_entry(&pd_chan->active_list, |
169 | struct pch_dma_desc, desc_node); | 172 | struct pch_dma_desc, desc_node); |
170 | } | 173 | } |
171 | 174 | ||
172 | static inline struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan) | 175 | static inline |
176 | struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan) | ||
173 | { | 177 | { |
174 | return list_first_entry(&pd_chan->queue, | 178 | return list_first_entry(&pd_chan->queue, |
175 | struct pch_dma_desc, desc_node); | 179 | struct pch_dma_desc, desc_node); |
@@ -199,16 +203,30 @@ static void pdc_set_dir(struct dma_chan *chan) | |||
199 | struct pch_dma *pd = to_pd(chan->device); | 203 | struct pch_dma *pd = to_pd(chan->device); |
200 | u32 val; | 204 | u32 val; |
201 | 205 | ||
202 | val = dma_readl(pd, CTL0); | 206 | if (chan->chan_id < 8) { |
207 | val = dma_readl(pd, CTL0); | ||
203 | 208 | ||
204 | if (pd_chan->dir == DMA_TO_DEVICE) | 209 | if (pd_chan->dir == DMA_TO_DEVICE) |
205 | val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + | 210 | val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + |
206 | DMA_CTL0_DIR_SHIFT_BITS); | 211 | DMA_CTL0_DIR_SHIFT_BITS); |
207 | else | 212 | else |
208 | val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + | 213 | val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + |
209 | DMA_CTL0_DIR_SHIFT_BITS)); | 214 | DMA_CTL0_DIR_SHIFT_BITS)); |
215 | |||
216 | dma_writel(pd, CTL0, val); | ||
217 | } else { | ||
218 | int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */ | ||
219 | val = dma_readl(pd, CTL3); | ||
210 | 220 | ||
211 | dma_writel(pd, CTL0, val); | 221 | if (pd_chan->dir == DMA_TO_DEVICE) |
222 | val |= 0x1 << (DMA_CTL0_BITS_PER_CH * ch + | ||
223 | DMA_CTL0_DIR_SHIFT_BITS); | ||
224 | else | ||
225 | val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * ch + | ||
226 | DMA_CTL0_DIR_SHIFT_BITS)); | ||
227 | |||
228 | dma_writel(pd, CTL3, val); | ||
229 | } | ||
212 | 230 | ||
213 | dev_dbg(chan2dev(chan), "pdc_set_dir: chan %d -> %x\n", | 231 | dev_dbg(chan2dev(chan), "pdc_set_dir: chan %d -> %x\n", |
214 | chan->chan_id, val); | 232 | chan->chan_id, val); |
@@ -219,13 +237,26 @@ static void pdc_set_mode(struct dma_chan *chan, u32 mode) | |||
219 | struct pch_dma *pd = to_pd(chan->device); | 237 | struct pch_dma *pd = to_pd(chan->device); |
220 | u32 val; | 238 | u32 val; |
221 | 239 | ||
222 | val = dma_readl(pd, CTL0); | 240 | if (chan->chan_id < 8) { |
241 | val = dma_readl(pd, CTL0); | ||
242 | |||
243 | val &= ~(DMA_CTL0_MODE_MASK_BITS << | ||
244 | (DMA_CTL0_BITS_PER_CH * chan->chan_id)); | ||
245 | val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id); | ||
223 | 246 | ||
224 | val &= ~(DMA_CTL0_MODE_MASK_BITS << | 247 | dma_writel(pd, CTL0, val); |
225 | (DMA_CTL0_BITS_PER_CH * chan->chan_id)); | 248 | } else { |
226 | val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id); | 249 | int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */ |
250 | |||
251 | val = dma_readl(pd, CTL3); | ||
252 | |||
253 | val &= ~(DMA_CTL0_MODE_MASK_BITS << | ||
254 | (DMA_CTL0_BITS_PER_CH * ch)); | ||
255 | val |= mode << (DMA_CTL0_BITS_PER_CH * ch); | ||
227 | 256 | ||
228 | dma_writel(pd, CTL0, val); | 257 | dma_writel(pd, CTL3, val); |
258 | |||
259 | } | ||
229 | 260 | ||
230 | dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n", | 261 | dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n", |
231 | chan->chan_id, val); | 262 | chan->chan_id, val); |
@@ -251,9 +282,6 @@ static bool pdc_is_idle(struct pch_dma_chan *pd_chan) | |||
251 | 282 | ||
252 | static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | 283 | static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) |
253 | { | 284 | { |
254 | struct pch_dma *pd = to_pd(pd_chan->chan.device); | ||
255 | u32 val; | ||
256 | |||
257 | if (!pdc_is_idle(pd_chan)) { | 285 | if (!pdc_is_idle(pd_chan)) { |
258 | dev_err(chan2dev(&pd_chan->chan), | 286 | dev_err(chan2dev(&pd_chan->chan), |
259 | "BUG: Attempt to start non-idle channel\n"); | 287 | "BUG: Attempt to start non-idle channel\n"); |
@@ -279,10 +307,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
279 | channel_writel(pd_chan, NEXT, desc->txd.phys); | 307 | channel_writel(pd_chan, NEXT, desc->txd.phys); |
280 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 308 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
281 | } | 309 | } |
282 | |||
283 | val = dma_readl(pd, CTL2); | ||
284 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | ||
285 | dma_writel(pd, CTL2, val); | ||
286 | } | 310 | } |
287 | 311 | ||
288 | static void pdc_chain_complete(struct pch_dma_chan *pd_chan, | 312 | static void pdc_chain_complete(struct pch_dma_chan *pd_chan, |
@@ -403,7 +427,7 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) | |||
403 | { | 427 | { |
404 | struct pch_dma_desc *desc, *_d; | 428 | struct pch_dma_desc *desc, *_d; |
405 | struct pch_dma_desc *ret = NULL; | 429 | struct pch_dma_desc *ret = NULL; |
406 | int i; | 430 | int i = 0; |
407 | 431 | ||
408 | spin_lock(&pd_chan->lock); | 432 | spin_lock(&pd_chan->lock); |
409 | list_for_each_entry_safe(desc, _d, &pd_chan->free_list, desc_node) { | 433 | list_for_each_entry_safe(desc, _d, &pd_chan->free_list, desc_node) { |
@@ -478,7 +502,6 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) | |||
478 | spin_unlock_bh(&pd_chan->lock); | 502 | spin_unlock_bh(&pd_chan->lock); |
479 | 503 | ||
480 | pdc_enable_irq(chan, 1); | 504 | pdc_enable_irq(chan, 1); |
481 | pdc_set_dir(chan); | ||
482 | 505 | ||
483 | return pd_chan->descs_allocated; | 506 | return pd_chan->descs_allocated; |
484 | } | 507 | } |
@@ -561,6 +584,9 @@ static struct dma_async_tx_descriptor *pd_prep_slave_sg(struct dma_chan *chan, | |||
561 | else | 584 | else |
562 | return NULL; | 585 | return NULL; |
563 | 586 | ||
587 | pd_chan->dir = direction; | ||
588 | pdc_set_dir(chan); | ||
589 | |||
564 | for_each_sg(sgl, sg, sg_len, i) { | 590 | for_each_sg(sgl, sg, sg_len, i) { |
565 | desc = pdc_desc_get(pd_chan); | 591 | desc = pdc_desc_get(pd_chan); |
566 | 592 | ||
@@ -703,6 +729,7 @@ static void pch_dma_save_regs(struct pch_dma *pd) | |||
703 | pd->regs.dma_ctl0 = dma_readl(pd, CTL0); | 729 | pd->regs.dma_ctl0 = dma_readl(pd, CTL0); |
704 | pd->regs.dma_ctl1 = dma_readl(pd, CTL1); | 730 | pd->regs.dma_ctl1 = dma_readl(pd, CTL1); |
705 | pd->regs.dma_ctl2 = dma_readl(pd, CTL2); | 731 | pd->regs.dma_ctl2 = dma_readl(pd, CTL2); |
732 | pd->regs.dma_ctl3 = dma_readl(pd, CTL3); | ||
706 | 733 | ||
707 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { | 734 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { |
708 | pd_chan = to_pd_chan(chan); | 735 | pd_chan = to_pd_chan(chan); |
@@ -725,6 +752,7 @@ static void pch_dma_restore_regs(struct pch_dma *pd) | |||
725 | dma_writel(pd, CTL0, pd->regs.dma_ctl0); | 752 | dma_writel(pd, CTL0, pd->regs.dma_ctl0); |
726 | dma_writel(pd, CTL1, pd->regs.dma_ctl1); | 753 | dma_writel(pd, CTL1, pd->regs.dma_ctl1); |
727 | dma_writel(pd, CTL2, pd->regs.dma_ctl2); | 754 | dma_writel(pd, CTL2, pd->regs.dma_ctl2); |
755 | dma_writel(pd, CTL3, pd->regs.dma_ctl3); | ||
728 | 756 | ||
729 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { | 757 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { |
730 | pd_chan = to_pd_chan(chan); | 758 | pd_chan = to_pd_chan(chan); |
@@ -850,8 +878,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, | |||
850 | 878 | ||
851 | pd_chan->membase = ®s->desc[i]; | 879 | pd_chan->membase = ®s->desc[i]; |
852 | 880 | ||
853 | pd_chan->dir = (i % 2) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
854 | |||
855 | spin_lock_init(&pd_chan->lock); | 881 | spin_lock_init(&pd_chan->lock); |
856 | 882 | ||
857 | INIT_LIST_HEAD(&pd_chan->active_list); | 883 | INIT_LIST_HEAD(&pd_chan->active_list); |
@@ -929,13 +955,23 @@ static void __devexit pch_dma_remove(struct pci_dev *pdev) | |||
929 | #define PCI_DEVICE_ID_ML7213_DMA1_8CH 0x8026 | 955 | #define PCI_DEVICE_ID_ML7213_DMA1_8CH 0x8026 |
930 | #define PCI_DEVICE_ID_ML7213_DMA2_8CH 0x802B | 956 | #define PCI_DEVICE_ID_ML7213_DMA2_8CH 0x802B |
931 | #define PCI_DEVICE_ID_ML7213_DMA3_4CH 0x8034 | 957 | #define PCI_DEVICE_ID_ML7213_DMA3_4CH 0x8034 |
958 | #define PCI_DEVICE_ID_ML7213_DMA4_12CH 0x8032 | ||
959 | #define PCI_DEVICE_ID_ML7223_DMA1_4CH 0x800B | ||
960 | #define PCI_DEVICE_ID_ML7223_DMA2_4CH 0x800E | ||
961 | #define PCI_DEVICE_ID_ML7223_DMA3_4CH 0x8017 | ||
962 | #define PCI_DEVICE_ID_ML7223_DMA4_4CH 0x803B | ||
932 | 963 | ||
933 | static const struct pci_device_id pch_dma_id_table[] = { | 964 | DEFINE_PCI_DEVICE_TABLE(pch_dma_id_table) = { |
934 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 }, | 965 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 }, |
935 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_4CH), 4 }, | 966 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_4CH), 4 }, |
936 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA1_8CH), 8}, /* UART Video */ | 967 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA1_8CH), 8}, /* UART Video */ |
937 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA2_8CH), 8}, /* PCMIF SPI */ | 968 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA2_8CH), 8}, /* PCMIF SPI */ |
938 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA3_4CH), 4}, /* FPGA */ | 969 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA3_4CH), 4}, /* FPGA */ |
970 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA4_12CH), 12}, /* I2S */ | ||
971 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA1_4CH), 4}, /* UART */ | ||
972 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA2_4CH), 4}, /* Video SPI */ | ||
973 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA3_4CH), 4}, /* Security */ | ||
974 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA4_4CH), 4}, /* FPGA */ | ||
939 | { 0, }, | 975 | { 0, }, |
940 | }; | 976 | }; |
941 | 977 | ||
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 3b0247e74cc4..fc457a7e8832 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
@@ -2313,7 +2313,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memcpy( | |||
2313 | if (unlikely(!len)) | 2313 | if (unlikely(!len)) |
2314 | return NULL; | 2314 | return NULL; |
2315 | 2315 | ||
2316 | BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT)); | 2316 | BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT); |
2317 | 2317 | ||
2318 | spin_lock_bh(&ppc440spe_chan->lock); | 2318 | spin_lock_bh(&ppc440spe_chan->lock); |
2319 | 2319 | ||
@@ -2354,7 +2354,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memset( | |||
2354 | if (unlikely(!len)) | 2354 | if (unlikely(!len)) |
2355 | return NULL; | 2355 | return NULL; |
2356 | 2356 | ||
2357 | BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT)); | 2357 | BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT); |
2358 | 2358 | ||
2359 | spin_lock_bh(&ppc440spe_chan->lock); | 2359 | spin_lock_bh(&ppc440spe_chan->lock); |
2360 | 2360 | ||
@@ -2397,7 +2397,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_xor( | |||
2397 | dma_dest, dma_src, src_cnt)); | 2397 | dma_dest, dma_src, src_cnt)); |
2398 | if (unlikely(!len)) | 2398 | if (unlikely(!len)) |
2399 | return NULL; | 2399 | return NULL; |
2400 | BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)); | 2400 | BUG_ON(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT); |
2401 | 2401 | ||
2402 | dev_dbg(ppc440spe_chan->device->common.dev, | 2402 | dev_dbg(ppc440spe_chan->device->common.dev, |
2403 | "ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n", | 2403 | "ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n", |
@@ -2887,7 +2887,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_pq( | |||
2887 | ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id, | 2887 | ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id, |
2888 | dst, src, src_cnt)); | 2888 | dst, src, src_cnt)); |
2889 | BUG_ON(!len); | 2889 | BUG_ON(!len); |
2890 | BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)); | 2890 | BUG_ON(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT); |
2891 | BUG_ON(!src_cnt); | 2891 | BUG_ON(!src_cnt); |
2892 | 2892 | ||
2893 | if (src_cnt == 1 && dst[1] == src[0]) { | 2893 | if (src_cnt == 1 && dst[1] == src[0]) { |
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 94ee15dd3aed..8f222d4db7de 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -1829,7 +1829,7 @@ d40_get_dev_addr(struct d40_chan *chan, enum dma_data_direction direction) | |||
1829 | { | 1829 | { |
1830 | struct stedma40_platform_data *plat = chan->base->plat_data; | 1830 | struct stedma40_platform_data *plat = chan->base->plat_data; |
1831 | struct stedma40_chan_cfg *cfg = &chan->dma_cfg; | 1831 | struct stedma40_chan_cfg *cfg = &chan->dma_cfg; |
1832 | dma_addr_t addr; | 1832 | dma_addr_t addr = 0; |
1833 | 1833 | ||
1834 | if (chan->runtime_addr) | 1834 | if (chan->runtime_addr) |
1835 | return chan->runtime_addr; | 1835 | return chan->runtime_addr; |
@@ -2962,4 +2962,4 @@ static int __init stedma40_init(void) | |||
2962 | { | 2962 | { |
2963 | return platform_driver_probe(&d40_driver, d40_probe); | 2963 | return platform_driver_probe(&d40_driver, d40_probe); |
2964 | } | 2964 | } |
2965 | arch_initcall(stedma40_init); | 2965 | subsys_initcall(stedma40_init); |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d21364603755..4a7f63143455 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -86,6 +86,34 @@ config GPIO_IT8761E | |||
86 | help | 86 | help |
87 | Say yes here to support GPIO functionality of IT8761E super I/O chip. | 87 | Say yes here to support GPIO functionality of IT8761E super I/O chip. |
88 | 88 | ||
89 | config GPIO_EXYNOS4 | ||
90 | bool "Samsung Exynos4 GPIO library support" | ||
91 | default y if CPU_EXYNOS4210 | ||
92 | depends on ARM | ||
93 | help | ||
94 | Say yes here to support Samsung Exynos4 series SoCs GPIO library | ||
95 | |||
96 | config GPIO_PLAT_SAMSUNG | ||
97 | bool "Samsung SoCs GPIO library support" | ||
98 | default y if SAMSUNG_GPIOLIB_4BIT | ||
99 | depends on ARM | ||
100 | help | ||
101 | Say yes here to support Samsung SoCs GPIO library | ||
102 | |||
103 | config GPIO_S5PC100 | ||
104 | bool "Samsung S5PC100 GPIO library support" | ||
105 | default y if CPU_S5PC100 | ||
106 | depends on ARM | ||
107 | help | ||
108 | Say yes here to support Samsung S5PC100 SoCs GPIO library | ||
109 | |||
110 | config GPIO_S5PV210 | ||
111 | bool "Samsung S5PV210/S5PC110 GPIO library support" | ||
112 | default y if CPU_S5PV210 | ||
113 | depends on ARM | ||
114 | help | ||
115 | Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library | ||
116 | |||
89 | config GPIO_PL061 | 117 | config GPIO_PL061 |
90 | bool "PrimeCell PL061 GPIO support" | 118 | bool "PrimeCell PL061 GPIO support" |
91 | depends on ARM_AMBA | 119 | depends on ARM_AMBA |
@@ -303,7 +331,7 @@ comment "PCI GPIO expanders:" | |||
303 | 331 | ||
304 | config GPIO_CS5535 | 332 | config GPIO_CS5535 |
305 | tristate "AMD CS5535/CS5536 GPIO support" | 333 | tristate "AMD CS5535/CS5536 GPIO support" |
306 | depends on PCI && X86 && !CS5535_GPIO | 334 | depends on PCI && X86 && !CS5535_GPIO && MFD_CS5535 |
307 | help | 335 | help |
308 | The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that | 336 | The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that |
309 | can be used for quite a number of things. The CS5535/6 is found on | 337 | can be used for quite a number of things. The CS5535/6 is found on |
@@ -334,13 +362,19 @@ config GPIO_LANGWELL | |||
334 | Say Y here to support Intel Langwell/Penwell GPIO. | 362 | Say Y here to support Intel Langwell/Penwell GPIO. |
335 | 363 | ||
336 | config GPIO_PCH | 364 | config GPIO_PCH |
337 | tristate "PCH GPIO of Intel Topcliff" | 365 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO" |
338 | depends on PCI && X86 | 366 | depends on PCI && X86 |
339 | help | 367 | help |
340 | This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff | 368 | This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff |
341 | which is an IOH(Input/Output Hub) for x86 embedded processor. | 369 | which is an IOH(Input/Output Hub) for x86 embedded processor. |
342 | This driver can access PCH GPIO device. | 370 | This driver can access PCH GPIO device. |
343 | 371 | ||
372 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ | ||
373 | Output Hub), ML7223. | ||
374 | ML7223 IOH is for MP(Media Phone) use. | ||
375 | ML7223 is companion chip for Intel Atom E6xx series. | ||
376 | ML7223 is completely compatible for Intel EG20T PCH. | ||
377 | |||
344 | config GPIO_ML_IOH | 378 | config GPIO_ML_IOH |
345 | tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" | 379 | tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" |
346 | depends on PCI | 380 | depends on PCI |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 6a3387acc0e5..b605f8ec6fbe 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -8,6 +8,10 @@ obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o | |||
8 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o | 8 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o |
9 | obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o | 9 | obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o |
10 | obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o | 10 | obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o |
11 | obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o | ||
12 | obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o | ||
13 | obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o | ||
14 | obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o | ||
11 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o | 15 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o |
12 | obj-$(CONFIG_GPIO_MAX730X) += max730x.o | 16 | obj-$(CONFIG_GPIO_MAX730X) += max730x.o |
13 | obj-$(CONFIG_GPIO_MAX7300) += max7300.o | 17 | obj-$(CONFIG_GPIO_MAX7300) += max7300.o |
@@ -16,6 +20,7 @@ obj-$(CONFIG_GPIO_MAX732X) += max732x.o | |||
16 | obj-$(CONFIG_GPIO_MC33880) += mc33880.o | 20 | obj-$(CONFIG_GPIO_MC33880) += mc33880.o |
17 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o | 21 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o |
18 | obj-$(CONFIG_GPIO_74X164) += 74x164.o | 22 | obj-$(CONFIG_GPIO_74X164) += 74x164.o |
23 | obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o | ||
19 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o | 24 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o |
20 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | 25 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o |
21 | obj-$(CONFIG_GPIO_PCH) += pch_gpio.o | 26 | obj-$(CONFIG_GPIO_PCH) += pch_gpio.o |
@@ -34,6 +39,8 @@ obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o | |||
34 | obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o | 39 | obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o |
35 | obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o | 40 | obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o |
36 | obj-$(CONFIG_GPIO_SCH) += sch_gpio.o | 41 | obj-$(CONFIG_GPIO_SCH) += sch_gpio.o |
42 | obj-$(CONFIG_MACH_U300) += gpio-u300.o | ||
43 | obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o | ||
37 | obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o | 44 | obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o |
38 | obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o | 45 | obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o |
39 | obj-$(CONFIG_GPIO_SX150X) += sx150x.o | 46 | obj-$(CONFIG_GPIO_SX150X) += sx150x.o |
diff --git a/arch/arm/mach-exynos4/gpiolib.c b/drivers/gpio/gpio-exynos4.c index d54ca6adb660..d54ca6adb660 100644 --- a/arch/arm/mach-exynos4/gpiolib.c +++ b/drivers/gpio/gpio-exynos4.c | |||
diff --git a/arch/arm/plat-nomadik/gpio.c b/drivers/gpio/gpio-nomadik.c index 307b8131aa8c..4961ef9bc153 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/drivers/gpio/gpio-nomadik.c | |||
@@ -57,6 +57,7 @@ struct nmk_gpio_chip { | |||
57 | u32 fwimsc; | 57 | u32 fwimsc; |
58 | u32 slpm; | 58 | u32 slpm; |
59 | u32 enabled; | 59 | u32 enabled; |
60 | u32 pull_up; | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | static struct nmk_gpio_chip * | 63 | static struct nmk_gpio_chip * |
@@ -103,16 +104,22 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip, | |||
103 | u32 pdis; | 104 | u32 pdis; |
104 | 105 | ||
105 | pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS); | 106 | pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS); |
106 | if (pull == NMK_GPIO_PULL_NONE) | 107 | if (pull == NMK_GPIO_PULL_NONE) { |
107 | pdis |= bit; | 108 | pdis |= bit; |
108 | else | 109 | nmk_chip->pull_up &= ~bit; |
110 | } else { | ||
109 | pdis &= ~bit; | 111 | pdis &= ~bit; |
112 | } | ||
113 | |||
110 | writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS); | 114 | writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS); |
111 | 115 | ||
112 | if (pull == NMK_GPIO_PULL_UP) | 116 | if (pull == NMK_GPIO_PULL_UP) { |
117 | nmk_chip->pull_up |= bit; | ||
113 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); | 118 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); |
114 | else if (pull == NMK_GPIO_PULL_DOWN) | 119 | } else if (pull == NMK_GPIO_PULL_DOWN) { |
120 | nmk_chip->pull_up &= ~bit; | ||
115 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | 121 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); |
122 | } | ||
116 | } | 123 | } |
117 | 124 | ||
118 | static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, | 125 | static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, |
@@ -811,20 +818,43 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
811 | bool pull; | 818 | bool pull; |
812 | u32 bit = 1 << i; | 819 | u32 bit = 1 << i; |
813 | 820 | ||
814 | if (!label) | ||
815 | continue; | ||
816 | |||
817 | is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit; | 821 | is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit; |
818 | pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); | 822 | pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); |
819 | mode = nmk_gpio_get_mode(gpio); | 823 | mode = nmk_gpio_get_mode(gpio); |
820 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", | 824 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", |
821 | gpio, label, | 825 | gpio, label ?: "(none)", |
822 | is_out ? "out" : "in ", | 826 | is_out ? "out" : "in ", |
823 | chip->get | 827 | chip->get |
824 | ? (chip->get(chip, i) ? "hi" : "lo") | 828 | ? (chip->get(chip, i) ? "hi" : "lo") |
825 | : "? ", | 829 | : "? ", |
826 | (mode < 0) ? "unknown" : modes[mode], | 830 | (mode < 0) ? "unknown" : modes[mode], |
827 | pull ? "pull" : "none"); | 831 | pull ? "pull" : "none"); |
832 | |||
833 | if (label && !is_out) { | ||
834 | int irq = gpio_to_irq(gpio); | ||
835 | struct irq_desc *desc = irq_to_desc(irq); | ||
836 | |||
837 | /* This races with request_irq(), set_irq_type(), | ||
838 | * and set_irq_wake() ... but those are "rare". | ||
839 | */ | ||
840 | if (irq >= 0 && desc->action) { | ||
841 | char *trigger; | ||
842 | u32 bitmask = nmk_gpio_get_bitmask(gpio); | ||
843 | |||
844 | if (nmk_chip->edge_rising & bitmask) | ||
845 | trigger = "edge-rising"; | ||
846 | else if (nmk_chip->edge_falling & bitmask) | ||
847 | trigger = "edge-falling"; | ||
848 | else | ||
849 | trigger = "edge-undefined"; | ||
850 | |||
851 | seq_printf(s, " irq-%d %s%s", | ||
852 | irq, trigger, | ||
853 | irqd_is_wakeup_set(&desc->irq_data) | ||
854 | ? " wakeup" : ""); | ||
855 | } | ||
856 | } | ||
857 | |||
828 | seq_printf(s, "\n"); | 858 | seq_printf(s, "\n"); |
829 | } | 859 | } |
830 | } | 860 | } |
@@ -898,6 +928,25 @@ void nmk_gpio_wakeups_resume(void) | |||
898 | } | 928 | } |
899 | } | 929 | } |
900 | 930 | ||
931 | /* | ||
932 | * Read the pull up/pull down status. | ||
933 | * A bit set in 'pull_up' means that pull up | ||
934 | * is selected if pull is enabled in PDIS register. | ||
935 | * Note: only pull up/down set via this driver can | ||
936 | * be detected due to HW limitations. | ||
937 | */ | ||
938 | void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) | ||
939 | { | ||
940 | if (gpio_bank < NUM_BANKS) { | ||
941 | struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank]; | ||
942 | |||
943 | if (!chip) | ||
944 | return; | ||
945 | |||
946 | *pull_up = chip->pull_up; | ||
947 | } | ||
948 | } | ||
949 | |||
901 | static int __devinit nmk_gpio_probe(struct platform_device *dev) | 950 | static int __devinit nmk_gpio_probe(struct platform_device *dev) |
902 | { | 951 | { |
903 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; | 952 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; |
diff --git a/arch/arm/plat-omap/gpio.c b/drivers/gpio/gpio-omap.c index efb869390199..6c51191da567 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-omap/gpio.c | ||
3 | * | ||
4 | * Support functions for OMAP GPIO | 2 | * Support functions for OMAP GPIO |
5 | * | 3 | * |
6 | * Copyright (C) 2003-2005 Nokia Corporation | 4 | * Copyright (C) 2003-2005 Nokia Corporation |
@@ -30,109 +28,6 @@ | |||
30 | #include <mach/gpio.h> | 28 | #include <mach/gpio.h> |
31 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
32 | 30 | ||
33 | /* | ||
34 | * OMAP1510 GPIO registers | ||
35 | */ | ||
36 | #define OMAP1510_GPIO_DATA_INPUT 0x00 | ||
37 | #define OMAP1510_GPIO_DATA_OUTPUT 0x04 | ||
38 | #define OMAP1510_GPIO_DIR_CONTROL 0x08 | ||
39 | #define OMAP1510_GPIO_INT_CONTROL 0x0c | ||
40 | #define OMAP1510_GPIO_INT_MASK 0x10 | ||
41 | #define OMAP1510_GPIO_INT_STATUS 0x14 | ||
42 | #define OMAP1510_GPIO_PIN_CONTROL 0x18 | ||
43 | |||
44 | #define OMAP1510_IH_GPIO_BASE 64 | ||
45 | |||
46 | /* | ||
47 | * OMAP1610 specific GPIO registers | ||
48 | */ | ||
49 | #define OMAP1610_GPIO_REVISION 0x0000 | ||
50 | #define OMAP1610_GPIO_SYSCONFIG 0x0010 | ||
51 | #define OMAP1610_GPIO_SYSSTATUS 0x0014 | ||
52 | #define OMAP1610_GPIO_IRQSTATUS1 0x0018 | ||
53 | #define OMAP1610_GPIO_IRQENABLE1 0x001c | ||
54 | #define OMAP1610_GPIO_WAKEUPENABLE 0x0028 | ||
55 | #define OMAP1610_GPIO_DATAIN 0x002c | ||
56 | #define OMAP1610_GPIO_DATAOUT 0x0030 | ||
57 | #define OMAP1610_GPIO_DIRECTION 0x0034 | ||
58 | #define OMAP1610_GPIO_EDGE_CTRL1 0x0038 | ||
59 | #define OMAP1610_GPIO_EDGE_CTRL2 0x003c | ||
60 | #define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c | ||
61 | #define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 | ||
62 | #define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 | ||
63 | #define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc | ||
64 | #define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 | ||
65 | #define OMAP1610_GPIO_SET_DATAOUT 0x00f0 | ||
66 | |||
67 | /* | ||
68 | * OMAP7XX specific GPIO registers | ||
69 | */ | ||
70 | #define OMAP7XX_GPIO_DATA_INPUT 0x00 | ||
71 | #define OMAP7XX_GPIO_DATA_OUTPUT 0x04 | ||
72 | #define OMAP7XX_GPIO_DIR_CONTROL 0x08 | ||
73 | #define OMAP7XX_GPIO_INT_CONTROL 0x0c | ||
74 | #define OMAP7XX_GPIO_INT_MASK 0x10 | ||
75 | #define OMAP7XX_GPIO_INT_STATUS 0x14 | ||
76 | |||
77 | /* | ||
78 | * omap2+ specific GPIO registers | ||
79 | */ | ||
80 | #define OMAP24XX_GPIO_REVISION 0x0000 | ||
81 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 | ||
82 | #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 | ||
83 | #define OMAP24XX_GPIO_IRQENABLE2 0x002c | ||
84 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c | ||
85 | #define OMAP24XX_GPIO_WAKE_EN 0x0020 | ||
86 | #define OMAP24XX_GPIO_CTRL 0x0030 | ||
87 | #define OMAP24XX_GPIO_OE 0x0034 | ||
88 | #define OMAP24XX_GPIO_DATAIN 0x0038 | ||
89 | #define OMAP24XX_GPIO_DATAOUT 0x003c | ||
90 | #define OMAP24XX_GPIO_LEVELDETECT0 0x0040 | ||
91 | #define OMAP24XX_GPIO_LEVELDETECT1 0x0044 | ||
92 | #define OMAP24XX_GPIO_RISINGDETECT 0x0048 | ||
93 | #define OMAP24XX_GPIO_FALLINGDETECT 0x004c | ||
94 | #define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 | ||
95 | #define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 | ||
96 | #define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 | ||
97 | #define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 | ||
98 | #define OMAP24XX_GPIO_CLEARWKUENA 0x0080 | ||
99 | #define OMAP24XX_GPIO_SETWKUENA 0x0084 | ||
100 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 | ||
101 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 | ||
102 | |||
103 | #define OMAP4_GPIO_REVISION 0x0000 | ||
104 | #define OMAP4_GPIO_EOI 0x0020 | ||
105 | #define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 | ||
106 | #define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 | ||
107 | #define OMAP4_GPIO_IRQSTATUS0 0x002c | ||
108 | #define OMAP4_GPIO_IRQSTATUS1 0x0030 | ||
109 | #define OMAP4_GPIO_IRQSTATUSSET0 0x0034 | ||
110 | #define OMAP4_GPIO_IRQSTATUSSET1 0x0038 | ||
111 | #define OMAP4_GPIO_IRQSTATUSCLR0 0x003c | ||
112 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 | ||
113 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 | ||
114 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 | ||
115 | #define OMAP4_GPIO_IRQENABLE1 0x011c | ||
116 | #define OMAP4_GPIO_WAKE_EN 0x0120 | ||
117 | #define OMAP4_GPIO_IRQSTATUS2 0x0128 | ||
118 | #define OMAP4_GPIO_IRQENABLE2 0x012c | ||
119 | #define OMAP4_GPIO_CTRL 0x0130 | ||
120 | #define OMAP4_GPIO_OE 0x0134 | ||
121 | #define OMAP4_GPIO_DATAIN 0x0138 | ||
122 | #define OMAP4_GPIO_DATAOUT 0x013c | ||
123 | #define OMAP4_GPIO_LEVELDETECT0 0x0140 | ||
124 | #define OMAP4_GPIO_LEVELDETECT1 0x0144 | ||
125 | #define OMAP4_GPIO_RISINGDETECT 0x0148 | ||
126 | #define OMAP4_GPIO_FALLINGDETECT 0x014c | ||
127 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 | ||
128 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 | ||
129 | #define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 | ||
130 | #define OMAP4_GPIO_SETIRQENABLE1 0x0164 | ||
131 | #define OMAP4_GPIO_CLEARWKUENA 0x0180 | ||
132 | #define OMAP4_GPIO_SETWKUENA 0x0184 | ||
133 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 | ||
134 | #define OMAP4_GPIO_SETDATAOUT 0x0194 | ||
135 | |||
136 | struct gpio_bank { | 31 | struct gpio_bank { |
137 | unsigned long pbase; | 32 | unsigned long pbase; |
138 | void __iomem *base; | 33 | void __iomem *base; |
diff --git a/arch/arm/plat-samsung/gpiolib.c b/drivers/gpio/gpio-plat-samsung.c index ea37c0461788..ea37c0461788 100644 --- a/arch/arm/plat-samsung/gpiolib.c +++ b/drivers/gpio/gpio-plat-samsung.c | |||
diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/drivers/gpio/gpio-s5pc100.c index 2842394b28b5..2842394b28b5 100644 --- a/arch/arm/mach-s5pc100/gpiolib.c +++ b/drivers/gpio/gpio-s5pc100.c | |||
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/drivers/gpio/gpio-s5pv210.c index 1ba20a703e05..1ba20a703e05 100644 --- a/arch/arm/mach-s5pv210/gpiolib.c +++ b/drivers/gpio/gpio-s5pv210.c | |||
diff --git a/arch/arm/mach-u300/gpio.c b/drivers/gpio/gpio-u300.c index d92790140fe5..d92790140fe5 100644 --- a/arch/arm/mach-u300/gpio.c +++ b/drivers/gpio/gpio-u300.c | |||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 137a8ca67822..a971e3d043ba 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1296,7 +1296,7 @@ EXPORT_SYMBOL_GPL(gpio_request_one); | |||
1296 | * @array: array of the 'struct gpio' | 1296 | * @array: array of the 'struct gpio' |
1297 | * @num: how many GPIOs in the array | 1297 | * @num: how many GPIOs in the array |
1298 | */ | 1298 | */ |
1299 | int gpio_request_array(struct gpio *array, size_t num) | 1299 | int gpio_request_array(const struct gpio *array, size_t num) |
1300 | { | 1300 | { |
1301 | int i, err; | 1301 | int i, err; |
1302 | 1302 | ||
@@ -1319,7 +1319,7 @@ EXPORT_SYMBOL_GPL(gpio_request_array); | |||
1319 | * @array: array of the 'struct gpio' | 1319 | * @array: array of the 'struct gpio' |
1320 | * @num: how many GPIOs in the array | 1320 | * @num: how many GPIOs in the array |
1321 | */ | 1321 | */ |
1322 | void gpio_free_array(struct gpio *array, size_t num) | 1322 | void gpio_free_array(const struct gpio *array, size_t num) |
1323 | { | 1323 | { |
1324 | while (num--) | 1324 | while (num--) |
1325 | gpio_free((array++)->gpio); | 1325 | gpio_free((array++)->gpio); |
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 1b06f67e1f69..bd6571e0097a 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/pm_runtime.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Langwell chip has 64 pins and thus there are 2 32bit registers to control | 39 | * Langwell chip has 64 pins and thus there are 2 32bit registers to control |
@@ -63,6 +64,7 @@ struct lnw_gpio { | |||
63 | void *reg_base; | 64 | void *reg_base; |
64 | spinlock_t lock; | 65 | spinlock_t lock; |
65 | unsigned irq_base; | 66 | unsigned irq_base; |
67 | struct pci_dev *pdev; | ||
66 | }; | 68 | }; |
67 | 69 | ||
68 | static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, | 70 | static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, |
@@ -104,11 +106,18 @@ static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
104 | u32 value; | 106 | u32 value; |
105 | unsigned long flags; | 107 | unsigned long flags; |
106 | 108 | ||
109 | if (lnw->pdev) | ||
110 | pm_runtime_get(&lnw->pdev->dev); | ||
111 | |||
107 | spin_lock_irqsave(&lnw->lock, flags); | 112 | spin_lock_irqsave(&lnw->lock, flags); |
108 | value = readl(gpdr); | 113 | value = readl(gpdr); |
109 | value &= ~BIT(offset % 32); | 114 | value &= ~BIT(offset % 32); |
110 | writel(value, gpdr); | 115 | writel(value, gpdr); |
111 | spin_unlock_irqrestore(&lnw->lock, flags); | 116 | spin_unlock_irqrestore(&lnw->lock, flags); |
117 | |||
118 | if (lnw->pdev) | ||
119 | pm_runtime_put(&lnw->pdev->dev); | ||
120 | |||
112 | return 0; | 121 | return 0; |
113 | } | 122 | } |
114 | 123 | ||
@@ -120,11 +129,19 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, | |||
120 | unsigned long flags; | 129 | unsigned long flags; |
121 | 130 | ||
122 | lnw_gpio_set(chip, offset, value); | 131 | lnw_gpio_set(chip, offset, value); |
132 | |||
133 | if (lnw->pdev) | ||
134 | pm_runtime_get(&lnw->pdev->dev); | ||
135 | |||
123 | spin_lock_irqsave(&lnw->lock, flags); | 136 | spin_lock_irqsave(&lnw->lock, flags); |
124 | value = readl(gpdr); | 137 | value = readl(gpdr); |
125 | value |= BIT(offset % 32); | 138 | value |= BIT(offset % 32); |
126 | writel(value, gpdr); | 139 | writel(value, gpdr); |
127 | spin_unlock_irqrestore(&lnw->lock, flags); | 140 | spin_unlock_irqrestore(&lnw->lock, flags); |
141 | |||
142 | if (lnw->pdev) | ||
143 | pm_runtime_put(&lnw->pdev->dev); | ||
144 | |||
128 | return 0; | 145 | return 0; |
129 | } | 146 | } |
130 | 147 | ||
@@ -145,6 +162,10 @@ static int lnw_irq_type(struct irq_data *d, unsigned type) | |||
145 | 162 | ||
146 | if (gpio >= lnw->chip.ngpio) | 163 | if (gpio >= lnw->chip.ngpio) |
147 | return -EINVAL; | 164 | return -EINVAL; |
165 | |||
166 | if (lnw->pdev) | ||
167 | pm_runtime_get(&lnw->pdev->dev); | ||
168 | |||
148 | spin_lock_irqsave(&lnw->lock, flags); | 169 | spin_lock_irqsave(&lnw->lock, flags); |
149 | if (type & IRQ_TYPE_EDGE_RISING) | 170 | if (type & IRQ_TYPE_EDGE_RISING) |
150 | value = readl(grer) | BIT(gpio % 32); | 171 | value = readl(grer) | BIT(gpio % 32); |
@@ -159,6 +180,9 @@ static int lnw_irq_type(struct irq_data *d, unsigned type) | |||
159 | writel(value, gfer); | 180 | writel(value, gfer); |
160 | spin_unlock_irqrestore(&lnw->lock, flags); | 181 | spin_unlock_irqrestore(&lnw->lock, flags); |
161 | 182 | ||
183 | if (lnw->pdev) | ||
184 | pm_runtime_put(&lnw->pdev->dev); | ||
185 | |||
162 | return 0; | 186 | return 0; |
163 | } | 187 | } |
164 | 188 | ||
@@ -211,6 +235,39 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) | |||
211 | chip->irq_eoi(data); | 235 | chip->irq_eoi(data); |
212 | } | 236 | } |
213 | 237 | ||
238 | #ifdef CONFIG_PM | ||
239 | static int lnw_gpio_runtime_resume(struct device *dev) | ||
240 | { | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int lnw_gpio_runtime_suspend(struct device *dev) | ||
245 | { | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int lnw_gpio_runtime_idle(struct device *dev) | ||
250 | { | ||
251 | int err = pm_schedule_suspend(dev, 500); | ||
252 | |||
253 | if (!err) | ||
254 | return 0; | ||
255 | |||
256 | return -EBUSY; | ||
257 | } | ||
258 | |||
259 | #else | ||
260 | #define lnw_gpio_runtime_suspend NULL | ||
261 | #define lnw_gpio_runtime_resume NULL | ||
262 | #define lnw_gpio_runtime_idle NULL | ||
263 | #endif | ||
264 | |||
265 | static const struct dev_pm_ops lnw_gpio_pm_ops = { | ||
266 | .runtime_suspend = lnw_gpio_runtime_suspend, | ||
267 | .runtime_resume = lnw_gpio_runtime_resume, | ||
268 | .runtime_idle = lnw_gpio_runtime_idle, | ||
269 | }; | ||
270 | |||
214 | static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | 271 | static int __devinit lnw_gpio_probe(struct pci_dev *pdev, |
215 | const struct pci_device_id *id) | 272 | const struct pci_device_id *id) |
216 | { | 273 | { |
@@ -270,6 +327,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
270 | lnw->chip.base = gpio_base; | 327 | lnw->chip.base = gpio_base; |
271 | lnw->chip.ngpio = id->driver_data; | 328 | lnw->chip.ngpio = id->driver_data; |
272 | lnw->chip.can_sleep = 0; | 329 | lnw->chip.can_sleep = 0; |
330 | lnw->pdev = pdev; | ||
273 | pci_set_drvdata(pdev, lnw); | 331 | pci_set_drvdata(pdev, lnw); |
274 | retval = gpiochip_add(&lnw->chip); | 332 | retval = gpiochip_add(&lnw->chip); |
275 | if (retval) { | 333 | if (retval) { |
@@ -285,6 +343,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
285 | } | 343 | } |
286 | 344 | ||
287 | spin_lock_init(&lnw->lock); | 345 | spin_lock_init(&lnw->lock); |
346 | |||
347 | pm_runtime_put_noidle(&pdev->dev); | ||
348 | pm_runtime_allow(&pdev->dev); | ||
349 | |||
288 | goto done; | 350 | goto done; |
289 | err5: | 351 | err5: |
290 | kfree(lnw); | 352 | kfree(lnw); |
@@ -302,6 +364,9 @@ static struct pci_driver lnw_gpio_driver = { | |||
302 | .name = "langwell_gpio", | 364 | .name = "langwell_gpio", |
303 | .id_table = lnw_gpio_ids, | 365 | .id_table = lnw_gpio_ids, |
304 | .probe = lnw_gpio_probe, | 366 | .probe = lnw_gpio_probe, |
367 | .driver = { | ||
368 | .pm = &lnw_gpio_pm_ops, | ||
369 | }, | ||
305 | }; | 370 | }; |
306 | 371 | ||
307 | 372 | ||
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 78a843947d82..0451d7ac94ac 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -24,33 +24,46 @@ | |||
24 | #include <linux/of_gpio.h> | 24 | #include <linux/of_gpio.h> |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #define PCA953X_INPUT 0 | 27 | #define PCA953X_INPUT 0 |
28 | #define PCA953X_OUTPUT 1 | 28 | #define PCA953X_OUTPUT 1 |
29 | #define PCA953X_INVERT 2 | 29 | #define PCA953X_INVERT 2 |
30 | #define PCA953X_DIRECTION 3 | 30 | #define PCA953X_DIRECTION 3 |
31 | 31 | ||
32 | #define PCA953X_GPIOS 0x00FF | 32 | #define PCA957X_IN 0 |
33 | #define PCA953X_INT 0x0100 | 33 | #define PCA957X_INVRT 1 |
34 | #define PCA957X_BKEN 2 | ||
35 | #define PCA957X_PUPD 3 | ||
36 | #define PCA957X_CFG 4 | ||
37 | #define PCA957X_OUT 5 | ||
38 | #define PCA957X_MSK 6 | ||
39 | #define PCA957X_INTS 7 | ||
40 | |||
41 | #define PCA_GPIO_MASK 0x00FF | ||
42 | #define PCA_INT 0x0100 | ||
43 | #define PCA953X_TYPE 0x1000 | ||
44 | #define PCA957X_TYPE 0x2000 | ||
34 | 45 | ||
35 | static const struct i2c_device_id pca953x_id[] = { | 46 | static const struct i2c_device_id pca953x_id[] = { |
36 | { "pca9534", 8 | PCA953X_INT, }, | 47 | { "pca9534", 8 | PCA953X_TYPE | PCA_INT, }, |
37 | { "pca9535", 16 | PCA953X_INT, }, | 48 | { "pca9535", 16 | PCA953X_TYPE | PCA_INT, }, |
38 | { "pca9536", 4, }, | 49 | { "pca9536", 4 | PCA953X_TYPE, }, |
39 | { "pca9537", 4 | PCA953X_INT, }, | 50 | { "pca9537", 4 | PCA953X_TYPE | PCA_INT, }, |
40 | { "pca9538", 8 | PCA953X_INT, }, | 51 | { "pca9538", 8 | PCA953X_TYPE | PCA_INT, }, |
41 | { "pca9539", 16 | PCA953X_INT, }, | 52 | { "pca9539", 16 | PCA953X_TYPE | PCA_INT, }, |
42 | { "pca9554", 8 | PCA953X_INT, }, | 53 | { "pca9554", 8 | PCA953X_TYPE | PCA_INT, }, |
43 | { "pca9555", 16 | PCA953X_INT, }, | 54 | { "pca9555", 16 | PCA953X_TYPE | PCA_INT, }, |
44 | { "pca9556", 8, }, | 55 | { "pca9556", 8 | PCA953X_TYPE, }, |
45 | { "pca9557", 8, }, | 56 | { "pca9557", 8 | PCA953X_TYPE, }, |
46 | 57 | { "pca9574", 8 | PCA957X_TYPE | PCA_INT, }, | |
47 | { "max7310", 8, }, | 58 | { "pca9575", 16 | PCA957X_TYPE | PCA_INT, }, |
48 | { "max7312", 16 | PCA953X_INT, }, | 59 | |
49 | { "max7313", 16 | PCA953X_INT, }, | 60 | { "max7310", 8 | PCA953X_TYPE, }, |
50 | { "max7315", 8 | PCA953X_INT, }, | 61 | { "max7312", 16 | PCA953X_TYPE | PCA_INT, }, |
51 | { "pca6107", 8 | PCA953X_INT, }, | 62 | { "max7313", 16 | PCA953X_TYPE | PCA_INT, }, |
52 | { "tca6408", 8 | PCA953X_INT, }, | 63 | { "max7315", 8 | PCA953X_TYPE | PCA_INT, }, |
53 | { "tca6416", 16 | PCA953X_INT, }, | 64 | { "pca6107", 8 | PCA953X_TYPE | PCA_INT, }, |
65 | { "tca6408", 8 | PCA953X_TYPE | PCA_INT, }, | ||
66 | { "tca6416", 16 | PCA953X_TYPE | PCA_INT, }, | ||
54 | /* NYET: { "tca6424", 24, }, */ | 67 | /* NYET: { "tca6424", 24, }, */ |
55 | { } | 68 | { } |
56 | }; | 69 | }; |
@@ -75,16 +88,32 @@ struct pca953x_chip { | |||
75 | struct pca953x_platform_data *dyn_pdata; | 88 | struct pca953x_platform_data *dyn_pdata; |
76 | struct gpio_chip gpio_chip; | 89 | struct gpio_chip gpio_chip; |
77 | const char *const *names; | 90 | const char *const *names; |
91 | int chip_type; | ||
78 | }; | 92 | }; |
79 | 93 | ||
80 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | 94 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) |
81 | { | 95 | { |
82 | int ret; | 96 | int ret = 0; |
83 | 97 | ||
84 | if (chip->gpio_chip.ngpio <= 8) | 98 | if (chip->gpio_chip.ngpio <= 8) |
85 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); | 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); |
86 | else | 100 | else { |
87 | ret = i2c_smbus_write_word_data(chip->client, reg << 1, val); | 101 | switch (chip->chip_type) { |
102 | case PCA953X_TYPE: | ||
103 | ret = i2c_smbus_write_word_data(chip->client, | ||
104 | reg << 1, val); | ||
105 | break; | ||
106 | case PCA957X_TYPE: | ||
107 | ret = i2c_smbus_write_byte_data(chip->client, reg << 1, | ||
108 | val & 0xff); | ||
109 | if (ret < 0) | ||
110 | break; | ||
111 | ret = i2c_smbus_write_byte_data(chip->client, | ||
112 | (reg << 1) + 1, | ||
113 | (val & 0xff00) >> 8); | ||
114 | break; | ||
115 | } | ||
116 | } | ||
88 | 117 | ||
89 | if (ret < 0) { | 118 | if (ret < 0) { |
90 | dev_err(&chip->client->dev, "failed writing register\n"); | 119 | dev_err(&chip->client->dev, "failed writing register\n"); |
@@ -116,13 +145,22 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) | |||
116 | { | 145 | { |
117 | struct pca953x_chip *chip; | 146 | struct pca953x_chip *chip; |
118 | uint16_t reg_val; | 147 | uint16_t reg_val; |
119 | int ret; | 148 | int ret, offset = 0; |
120 | 149 | ||
121 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 150 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
122 | 151 | ||
123 | mutex_lock(&chip->i2c_lock); | 152 | mutex_lock(&chip->i2c_lock); |
124 | reg_val = chip->reg_direction | (1u << off); | 153 | reg_val = chip->reg_direction | (1u << off); |
125 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | 154 | |
155 | switch (chip->chip_type) { | ||
156 | case PCA953X_TYPE: | ||
157 | offset = PCA953X_DIRECTION; | ||
158 | break; | ||
159 | case PCA957X_TYPE: | ||
160 | offset = PCA957X_CFG; | ||
161 | break; | ||
162 | } | ||
163 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
126 | if (ret) | 164 | if (ret) |
127 | goto exit; | 165 | goto exit; |
128 | 166 | ||
@@ -138,7 +176,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
138 | { | 176 | { |
139 | struct pca953x_chip *chip; | 177 | struct pca953x_chip *chip; |
140 | uint16_t reg_val; | 178 | uint16_t reg_val; |
141 | int ret; | 179 | int ret, offset = 0; |
142 | 180 | ||
143 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 181 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
144 | 182 | ||
@@ -149,7 +187,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
149 | else | 187 | else |
150 | reg_val = chip->reg_output & ~(1u << off); | 188 | reg_val = chip->reg_output & ~(1u << off); |
151 | 189 | ||
152 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | 190 | switch (chip->chip_type) { |
191 | case PCA953X_TYPE: | ||
192 | offset = PCA953X_OUTPUT; | ||
193 | break; | ||
194 | case PCA957X_TYPE: | ||
195 | offset = PCA957X_OUT; | ||
196 | break; | ||
197 | } | ||
198 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
153 | if (ret) | 199 | if (ret) |
154 | goto exit; | 200 | goto exit; |
155 | 201 | ||
@@ -157,7 +203,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
157 | 203 | ||
158 | /* then direction */ | 204 | /* then direction */ |
159 | reg_val = chip->reg_direction & ~(1u << off); | 205 | reg_val = chip->reg_direction & ~(1u << off); |
160 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | 206 | switch (chip->chip_type) { |
207 | case PCA953X_TYPE: | ||
208 | offset = PCA953X_DIRECTION; | ||
209 | break; | ||
210 | case PCA957X_TYPE: | ||
211 | offset = PCA957X_CFG; | ||
212 | break; | ||
213 | } | ||
214 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
161 | if (ret) | 215 | if (ret) |
162 | goto exit; | 216 | goto exit; |
163 | 217 | ||
@@ -172,12 +226,20 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | |||
172 | { | 226 | { |
173 | struct pca953x_chip *chip; | 227 | struct pca953x_chip *chip; |
174 | uint16_t reg_val; | 228 | uint16_t reg_val; |
175 | int ret; | 229 | int ret, offset = 0; |
176 | 230 | ||
177 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 231 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
178 | 232 | ||
179 | mutex_lock(&chip->i2c_lock); | 233 | mutex_lock(&chip->i2c_lock); |
180 | ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); | 234 | switch (chip->chip_type) { |
235 | case PCA953X_TYPE: | ||
236 | offset = PCA953X_INPUT; | ||
237 | break; | ||
238 | case PCA957X_TYPE: | ||
239 | offset = PCA957X_IN; | ||
240 | break; | ||
241 | } | ||
242 | ret = pca953x_read_reg(chip, offset, ®_val); | ||
181 | mutex_unlock(&chip->i2c_lock); | 243 | mutex_unlock(&chip->i2c_lock); |
182 | if (ret < 0) { | 244 | if (ret < 0) { |
183 | /* NOTE: diagnostic already emitted; that's all we should | 245 | /* NOTE: diagnostic already emitted; that's all we should |
@@ -194,7 +256,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | |||
194 | { | 256 | { |
195 | struct pca953x_chip *chip; | 257 | struct pca953x_chip *chip; |
196 | uint16_t reg_val; | 258 | uint16_t reg_val; |
197 | int ret; | 259 | int ret, offset = 0; |
198 | 260 | ||
199 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 261 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
200 | 262 | ||
@@ -204,7 +266,15 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | |||
204 | else | 266 | else |
205 | reg_val = chip->reg_output & ~(1u << off); | 267 | reg_val = chip->reg_output & ~(1u << off); |
206 | 268 | ||
207 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | 269 | switch (chip->chip_type) { |
270 | case PCA953X_TYPE: | ||
271 | offset = PCA953X_OUTPUT; | ||
272 | break; | ||
273 | case PCA957X_TYPE: | ||
274 | offset = PCA957X_OUT; | ||
275 | break; | ||
276 | } | ||
277 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
208 | if (ret) | 278 | if (ret) |
209 | goto exit; | 279 | goto exit; |
210 | 280 | ||
@@ -322,9 +392,17 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | |||
322 | uint16_t old_stat; | 392 | uint16_t old_stat; |
323 | uint16_t pending; | 393 | uint16_t pending; |
324 | uint16_t trigger; | 394 | uint16_t trigger; |
325 | int ret; | 395 | int ret, offset = 0; |
326 | 396 | ||
327 | ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat); | 397 | switch (chip->chip_type) { |
398 | case PCA953X_TYPE: | ||
399 | offset = PCA953X_INPUT; | ||
400 | break; | ||
401 | case PCA957X_TYPE: | ||
402 | offset = PCA957X_IN; | ||
403 | break; | ||
404 | } | ||
405 | ret = pca953x_read_reg(chip, offset, &cur_stat); | ||
328 | if (ret) | 406 | if (ret) |
329 | return 0; | 407 | return 0; |
330 | 408 | ||
@@ -372,14 +450,21 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
372 | { | 450 | { |
373 | struct i2c_client *client = chip->client; | 451 | struct i2c_client *client = chip->client; |
374 | struct pca953x_platform_data *pdata = client->dev.platform_data; | 452 | struct pca953x_platform_data *pdata = client->dev.platform_data; |
375 | int ret; | 453 | int ret, offset = 0; |
376 | 454 | ||
377 | if (pdata->irq_base != -1 | 455 | if (pdata->irq_base != -1 |
378 | && (id->driver_data & PCA953X_INT)) { | 456 | && (id->driver_data & PCA_INT)) { |
379 | int lvl; | 457 | int lvl; |
380 | 458 | ||
381 | ret = pca953x_read_reg(chip, PCA953X_INPUT, | 459 | switch (chip->chip_type) { |
382 | &chip->irq_stat); | 460 | case PCA953X_TYPE: |
461 | offset = PCA953X_INPUT; | ||
462 | break; | ||
463 | case PCA957X_TYPE: | ||
464 | offset = PCA957X_IN; | ||
465 | break; | ||
466 | } | ||
467 | ret = pca953x_read_reg(chip, offset, &chip->irq_stat); | ||
383 | if (ret) | 468 | if (ret) |
384 | goto out_failed; | 469 | goto out_failed; |
385 | 470 | ||
@@ -439,7 +524,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
439 | struct i2c_client *client = chip->client; | 524 | struct i2c_client *client = chip->client; |
440 | struct pca953x_platform_data *pdata = client->dev.platform_data; | 525 | struct pca953x_platform_data *pdata = client->dev.platform_data; |
441 | 526 | ||
442 | if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT)) | 527 | if (pdata->irq_base != -1 && (id->driver_data & PCA_INT)) |
443 | dev_warn(&client->dev, "interrupt support not compiled in\n"); | 528 | dev_warn(&client->dev, "interrupt support not compiled in\n"); |
444 | 529 | ||
445 | return 0; | 530 | return 0; |
@@ -499,12 +584,65 @@ pca953x_get_alt_pdata(struct i2c_client *client) | |||
499 | } | 584 | } |
500 | #endif | 585 | #endif |
501 | 586 | ||
587 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) | ||
588 | { | ||
589 | int ret; | ||
590 | |||
591 | ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); | ||
592 | if (ret) | ||
593 | goto out; | ||
594 | |||
595 | ret = pca953x_read_reg(chip, PCA953X_DIRECTION, | ||
596 | &chip->reg_direction); | ||
597 | if (ret) | ||
598 | goto out; | ||
599 | |||
600 | /* set platform specific polarity inversion */ | ||
601 | ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); | ||
602 | if (ret) | ||
603 | goto out; | ||
604 | return 0; | ||
605 | out: | ||
606 | return ret; | ||
607 | } | ||
608 | |||
609 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) | ||
610 | { | ||
611 | int ret; | ||
612 | uint16_t val = 0; | ||
613 | |||
614 | /* Let every port in proper state, that could save power */ | ||
615 | pca953x_write_reg(chip, PCA957X_PUPD, 0x0); | ||
616 | pca953x_write_reg(chip, PCA957X_CFG, 0xffff); | ||
617 | pca953x_write_reg(chip, PCA957X_OUT, 0x0); | ||
618 | |||
619 | ret = pca953x_read_reg(chip, PCA957X_IN, &val); | ||
620 | if (ret) | ||
621 | goto out; | ||
622 | ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output); | ||
623 | if (ret) | ||
624 | goto out; | ||
625 | ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction); | ||
626 | if (ret) | ||
627 | goto out; | ||
628 | |||
629 | /* set platform specific polarity inversion */ | ||
630 | pca953x_write_reg(chip, PCA957X_INVRT, invert); | ||
631 | |||
632 | /* To enable register 6, 7 to controll pull up and pull down */ | ||
633 | pca953x_write_reg(chip, PCA957X_BKEN, 0x202); | ||
634 | |||
635 | return 0; | ||
636 | out: | ||
637 | return ret; | ||
638 | } | ||
639 | |||
502 | static int __devinit pca953x_probe(struct i2c_client *client, | 640 | static int __devinit pca953x_probe(struct i2c_client *client, |
503 | const struct i2c_device_id *id) | 641 | const struct i2c_device_id *id) |
504 | { | 642 | { |
505 | struct pca953x_platform_data *pdata; | 643 | struct pca953x_platform_data *pdata; |
506 | struct pca953x_chip *chip; | 644 | struct pca953x_chip *chip; |
507 | int ret; | 645 | int ret = 0; |
508 | 646 | ||
509 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 647 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
510 | if (chip == NULL) | 648 | if (chip == NULL) |
@@ -531,25 +669,20 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
531 | chip->gpio_start = pdata->gpio_base; | 669 | chip->gpio_start = pdata->gpio_base; |
532 | 670 | ||
533 | chip->names = pdata->names; | 671 | chip->names = pdata->names; |
672 | chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE); | ||
534 | 673 | ||
535 | mutex_init(&chip->i2c_lock); | 674 | mutex_init(&chip->i2c_lock); |
536 | 675 | ||
537 | /* initialize cached registers from their original values. | 676 | /* initialize cached registers from their original values. |
538 | * we can't share this chip with another i2c master. | 677 | * we can't share this chip with another i2c master. |
539 | */ | 678 | */ |
540 | pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS); | 679 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); |
541 | 680 | ||
542 | ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); | 681 | if (chip->chip_type == PCA953X_TYPE) |
543 | if (ret) | 682 | device_pca953x_init(chip, pdata->invert); |
544 | goto out_failed; | 683 | else if (chip->chip_type == PCA957X_TYPE) |
545 | 684 | device_pca957x_init(chip, pdata->invert); | |
546 | ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); | 685 | else |
547 | if (ret) | ||
548 | goto out_failed; | ||
549 | |||
550 | /* set platform specific polarity inversion */ | ||
551 | ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); | ||
552 | if (ret) | ||
553 | goto out_failed; | 686 | goto out_failed; |
554 | 687 | ||
555 | ret = pca953x_irq_setup(chip, id); | 688 | ret = pca953x_irq_setup(chip, id); |
diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/pch_gpio.c index f970a5f3585e..36919e77c495 100644 --- a/drivers/gpio/pch_gpio.c +++ b/drivers/gpio/pch_gpio.c | |||
@@ -283,8 +283,10 @@ static int pch_gpio_resume(struct pci_dev *pdev) | |||
283 | #define pch_gpio_resume NULL | 283 | #define pch_gpio_resume NULL |
284 | #endif | 284 | #endif |
285 | 285 | ||
286 | #define PCI_VENDOR_ID_ROHM 0x10DB | ||
286 | static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { | 287 | static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { |
287 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, | 288 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, |
289 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, | ||
288 | { 0, } | 290 | { 0, } |
289 | }; | 291 | }; |
290 | MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); | 292 | MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 6e5123b1d341..144d27261e43 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -1782,7 +1782,6 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
1782 | ide_cd_read_toc(drive, &sense); | 1782 | ide_cd_read_toc(drive, &sense); |
1783 | g->fops = &idecd_ops; | 1783 | g->fops = &idecd_ops; |
1784 | g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; | 1784 | g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
1785 | g->events = DISK_EVENT_MEDIA_CHANGE; | ||
1786 | add_disk(g); | 1785 | add_disk(g); |
1787 | return 0; | 1786 | return 0; |
1788 | 1787 | ||
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 76a5af00a26b..2067288f61f9 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #define DM_MSG_PREFIX "io" | 19 | #define DM_MSG_PREFIX "io" |
20 | 20 | ||
21 | #define DM_IO_MAX_REGIONS BITS_PER_LONG | 21 | #define DM_IO_MAX_REGIONS BITS_PER_LONG |
22 | #define MIN_IOS 16 | ||
23 | #define MIN_BIOS 16 | ||
22 | 24 | ||
23 | struct dm_io_client { | 25 | struct dm_io_client { |
24 | mempool_t *pool; | 26 | mempool_t *pool; |
@@ -41,33 +43,21 @@ struct io { | |||
41 | static struct kmem_cache *_dm_io_cache; | 43 | static struct kmem_cache *_dm_io_cache; |
42 | 44 | ||
43 | /* | 45 | /* |
44 | * io contexts are only dynamically allocated for asynchronous | ||
45 | * io. Since async io is likely to be the majority of io we'll | ||
46 | * have the same number of io contexts as bios! (FIXME: must reduce this). | ||
47 | */ | ||
48 | |||
49 | static unsigned int pages_to_ios(unsigned int pages) | ||
50 | { | ||
51 | return 4 * pages; /* too many ? */ | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Create a client with mempool and bioset. | 46 | * Create a client with mempool and bioset. |
56 | */ | 47 | */ |
57 | struct dm_io_client *dm_io_client_create(unsigned num_pages) | 48 | struct dm_io_client *dm_io_client_create(void) |
58 | { | 49 | { |
59 | unsigned ios = pages_to_ios(num_pages); | ||
60 | struct dm_io_client *client; | 50 | struct dm_io_client *client; |
61 | 51 | ||
62 | client = kmalloc(sizeof(*client), GFP_KERNEL); | 52 | client = kmalloc(sizeof(*client), GFP_KERNEL); |
63 | if (!client) | 53 | if (!client) |
64 | return ERR_PTR(-ENOMEM); | 54 | return ERR_PTR(-ENOMEM); |
65 | 55 | ||
66 | client->pool = mempool_create_slab_pool(ios, _dm_io_cache); | 56 | client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache); |
67 | if (!client->pool) | 57 | if (!client->pool) |
68 | goto bad; | 58 | goto bad; |
69 | 59 | ||
70 | client->bios = bioset_create(16, 0); | 60 | client->bios = bioset_create(MIN_BIOS, 0); |
71 | if (!client->bios) | 61 | if (!client->bios) |
72 | goto bad; | 62 | goto bad; |
73 | 63 | ||
@@ -81,13 +71,6 @@ struct dm_io_client *dm_io_client_create(unsigned num_pages) | |||
81 | } | 71 | } |
82 | EXPORT_SYMBOL(dm_io_client_create); | 72 | EXPORT_SYMBOL(dm_io_client_create); |
83 | 73 | ||
84 | int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client) | ||
85 | { | ||
86 | return mempool_resize(client->pool, pages_to_ios(num_pages), | ||
87 | GFP_KERNEL); | ||
88 | } | ||
89 | EXPORT_SYMBOL(dm_io_client_resize); | ||
90 | |||
91 | void dm_io_client_destroy(struct dm_io_client *client) | 74 | void dm_io_client_destroy(struct dm_io_client *client) |
92 | { | 75 | { |
93 | mempool_destroy(client->pool); | 76 | mempool_destroy(client->pool); |
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 1bb73a13ca40..819e37eaaeba 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c | |||
@@ -27,15 +27,19 @@ | |||
27 | 27 | ||
28 | #include "dm.h" | 28 | #include "dm.h" |
29 | 29 | ||
30 | #define SUB_JOB_SIZE 128 | ||
31 | #define SPLIT_COUNT 8 | ||
32 | #define MIN_JOBS 8 | ||
33 | #define RESERVE_PAGES (DIV_ROUND_UP(SUB_JOB_SIZE << SECTOR_SHIFT, PAGE_SIZE)) | ||
34 | |||
30 | /*----------------------------------------------------------------- | 35 | /*----------------------------------------------------------------- |
31 | * Each kcopyd client has its own little pool of preallocated | 36 | * Each kcopyd client has its own little pool of preallocated |
32 | * pages for kcopyd io. | 37 | * pages for kcopyd io. |
33 | *---------------------------------------------------------------*/ | 38 | *---------------------------------------------------------------*/ |
34 | struct dm_kcopyd_client { | 39 | struct dm_kcopyd_client { |
35 | spinlock_t lock; | ||
36 | struct page_list *pages; | 40 | struct page_list *pages; |
37 | unsigned int nr_pages; | 41 | unsigned nr_reserved_pages; |
38 | unsigned int nr_free_pages; | 42 | unsigned nr_free_pages; |
39 | 43 | ||
40 | struct dm_io_client *io_client; | 44 | struct dm_io_client *io_client; |
41 | 45 | ||
@@ -67,15 +71,18 @@ static void wake(struct dm_kcopyd_client *kc) | |||
67 | queue_work(kc->kcopyd_wq, &kc->kcopyd_work); | 71 | queue_work(kc->kcopyd_wq, &kc->kcopyd_work); |
68 | } | 72 | } |
69 | 73 | ||
70 | static struct page_list *alloc_pl(void) | 74 | /* |
75 | * Obtain one page for the use of kcopyd. | ||
76 | */ | ||
77 | static struct page_list *alloc_pl(gfp_t gfp) | ||
71 | { | 78 | { |
72 | struct page_list *pl; | 79 | struct page_list *pl; |
73 | 80 | ||
74 | pl = kmalloc(sizeof(*pl), GFP_KERNEL); | 81 | pl = kmalloc(sizeof(*pl), gfp); |
75 | if (!pl) | 82 | if (!pl) |
76 | return NULL; | 83 | return NULL; |
77 | 84 | ||
78 | pl->page = alloc_page(GFP_KERNEL); | 85 | pl->page = alloc_page(gfp); |
79 | if (!pl->page) { | 86 | if (!pl->page) { |
80 | kfree(pl); | 87 | kfree(pl); |
81 | return NULL; | 88 | return NULL; |
@@ -90,41 +97,56 @@ static void free_pl(struct page_list *pl) | |||
90 | kfree(pl); | 97 | kfree(pl); |
91 | } | 98 | } |
92 | 99 | ||
93 | static int kcopyd_get_pages(struct dm_kcopyd_client *kc, | 100 | /* |
94 | unsigned int nr, struct page_list **pages) | 101 | * Add the provided pages to a client's free page list, releasing |
102 | * back to the system any beyond the reserved_pages limit. | ||
103 | */ | ||
104 | static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) | ||
95 | { | 105 | { |
96 | struct page_list *pl; | 106 | struct page_list *next; |
97 | |||
98 | spin_lock(&kc->lock); | ||
99 | if (kc->nr_free_pages < nr) { | ||
100 | spin_unlock(&kc->lock); | ||
101 | return -ENOMEM; | ||
102 | } | ||
103 | |||
104 | kc->nr_free_pages -= nr; | ||
105 | for (*pages = pl = kc->pages; --nr; pl = pl->next) | ||
106 | ; | ||
107 | 107 | ||
108 | kc->pages = pl->next; | 108 | do { |
109 | pl->next = NULL; | 109 | next = pl->next; |
110 | 110 | ||
111 | spin_unlock(&kc->lock); | 111 | if (kc->nr_free_pages >= kc->nr_reserved_pages) |
112 | free_pl(pl); | ||
113 | else { | ||
114 | pl->next = kc->pages; | ||
115 | kc->pages = pl; | ||
116 | kc->nr_free_pages++; | ||
117 | } | ||
112 | 118 | ||
113 | return 0; | 119 | pl = next; |
120 | } while (pl); | ||
114 | } | 121 | } |
115 | 122 | ||
116 | static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) | 123 | static int kcopyd_get_pages(struct dm_kcopyd_client *kc, |
124 | unsigned int nr, struct page_list **pages) | ||
117 | { | 125 | { |
118 | struct page_list *cursor; | 126 | struct page_list *pl; |
127 | |||
128 | *pages = NULL; | ||
129 | |||
130 | do { | ||
131 | pl = alloc_pl(__GFP_NOWARN | __GFP_NORETRY); | ||
132 | if (unlikely(!pl)) { | ||
133 | /* Use reserved pages */ | ||
134 | pl = kc->pages; | ||
135 | if (unlikely(!pl)) | ||
136 | goto out_of_memory; | ||
137 | kc->pages = pl->next; | ||
138 | kc->nr_free_pages--; | ||
139 | } | ||
140 | pl->next = *pages; | ||
141 | *pages = pl; | ||
142 | } while (--nr); | ||
119 | 143 | ||
120 | spin_lock(&kc->lock); | 144 | return 0; |
121 | for (cursor = pl; cursor->next; cursor = cursor->next) | ||
122 | kc->nr_free_pages++; | ||
123 | 145 | ||
124 | kc->nr_free_pages++; | 146 | out_of_memory: |
125 | cursor->next = kc->pages; | 147 | if (*pages) |
126 | kc->pages = pl; | 148 | kcopyd_put_pages(kc, *pages); |
127 | spin_unlock(&kc->lock); | 149 | return -ENOMEM; |
128 | } | 150 | } |
129 | 151 | ||
130 | /* | 152 | /* |
@@ -141,13 +163,16 @@ static void drop_pages(struct page_list *pl) | |||
141 | } | 163 | } |
142 | } | 164 | } |
143 | 165 | ||
144 | static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) | 166 | /* |
167 | * Allocate and reserve nr_pages for the use of a specific client. | ||
168 | */ | ||
169 | static int client_reserve_pages(struct dm_kcopyd_client *kc, unsigned nr_pages) | ||
145 | { | 170 | { |
146 | unsigned int i; | 171 | unsigned i; |
147 | struct page_list *pl = NULL, *next; | 172 | struct page_list *pl = NULL, *next; |
148 | 173 | ||
149 | for (i = 0; i < nr; i++) { | 174 | for (i = 0; i < nr_pages; i++) { |
150 | next = alloc_pl(); | 175 | next = alloc_pl(GFP_KERNEL); |
151 | if (!next) { | 176 | if (!next) { |
152 | if (pl) | 177 | if (pl) |
153 | drop_pages(pl); | 178 | drop_pages(pl); |
@@ -157,17 +182,18 @@ static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) | |||
157 | pl = next; | 182 | pl = next; |
158 | } | 183 | } |
159 | 184 | ||
185 | kc->nr_reserved_pages += nr_pages; | ||
160 | kcopyd_put_pages(kc, pl); | 186 | kcopyd_put_pages(kc, pl); |
161 | kc->nr_pages += nr; | 187 | |
162 | return 0; | 188 | return 0; |
163 | } | 189 | } |
164 | 190 | ||
165 | static void client_free_pages(struct dm_kcopyd_client *kc) | 191 | static void client_free_pages(struct dm_kcopyd_client *kc) |
166 | { | 192 | { |
167 | BUG_ON(kc->nr_free_pages != kc->nr_pages); | 193 | BUG_ON(kc->nr_free_pages != kc->nr_reserved_pages); |
168 | drop_pages(kc->pages); | 194 | drop_pages(kc->pages); |
169 | kc->pages = NULL; | 195 | kc->pages = NULL; |
170 | kc->nr_free_pages = kc->nr_pages = 0; | 196 | kc->nr_free_pages = kc->nr_reserved_pages = 0; |
171 | } | 197 | } |
172 | 198 | ||
173 | /*----------------------------------------------------------------- | 199 | /*----------------------------------------------------------------- |
@@ -216,16 +242,17 @@ struct kcopyd_job { | |||
216 | struct mutex lock; | 242 | struct mutex lock; |
217 | atomic_t sub_jobs; | 243 | atomic_t sub_jobs; |
218 | sector_t progress; | 244 | sector_t progress; |
219 | }; | ||
220 | 245 | ||
221 | /* FIXME: this should scale with the number of pages */ | 246 | struct kcopyd_job *master_job; |
222 | #define MIN_JOBS 512 | 247 | }; |
223 | 248 | ||
224 | static struct kmem_cache *_job_cache; | 249 | static struct kmem_cache *_job_cache; |
225 | 250 | ||
226 | int __init dm_kcopyd_init(void) | 251 | int __init dm_kcopyd_init(void) |
227 | { | 252 | { |
228 | _job_cache = KMEM_CACHE(kcopyd_job, 0); | 253 | _job_cache = kmem_cache_create("kcopyd_job", |
254 | sizeof(struct kcopyd_job) * (SPLIT_COUNT + 1), | ||
255 | __alignof__(struct kcopyd_job), 0, NULL); | ||
229 | if (!_job_cache) | 256 | if (!_job_cache) |
230 | return -ENOMEM; | 257 | return -ENOMEM; |
231 | 258 | ||
@@ -299,7 +326,12 @@ static int run_complete_job(struct kcopyd_job *job) | |||
299 | 326 | ||
300 | if (job->pages) | 327 | if (job->pages) |
301 | kcopyd_put_pages(kc, job->pages); | 328 | kcopyd_put_pages(kc, job->pages); |
302 | mempool_free(job, kc->job_pool); | 329 | /* |
330 | * If this is the master job, the sub jobs have already | ||
331 | * completed so we can free everything. | ||
332 | */ | ||
333 | if (job->master_job == job) | ||
334 | mempool_free(job, kc->job_pool); | ||
303 | fn(read_err, write_err, context); | 335 | fn(read_err, write_err, context); |
304 | 336 | ||
305 | if (atomic_dec_and_test(&kc->nr_jobs)) | 337 | if (atomic_dec_and_test(&kc->nr_jobs)) |
@@ -460,14 +492,14 @@ static void dispatch_job(struct kcopyd_job *job) | |||
460 | wake(kc); | 492 | wake(kc); |
461 | } | 493 | } |
462 | 494 | ||
463 | #define SUB_JOB_SIZE 128 | ||
464 | static void segment_complete(int read_err, unsigned long write_err, | 495 | static void segment_complete(int read_err, unsigned long write_err, |
465 | void *context) | 496 | void *context) |
466 | { | 497 | { |
467 | /* FIXME: tidy this function */ | 498 | /* FIXME: tidy this function */ |
468 | sector_t progress = 0; | 499 | sector_t progress = 0; |
469 | sector_t count = 0; | 500 | sector_t count = 0; |
470 | struct kcopyd_job *job = (struct kcopyd_job *) context; | 501 | struct kcopyd_job *sub_job = (struct kcopyd_job *) context; |
502 | struct kcopyd_job *job = sub_job->master_job; | ||
471 | struct dm_kcopyd_client *kc = job->kc; | 503 | struct dm_kcopyd_client *kc = job->kc; |
472 | 504 | ||
473 | mutex_lock(&job->lock); | 505 | mutex_lock(&job->lock); |
@@ -498,8 +530,6 @@ static void segment_complete(int read_err, unsigned long write_err, | |||
498 | 530 | ||
499 | if (count) { | 531 | if (count) { |
500 | int i; | 532 | int i; |
501 | struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool, | ||
502 | GFP_NOIO); | ||
503 | 533 | ||
504 | *sub_job = *job; | 534 | *sub_job = *job; |
505 | sub_job->source.sector += progress; | 535 | sub_job->source.sector += progress; |
@@ -511,7 +541,7 @@ static void segment_complete(int read_err, unsigned long write_err, | |||
511 | } | 541 | } |
512 | 542 | ||
513 | sub_job->fn = segment_complete; | 543 | sub_job->fn = segment_complete; |
514 | sub_job->context = job; | 544 | sub_job->context = sub_job; |
515 | dispatch_job(sub_job); | 545 | dispatch_job(sub_job); |
516 | 546 | ||
517 | } else if (atomic_dec_and_test(&job->sub_jobs)) { | 547 | } else if (atomic_dec_and_test(&job->sub_jobs)) { |
@@ -531,19 +561,19 @@ static void segment_complete(int read_err, unsigned long write_err, | |||
531 | } | 561 | } |
532 | 562 | ||
533 | /* | 563 | /* |
534 | * Create some little jobs that will do the move between | 564 | * Create some sub jobs to share the work between them. |
535 | * them. | ||
536 | */ | 565 | */ |
537 | #define SPLIT_COUNT 8 | 566 | static void split_job(struct kcopyd_job *master_job) |
538 | static void split_job(struct kcopyd_job *job) | ||
539 | { | 567 | { |
540 | int i; | 568 | int i; |
541 | 569 | ||
542 | atomic_inc(&job->kc->nr_jobs); | 570 | atomic_inc(&master_job->kc->nr_jobs); |
543 | 571 | ||
544 | atomic_set(&job->sub_jobs, SPLIT_COUNT); | 572 | atomic_set(&master_job->sub_jobs, SPLIT_COUNT); |
545 | for (i = 0; i < SPLIT_COUNT; i++) | 573 | for (i = 0; i < SPLIT_COUNT; i++) { |
546 | segment_complete(0, 0u, job); | 574 | master_job[i + 1].master_job = master_job; |
575 | segment_complete(0, 0u, &master_job[i + 1]); | ||
576 | } | ||
547 | } | 577 | } |
548 | 578 | ||
549 | int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | 579 | int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, |
@@ -553,7 +583,8 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | |||
553 | struct kcopyd_job *job; | 583 | struct kcopyd_job *job; |
554 | 584 | ||
555 | /* | 585 | /* |
556 | * Allocate a new job. | 586 | * Allocate an array of jobs consisting of one master job |
587 | * followed by SPLIT_COUNT sub jobs. | ||
557 | */ | 588 | */ |
558 | job = mempool_alloc(kc->job_pool, GFP_NOIO); | 589 | job = mempool_alloc(kc->job_pool, GFP_NOIO); |
559 | 590 | ||
@@ -577,10 +608,10 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | |||
577 | 608 | ||
578 | job->fn = fn; | 609 | job->fn = fn; |
579 | job->context = context; | 610 | job->context = context; |
611 | job->master_job = job; | ||
580 | 612 | ||
581 | if (job->source.count < SUB_JOB_SIZE) | 613 | if (job->source.count <= SUB_JOB_SIZE) |
582 | dispatch_job(job); | 614 | dispatch_job(job); |
583 | |||
584 | else { | 615 | else { |
585 | mutex_init(&job->lock); | 616 | mutex_init(&job->lock); |
586 | job->progress = 0; | 617 | job->progress = 0; |
@@ -606,17 +637,15 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) | |||
606 | /*----------------------------------------------------------------- | 637 | /*----------------------------------------------------------------- |
607 | * Client setup | 638 | * Client setup |
608 | *---------------------------------------------------------------*/ | 639 | *---------------------------------------------------------------*/ |
609 | int dm_kcopyd_client_create(unsigned int nr_pages, | 640 | struct dm_kcopyd_client *dm_kcopyd_client_create(void) |
610 | struct dm_kcopyd_client **result) | ||
611 | { | 641 | { |
612 | int r = -ENOMEM; | 642 | int r = -ENOMEM; |
613 | struct dm_kcopyd_client *kc; | 643 | struct dm_kcopyd_client *kc; |
614 | 644 | ||
615 | kc = kmalloc(sizeof(*kc), GFP_KERNEL); | 645 | kc = kmalloc(sizeof(*kc), GFP_KERNEL); |
616 | if (!kc) | 646 | if (!kc) |
617 | return -ENOMEM; | 647 | return ERR_PTR(-ENOMEM); |
618 | 648 | ||
619 | spin_lock_init(&kc->lock); | ||
620 | spin_lock_init(&kc->job_lock); | 649 | spin_lock_init(&kc->job_lock); |
621 | INIT_LIST_HEAD(&kc->complete_jobs); | 650 | INIT_LIST_HEAD(&kc->complete_jobs); |
622 | INIT_LIST_HEAD(&kc->io_jobs); | 651 | INIT_LIST_HEAD(&kc->io_jobs); |
@@ -633,12 +662,12 @@ int dm_kcopyd_client_create(unsigned int nr_pages, | |||
633 | goto bad_workqueue; | 662 | goto bad_workqueue; |
634 | 663 | ||
635 | kc->pages = NULL; | 664 | kc->pages = NULL; |
636 | kc->nr_pages = kc->nr_free_pages = 0; | 665 | kc->nr_reserved_pages = kc->nr_free_pages = 0; |
637 | r = client_alloc_pages(kc, nr_pages); | 666 | r = client_reserve_pages(kc, RESERVE_PAGES); |
638 | if (r) | 667 | if (r) |
639 | goto bad_client_pages; | 668 | goto bad_client_pages; |
640 | 669 | ||
641 | kc->io_client = dm_io_client_create(nr_pages); | 670 | kc->io_client = dm_io_client_create(); |
642 | if (IS_ERR(kc->io_client)) { | 671 | if (IS_ERR(kc->io_client)) { |
643 | r = PTR_ERR(kc->io_client); | 672 | r = PTR_ERR(kc->io_client); |
644 | goto bad_io_client; | 673 | goto bad_io_client; |
@@ -647,8 +676,7 @@ int dm_kcopyd_client_create(unsigned int nr_pages, | |||
647 | init_waitqueue_head(&kc->destroyq); | 676 | init_waitqueue_head(&kc->destroyq); |
648 | atomic_set(&kc->nr_jobs, 0); | 677 | atomic_set(&kc->nr_jobs, 0); |
649 | 678 | ||
650 | *result = kc; | 679 | return kc; |
651 | return 0; | ||
652 | 680 | ||
653 | bad_io_client: | 681 | bad_io_client: |
654 | client_free_pages(kc); | 682 | client_free_pages(kc); |
@@ -659,7 +687,7 @@ bad_workqueue: | |||
659 | bad_slab: | 687 | bad_slab: |
660 | kfree(kc); | 688 | kfree(kc); |
661 | 689 | ||
662 | return r; | 690 | return ERR_PTR(r); |
663 | } | 691 | } |
664 | EXPORT_SYMBOL(dm_kcopyd_client_create); | 692 | EXPORT_SYMBOL(dm_kcopyd_client_create); |
665 | 693 | ||
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index a1f321889676..948e3f4925bf 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -449,8 +449,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, | |||
449 | 449 | ||
450 | lc->io_req.mem.type = DM_IO_VMA; | 450 | lc->io_req.mem.type = DM_IO_VMA; |
451 | lc->io_req.notify.fn = NULL; | 451 | lc->io_req.notify.fn = NULL; |
452 | lc->io_req.client = dm_io_client_create(dm_div_up(buf_size, | 452 | lc->io_req.client = dm_io_client_create(); |
453 | PAGE_SIZE)); | ||
454 | if (IS_ERR(lc->io_req.client)) { | 453 | if (IS_ERR(lc->io_req.client)) { |
455 | r = PTR_ERR(lc->io_req.client); | 454 | r = PTR_ERR(lc->io_req.client); |
456 | DMWARN("couldn't allocate disk io client"); | 455 | DMWARN("couldn't allocate disk io client"); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index a550a057d991..aa4e570c2cb5 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1290,7 +1290,7 @@ static int do_end_io(struct multipath *m, struct request *clone, | |||
1290 | if (!error && !clone->errors) | 1290 | if (!error && !clone->errors) |
1291 | return 0; /* I/O complete */ | 1291 | return 0; /* I/O complete */ |
1292 | 1292 | ||
1293 | if (error == -EOPNOTSUPP || error == -EREMOTEIO) | 1293 | if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) |
1294 | return error; | 1294 | return error; |
1295 | 1295 | ||
1296 | if (mpio->pgpath) | 1296 | if (mpio->pgpath) |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 976ad4688afc..9bfd057be686 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #define DM_MSG_PREFIX "raid1" | 22 | #define DM_MSG_PREFIX "raid1" |
23 | 23 | ||
24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ | 24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ |
25 | #define DM_IO_PAGES 64 | ||
26 | #define DM_KCOPYD_PAGES 64 | ||
27 | 25 | ||
28 | #define DM_RAID1_HANDLE_ERRORS 0x01 | 26 | #define DM_RAID1_HANDLE_ERRORS 0x01 |
29 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) | 27 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) |
@@ -887,7 +885,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
887 | return NULL; | 885 | return NULL; |
888 | } | 886 | } |
889 | 887 | ||
890 | ms->io_client = dm_io_client_create(DM_IO_PAGES); | 888 | ms->io_client = dm_io_client_create(); |
891 | if (IS_ERR(ms->io_client)) { | 889 | if (IS_ERR(ms->io_client)) { |
892 | ti->error = "Error creating dm_io client"; | 890 | ti->error = "Error creating dm_io client"; |
893 | mempool_destroy(ms->read_record_pool); | 891 | mempool_destroy(ms->read_record_pool); |
@@ -1117,9 +1115,11 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1117 | goto err_destroy_wq; | 1115 | goto err_destroy_wq; |
1118 | } | 1116 | } |
1119 | 1117 | ||
1120 | r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client); | 1118 | ms->kcopyd_client = dm_kcopyd_client_create(); |
1121 | if (r) | 1119 | if (IS_ERR(ms->kcopyd_client)) { |
1120 | r = PTR_ERR(ms->kcopyd_client); | ||
1122 | goto err_destroy_wq; | 1121 | goto err_destroy_wq; |
1122 | } | ||
1123 | 1123 | ||
1124 | wakeup_mirrord(ms); | 1124 | wakeup_mirrord(ms); |
1125 | return 0; | 1125 | return 0; |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 95891dfcbca0..135c2f1fdbfc 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -154,11 +154,6 @@ struct pstore { | |||
154 | struct workqueue_struct *metadata_wq; | 154 | struct workqueue_struct *metadata_wq; |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static unsigned sectors_to_pages(unsigned sectors) | ||
158 | { | ||
159 | return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9); | ||
160 | } | ||
161 | |||
162 | static int alloc_area(struct pstore *ps) | 157 | static int alloc_area(struct pstore *ps) |
163 | { | 158 | { |
164 | int r = -ENOMEM; | 159 | int r = -ENOMEM; |
@@ -318,8 +313,7 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
318 | chunk_size_supplied = 0; | 313 | chunk_size_supplied = 0; |
319 | } | 314 | } |
320 | 315 | ||
321 | ps->io_client = dm_io_client_create(sectors_to_pages(ps->store-> | 316 | ps->io_client = dm_io_client_create(); |
322 | chunk_size)); | ||
323 | if (IS_ERR(ps->io_client)) | 317 | if (IS_ERR(ps->io_client)) |
324 | return PTR_ERR(ps->io_client); | 318 | return PTR_ERR(ps->io_client); |
325 | 319 | ||
@@ -368,11 +362,6 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
368 | return r; | 362 | return r; |
369 | } | 363 | } |
370 | 364 | ||
371 | r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), | ||
372 | ps->io_client); | ||
373 | if (r) | ||
374 | return r; | ||
375 | |||
376 | r = alloc_area(ps); | 365 | r = alloc_area(ps); |
377 | return r; | 366 | return r; |
378 | 367 | ||
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a2d330942cb2..9ecff5f3023a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -40,11 +40,6 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; | |||
40 | #define SNAPSHOT_COPY_PRIORITY 2 | 40 | #define SNAPSHOT_COPY_PRIORITY 2 |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Reserve 1MB for each snapshot initially (with minimum of 1 page). | ||
44 | */ | ||
45 | #define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) | ||
46 | |||
47 | /* | ||
48 | * The size of the mempool used to track chunks in use. | 43 | * The size of the mempool used to track chunks in use. |
49 | */ | 44 | */ |
50 | #define MIN_IOS 256 | 45 | #define MIN_IOS 256 |
@@ -1116,8 +1111,9 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1116 | goto bad_hash_tables; | 1111 | goto bad_hash_tables; |
1117 | } | 1112 | } |
1118 | 1113 | ||
1119 | r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); | 1114 | s->kcopyd_client = dm_kcopyd_client_create(); |
1120 | if (r) { | 1115 | if (IS_ERR(s->kcopyd_client)) { |
1116 | r = PTR_ERR(s->kcopyd_client); | ||
1121 | ti->error = "Could not create kcopyd client"; | 1117 | ti->error = "Could not create kcopyd client"; |
1122 | goto bad_kcopyd; | 1118 | goto bad_kcopyd; |
1123 | } | 1119 | } |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index cb8380c9767f..451c3bb176d2 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -362,6 +362,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) | |||
362 | static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, | 362 | static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, |
363 | sector_t start, sector_t len, void *data) | 363 | sector_t start, sector_t len, void *data) |
364 | { | 364 | { |
365 | struct request_queue *q; | ||
365 | struct queue_limits *limits = data; | 366 | struct queue_limits *limits = data; |
366 | struct block_device *bdev = dev->bdev; | 367 | struct block_device *bdev = dev->bdev; |
367 | sector_t dev_size = | 368 | sector_t dev_size = |
@@ -370,6 +371,22 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, | |||
370 | limits->logical_block_size >> SECTOR_SHIFT; | 371 | limits->logical_block_size >> SECTOR_SHIFT; |
371 | char b[BDEVNAME_SIZE]; | 372 | char b[BDEVNAME_SIZE]; |
372 | 373 | ||
374 | /* | ||
375 | * Some devices exist without request functions, | ||
376 | * such as loop devices not yet bound to backing files. | ||
377 | * Forbid the use of such devices. | ||
378 | */ | ||
379 | q = bdev_get_queue(bdev); | ||
380 | if (!q || !q->make_request_fn) { | ||
381 | DMWARN("%s: %s is not yet initialised: " | ||
382 | "start=%llu, len=%llu, dev_size=%llu", | ||
383 | dm_device_name(ti->table->md), bdevname(bdev, b), | ||
384 | (unsigned long long)start, | ||
385 | (unsigned long long)len, | ||
386 | (unsigned long long)dev_size); | ||
387 | return 1; | ||
388 | } | ||
389 | |||
373 | if (!dev_size) | 390 | if (!dev_size) |
374 | return 0; | 391 | return 0; |
375 | 392 | ||
@@ -1346,7 +1363,8 @@ bool dm_table_supports_discards(struct dm_table *t) | |||
1346 | return 0; | 1363 | return 0; |
1347 | 1364 | ||
1348 | /* | 1365 | /* |
1349 | * Ensure that at least one underlying device supports discards. | 1366 | * Unless any target used by the table set discards_supported, |
1367 | * require at least one underlying device to support discards. | ||
1350 | * t->devices includes internal dm devices such as mirror logs | 1368 | * t->devices includes internal dm devices such as mirror logs |
1351 | * so we need to use iterate_devices here, which targets | 1369 | * so we need to use iterate_devices here, which targets |
1352 | * supporting discard must provide. | 1370 | * supporting discard must provide. |
@@ -1354,6 +1372,9 @@ bool dm_table_supports_discards(struct dm_table *t) | |||
1354 | while (i < dm_table_get_num_targets(t)) { | 1372 | while (i < dm_table_get_num_targets(t)) { |
1355 | ti = dm_table_get_target(t, i++); | 1373 | ti = dm_table_get_target(t, i++); |
1356 | 1374 | ||
1375 | if (ti->discards_supported) | ||
1376 | return 1; | ||
1377 | |||
1357 | if (ti->type->iterate_devices && | 1378 | if (ti->type->iterate_devices && |
1358 | ti->type->iterate_devices(ti, device_discard_capable, NULL)) | 1379 | ti->type->iterate_devices(ti, device_discard_capable, NULL)) |
1359 | return 1; | 1380 | return 1; |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b6c267724e14..0f09c057e796 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -721,7 +721,7 @@ config MFD_PM8XXX_IRQ | |||
721 | 721 | ||
722 | config MFD_TPS65910 | 722 | config MFD_TPS65910 |
723 | bool "TPS65910 Power Management chip" | 723 | bool "TPS65910 Power Management chip" |
724 | depends on I2C=y | 724 | depends on I2C=y && GPIOLIB |
725 | select MFD_CORE | 725 | select MFD_CORE |
726 | select GPIO_TPS65910 | 726 | select GPIO_TPS65910 |
727 | help | 727 | help |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index e63782107e2f..02a15d7cb3b0 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -2005,7 +2005,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
2005 | static struct mfd_cell db8500_prcmu_devs[] = { | 2005 | static struct mfd_cell db8500_prcmu_devs[] = { |
2006 | { | 2006 | { |
2007 | .name = "db8500-prcmu-regulators", | 2007 | .name = "db8500-prcmu-regulators", |
2008 | .mfd_data = &db8500_regulators, | 2008 | .platform_data = &db8500_regulators, |
2009 | .pdata_size = sizeof(db8500_regulators), | ||
2009 | }, | 2010 | }, |
2010 | { | 2011 | { |
2011 | .name = "cpufreq-u8500", | 2012 | .name = "cpufreq-u8500", |
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index b0c56313dbbb..8cebec5e85ee 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -304,7 +304,10 @@ static int check_and_rewind_pc(char *put_str, char *arg) | |||
304 | return 1; | 304 | return 1; |
305 | } | 305 | } |
306 | /* Readjust the instruction pointer if needed */ | 306 | /* Readjust the instruction pointer if needed */ |
307 | instruction_pointer_set(&kgdbts_regs, ip + offset); | 307 | ip += offset; |
308 | #ifdef GDB_ADJUSTS_BREAK_OFFSET | ||
309 | instruction_pointer_set(&kgdbts_regs, ip); | ||
310 | #endif | ||
308 | return 0; | 311 | return 0; |
309 | } | 312 | } |
310 | 313 | ||
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4941e06fe2e1..5da5bea0f9f0 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -51,6 +51,7 @@ static unsigned int fmax = 515633; | |||
51 | * is asserted (likewise for RX) | 51 | * is asserted (likewise for RX) |
52 | * @sdio: variant supports SDIO | 52 | * @sdio: variant supports SDIO |
53 | * @st_clkdiv: true if using a ST-specific clock divider algorithm | 53 | * @st_clkdiv: true if using a ST-specific clock divider algorithm |
54 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register | ||
54 | */ | 55 | */ |
55 | struct variant_data { | 56 | struct variant_data { |
56 | unsigned int clkreg; | 57 | unsigned int clkreg; |
@@ -60,6 +61,7 @@ struct variant_data { | |||
60 | unsigned int fifohalfsize; | 61 | unsigned int fifohalfsize; |
61 | bool sdio; | 62 | bool sdio; |
62 | bool st_clkdiv; | 63 | bool st_clkdiv; |
64 | bool blksz_datactrl16; | ||
63 | }; | 65 | }; |
64 | 66 | ||
65 | static struct variant_data variant_arm = { | 67 | static struct variant_data variant_arm = { |
@@ -92,6 +94,17 @@ static struct variant_data variant_ux500 = { | |||
92 | .st_clkdiv = true, | 94 | .st_clkdiv = true, |
93 | }; | 95 | }; |
94 | 96 | ||
97 | static struct variant_data variant_ux500v2 = { | ||
98 | .fifosize = 30 * 4, | ||
99 | .fifohalfsize = 8 * 4, | ||
100 | .clkreg = MCI_CLK_ENABLE, | ||
101 | .clkreg_enable = MCI_ST_UX500_HWFCEN, | ||
102 | .datalength_bits = 24, | ||
103 | .sdio = true, | ||
104 | .st_clkdiv = true, | ||
105 | .blksz_datactrl16 = true, | ||
106 | }; | ||
107 | |||
95 | /* | 108 | /* |
96 | * This must be called with host->lock held | 109 | * This must be called with host->lock held |
97 | */ | 110 | */ |
@@ -465,7 +478,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
465 | blksz_bits = ffs(data->blksz) - 1; | 478 | blksz_bits = ffs(data->blksz) - 1; |
466 | BUG_ON(1 << blksz_bits != data->blksz); | 479 | BUG_ON(1 << blksz_bits != data->blksz); |
467 | 480 | ||
468 | datactrl = MCI_DPSM_ENABLE | blksz_bits << 4; | 481 | if (variant->blksz_datactrl16) |
482 | datactrl = MCI_DPSM_ENABLE | (data->blksz << 16); | ||
483 | else | ||
484 | datactrl = MCI_DPSM_ENABLE | blksz_bits << 4; | ||
469 | 485 | ||
470 | if (data->flags & MMC_DATA_READ) | 486 | if (data->flags & MMC_DATA_READ) |
471 | datactrl |= MCI_DPSM_DIRECTION; | 487 | datactrl |= MCI_DPSM_DIRECTION; |
@@ -1311,9 +1327,14 @@ static struct amba_id mmci_ids[] = { | |||
1311 | }, | 1327 | }, |
1312 | { | 1328 | { |
1313 | .id = 0x00480180, | 1329 | .id = 0x00480180, |
1314 | .mask = 0x00ffffff, | 1330 | .mask = 0xf0ffffff, |
1315 | .data = &variant_ux500, | 1331 | .data = &variant_ux500, |
1316 | }, | 1332 | }, |
1333 | { | ||
1334 | .id = 0x10480180, | ||
1335 | .mask = 0xf0ffffff, | ||
1336 | .data = &variant_ux500v2, | ||
1337 | }, | ||
1317 | { 0, 0 }, | 1338 | { 0, 0 }, |
1318 | }; | 1339 | }; |
1319 | 1340 | ||
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index bc50d5ea5534..4be8373d43e5 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig | |||
@@ -33,20 +33,6 @@ config MTD_TESTS | |||
33 | should normally be compiled as kernel modules. The modules perform | 33 | should normally be compiled as kernel modules. The modules perform |
34 | various checks and verifications when loaded. | 34 | various checks and verifications when loaded. |
35 | 35 | ||
36 | config MTD_PARTITIONS | ||
37 | bool "MTD partitioning support" | ||
38 | help | ||
39 | If you have a device which needs to divide its flash chip(s) up | ||
40 | into multiple 'partitions', each of which appears to the user as | ||
41 | a separate MTD device, you require this option to be enabled. If | ||
42 | unsure, say 'Y'. | ||
43 | |||
44 | Note, however, that you don't need this option for the DiskOnChip | ||
45 | devices. Partitioning on NFTL 'devices' is a different - that's the | ||
46 | 'normal' form of partitioning used on a block device. | ||
47 | |||
48 | if MTD_PARTITIONS | ||
49 | |||
50 | config MTD_REDBOOT_PARTS | 36 | config MTD_REDBOOT_PARTS |
51 | tristate "RedBoot partition table parsing" | 37 | tristate "RedBoot partition table parsing" |
52 | ---help--- | 38 | ---help--- |
@@ -99,7 +85,7 @@ endif # MTD_REDBOOT_PARTS | |||
99 | 85 | ||
100 | config MTD_CMDLINE_PARTS | 86 | config MTD_CMDLINE_PARTS |
101 | bool "Command line partition table parsing" | 87 | bool "Command line partition table parsing" |
102 | depends on MTD_PARTITIONS = "y" && MTD = "y" | 88 | depends on MTD = "y" |
103 | ---help--- | 89 | ---help--- |
104 | Allow generic configuration of the MTD partition tables via the kernel | 90 | Allow generic configuration of the MTD partition tables via the kernel |
105 | command line. Multiple flash resources are supported for hardware where | 91 | command line. Multiple flash resources are supported for hardware where |
@@ -163,8 +149,6 @@ config MTD_AR7_PARTS | |||
163 | ---help--- | 149 | ---help--- |
164 | TI AR7 partitioning support | 150 | TI AR7 partitioning support |
165 | 151 | ||
166 | endif # MTD_PARTITIONS | ||
167 | |||
168 | comment "User Modules And Translation Layers" | 152 | comment "User Modules And Translation Layers" |
169 | 153 | ||
170 | config MTD_CHAR | 154 | config MTD_CHAR |
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index d578095fb255..39664c4229ff 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile | |||
@@ -4,8 +4,7 @@ | |||
4 | 4 | ||
5 | # Core functionality. | 5 | # Core functionality. |
6 | obj-$(CONFIG_MTD) += mtd.o | 6 | obj-$(CONFIG_MTD) += mtd.o |
7 | mtd-y := mtdcore.o mtdsuper.o mtdconcat.o | 7 | mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o |
8 | mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o | ||
9 | mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o | 8 | mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o |
10 | 9 | ||
11 | obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o | 10 | obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 09cb7c8d93b4..e1e122f2f929 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -812,12 +812,9 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long | |||
812 | break; | 812 | break; |
813 | 813 | ||
814 | if (time_after(jiffies, timeo)) { | 814 | if (time_after(jiffies, timeo)) { |
815 | /* Urgh. Resume and pretend we weren't here. */ | 815 | /* Urgh. Resume and pretend we weren't here. |
816 | map_write(map, CMD(0xd0), adr); | 816 | * Make sure we're in 'read status' mode if it had finished */ |
817 | /* Make sure we're in 'read status' mode if it had finished */ | 817 | put_chip(map, chip, adr); |
818 | map_write(map, CMD(0x70), adr); | ||
819 | chip->state = FL_ERASING; | ||
820 | chip->oldstate = FL_READY; | ||
821 | printk(KERN_ERR "%s: Chip not ready after erase " | 818 | printk(KERN_ERR "%s: Chip not ready after erase " |
822 | "suspended: status = 0x%lx\n", map->name, status.x[0]); | 819 | "suspended: status = 0x%lx\n", map->name, status.x[0]); |
823 | return -EIO; | 820 | return -EIO; |
@@ -997,7 +994,6 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad | |||
997 | 994 | ||
998 | switch(chip->oldstate) { | 995 | switch(chip->oldstate) { |
999 | case FL_ERASING: | 996 | case FL_ERASING: |
1000 | chip->state = chip->oldstate; | ||
1001 | /* What if one interleaved chip has finished and the | 997 | /* What if one interleaved chip has finished and the |
1002 | other hasn't? The old code would leave the finished | 998 | other hasn't? The old code would leave the finished |
1003 | one in READY mode. That's bad, and caused -EROFS | 999 | one in READY mode. That's bad, and caused -EROFS |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 0b49266840b9..23175edd5634 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -462,13 +462,14 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
462 | cfi_fixup_major_minor(cfi, extp); | 462 | cfi_fixup_major_minor(cfi, extp); |
463 | 463 | ||
464 | /* | 464 | /* |
465 | * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4 | 465 | * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 |
466 | * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19 | 466 | * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19 |
467 | * http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf | 467 | * http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf |
468 | * http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf | 468 | * http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf |
469 | * http://www.spansion.com/Support/Datasheets/S29GL_128S_01GS_00_02_e.pdf | ||
469 | */ | 470 | */ |
470 | if (extp->MajorVersion != '1' || | 471 | if (extp->MajorVersion != '1' || |
471 | (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) { | 472 | (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '5'))) { |
472 | printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query " | 473 | printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query " |
473 | "version %c.%c (%#02x/%#02x).\n", | 474 | "version %c.%c (%#02x/%#02x).\n", |
474 | extp->MajorVersion, extp->MinorVersion, | 475 | extp->MajorVersion, extp->MinorVersion, |
@@ -710,9 +711,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
710 | * there was an error (so leave the erase | 711 | * there was an error (so leave the erase |
711 | * routine to recover from it) or we trying to | 712 | * routine to recover from it) or we trying to |
712 | * use the erase-in-progress sector. */ | 713 | * use the erase-in-progress sector. */ |
713 | map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr); | 714 | put_chip(map, chip, adr); |
714 | chip->state = FL_ERASING; | ||
715 | chip->oldstate = FL_READY; | ||
716 | printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); | 715 | printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); |
717 | return -EIO; | 716 | return -EIO; |
718 | } | 717 | } |
@@ -762,7 +761,6 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad | |||
762 | 761 | ||
763 | switch(chip->oldstate) { | 762 | switch(chip->oldstate) { |
764 | case FL_ERASING: | 763 | case FL_ERASING: |
765 | chip->state = chip->oldstate; | ||
766 | map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr); | 764 | map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr); |
767 | chip->oldstate = FL_READY; | 765 | chip->oldstate = FL_READY; |
768 | chip->state = FL_ERASING; | 766 | chip->state = FL_ERASING; |
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index ed56ad3884fb..179814a95f3a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c | |||
@@ -296,6 +296,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
296 | /* make sure we're in 'read status' mode */ | 296 | /* make sure we're in 'read status' mode */ |
297 | map_write(map, CMD(0x70), cmd_addr); | 297 | map_write(map, CMD(0x70), cmd_addr); |
298 | chip->state = FL_ERASING; | 298 | chip->state = FL_ERASING; |
299 | wake_up(&chip->wq); | ||
299 | mutex_unlock(&chip->mutex); | 300 | mutex_unlock(&chip->mutex); |
300 | printk(KERN_ERR "Chip not ready after erase " | 301 | printk(KERN_ERR "Chip not ready after erase " |
301 | "suspended: status = 0x%lx\n", status.x[0]); | 302 | "suspended: status = 0x%lx\n", status.x[0]); |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 97183c8c9e33..b78f23169d4e 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -294,7 +294,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
294 | dev->mtd.priv = dev; | 294 | dev->mtd.priv = dev; |
295 | dev->mtd.owner = THIS_MODULE; | 295 | dev->mtd.owner = THIS_MODULE; |
296 | 296 | ||
297 | if (add_mtd_device(&dev->mtd)) { | 297 | if (mtd_device_register(&dev->mtd, NULL, 0)) { |
298 | /* Device didn't get added, so free the entry */ | 298 | /* Device didn't get added, so free the entry */ |
299 | goto devinit_err; | 299 | goto devinit_err; |
300 | } | 300 | } |
@@ -465,7 +465,7 @@ static void __devexit block2mtd_exit(void) | |||
465 | list_for_each_safe(pos, next, &blkmtd_device_list) { | 465 | list_for_each_safe(pos, next, &blkmtd_device_list) { |
466 | struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list); | 466 | struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list); |
467 | block2mtd_sync(&dev->mtd); | 467 | block2mtd_sync(&dev->mtd); |
468 | del_mtd_device(&dev->mtd); | 468 | mtd_device_unregister(&dev->mtd); |
469 | INFO("mtd%d: [%s] removed", dev->mtd.index, | 469 | INFO("mtd%d: [%s] removed", dev->mtd.index, |
470 | dev->mtd.name + strlen("block2mtd: ")); | 470 | dev->mtd.name + strlen("block2mtd: ")); |
471 | list_del(&dev->list); | 471 | list_del(&dev->list); |
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 5bf5f460e132..f7fbf6025ef2 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c | |||
@@ -597,7 +597,7 @@ void DoC2k_init(struct mtd_info *mtd) | |||
597 | doc2klist = mtd; | 597 | doc2klist = mtd; |
598 | mtd->size = this->totlen; | 598 | mtd->size = this->totlen; |
599 | mtd->erasesize = this->erasesize; | 599 | mtd->erasesize = this->erasesize; |
600 | add_mtd_device(mtd); | 600 | mtd_device_register(mtd, NULL, 0); |
601 | return; | 601 | return; |
602 | } | 602 | } |
603 | } | 603 | } |
@@ -1185,7 +1185,7 @@ static void __exit cleanup_doc2000(void) | |||
1185 | this = mtd->priv; | 1185 | this = mtd->priv; |
1186 | doc2klist = this->nextdoc; | 1186 | doc2klist = this->nextdoc; |
1187 | 1187 | ||
1188 | del_mtd_device(mtd); | 1188 | mtd_device_unregister(mtd); |
1189 | 1189 | ||
1190 | iounmap(this->virtadr); | 1190 | iounmap(this->virtadr); |
1191 | kfree(this->chips); | 1191 | kfree(this->chips); |
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 0990f7803628..241192f05bc8 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c | |||
@@ -376,7 +376,7 @@ void DoCMil_init(struct mtd_info *mtd) | |||
376 | this->nextdoc = docmillist; | 376 | this->nextdoc = docmillist; |
377 | docmillist = mtd; | 377 | docmillist = mtd; |
378 | mtd->size = this->totlen; | 378 | mtd->size = this->totlen; |
379 | add_mtd_device(mtd); | 379 | mtd_device_register(mtd, NULL, 0); |
380 | return; | 380 | return; |
381 | } | 381 | } |
382 | } | 382 | } |
@@ -826,7 +826,7 @@ static void __exit cleanup_doc2001(void) | |||
826 | this = mtd->priv; | 826 | this = mtd->priv; |
827 | docmillist = this->nextdoc; | 827 | docmillist = this->nextdoc; |
828 | 828 | ||
829 | del_mtd_device(mtd); | 829 | mtd_device_unregister(mtd); |
830 | 830 | ||
831 | iounmap(this->virtadr); | 831 | iounmap(this->virtadr); |
832 | kfree(this->chips); | 832 | kfree(this->chips); |
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 8b36fa77a195..09ae0adc3ad0 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c | |||
@@ -499,7 +499,7 @@ void DoCMilPlus_init(struct mtd_info *mtd) | |||
499 | docmilpluslist = mtd; | 499 | docmilpluslist = mtd; |
500 | mtd->size = this->totlen; | 500 | mtd->size = this->totlen; |
501 | mtd->erasesize = this->erasesize; | 501 | mtd->erasesize = this->erasesize; |
502 | add_mtd_device(mtd); | 502 | mtd_device_register(mtd, NULL, 0); |
503 | return; | 503 | return; |
504 | } | 504 | } |
505 | } | 505 | } |
@@ -1091,7 +1091,7 @@ static void __exit cleanup_doc2001plus(void) | |||
1091 | this = mtd->priv; | 1091 | this = mtd->priv; |
1092 | docmilpluslist = this->nextdoc; | 1092 | docmilpluslist = this->nextdoc; |
1093 | 1093 | ||
1094 | del_mtd_device(mtd); | 1094 | mtd_device_unregister(mtd); |
1095 | 1095 | ||
1096 | iounmap(this->virtadr); | 1096 | iounmap(this->virtadr); |
1097 | kfree(this->chips); | 1097 | kfree(this->chips); |
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 4b829f97d56c..772a0ff89e0f 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c | |||
@@ -684,9 +684,10 @@ static int __init lart_flash_init (void) | |||
684 | #endif | 684 | #endif |
685 | 685 | ||
686 | #ifndef HAVE_PARTITIONS | 686 | #ifndef HAVE_PARTITIONS |
687 | result = add_mtd_device (&mtd); | 687 | result = mtd_device_register(&mtd, NULL, 0); |
688 | #else | 688 | #else |
689 | result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); | 689 | result = mtd_device_register(&mtd, lart_partitions, |
690 | ARRAY_SIZE(lart_partitions)); | ||
690 | #endif | 691 | #endif |
691 | 692 | ||
692 | return (result); | 693 | return (result); |
@@ -695,9 +696,9 @@ static int __init lart_flash_init (void) | |||
695 | static void __exit lart_flash_exit (void) | 696 | static void __exit lart_flash_exit (void) |
696 | { | 697 | { |
697 | #ifndef HAVE_PARTITIONS | 698 | #ifndef HAVE_PARTITIONS |
698 | del_mtd_device (&mtd); | 699 | mtd_device_unregister(&mtd); |
699 | #else | 700 | #else |
700 | del_mtd_partitions (&mtd); | 701 | mtd_device_unregister(&mtd); |
701 | #endif | 702 | #endif |
702 | } | 703 | } |
703 | 704 | ||
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 3fb981d4bb51..35180e475c4c 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/mod_devicetable.h> | 28 | #include <linux/mod_devicetable.h> |
29 | 29 | ||
30 | #include <linux/mtd/cfi.h> | ||
30 | #include <linux/mtd/mtd.h> | 31 | #include <linux/mtd/mtd.h> |
31 | #include <linux/mtd/partitions.h> | 32 | #include <linux/mtd/partitions.h> |
32 | 33 | ||
@@ -55,6 +56,9 @@ | |||
55 | #define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */ | 56 | #define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */ |
56 | #define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */ | 57 | #define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */ |
57 | 58 | ||
59 | /* Used for Spansion flashes only. */ | ||
60 | #define OPCODE_BRWR 0x17 /* Bank register write */ | ||
61 | |||
58 | /* Status Register bits. */ | 62 | /* Status Register bits. */ |
59 | #define SR_WIP 1 /* Write in progress */ | 63 | #define SR_WIP 1 /* Write in progress */ |
60 | #define SR_WEL 2 /* Write enable latch */ | 64 | #define SR_WEL 2 /* Write enable latch */ |
@@ -76,6 +80,8 @@ | |||
76 | #define FAST_READ_DUMMY_BYTE 0 | 80 | #define FAST_READ_DUMMY_BYTE 0 |
77 | #endif | 81 | #endif |
78 | 82 | ||
83 | #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) | ||
84 | |||
79 | /****************************************************************************/ | 85 | /****************************************************************************/ |
80 | 86 | ||
81 | struct m25p { | 87 | struct m25p { |
@@ -158,11 +164,18 @@ static inline int write_disable(struct m25p *flash) | |||
158 | /* | 164 | /* |
159 | * Enable/disable 4-byte addressing mode. | 165 | * Enable/disable 4-byte addressing mode. |
160 | */ | 166 | */ |
161 | static inline int set_4byte(struct m25p *flash, int enable) | 167 | static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) |
162 | { | 168 | { |
163 | u8 code = enable ? OPCODE_EN4B : OPCODE_EX4B; | 169 | switch (JEDEC_MFR(jedec_id)) { |
164 | 170 | case CFI_MFR_MACRONIX: | |
165 | return spi_write_then_read(flash->spi, &code, 1, NULL, 0); | 171 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; |
172 | return spi_write(flash->spi, flash->command, 1); | ||
173 | default: | ||
174 | /* Spansion style */ | ||
175 | flash->command[0] = OPCODE_BRWR; | ||
176 | flash->command[1] = enable << 7; | ||
177 | return spi_write(flash->spi, flash->command, 2); | ||
178 | } | ||
166 | } | 179 | } |
167 | 180 | ||
168 | /* | 181 | /* |
@@ -668,6 +681,7 @@ static const struct spi_device_id m25p_ids[] = { | |||
668 | /* Macronix */ | 681 | /* Macronix */ |
669 | { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, | 682 | { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, |
670 | { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, | 683 | { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, |
684 | { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, | ||
671 | { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, | 685 | { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, |
672 | { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, | 686 | { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, |
673 | { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, | 687 | { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, |
@@ -684,6 +698,10 @@ static const struct spi_device_id m25p_ids[] = { | |||
684 | { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, | 698 | { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, |
685 | { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SECT_4K) }, | 699 | { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SECT_4K) }, |
686 | { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, | 700 | { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, |
701 | { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, | ||
702 | { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) }, | ||
703 | { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) }, | ||
704 | { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, | ||
687 | { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, | 705 | { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, |
688 | { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, | 706 | { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, |
689 | { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) }, | 707 | { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) }, |
@@ -729,7 +747,10 @@ static const struct spi_device_id m25p_ids[] = { | |||
729 | { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, | 747 | { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, |
730 | { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, | 748 | { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, |
731 | 749 | ||
732 | { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, | 750 | { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, |
751 | { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, | ||
752 | { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, | ||
753 | { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, | ||
733 | 754 | ||
734 | /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ | 755 | /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ |
735 | { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, | 756 | { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, |
@@ -804,6 +825,8 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
804 | struct m25p *flash; | 825 | struct m25p *flash; |
805 | struct flash_info *info; | 826 | struct flash_info *info; |
806 | unsigned i; | 827 | unsigned i; |
828 | struct mtd_partition *parts = NULL; | ||
829 | int nr_parts = 0; | ||
807 | 830 | ||
808 | /* Platform data helps sort out which chip type we have, as | 831 | /* Platform data helps sort out which chip type we have, as |
809 | * well as how this board partitions it. If we don't have | 832 | * well as how this board partitions it. If we don't have |
@@ -868,9 +891,9 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
868 | * up with the software protection bits set | 891 | * up with the software protection bits set |
869 | */ | 892 | */ |
870 | 893 | ||
871 | if (info->jedec_id >> 16 == 0x1f || | 894 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL || |
872 | info->jedec_id >> 16 == 0x89 || | 895 | JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL || |
873 | info->jedec_id >> 16 == 0xbf) { | 896 | JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) { |
874 | write_enable(flash); | 897 | write_enable(flash); |
875 | write_sr(flash, 0); | 898 | write_sr(flash, 0); |
876 | } | 899 | } |
@@ -888,7 +911,7 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
888 | flash->mtd.read = m25p80_read; | 911 | flash->mtd.read = m25p80_read; |
889 | 912 | ||
890 | /* sst flash chips use AAI word program */ | 913 | /* sst flash chips use AAI word program */ |
891 | if (info->jedec_id >> 16 == 0xbf) | 914 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) |
892 | flash->mtd.write = sst_write; | 915 | flash->mtd.write = sst_write; |
893 | else | 916 | else |
894 | flash->mtd.write = m25p80_write; | 917 | flash->mtd.write = m25p80_write; |
@@ -914,7 +937,7 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
914 | /* enable 4-byte addressing if the device exceeds 16MiB */ | 937 | /* enable 4-byte addressing if the device exceeds 16MiB */ |
915 | if (flash->mtd.size > 0x1000000) { | 938 | if (flash->mtd.size > 0x1000000) { |
916 | flash->addr_width = 4; | 939 | flash->addr_width = 4; |
917 | set_4byte(flash, 1); | 940 | set_4byte(flash, info->jedec_id, 1); |
918 | } else | 941 | } else |
919 | flash->addr_width = 3; | 942 | flash->addr_width = 3; |
920 | } | 943 | } |
@@ -945,48 +968,41 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
945 | /* partitions should match sector boundaries; and it may be good to | 968 | /* partitions should match sector boundaries; and it may be good to |
946 | * use readonly partitions for writeprotected sectors (BP2..BP0). | 969 | * use readonly partitions for writeprotected sectors (BP2..BP0). |
947 | */ | 970 | */ |
948 | if (mtd_has_partitions()) { | 971 | if (mtd_has_cmdlinepart()) { |
949 | struct mtd_partition *parts = NULL; | 972 | static const char *part_probes[] |
950 | int nr_parts = 0; | 973 | = { "cmdlinepart", NULL, }; |
951 | |||
952 | if (mtd_has_cmdlinepart()) { | ||
953 | static const char *part_probes[] | ||
954 | = { "cmdlinepart", NULL, }; | ||
955 | 974 | ||
956 | nr_parts = parse_mtd_partitions(&flash->mtd, | 975 | nr_parts = parse_mtd_partitions(&flash->mtd, |
957 | part_probes, &parts, 0); | 976 | part_probes, &parts, 0); |
958 | } | 977 | } |
959 | 978 | ||
960 | if (nr_parts <= 0 && data && data->parts) { | 979 | if (nr_parts <= 0 && data && data->parts) { |
961 | parts = data->parts; | 980 | parts = data->parts; |
962 | nr_parts = data->nr_parts; | 981 | nr_parts = data->nr_parts; |
963 | } | 982 | } |
964 | 983 | ||
965 | #ifdef CONFIG_MTD_OF_PARTS | 984 | #ifdef CONFIG_MTD_OF_PARTS |
966 | if (nr_parts <= 0 && spi->dev.of_node) { | 985 | if (nr_parts <= 0 && spi->dev.of_node) { |
967 | nr_parts = of_mtd_parse_partitions(&spi->dev, | 986 | nr_parts = of_mtd_parse_partitions(&spi->dev, |
968 | spi->dev.of_node, &parts); | 987 | spi->dev.of_node, &parts); |
969 | } | 988 | } |
970 | #endif | 989 | #endif |
971 | 990 | ||
972 | if (nr_parts > 0) { | 991 | if (nr_parts > 0) { |
973 | for (i = 0; i < nr_parts; i++) { | 992 | for (i = 0; i < nr_parts; i++) { |
974 | DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " | 993 | DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " |
975 | "{.name = %s, .offset = 0x%llx, " | 994 | "{.name = %s, .offset = 0x%llx, " |
976 | ".size = 0x%llx (%lldKiB) }\n", | 995 | ".size = 0x%llx (%lldKiB) }\n", |
977 | i, parts[i].name, | 996 | i, parts[i].name, |
978 | (long long)parts[i].offset, | 997 | (long long)parts[i].offset, |
979 | (long long)parts[i].size, | 998 | (long long)parts[i].size, |
980 | (long long)(parts[i].size >> 10)); | 999 | (long long)(parts[i].size >> 10)); |
981 | } | ||
982 | flash->partitioned = 1; | ||
983 | return add_mtd_partitions(&flash->mtd, parts, nr_parts); | ||
984 | } | 1000 | } |
985 | } else if (data && data->nr_parts) | 1001 | flash->partitioned = 1; |
986 | dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", | 1002 | } |
987 | data->nr_parts, data->name); | ||
988 | 1003 | ||
989 | return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0; | 1004 | return mtd_device_register(&flash->mtd, parts, nr_parts) == 1 ? |
1005 | -ENODEV : 0; | ||
990 | } | 1006 | } |
991 | 1007 | ||
992 | 1008 | ||
@@ -996,10 +1012,7 @@ static int __devexit m25p_remove(struct spi_device *spi) | |||
996 | int status; | 1012 | int status; |
997 | 1013 | ||
998 | /* Clean up MTD stuff. */ | 1014 | /* Clean up MTD stuff. */ |
999 | if (mtd_has_partitions() && flash->partitioned) | 1015 | status = mtd_device_unregister(&flash->mtd); |
1000 | status = del_mtd_partitions(&flash->mtd); | ||
1001 | else | ||
1002 | status = del_mtd_device(&flash->mtd); | ||
1003 | if (status == 0) { | 1016 | if (status == 0) { |
1004 | kfree(flash->command); | 1017 | kfree(flash->command); |
1005 | kfree(flash); | 1018 | kfree(flash); |
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 6a9a24a80a6d..8423fb6d4f26 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c | |||
@@ -220,7 +220,7 @@ static int __init ms02nv_init_one(ulong addr) | |||
220 | mtd->writesize = 1; | 220 | mtd->writesize = 1; |
221 | 221 | ||
222 | ret = -EIO; | 222 | ret = -EIO; |
223 | if (add_mtd_device(mtd)) { | 223 | if (mtd_device_register(mtd, NULL, 0)) { |
224 | printk(KERN_ERR | 224 | printk(KERN_ERR |
225 | "ms02-nv: Unable to register MTD device, aborting!\n"); | 225 | "ms02-nv: Unable to register MTD device, aborting!\n"); |
226 | goto err_out_csr_res; | 226 | goto err_out_csr_res; |
@@ -262,7 +262,7 @@ static void __exit ms02nv_remove_one(void) | |||
262 | 262 | ||
263 | root_ms02nv_mtd = mp->next; | 263 | root_ms02nv_mtd = mp->next; |
264 | 264 | ||
265 | del_mtd_device(mtd); | 265 | mtd_device_unregister(mtd); |
266 | 266 | ||
267 | release_resource(mp->resource.csr); | 267 | release_resource(mp->resource.csr); |
268 | kfree(mp->resource.csr); | 268 | kfree(mp->resource.csr); |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index c5015cc721d5..13749d458a31 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -637,6 +637,8 @@ add_dataflash_otp(struct spi_device *spi, char *name, | |||
637 | struct flash_platform_data *pdata = spi->dev.platform_data; | 637 | struct flash_platform_data *pdata = spi->dev.platform_data; |
638 | char *otp_tag = ""; | 638 | char *otp_tag = ""; |
639 | int err = 0; | 639 | int err = 0; |
640 | struct mtd_partition *parts; | ||
641 | int nr_parts = 0; | ||
640 | 642 | ||
641 | priv = kzalloc(sizeof *priv, GFP_KERNEL); | 643 | priv = kzalloc(sizeof *priv, GFP_KERNEL); |
642 | if (!priv) | 644 | if (!priv) |
@@ -675,33 +677,25 @@ add_dataflash_otp(struct spi_device *spi, char *name, | |||
675 | pagesize, otp_tag); | 677 | pagesize, otp_tag); |
676 | dev_set_drvdata(&spi->dev, priv); | 678 | dev_set_drvdata(&spi->dev, priv); |
677 | 679 | ||
678 | if (mtd_has_partitions()) { | 680 | if (mtd_has_cmdlinepart()) { |
679 | struct mtd_partition *parts; | 681 | static const char *part_probes[] = { "cmdlinepart", NULL, }; |
680 | int nr_parts = 0; | ||
681 | 682 | ||
682 | if (mtd_has_cmdlinepart()) { | 683 | nr_parts = parse_mtd_partitions(device, part_probes, &parts, |
683 | static const char *part_probes[] | 684 | 0); |
684 | = { "cmdlinepart", NULL, }; | 685 | } |
685 | |||
686 | nr_parts = parse_mtd_partitions(device, | ||
687 | part_probes, &parts, 0); | ||
688 | } | ||
689 | 686 | ||
690 | if (nr_parts <= 0 && pdata && pdata->parts) { | 687 | if (nr_parts <= 0 && pdata && pdata->parts) { |
691 | parts = pdata->parts; | 688 | parts = pdata->parts; |
692 | nr_parts = pdata->nr_parts; | 689 | nr_parts = pdata->nr_parts; |
693 | } | 690 | } |
694 | 691 | ||
695 | if (nr_parts > 0) { | 692 | if (nr_parts > 0) { |
696 | priv->partitioned = 1; | 693 | priv->partitioned = 1; |
697 | err = add_mtd_partitions(device, parts, nr_parts); | 694 | err = mtd_device_register(device, parts, nr_parts); |
698 | goto out; | 695 | goto out; |
699 | } | 696 | } |
700 | } else if (pdata && pdata->nr_parts) | ||
701 | dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", | ||
702 | pdata->nr_parts, device->name); | ||
703 | 697 | ||
704 | if (add_mtd_device(device) == 1) | 698 | if (mtd_device_register(device, NULL, 0) == 1) |
705 | err = -ENODEV; | 699 | err = -ENODEV; |
706 | 700 | ||
707 | out: | 701 | out: |
@@ -939,10 +933,7 @@ static int __devexit dataflash_remove(struct spi_device *spi) | |||
939 | 933 | ||
940 | DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev)); | 934 | DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev)); |
941 | 935 | ||
942 | if (mtd_has_partitions() && flash->partitioned) | 936 | status = mtd_device_unregister(&flash->mtd); |
943 | status = del_mtd_partitions(&flash->mtd); | ||
944 | else | ||
945 | status = del_mtd_device(&flash->mtd); | ||
946 | if (status == 0) { | 937 | if (status == 0) { |
947 | dev_set_drvdata(&spi->dev, NULL); | 938 | dev_set_drvdata(&spi->dev, NULL); |
948 | kfree(flash); | 939 | kfree(flash); |
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index 1483e18971ce..2562689ba6b4 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c | |||
@@ -104,7 +104,7 @@ static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
104 | static void __exit cleanup_mtdram(void) | 104 | static void __exit cleanup_mtdram(void) |
105 | { | 105 | { |
106 | if (mtd_info) { | 106 | if (mtd_info) { |
107 | del_mtd_device(mtd_info); | 107 | mtd_device_unregister(mtd_info); |
108 | vfree(mtd_info->priv); | 108 | vfree(mtd_info->priv); |
109 | kfree(mtd_info); | 109 | kfree(mtd_info); |
110 | } | 110 | } |
@@ -133,9 +133,8 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, | |||
133 | mtd->read = ram_read; | 133 | mtd->read = ram_read; |
134 | mtd->write = ram_write; | 134 | mtd->write = ram_write; |
135 | 135 | ||
136 | if (add_mtd_device(mtd)) { | 136 | if (mtd_device_register(mtd, NULL, 0)) |
137 | return -EIO; | 137 | return -EIO; |
138 | } | ||
139 | 138 | ||
140 | return 0; | 139 | return 0; |
141 | } | 140 | } |
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 8d28fa02a5a2..23423bd00b06 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -115,7 +115,7 @@ static void unregister_devices(void) | |||
115 | struct phram_mtd_list *this, *safe; | 115 | struct phram_mtd_list *this, *safe; |
116 | 116 | ||
117 | list_for_each_entry_safe(this, safe, &phram_list, list) { | 117 | list_for_each_entry_safe(this, safe, &phram_list, list) { |
118 | del_mtd_device(&this->mtd); | 118 | mtd_device_unregister(&this->mtd); |
119 | iounmap(this->mtd.priv); | 119 | iounmap(this->mtd.priv); |
120 | kfree(this->mtd.name); | 120 | kfree(this->mtd.name); |
121 | kfree(this); | 121 | kfree(this); |
@@ -153,7 +153,7 @@ static int register_device(char *name, unsigned long start, unsigned long len) | |||
153 | new->mtd.writesize = 1; | 153 | new->mtd.writesize = 1; |
154 | 154 | ||
155 | ret = -EAGAIN; | 155 | ret = -EAGAIN; |
156 | if (add_mtd_device(&new->mtd)) { | 156 | if (mtd_device_register(&new->mtd, NULL, 0)) { |
157 | pr_err("Failed to register new device\n"); | 157 | pr_err("Failed to register new device\n"); |
158 | goto out2; | 158 | goto out2; |
159 | } | 159 | } |
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 41b8cdcc64cb..ecff765579dd 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c | |||
@@ -798,7 +798,7 @@ static int __init init_pmc551(void) | |||
798 | mtd->writesize = 1; | 798 | mtd->writesize = 1; |
799 | mtd->owner = THIS_MODULE; | 799 | mtd->owner = THIS_MODULE; |
800 | 800 | ||
801 | if (add_mtd_device(mtd)) { | 801 | if (mtd_device_register(mtd, NULL, 0)) { |
802 | printk(KERN_NOTICE "pmc551: Failed to register new device\n"); | 802 | printk(KERN_NOTICE "pmc551: Failed to register new device\n"); |
803 | pci_iounmap(PCI_Device, priv->start); | 803 | pci_iounmap(PCI_Device, priv->start); |
804 | kfree(mtd->priv); | 804 | kfree(mtd->priv); |
@@ -806,7 +806,7 @@ static int __init init_pmc551(void) | |||
806 | break; | 806 | break; |
807 | } | 807 | } |
808 | 808 | ||
809 | /* Keep a reference as the add_mtd_device worked */ | 809 | /* Keep a reference as the mtd_device_register worked */ |
810 | pci_dev_get(PCI_Device); | 810 | pci_dev_get(PCI_Device); |
811 | 811 | ||
812 | printk(KERN_NOTICE "Registered pmc551 memory device.\n"); | 812 | printk(KERN_NOTICE "Registered pmc551 memory device.\n"); |
@@ -856,7 +856,7 @@ static void __exit cleanup_pmc551(void) | |||
856 | pci_dev_put(priv->dev); | 856 | pci_dev_put(priv->dev); |
857 | 857 | ||
858 | kfree(mtd->priv); | 858 | kfree(mtd->priv); |
859 | del_mtd_device(mtd); | 859 | mtd_device_unregister(mtd); |
860 | kfree(mtd); | 860 | kfree(mtd); |
861 | found++; | 861 | found++; |
862 | } | 862 | } |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 592016a0668f..e585263161b9 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -210,7 +210,7 @@ static int register_device(char *name, unsigned long start, unsigned long length | |||
210 | (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; | 210 | (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; |
211 | (*curmtd)->mtdinfo->writesize = 1; | 211 | (*curmtd)->mtdinfo->writesize = 1; |
212 | 212 | ||
213 | if (add_mtd_device((*curmtd)->mtdinfo)) { | 213 | if (mtd_device_register((*curmtd)->mtdinfo, NULL, 0)) { |
214 | E("slram: Failed to register new device\n"); | 214 | E("slram: Failed to register new device\n"); |
215 | iounmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start); | 215 | iounmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start); |
216 | kfree((*curmtd)->mtdinfo->priv); | 216 | kfree((*curmtd)->mtdinfo->priv); |
@@ -231,7 +231,7 @@ static void unregister_devices(void) | |||
231 | 231 | ||
232 | while (slram_mtdlist) { | 232 | while (slram_mtdlist) { |
233 | nextitem = slram_mtdlist->next; | 233 | nextitem = slram_mtdlist->next; |
234 | del_mtd_device(slram_mtdlist->mtdinfo); | 234 | mtd_device_unregister(slram_mtdlist->mtdinfo); |
235 | iounmap(((slram_priv_t *)slram_mtdlist->mtdinfo->priv)->start); | 235 | iounmap(((slram_priv_t *)slram_mtdlist->mtdinfo->priv)->start); |
236 | kfree(slram_mtdlist->mtdinfo->priv); | 236 | kfree(slram_mtdlist->mtdinfo->priv); |
237 | kfree(slram_mtdlist->mtdinfo); | 237 | kfree(slram_mtdlist->mtdinfo); |
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index c163e619abc9..1e2c430aaad2 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c | |||
@@ -66,7 +66,7 @@ struct flash_info { | |||
66 | 66 | ||
67 | #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) | 67 | #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) |
68 | 68 | ||
69 | static struct flash_info __initdata sst25l_flash_info[] = { | 69 | static struct flash_info __devinitdata sst25l_flash_info[] = { |
70 | {"sst25lf020a", 0xbf43, 256, 1024, 4096}, | 70 | {"sst25lf020a", 0xbf43, 256, 1024, 4096}, |
71 | {"sst25lf040a", 0xbf44, 256, 2048, 4096}, | 71 | {"sst25lf040a", 0xbf44, 256, 2048, 4096}, |
72 | }; | 72 | }; |
@@ -381,6 +381,8 @@ static int __devinit sst25l_probe(struct spi_device *spi) | |||
381 | struct sst25l_flash *flash; | 381 | struct sst25l_flash *flash; |
382 | struct flash_platform_data *data; | 382 | struct flash_platform_data *data; |
383 | int ret, i; | 383 | int ret, i; |
384 | struct mtd_partition *parts = NULL; | ||
385 | int nr_parts = 0; | ||
384 | 386 | ||
385 | flash_info = sst25l_match_device(spi); | 387 | flash_info = sst25l_match_device(spi); |
386 | if (!flash_info) | 388 | if (!flash_info) |
@@ -420,46 +422,37 @@ static int __devinit sst25l_probe(struct spi_device *spi) | |||
420 | flash->mtd.erasesize, flash->mtd.erasesize / 1024, | 422 | flash->mtd.erasesize, flash->mtd.erasesize / 1024, |
421 | flash->mtd.numeraseregions); | 423 | flash->mtd.numeraseregions); |
422 | 424 | ||
423 | if (mtd_has_partitions()) { | ||
424 | struct mtd_partition *parts = NULL; | ||
425 | int nr_parts = 0; | ||
426 | 425 | ||
427 | if (mtd_has_cmdlinepart()) { | 426 | if (mtd_has_cmdlinepart()) { |
428 | static const char *part_probes[] = | 427 | static const char *part_probes[] = {"cmdlinepart", NULL}; |
429 | {"cmdlinepart", NULL}; | ||
430 | 428 | ||
431 | nr_parts = parse_mtd_partitions(&flash->mtd, | 429 | nr_parts = parse_mtd_partitions(&flash->mtd, |
432 | part_probes, | 430 | part_probes, |
433 | &parts, 0); | 431 | &parts, 0); |
434 | } | 432 | } |
435 | 433 | ||
436 | if (nr_parts <= 0 && data && data->parts) { | 434 | if (nr_parts <= 0 && data && data->parts) { |
437 | parts = data->parts; | 435 | parts = data->parts; |
438 | nr_parts = data->nr_parts; | 436 | nr_parts = data->nr_parts; |
439 | } | 437 | } |
440 | 438 | ||
441 | if (nr_parts > 0) { | 439 | if (nr_parts > 0) { |
442 | for (i = 0; i < nr_parts; i++) { | 440 | for (i = 0; i < nr_parts; i++) { |
443 | DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " | 441 | DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " |
444 | "{.name = %s, .offset = 0x%llx, " | 442 | "{.name = %s, .offset = 0x%llx, " |
445 | ".size = 0x%llx (%lldKiB) }\n", | 443 | ".size = 0x%llx (%lldKiB) }\n", |
446 | i, parts[i].name, | 444 | i, parts[i].name, |
447 | (long long)parts[i].offset, | 445 | (long long)parts[i].offset, |
448 | (long long)parts[i].size, | 446 | (long long)parts[i].size, |
449 | (long long)(parts[i].size >> 10)); | 447 | (long long)(parts[i].size >> 10)); |
450 | } | ||
451 | |||
452 | flash->partitioned = 1; | ||
453 | return add_mtd_partitions(&flash->mtd, | ||
454 | parts, nr_parts); | ||
455 | } | 448 | } |
456 | 449 | ||
457 | } else if (data && data->nr_parts) { | 450 | flash->partitioned = 1; |
458 | dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", | 451 | return mtd_device_register(&flash->mtd, parts, |
459 | data->nr_parts, data->name); | 452 | nr_parts); |
460 | } | 453 | } |
461 | 454 | ||
462 | ret = add_mtd_device(&flash->mtd); | 455 | ret = mtd_device_register(&flash->mtd, NULL, 0); |
463 | if (ret == 1) { | 456 | if (ret == 1) { |
464 | kfree(flash); | 457 | kfree(flash); |
465 | dev_set_drvdata(&spi->dev, NULL); | 458 | dev_set_drvdata(&spi->dev, NULL); |
@@ -469,15 +462,12 @@ static int __devinit sst25l_probe(struct spi_device *spi) | |||
469 | return 0; | 462 | return 0; |
470 | } | 463 | } |
471 | 464 | ||
472 | static int __exit sst25l_remove(struct spi_device *spi) | 465 | static int __devexit sst25l_remove(struct spi_device *spi) |
473 | { | 466 | { |
474 | struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); | 467 | struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); |
475 | int ret; | 468 | int ret; |
476 | 469 | ||
477 | if (mtd_has_partitions() && flash->partitioned) | 470 | ret = mtd_device_unregister(&flash->mtd); |
478 | ret = del_mtd_partitions(&flash->mtd); | ||
479 | else | ||
480 | ret = del_mtd_device(&flash->mtd); | ||
481 | if (ret == 0) | 471 | if (ret == 0) |
482 | kfree(flash); | 472 | kfree(flash); |
483 | return ret; | 473 | return ret; |
@@ -490,7 +480,7 @@ static struct spi_driver sst25l_driver = { | |||
490 | .owner = THIS_MODULE, | 480 | .owner = THIS_MODULE, |
491 | }, | 481 | }, |
492 | .probe = sst25l_probe, | 482 | .probe = sst25l_probe, |
493 | .remove = __exit_p(sst25l_remove), | 483 | .remove = __devexit_p(sst25l_remove), |
494 | }; | 484 | }; |
495 | 485 | ||
496 | static int __init sst25l_init(void) | 486 | static int __init sst25l_init(void) |
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index 12679925b420..65655dd59e1f 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c | |||
@@ -313,12 +313,7 @@ static int chip_ready(struct map_info *map, struct flchip *chip, int mode) | |||
313 | if (ret) { | 313 | if (ret) { |
314 | /* Oops. something got wrong. */ | 314 | /* Oops. something got wrong. */ |
315 | /* Resume and pretend we weren't here. */ | 315 | /* Resume and pretend we weren't here. */ |
316 | map_write(map, CMD(LPDDR_RESUME), | 316 | put_chip(map, chip); |
317 | map->pfow_base + PFOW_COMMAND_CODE); | ||
318 | map_write(map, CMD(LPDDR_START_EXECUTION), | ||
319 | map->pfow_base + PFOW_COMMAND_EXECUTE); | ||
320 | chip->state = FL_ERASING; | ||
321 | chip->oldstate = FL_READY; | ||
322 | printk(KERN_ERR "%s: suspend operation failed." | 317 | printk(KERN_ERR "%s: suspend operation failed." |
323 | "State may be wrong \n", map->name); | 318 | "State may be wrong \n", map->name); |
324 | return -EIO; | 319 | return -EIO; |
@@ -383,7 +378,6 @@ static void put_chip(struct map_info *map, struct flchip *chip) | |||
383 | 378 | ||
384 | switch (chip->oldstate) { | 379 | switch (chip->oldstate) { |
385 | case FL_ERASING: | 380 | case FL_ERASING: |
386 | chip->state = chip->oldstate; | ||
387 | map_write(map, CMD(LPDDR_RESUME), | 381 | map_write(map, CMD(LPDDR_RESUME), |
388 | map->pfow_base + PFOW_COMMAND_CODE); | 382 | map->pfow_base + PFOW_COMMAND_CODE); |
389 | map_write(map, CMD(LPDDR_START_EXECUTION), | 383 | map_write(map, CMD(LPDDR_START_EXECUTION), |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 5069111c81cc..c0c328c5b133 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -82,7 +82,6 @@ config MTD_PHYSMAP_OF | |||
82 | config MTD_PMC_MSP_EVM | 82 | config MTD_PMC_MSP_EVM |
83 | tristate "CFI Flash device mapped on PMC-Sierra MSP" | 83 | tristate "CFI Flash device mapped on PMC-Sierra MSP" |
84 | depends on PMC_MSP && MTD_CFI | 84 | depends on PMC_MSP && MTD_CFI |
85 | select MTD_PARTITIONS | ||
86 | help | 85 | help |
87 | This provides a 'mapping' driver which supports the way | 86 | This provides a 'mapping' driver which supports the way |
88 | in which user-programmable flash chips are connected on the | 87 | in which user-programmable flash chips are connected on the |
@@ -122,7 +121,7 @@ config MTD_SC520CDP | |||
122 | 121 | ||
123 | config MTD_NETSC520 | 122 | config MTD_NETSC520 |
124 | tristate "CFI Flash device mapped on AMD NetSc520" | 123 | tristate "CFI Flash device mapped on AMD NetSc520" |
125 | depends on X86 && MTD_CFI && MTD_PARTITIONS | 124 | depends on X86 && MTD_CFI |
126 | help | 125 | help |
127 | This enables access routines for the flash chips on the AMD NetSc520 | 126 | This enables access routines for the flash chips on the AMD NetSc520 |
128 | demonstration board. If you have one of these boards and would like | 127 | demonstration board. If you have one of these boards and would like |
@@ -131,7 +130,6 @@ config MTD_NETSC520 | |||
131 | config MTD_TS5500 | 130 | config MTD_TS5500 |
132 | tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" | 131 | tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" |
133 | depends on X86 | 132 | depends on X86 |
134 | select MTD_PARTITIONS | ||
135 | select MTD_JEDECPROBE | 133 | select MTD_JEDECPROBE |
136 | select MTD_CFI_AMDSTD | 134 | select MTD_CFI_AMDSTD |
137 | help | 135 | help |
@@ -149,7 +147,7 @@ config MTD_TS5500 | |||
149 | 147 | ||
150 | config MTD_SBC_GXX | 148 | config MTD_SBC_GXX |
151 | tristate "CFI Flash device mapped on Arcom SBC-GXx boards" | 149 | tristate "CFI Flash device mapped on Arcom SBC-GXx boards" |
152 | depends on X86 && MTD_CFI_INTELEXT && MTD_PARTITIONS && MTD_COMPLEX_MAPPINGS | 150 | depends on X86 && MTD_CFI_INTELEXT && MTD_COMPLEX_MAPPINGS |
153 | help | 151 | help |
154 | This provides a driver for the on-board flash of Arcom Control | 152 | This provides a driver for the on-board flash of Arcom Control |
155 | Systems' SBC-GXn family of boards, formerly known as SBC-MediaGX. | 153 | Systems' SBC-GXn family of boards, formerly known as SBC-MediaGX. |
@@ -161,7 +159,6 @@ config MTD_SBC_GXX | |||
161 | config MTD_PXA2XX | 159 | config MTD_PXA2XX |
162 | tristate "CFI Flash device mapped on Intel XScale PXA2xx based boards" | 160 | tristate "CFI Flash device mapped on Intel XScale PXA2xx based boards" |
163 | depends on (PXA25x || PXA27x) && MTD_CFI_INTELEXT | 161 | depends on (PXA25x || PXA27x) && MTD_CFI_INTELEXT |
164 | select MTD_PARTITIONS | ||
165 | help | 162 | help |
166 | This provides a driver for the NOR flash attached to a PXA2xx chip. | 163 | This provides a driver for the NOR flash attached to a PXA2xx chip. |
167 | 164 | ||
@@ -185,7 +182,7 @@ config MTD_VMAX | |||
185 | 182 | ||
186 | config MTD_SCx200_DOCFLASH | 183 | config MTD_SCx200_DOCFLASH |
187 | tristate "Flash device mapped with DOCCS on NatSemi SCx200" | 184 | tristate "Flash device mapped with DOCCS on NatSemi SCx200" |
188 | depends on SCx200 && MTD_CFI && MTD_PARTITIONS | 185 | depends on SCx200 && MTD_CFI |
189 | help | 186 | help |
190 | Enable support for a flash chip mapped using the DOCCS signal on a | 187 | Enable support for a flash chip mapped using the DOCCS signal on a |
191 | National Semiconductor SCx200 processor. | 188 | National Semiconductor SCx200 processor. |
@@ -247,7 +244,7 @@ config MTD_TSUNAMI | |||
247 | 244 | ||
248 | config MTD_NETtel | 245 | config MTD_NETtel |
249 | tristate "CFI flash device on SnapGear/SecureEdge" | 246 | tristate "CFI flash device on SnapGear/SecureEdge" |
250 | depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE | 247 | depends on X86 && MTD_JEDECPROBE |
251 | help | 248 | help |
252 | Support for flash chips on NETtel/SecureEdge/SnapGear boards. | 249 | Support for flash chips on NETtel/SecureEdge/SnapGear boards. |
253 | 250 | ||
@@ -269,7 +266,7 @@ config MTD_LANTIQ | |||
269 | 266 | ||
270 | config MTD_DILNETPC | 267 | config MTD_DILNETPC |
271 | tristate "CFI Flash device mapped on DIL/Net PC" | 268 | tristate "CFI Flash device mapped on DIL/Net PC" |
272 | depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN | 269 | depends on X86 && MTD_CFI_INTELEXT && BROKEN |
273 | help | 270 | help |
274 | MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". | 271 | MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". |
275 | For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm> | 272 | For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm> |
@@ -355,7 +352,7 @@ config MTD_CDB89712 | |||
355 | 352 | ||
356 | config MTD_SA1100 | 353 | config MTD_SA1100 |
357 | tristate "CFI Flash device mapped on StrongARM SA11x0" | 354 | tristate "CFI Flash device mapped on StrongARM SA11x0" |
358 | depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS | 355 | depends on MTD_CFI && ARCH_SA1100 |
359 | help | 356 | help |
360 | This enables access to the flash chips on most platforms based on | 357 | This enables access to the flash chips on most platforms based on |
361 | the SA1100 and SA1110, including the Assabet and the Compaq iPAQ. | 358 | the SA1100 and SA1110, including the Assabet and the Compaq iPAQ. |
@@ -389,7 +386,7 @@ config MTD_IXP2000 | |||
389 | 386 | ||
390 | config MTD_FORTUNET | 387 | config MTD_FORTUNET |
391 | tristate "CFI Flash device mapped on the FortuNet board" | 388 | tristate "CFI Flash device mapped on the FortuNet board" |
392 | depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET | 389 | depends on MTD_CFI && SA1100_FORTUNET |
393 | help | 390 | help |
394 | This enables access to the Flash on the FortuNet board. If you | 391 | This enables access to the Flash on the FortuNet board. If you |
395 | have such a board, say 'Y'. | 392 | have such a board, say 'Y'. |
@@ -461,7 +458,6 @@ config MTD_PCMCIA_ANONYMOUS | |||
461 | config MTD_BFIN_ASYNC | 458 | config MTD_BFIN_ASYNC |
462 | tristate "Blackfin BF533-STAMP Flash Chip Support" | 459 | tristate "Blackfin BF533-STAMP Flash Chip Support" |
463 | depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS | 460 | depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS |
464 | select MTD_PARTITIONS | ||
465 | default y | 461 | default y |
466 | help | 462 | help |
467 | Map driver which allows for simultaneous utilization of | 463 | Map driver which allows for simultaneous utilization of |
@@ -473,7 +469,6 @@ config MTD_GPIO_ADDR | |||
473 | tristate "GPIO-assisted Flash Chip Support" | 469 | tristate "GPIO-assisted Flash Chip Support" |
474 | depends on GENERIC_GPIO || GPIOLIB | 470 | depends on GENERIC_GPIO || GPIOLIB |
475 | depends on MTD_COMPLEX_MAPPINGS | 471 | depends on MTD_COMPLEX_MAPPINGS |
476 | select MTD_PARTITIONS | ||
477 | help | 472 | help |
478 | Map driver which allows flashes to be partially physically addressed | 473 | Map driver which allows flashes to be partially physically addressed |
479 | and assisted by GPIOs. | 474 | and assisted by GPIOs. |
@@ -482,14 +477,13 @@ config MTD_GPIO_ADDR | |||
482 | 477 | ||
483 | config MTD_UCLINUX | 478 | config MTD_UCLINUX |
484 | bool "Generic uClinux RAM/ROM filesystem support" | 479 | bool "Generic uClinux RAM/ROM filesystem support" |
485 | depends on MTD_PARTITIONS && MTD_RAM=y && !MMU | 480 | depends on MTD_RAM=y && !MMU |
486 | help | 481 | help |
487 | Map driver to support image based filesystems for uClinux. | 482 | Map driver to support image based filesystems for uClinux. |
488 | 483 | ||
489 | config MTD_WRSBC8260 | 484 | config MTD_WRSBC8260 |
490 | tristate "Map driver for WindRiver PowerQUICC II MPC82xx board" | 485 | tristate "Map driver for WindRiver PowerQUICC II MPC82xx board" |
491 | depends on (SBC82xx || SBC8560) | 486 | depends on (SBC82xx || SBC8560) |
492 | select MTD_PARTITIONS | ||
493 | select MTD_MAP_BANK_WIDTH_4 | 487 | select MTD_MAP_BANK_WIDTH_4 |
494 | select MTD_MAP_BANK_WIDTH_1 | 488 | select MTD_MAP_BANK_WIDTH_1 |
495 | select MTD_CFI_I1 | 489 | select MTD_CFI_I1 |
@@ -502,7 +496,6 @@ config MTD_WRSBC8260 | |||
502 | config MTD_DMV182 | 496 | config MTD_DMV182 |
503 | tristate "Map driver for Dy-4 SVME/DMV-182 board." | 497 | tristate "Map driver for Dy-4 SVME/DMV-182 board." |
504 | depends on DMV182 | 498 | depends on DMV182 |
505 | select MTD_PARTITIONS | ||
506 | select MTD_MAP_BANK_WIDTH_32 | 499 | select MTD_MAP_BANK_WIDTH_32 |
507 | select MTD_CFI_I8 | 500 | select MTD_CFI_I8 |
508 | select MTD_CFI_AMDSTD | 501 | select MTD_CFI_AMDSTD |
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 92de7e3a49a5..e2875d6fe129 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c | |||
@@ -82,7 +82,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window) | |||
82 | if (map->rsrc.parent) { | 82 | if (map->rsrc.parent) { |
83 | release_resource(&map->rsrc); | 83 | release_resource(&map->rsrc); |
84 | } | 84 | } |
85 | del_mtd_device(map->mtd); | 85 | mtd_device_unregister(map->mtd); |
86 | map_destroy(map->mtd); | 86 | map_destroy(map->mtd); |
87 | list_del(&map->list); | 87 | list_del(&map->list); |
88 | kfree(map); | 88 | kfree(map); |
@@ -262,7 +262,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | |||
262 | 262 | ||
263 | /* Now that the mtd devices is complete claim and export it */ | 263 | /* Now that the mtd devices is complete claim and export it */ |
264 | map->mtd->owner = THIS_MODULE; | 264 | map->mtd->owner = THIS_MODULE; |
265 | if (add_mtd_device(map->mtd)) { | 265 | if (mtd_device_register(map->mtd, NULL, 0)) { |
266 | map_destroy(map->mtd); | 266 | map_destroy(map->mtd); |
267 | map->mtd = NULL; | 267 | map->mtd = NULL; |
268 | goto out; | 268 | goto out; |
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c index 53664188fc47..e5bfd0e093bb 100644 --- a/drivers/mtd/maps/autcpu12-nvram.c +++ b/drivers/mtd/maps/autcpu12-nvram.c | |||
@@ -88,7 +88,7 @@ map: | |||
88 | sram_mtd->owner = THIS_MODULE; | 88 | sram_mtd->owner = THIS_MODULE; |
89 | sram_mtd->erasesize = 16; | 89 | sram_mtd->erasesize = 16; |
90 | 90 | ||
91 | if (add_mtd_device(sram_mtd)) { | 91 | if (mtd_device_register(sram_mtd, NULL, 0)) { |
92 | printk("NV-RAM device addition failed\n"); | 92 | printk("NV-RAM device addition failed\n"); |
93 | err = -ENOMEM; | 93 | err = -ENOMEM; |
94 | goto out_probe; | 94 | goto out_probe; |
@@ -111,7 +111,7 @@ out: | |||
111 | static void __exit cleanup_autcpu12_maps(void) | 111 | static void __exit cleanup_autcpu12_maps(void) |
112 | { | 112 | { |
113 | if (sram_mtd) { | 113 | if (sram_mtd) { |
114 | del_mtd_device(sram_mtd); | 114 | mtd_device_unregister(sram_mtd); |
115 | map_destroy(sram_mtd); | 115 | map_destroy(sram_mtd); |
116 | iounmap((void *)autcpu12_sram_map.virt); | 116 | iounmap((void *)autcpu12_sram_map.virt); |
117 | } | 117 | } |
diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c index 1f3049590d9e..608967fe74c6 100644 --- a/drivers/mtd/maps/bcm963xx-flash.c +++ b/drivers/mtd/maps/bcm963xx-flash.c | |||
@@ -224,8 +224,8 @@ probe_ok: | |||
224 | goto err_probe; | 224 | goto err_probe; |
225 | } | 225 | } |
226 | 226 | ||
227 | return add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, | 227 | return mtd_device_register(bcm963xx_mtd_info, parsed_parts, |
228 | parsed_nr_parts); | 228 | parsed_nr_parts); |
229 | 229 | ||
230 | err_probe: | 230 | err_probe: |
231 | iounmap(bcm963xx_map.virt); | 231 | iounmap(bcm963xx_map.virt); |
@@ -235,7 +235,7 @@ err_probe: | |||
235 | static int bcm963xx_remove(struct platform_device *pdev) | 235 | static int bcm963xx_remove(struct platform_device *pdev) |
236 | { | 236 | { |
237 | if (bcm963xx_mtd_info) { | 237 | if (bcm963xx_mtd_info) { |
238 | del_mtd_partitions(bcm963xx_mtd_info); | 238 | mtd_device_unregister(bcm963xx_mtd_info); |
239 | map_destroy(bcm963xx_mtd_info); | 239 | map_destroy(bcm963xx_mtd_info); |
240 | } | 240 | } |
241 | 241 | ||
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 85dd18193cf2..d4297a97e100 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c | |||
@@ -41,9 +41,7 @@ struct async_state { | |||
41 | uint32_t flash_ambctl0, flash_ambctl1; | 41 | uint32_t flash_ambctl0, flash_ambctl1; |
42 | uint32_t save_ambctl0, save_ambctl1; | 42 | uint32_t save_ambctl0, save_ambctl1; |
43 | unsigned long irq_flags; | 43 | unsigned long irq_flags; |
44 | #ifdef CONFIG_MTD_PARTITIONS | ||
45 | struct mtd_partition *parts; | 44 | struct mtd_partition *parts; |
46 | #endif | ||
47 | }; | 45 | }; |
48 | 46 | ||
49 | static void switch_to_flash(struct async_state *state) | 47 | static void switch_to_flash(struct async_state *state) |
@@ -124,9 +122,7 @@ static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const voi | |||
124 | switch_back(state); | 122 | switch_back(state); |
125 | } | 123 | } |
126 | 124 | ||
127 | #ifdef CONFIG_MTD_PARTITIONS | ||
128 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | 125 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; |
129 | #endif | ||
130 | 126 | ||
131 | static int __devinit bfin_flash_probe(struct platform_device *pdev) | 127 | static int __devinit bfin_flash_probe(struct platform_device *pdev) |
132 | { | 128 | { |
@@ -169,22 +165,17 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) | |||
169 | return -ENXIO; | 165 | return -ENXIO; |
170 | } | 166 | } |
171 | 167 | ||
172 | #ifdef CONFIG_MTD_PARTITIONS | ||
173 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); | 168 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); |
174 | if (ret > 0) { | 169 | if (ret > 0) { |
175 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); | 170 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); |
176 | add_mtd_partitions(state->mtd, pdata->parts, ret); | 171 | mtd_device_register(state->mtd, pdata->parts, ret); |
177 | state->parts = pdata->parts; | 172 | state->parts = pdata->parts; |
178 | |||
179 | } else if (pdata->nr_parts) { | 173 | } else if (pdata->nr_parts) { |
180 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); | 174 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); |
181 | add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts); | 175 | mtd_device_register(state->mtd, pdata->parts, pdata->nr_parts); |
182 | 176 | } else { | |
183 | } else | ||
184 | #endif | ||
185 | { | ||
186 | pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); | 177 | pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); |
187 | add_mtd_device(state->mtd); | 178 | mtd_device_register(state->mtd, NULL, 0); |
188 | } | 179 | } |
189 | 180 | ||
190 | platform_set_drvdata(pdev, state); | 181 | platform_set_drvdata(pdev, state); |
@@ -196,10 +187,8 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev) | |||
196 | { | 187 | { |
197 | struct async_state *state = platform_get_drvdata(pdev); | 188 | struct async_state *state = platform_get_drvdata(pdev); |
198 | gpio_free(state->enet_flash_pin); | 189 | gpio_free(state->enet_flash_pin); |
199 | #ifdef CONFIG_MTD_PARTITIONS | 190 | mtd_device_unregister(state->mtd); |
200 | del_mtd_partitions(state->mtd); | ||
201 | kfree(state->parts); | 191 | kfree(state->parts); |
202 | #endif | ||
203 | map_destroy(state->mtd); | 192 | map_destroy(state->mtd); |
204 | kfree(state); | 193 | kfree(state); |
205 | return 0; | 194 | return 0; |
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c index 8d92d8db9a98..c29cbf87ea0c 100644 --- a/drivers/mtd/maps/cdb89712.c +++ b/drivers/mtd/maps/cdb89712.c | |||
@@ -75,7 +75,7 @@ static int __init init_cdb89712_flash (void) | |||
75 | 75 | ||
76 | flash_mtd->owner = THIS_MODULE; | 76 | flash_mtd->owner = THIS_MODULE; |
77 | 77 | ||
78 | if (add_mtd_device(flash_mtd)) { | 78 | if (mtd_device_register(flash_mtd, NULL, 0)) { |
79 | printk("FLASH device addition failed\n"); | 79 | printk("FLASH device addition failed\n"); |
80 | err = -ENOMEM; | 80 | err = -ENOMEM; |
81 | goto out_probe; | 81 | goto out_probe; |
@@ -141,7 +141,7 @@ static int __init init_cdb89712_sram (void) | |||
141 | sram_mtd->owner = THIS_MODULE; | 141 | sram_mtd->owner = THIS_MODULE; |
142 | sram_mtd->erasesize = 16; | 142 | sram_mtd->erasesize = 16; |
143 | 143 | ||
144 | if (add_mtd_device(sram_mtd)) { | 144 | if (mtd_device_register(sram_mtd, NULL, 0)) { |
145 | printk("SRAM device addition failed\n"); | 145 | printk("SRAM device addition failed\n"); |
146 | err = -ENOMEM; | 146 | err = -ENOMEM; |
147 | goto out_probe; | 147 | goto out_probe; |
@@ -209,7 +209,7 @@ static int __init init_cdb89712_bootrom (void) | |||
209 | bootrom_mtd->owner = THIS_MODULE; | 209 | bootrom_mtd->owner = THIS_MODULE; |
210 | bootrom_mtd->erasesize = 0x10000; | 210 | bootrom_mtd->erasesize = 0x10000; |
211 | 211 | ||
212 | if (add_mtd_device(bootrom_mtd)) { | 212 | if (mtd_device_register(bootrom_mtd, NULL, 0)) { |
213 | printk("BootROM device addition failed\n"); | 213 | printk("BootROM device addition failed\n"); |
214 | err = -ENOMEM; | 214 | err = -ENOMEM; |
215 | goto out_probe; | 215 | goto out_probe; |
@@ -249,21 +249,21 @@ static int __init init_cdb89712_maps(void) | |||
249 | static void __exit cleanup_cdb89712_maps(void) | 249 | static void __exit cleanup_cdb89712_maps(void) |
250 | { | 250 | { |
251 | if (sram_mtd) { | 251 | if (sram_mtd) { |
252 | del_mtd_device(sram_mtd); | 252 | mtd_device_unregister(sram_mtd); |
253 | map_destroy(sram_mtd); | 253 | map_destroy(sram_mtd); |
254 | iounmap((void *)cdb89712_sram_map.virt); | 254 | iounmap((void *)cdb89712_sram_map.virt); |
255 | release_resource (&cdb89712_sram_resource); | 255 | release_resource (&cdb89712_sram_resource); |
256 | } | 256 | } |
257 | 257 | ||
258 | if (flash_mtd) { | 258 | if (flash_mtd) { |
259 | del_mtd_device(flash_mtd); | 259 | mtd_device_unregister(flash_mtd); |
260 | map_destroy(flash_mtd); | 260 | map_destroy(flash_mtd); |
261 | iounmap((void *)cdb89712_flash_map.virt); | 261 | iounmap((void *)cdb89712_flash_map.virt); |
262 | release_resource (&cdb89712_flash_resource); | 262 | release_resource (&cdb89712_flash_resource); |
263 | } | 263 | } |
264 | 264 | ||
265 | if (bootrom_mtd) { | 265 | if (bootrom_mtd) { |
266 | del_mtd_device(bootrom_mtd); | 266 | mtd_device_unregister(bootrom_mtd); |
267 | map_destroy(bootrom_mtd); | 267 | map_destroy(bootrom_mtd); |
268 | iounmap((void *)cdb89712_bootrom_map.virt); | 268 | iounmap((void *)cdb89712_bootrom_map.virt); |
269 | release_resource (&cdb89712_bootrom_resource); | 269 | release_resource (&cdb89712_bootrom_resource); |
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c index 23f551dc8ca8..06f9c9815720 100644 --- a/drivers/mtd/maps/ceiva.c +++ b/drivers/mtd/maps/ceiva.c | |||
@@ -224,7 +224,7 @@ static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd | |||
224 | { | 224 | { |
225 | int i; | 225 | int i; |
226 | 226 | ||
227 | del_mtd_partitions(mtd); | 227 | mtd_device_unregister(mtd); |
228 | 228 | ||
229 | if (mtd != clps[0].mtd) | 229 | if (mtd != clps[0].mtd) |
230 | mtd_concat_destroy(mtd); | 230 | mtd_concat_destroy(mtd); |
@@ -292,11 +292,11 @@ static void __init clps_locate_partitions(struct mtd_info *mtd) | |||
292 | if (nr_parts == 0) { | 292 | if (nr_parts == 0) { |
293 | printk(KERN_NOTICE "clps flash: no partition info " | 293 | printk(KERN_NOTICE "clps flash: no partition info " |
294 | "available, registering whole flash\n"); | 294 | "available, registering whole flash\n"); |
295 | add_mtd_device(mtd); | 295 | mtd_device_register(mtd, NULL, 0); |
296 | } else { | 296 | } else { |
297 | printk(KERN_NOTICE "clps flash: using %s partition " | 297 | printk(KERN_NOTICE "clps flash: using %s partition " |
298 | "definition\n", part_type); | 298 | "definition\n", part_type); |
299 | add_mtd_partitions(mtd, parsed_parts, nr_parts); | 299 | mtd_device_register(mtd, parsed_parts, nr_parts); |
300 | } | 300 | } |
301 | 301 | ||
302 | /* Always succeeds. */ | 302 | /* Always succeeds. */ |
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c index f71343cd77cc..d16fc9d3b8cd 100644 --- a/drivers/mtd/maps/cfi_flagadm.c +++ b/drivers/mtd/maps/cfi_flagadm.c | |||
@@ -107,7 +107,7 @@ static int __init init_flagadm(void) | |||
107 | mymtd = do_map_probe("cfi_probe", &flagadm_map); | 107 | mymtd = do_map_probe("cfi_probe", &flagadm_map); |
108 | if (mymtd) { | 108 | if (mymtd) { |
109 | mymtd->owner = THIS_MODULE; | 109 | mymtd->owner = THIS_MODULE; |
110 | add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT); | 110 | mtd_device_register(mymtd, flagadm_parts, PARTITION_COUNT); |
111 | printk(KERN_NOTICE "FlagaDM flash device initialized\n"); | 111 | printk(KERN_NOTICE "FlagaDM flash device initialized\n"); |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
@@ -119,7 +119,7 @@ static int __init init_flagadm(void) | |||
119 | static void __exit cleanup_flagadm(void) | 119 | static void __exit cleanup_flagadm(void) |
120 | { | 120 | { |
121 | if (mymtd) { | 121 | if (mymtd) { |
122 | del_mtd_partitions(mymtd); | 122 | mtd_device_unregister(mymtd); |
123 | map_destroy(mymtd); | 123 | map_destroy(mymtd); |
124 | } | 124 | } |
125 | if (flagadm_map.virt) { | 125 | if (flagadm_map.virt) { |
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 5fdb7b26cea3..3d0e762fa5f2 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c | |||
@@ -94,7 +94,7 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window) | |||
94 | if (map->rsrc.parent) | 94 | if (map->rsrc.parent) |
95 | release_resource(&map->rsrc); | 95 | release_resource(&map->rsrc); |
96 | 96 | ||
97 | del_mtd_device(map->mtd); | 97 | mtd_device_unregister(map->mtd); |
98 | map_destroy(map->mtd); | 98 | map_destroy(map->mtd); |
99 | list_del(&map->list); | 99 | list_del(&map->list); |
100 | kfree(map); | 100 | kfree(map); |
@@ -291,7 +291,7 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev, | |||
291 | 291 | ||
292 | /* Now that the mtd devices is complete claim and export it */ | 292 | /* Now that the mtd devices is complete claim and export it */ |
293 | map->mtd->owner = THIS_MODULE; | 293 | map->mtd->owner = THIS_MODULE; |
294 | if (add_mtd_device(map->mtd)) { | 294 | if (mtd_device_register(map->mtd, NULL, 0)) { |
295 | map_destroy(map->mtd); | 295 | map_destroy(map->mtd); |
296 | map->mtd = NULL; | 296 | map->mtd = NULL; |
297 | goto out; | 297 | goto out; |
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c index cfacfa6f45dd..85bdece6ab3f 100644 --- a/drivers/mtd/maps/dbox2-flash.c +++ b/drivers/mtd/maps/dbox2-flash.c | |||
@@ -93,7 +93,7 @@ static int __init init_dbox2_flash(void) | |||
93 | mymtd->owner = THIS_MODULE; | 93 | mymtd->owner = THIS_MODULE; |
94 | 94 | ||
95 | /* Create MTD devices for each partition. */ | 95 | /* Create MTD devices for each partition. */ |
96 | add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); | 96 | mtd_device_register(mymtd, partition_info, NUM_PARTITIONS); |
97 | 97 | ||
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
@@ -105,7 +105,7 @@ static int __init init_dbox2_flash(void) | |||
105 | static void __exit cleanup_dbox2_flash(void) | 105 | static void __exit cleanup_dbox2_flash(void) |
106 | { | 106 | { |
107 | if (mymtd) { | 107 | if (mymtd) { |
108 | del_mtd_partitions(mymtd); | 108 | mtd_device_unregister(mymtd); |
109 | map_destroy(mymtd); | 109 | map_destroy(mymtd); |
110 | } | 110 | } |
111 | if (dbox2_flash_map.virt) { | 111 | if (dbox2_flash_map.virt) { |
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c index b3cb3a183809..7a9e1989c977 100644 --- a/drivers/mtd/maps/dc21285.c +++ b/drivers/mtd/maps/dc21285.c | |||
@@ -145,17 +145,13 @@ static struct map_info dc21285_map = { | |||
145 | 145 | ||
146 | 146 | ||
147 | /* Partition stuff */ | 147 | /* Partition stuff */ |
148 | #ifdef CONFIG_MTD_PARTITIONS | ||
149 | static struct mtd_partition *dc21285_parts; | 148 | static struct mtd_partition *dc21285_parts; |
150 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 149 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
151 | #endif | ||
152 | 150 | ||
153 | static int __init init_dc21285(void) | 151 | static int __init init_dc21285(void) |
154 | { | 152 | { |
155 | 153 | ||
156 | #ifdef CONFIG_MTD_PARTITIONS | ||
157 | int nrparts; | 154 | int nrparts; |
158 | #endif | ||
159 | 155 | ||
160 | /* Determine bankwidth */ | 156 | /* Determine bankwidth */ |
161 | switch (*CSR_SA110_CNTL & (3<<14)) { | 157 | switch (*CSR_SA110_CNTL & (3<<14)) { |
@@ -204,13 +200,8 @@ static int __init init_dc21285(void) | |||
204 | 200 | ||
205 | dc21285_mtd->owner = THIS_MODULE; | 201 | dc21285_mtd->owner = THIS_MODULE; |
206 | 202 | ||
207 | #ifdef CONFIG_MTD_PARTITIONS | ||
208 | nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); | 203 | nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); |
209 | if (nrparts > 0) | 204 | mtd_device_register(dc21285_mtd, dc21285_parts, nrparts); |
210 | add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); | ||
211 | else | ||
212 | #endif | ||
213 | add_mtd_device(dc21285_mtd); | ||
214 | 205 | ||
215 | if(machine_is_ebsa285()) { | 206 | if(machine_is_ebsa285()) { |
216 | /* | 207 | /* |
@@ -232,14 +223,9 @@ static int __init init_dc21285(void) | |||
232 | 223 | ||
233 | static void __exit cleanup_dc21285(void) | 224 | static void __exit cleanup_dc21285(void) |
234 | { | 225 | { |
235 | #ifdef CONFIG_MTD_PARTITIONS | 226 | mtd_device_unregister(dc21285_mtd); |
236 | if (dc21285_parts) { | 227 | if (dc21285_parts) |
237 | del_mtd_partitions(dc21285_mtd); | ||
238 | kfree(dc21285_parts); | 228 | kfree(dc21285_parts); |
239 | } else | ||
240 | #endif | ||
241 | del_mtd_device(dc21285_mtd); | ||
242 | |||
243 | map_destroy(dc21285_mtd); | 229 | map_destroy(dc21285_mtd); |
244 | iounmap(dc21285_map.virt); | 230 | iounmap(dc21285_map.virt); |
245 | } | 231 | } |
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c index 0713e3a5a22c..3e393f0da823 100644 --- a/drivers/mtd/maps/dilnetpc.c +++ b/drivers/mtd/maps/dilnetpc.c | |||
@@ -450,7 +450,7 @@ static int __init init_dnpc(void) | |||
450 | partition_info[2].mtdp = &lowlvl_parts[1]; | 450 | partition_info[2].mtdp = &lowlvl_parts[1]; |
451 | partition_info[3].mtdp = &lowlvl_parts[3]; | 451 | partition_info[3].mtdp = &lowlvl_parts[3]; |
452 | 452 | ||
453 | add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); | 453 | mtd_device_register(mymtd, partition_info, NUM_PARTITIONS); |
454 | 454 | ||
455 | /* | 455 | /* |
456 | ** now create a virtual MTD device by concatenating the for partitions | 456 | ** now create a virtual MTD device by concatenating the for partitions |
@@ -463,7 +463,8 @@ static int __init init_dnpc(void) | |||
463 | ** we do not supply mtd pointers in higlvl_partition_info, so | 463 | ** we do not supply mtd pointers in higlvl_partition_info, so |
464 | ** add_mtd_partitions() will register the devices. | 464 | ** add_mtd_partitions() will register the devices. |
465 | */ | 465 | */ |
466 | add_mtd_partitions(merged_mtd, higlvl_partition_info, NUM_HIGHLVL_PARTITIONS); | 466 | mtd_device_register(merged_mtd, higlvl_partition_info, |
467 | NUM_HIGHLVL_PARTITIONS); | ||
467 | } | 468 | } |
468 | 469 | ||
469 | return 0; | 470 | return 0; |
@@ -472,12 +473,12 @@ static int __init init_dnpc(void) | |||
472 | static void __exit cleanup_dnpc(void) | 473 | static void __exit cleanup_dnpc(void) |
473 | { | 474 | { |
474 | if(merged_mtd) { | 475 | if(merged_mtd) { |
475 | del_mtd_partitions(merged_mtd); | 476 | mtd_device_unregister(merged_mtd); |
476 | mtd_concat_destroy(merged_mtd); | 477 | mtd_concat_destroy(merged_mtd); |
477 | } | 478 | } |
478 | 479 | ||
479 | if (mymtd) { | 480 | if (mymtd) { |
480 | del_mtd_partitions(mymtd); | 481 | mtd_device_unregister(mymtd); |
481 | map_destroy(mymtd); | 482 | map_destroy(mymtd); |
482 | } | 483 | } |
483 | if (dnpc_map.virt) { | 484 | if (dnpc_map.virt) { |
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c index d171674eb2ed..6538ac675e00 100644 --- a/drivers/mtd/maps/dmv182.c +++ b/drivers/mtd/maps/dmv182.c | |||
@@ -120,7 +120,7 @@ static int __init init_svme182(void) | |||
120 | this_mtd->size >> 20, FLASH_BASE_ADDR); | 120 | this_mtd->size >> 20, FLASH_BASE_ADDR); |
121 | 121 | ||
122 | this_mtd->owner = THIS_MODULE; | 122 | this_mtd->owner = THIS_MODULE; |
123 | add_mtd_partitions(this_mtd, partitions, num_parts); | 123 | mtd_device_register(this_mtd, partitions, num_parts); |
124 | 124 | ||
125 | return 0; | 125 | return 0; |
126 | } | 126 | } |
@@ -129,7 +129,7 @@ static void __exit cleanup_svme182(void) | |||
129 | { | 129 | { |
130 | if (this_mtd) | 130 | if (this_mtd) |
131 | { | 131 | { |
132 | del_mtd_partitions(this_mtd); | 132 | mtd_device_unregister(this_mtd); |
133 | map_destroy(this_mtd); | 133 | map_destroy(this_mtd); |
134 | } | 134 | } |
135 | 135 | ||
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c index be9e90b44587..fe42a212bb3e 100644 --- a/drivers/mtd/maps/edb7312.c +++ b/drivers/mtd/maps/edb7312.c | |||
@@ -15,10 +15,7 @@ | |||
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
17 | #include <linux/mtd/map.h> | 17 | #include <linux/mtd/map.h> |
18 | |||
19 | #ifdef CONFIG_MTD_PARTITIONS | ||
20 | #include <linux/mtd/partitions.h> | 18 | #include <linux/mtd/partitions.h> |
21 | #endif | ||
22 | 19 | ||
23 | #define WINDOW_ADDR 0x00000000 /* physical properties of flash */ | 20 | #define WINDOW_ADDR 0x00000000 /* physical properties of flash */ |
24 | #define WINDOW_SIZE 0x01000000 | 21 | #define WINDOW_SIZE 0x01000000 |
@@ -40,8 +37,6 @@ struct map_info edb7312nor_map = { | |||
40 | .phys = WINDOW_ADDR, | 37 | .phys = WINDOW_ADDR, |
41 | }; | 38 | }; |
42 | 39 | ||
43 | #ifdef CONFIG_MTD_PARTITIONS | ||
44 | |||
45 | /* | 40 | /* |
46 | * MTD partitioning stuff | 41 | * MTD partitioning stuff |
47 | */ | 42 | */ |
@@ -66,8 +61,6 @@ static struct mtd_partition static_partitions[3] = | |||
66 | 61 | ||
67 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 62 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
68 | 63 | ||
69 | #endif | ||
70 | |||
71 | static int mtd_parts_nb = 0; | 64 | static int mtd_parts_nb = 0; |
72 | static struct mtd_partition *mtd_parts = 0; | 65 | static struct mtd_partition *mtd_parts = 0; |
73 | 66 | ||
@@ -96,27 +89,24 @@ static int __init init_edb7312nor(void) | |||
96 | if (mymtd) { | 89 | if (mymtd) { |
97 | mymtd->owner = THIS_MODULE; | 90 | mymtd->owner = THIS_MODULE; |
98 | 91 | ||
99 | #ifdef CONFIG_MTD_PARTITIONS | ||
100 | mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID); | 92 | mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID); |
101 | if (mtd_parts_nb > 0) | 93 | if (mtd_parts_nb > 0) |
102 | part_type = "detected"; | 94 | part_type = "detected"; |
103 | 95 | ||
104 | if (mtd_parts_nb == 0) | 96 | if (mtd_parts_nb == 0) { |
105 | { | ||
106 | mtd_parts = static_partitions; | 97 | mtd_parts = static_partitions; |
107 | mtd_parts_nb = ARRAY_SIZE(static_partitions); | 98 | mtd_parts_nb = ARRAY_SIZE(static_partitions); |
108 | part_type = "static"; | 99 | part_type = "static"; |
109 | } | 100 | } |
110 | #endif | 101 | |
111 | add_mtd_device(mymtd); | ||
112 | if (mtd_parts_nb == 0) | 102 | if (mtd_parts_nb == 0) |
113 | printk(KERN_NOTICE MSG_PREFIX "no partition info available\n"); | 103 | printk(KERN_NOTICE MSG_PREFIX "no partition info available\n"); |
114 | else | 104 | else |
115 | { | ||
116 | printk(KERN_NOTICE MSG_PREFIX | 105 | printk(KERN_NOTICE MSG_PREFIX |
117 | "using %s partition definition\n", part_type); | 106 | "using %s partition definition\n", part_type); |
118 | add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb); | 107 | /* Register the whole device first. */ |
119 | } | 108 | mtd_device_register(mymtd, NULL, 0); |
109 | mtd_device_register(mymtd, mtd_parts, mtd_parts_nb); | ||
120 | return 0; | 110 | return 0; |
121 | } | 111 | } |
122 | 112 | ||
@@ -127,7 +117,7 @@ static int __init init_edb7312nor(void) | |||
127 | static void __exit cleanup_edb7312nor(void) | 117 | static void __exit cleanup_edb7312nor(void) |
128 | { | 118 | { |
129 | if (mymtd) { | 119 | if (mymtd) { |
130 | del_mtd_device(mymtd); | 120 | mtd_device_unregister(mymtd); |
131 | map_destroy(mymtd); | 121 | map_destroy(mymtd); |
132 | } | 122 | } |
133 | if (edb7312nor_map.virt) { | 123 | if (edb7312nor_map.virt) { |
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index 4feb7507ab7c..08322b1c3e81 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c | |||
@@ -128,7 +128,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window) | |||
128 | list_for_each_entry_safe(map, scratch, &window->maps, list) { | 128 | list_for_each_entry_safe(map, scratch, &window->maps, list) { |
129 | if (map->rsrc.parent) | 129 | if (map->rsrc.parent) |
130 | release_resource(&map->rsrc); | 130 | release_resource(&map->rsrc); |
131 | del_mtd_device(map->mtd); | 131 | mtd_device_unregister(map->mtd); |
132 | map_destroy(map->mtd); | 132 | map_destroy(map->mtd); |
133 | list_del(&map->list); | 133 | list_del(&map->list); |
134 | kfree(map); | 134 | kfree(map); |
@@ -352,7 +352,7 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev, | |||
352 | 352 | ||
353 | /* Now that the mtd devices is complete claim and export it */ | 353 | /* Now that the mtd devices is complete claim and export it */ |
354 | map->mtd->owner = THIS_MODULE; | 354 | map->mtd->owner = THIS_MODULE; |
355 | if (add_mtd_device(map->mtd)) { | 355 | if (mtd_device_register(map->mtd, NULL, 0)) { |
356 | map_destroy(map->mtd); | 356 | map_destroy(map->mtd); |
357 | map->mtd = NULL; | 357 | map->mtd = NULL; |
358 | goto out; | 358 | goto out; |
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c index 1e43124d498b..956e2e4f30ea 100644 --- a/drivers/mtd/maps/fortunet.c +++ b/drivers/mtd/maps/fortunet.c | |||
@@ -243,8 +243,9 @@ static int __init init_fortunet(void) | |||
243 | &map_regions[ix].map_info); | 243 | &map_regions[ix].map_info); |
244 | } | 244 | } |
245 | map_regions[ix].mymtd->owner = THIS_MODULE; | 245 | map_regions[ix].mymtd->owner = THIS_MODULE; |
246 | add_mtd_partitions(map_regions[ix].mymtd, | 246 | mtd_device_register(map_regions[ix].mymtd, |
247 | map_regions[ix].parts,map_regions_parts[ix]); | 247 | map_regions[ix].parts, |
248 | map_regions_parts[ix]); | ||
248 | } | 249 | } |
249 | } | 250 | } |
250 | if(iy) | 251 | if(iy) |
@@ -261,7 +262,7 @@ static void __exit cleanup_fortunet(void) | |||
261 | { | 262 | { |
262 | if( map_regions[ix].mymtd ) | 263 | if( map_regions[ix].mymtd ) |
263 | { | 264 | { |
264 | del_mtd_partitions( map_regions[ix].mymtd ); | 265 | mtd_device_unregister(map_regions[ix].mymtd); |
265 | map_destroy( map_regions[ix].mymtd ); | 266 | map_destroy( map_regions[ix].mymtd ); |
266 | } | 267 | } |
267 | iounmap((void *)map_regions[ix].map_info.virt); | 268 | iounmap((void *)map_regions[ix].map_info.virt); |
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index af5707a80205..7568c5f8b8ae 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c | |||
@@ -155,9 +155,7 @@ static void gf_copy_to(struct map_info *map, unsigned long to, const void *from, | |||
155 | memcpy_toio(map->virt + (to % state->win_size), from, len); | 155 | memcpy_toio(map->virt + (to % state->win_size), from, len); |
156 | } | 156 | } |
157 | 157 | ||
158 | #ifdef CONFIG_MTD_PARTITIONS | ||
159 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | 158 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; |
160 | #endif | ||
161 | 159 | ||
162 | /** | 160 | /** |
163 | * gpio_flash_probe() - setup a mapping for a GPIO assisted flash | 161 | * gpio_flash_probe() - setup a mapping for a GPIO assisted flash |
@@ -189,7 +187,7 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | |||
189 | */ | 187 | */ |
190 | static int __devinit gpio_flash_probe(struct platform_device *pdev) | 188 | static int __devinit gpio_flash_probe(struct platform_device *pdev) |
191 | { | 189 | { |
192 | int ret; | 190 | int nr_parts; |
193 | size_t i, arr_size; | 191 | size_t i, arr_size; |
194 | struct physmap_flash_data *pdata; | 192 | struct physmap_flash_data *pdata; |
195 | struct resource *memory; | 193 | struct resource *memory; |
@@ -254,24 +252,21 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev) | |||
254 | return -ENXIO; | 252 | return -ENXIO; |
255 | } | 253 | } |
256 | 254 | ||
257 | #ifdef CONFIG_MTD_PARTITIONS | 255 | nr_parts = parse_mtd_partitions(state->mtd, part_probe_types, |
258 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); | 256 | &pdata->parts, 0); |
259 | if (ret > 0) { | 257 | if (nr_parts > 0) { |
260 | pr_devinit(KERN_NOTICE PFX "Using commandline partition definition\n"); | 258 | pr_devinit(KERN_NOTICE PFX "Using commandline partition definition\n"); |
261 | add_mtd_partitions(state->mtd, pdata->parts, ret); | ||
262 | kfree(pdata->parts); | 259 | kfree(pdata->parts); |
263 | |||
264 | } else if (pdata->nr_parts) { | 260 | } else if (pdata->nr_parts) { |
265 | pr_devinit(KERN_NOTICE PFX "Using board partition definition\n"); | 261 | pr_devinit(KERN_NOTICE PFX "Using board partition definition\n"); |
266 | add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts); | 262 | nr_parts = pdata->nr_parts; |
267 | 263 | } else { | |
268 | } else | ||
269 | #endif | ||
270 | { | ||
271 | pr_devinit(KERN_NOTICE PFX "no partition info available, registering whole flash at once\n"); | 264 | pr_devinit(KERN_NOTICE PFX "no partition info available, registering whole flash at once\n"); |
272 | add_mtd_device(state->mtd); | 265 | nr_parts = 0; |
273 | } | 266 | } |
274 | 267 | ||
268 | mtd_device_register(state->mtd, pdata->parts, nr_parts); | ||
269 | |||
275 | return 0; | 270 | return 0; |
276 | } | 271 | } |
277 | 272 | ||
@@ -282,9 +277,7 @@ static int __devexit gpio_flash_remove(struct platform_device *pdev) | |||
282 | do { | 277 | do { |
283 | gpio_free(state->gpio_addrs[i]); | 278 | gpio_free(state->gpio_addrs[i]); |
284 | } while (++i < state->gpio_count); | 279 | } while (++i < state->gpio_count); |
285 | #ifdef CONFIG_MTD_PARTITIONS | 280 | mtd_device_unregister(state->mtd); |
286 | del_mtd_partitions(state->mtd); | ||
287 | #endif | ||
288 | map_destroy(state->mtd); | 281 | map_destroy(state->mtd); |
289 | kfree(state); | 282 | kfree(state); |
290 | return 0; | 283 | return 0; |
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 72c724fa8c27..7f035860a36b 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c | |||
@@ -92,18 +92,16 @@ static int __init h720x_mtd_init(void) | |||
92 | if (mymtd) { | 92 | if (mymtd) { |
93 | mymtd->owner = THIS_MODULE; | 93 | mymtd->owner = THIS_MODULE; |
94 | 94 | ||
95 | #ifdef CONFIG_MTD_PARTITIONS | ||
96 | nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0); | 95 | nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0); |
97 | if (nr_mtd_parts > 0) | 96 | if (nr_mtd_parts > 0) |
98 | part_type = "command line"; | 97 | part_type = "command line"; |
99 | #endif | ||
100 | if (nr_mtd_parts <= 0) { | 98 | if (nr_mtd_parts <= 0) { |
101 | mtd_parts = h720x_partitions; | 99 | mtd_parts = h720x_partitions; |
102 | nr_mtd_parts = NUM_PARTITIONS; | 100 | nr_mtd_parts = NUM_PARTITIONS; |
103 | part_type = "builtin"; | 101 | part_type = "builtin"; |
104 | } | 102 | } |
105 | printk(KERN_INFO "Using %s partition table\n", part_type); | 103 | printk(KERN_INFO "Using %s partition table\n", part_type); |
106 | add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts); | 104 | mtd_device_register(mymtd, mtd_parts, nr_mtd_parts); |
107 | return 0; | 105 | return 0; |
108 | } | 106 | } |
109 | 107 | ||
@@ -118,7 +116,7 @@ static void __exit h720x_mtd_cleanup(void) | |||
118 | { | 116 | { |
119 | 117 | ||
120 | if (mymtd) { | 118 | if (mymtd) { |
121 | del_mtd_partitions(mymtd); | 119 | mtd_device_unregister(mymtd); |
122 | map_destroy(mymtd); | 120 | map_destroy(mymtd); |
123 | } | 121 | } |
124 | 122 | ||
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index 1337a4191a0c..6689dcb3124d 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c | |||
@@ -67,7 +67,7 @@ static void ichxrom_cleanup(struct ichxrom_window *window) | |||
67 | list_for_each_entry_safe(map, scratch, &window->maps, list) { | 67 | list_for_each_entry_safe(map, scratch, &window->maps, list) { |
68 | if (map->rsrc.parent) | 68 | if (map->rsrc.parent) |
69 | release_resource(&map->rsrc); | 69 | release_resource(&map->rsrc); |
70 | del_mtd_device(map->mtd); | 70 | mtd_device_unregister(map->mtd); |
71 | map_destroy(map->mtd); | 71 | map_destroy(map->mtd); |
72 | list_del(&map->list); | 72 | list_del(&map->list); |
73 | kfree(map); | 73 | kfree(map); |
@@ -287,7 +287,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, | |||
287 | 287 | ||
288 | /* Now that the mtd devices is complete claim and export it */ | 288 | /* Now that the mtd devices is complete claim and export it */ |
289 | map->mtd->owner = THIS_MODULE; | 289 | map->mtd->owner = THIS_MODULE; |
290 | if (add_mtd_device(map->mtd)) { | 290 | if (mtd_device_register(map->mtd, NULL, 0)) { |
291 | map_destroy(map->mtd); | 291 | map_destroy(map->mtd); |
292 | map->mtd = NULL; | 292 | map->mtd = NULL; |
293 | goto out; | 293 | goto out; |
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c index 998a27da97f3..404a50cbafa0 100644 --- a/drivers/mtd/maps/impa7.c +++ b/drivers/mtd/maps/impa7.c | |||
@@ -15,10 +15,7 @@ | |||
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
17 | #include <linux/mtd/map.h> | 17 | #include <linux/mtd/map.h> |
18 | |||
19 | #ifdef CONFIG_MTD_PARTITIONS | ||
20 | #include <linux/mtd/partitions.h> | 18 | #include <linux/mtd/partitions.h> |
21 | #endif | ||
22 | 19 | ||
23 | #define WINDOW_ADDR0 0x00000000 /* physical properties of flash */ | 20 | #define WINDOW_ADDR0 0x00000000 /* physical properties of flash */ |
24 | #define WINDOW_SIZE0 0x00800000 | 21 | #define WINDOW_SIZE0 0x00800000 |
@@ -49,8 +46,6 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = { | |||
49 | }, | 46 | }, |
50 | }; | 47 | }; |
51 | 48 | ||
52 | #ifdef CONFIG_MTD_PARTITIONS | ||
53 | |||
54 | /* | 49 | /* |
55 | * MTD partitioning stuff | 50 | * MTD partitioning stuff |
56 | */ | 51 | */ |
@@ -66,8 +61,6 @@ static struct mtd_partition static_partitions[] = | |||
66 | static int mtd_parts_nb[NUM_FLASHBANKS]; | 61 | static int mtd_parts_nb[NUM_FLASHBANKS]; |
67 | static struct mtd_partition *mtd_parts[NUM_FLASHBANKS]; | 62 | static struct mtd_partition *mtd_parts[NUM_FLASHBANKS]; |
68 | 63 | ||
69 | #endif | ||
70 | |||
71 | static const char *probes[] = { "cmdlinepart", NULL }; | 64 | static const char *probes[] = { "cmdlinepart", NULL }; |
72 | 65 | ||
73 | static int __init init_impa7(void) | 66 | static int __init init_impa7(void) |
@@ -104,7 +97,6 @@ static int __init init_impa7(void) | |||
104 | if (impa7_mtd[i]) { | 97 | if (impa7_mtd[i]) { |
105 | impa7_mtd[i]->owner = THIS_MODULE; | 98 | impa7_mtd[i]->owner = THIS_MODULE; |
106 | devicesfound++; | 99 | devicesfound++; |
107 | #ifdef CONFIG_MTD_PARTITIONS | ||
108 | mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], | 100 | mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], |
109 | probes, | 101 | probes, |
110 | &mtd_parts[i], | 102 | &mtd_parts[i], |
@@ -120,12 +112,8 @@ static int __init init_impa7(void) | |||
120 | printk(KERN_NOTICE MSG_PREFIX | 112 | printk(KERN_NOTICE MSG_PREFIX |
121 | "using %s partition definition\n", | 113 | "using %s partition definition\n", |
122 | part_type); | 114 | part_type); |
123 | add_mtd_partitions(impa7_mtd[i], | 115 | mtd_device_register(impa7_mtd[i], |
124 | mtd_parts[i], mtd_parts_nb[i]); | 116 | mtd_parts[i], mtd_parts_nb[i]); |
125 | #else | ||
126 | add_mtd_device(impa7_mtd[i]); | ||
127 | |||
128 | #endif | ||
129 | } | 117 | } |
130 | else | 118 | else |
131 | iounmap((void *)impa7_map[i].virt); | 119 | iounmap((void *)impa7_map[i].virt); |
@@ -138,11 +126,7 @@ static void __exit cleanup_impa7(void) | |||
138 | int i; | 126 | int i; |
139 | for (i=0; i<NUM_FLASHBANKS; i++) { | 127 | for (i=0; i<NUM_FLASHBANKS; i++) { |
140 | if (impa7_mtd[i]) { | 128 | if (impa7_mtd[i]) { |
141 | #ifdef CONFIG_MTD_PARTITIONS | 129 | mtd_device_unregister(impa7_mtd[i]); |
142 | del_mtd_partitions(impa7_mtd[i]); | ||
143 | #else | ||
144 | del_mtd_device(impa7_mtd[i]); | ||
145 | #endif | ||
146 | map_destroy(impa7_mtd[i]); | 130 | map_destroy(impa7_mtd[i]); |
147 | iounmap((void *)impa7_map[i].virt); | 131 | iounmap((void *)impa7_map[i].virt); |
148 | impa7_map[i].virt = 0; | 132 | impa7_map[i].virt = 0; |
diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c index fc1998512eb4..d2f47be8754b 100644 --- a/drivers/mtd/maps/intel_vr_nor.c +++ b/drivers/mtd/maps/intel_vr_nor.c | |||
@@ -66,33 +66,18 @@ struct vr_nor_mtd { | |||
66 | 66 | ||
67 | static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p) | 67 | static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p) |
68 | { | 68 | { |
69 | if (p->nr_parts > 0) { | 69 | mtd_device_unregister(p->info); |
70 | #if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE) | ||
71 | del_mtd_partitions(p->info); | ||
72 | #endif | ||
73 | } else | ||
74 | del_mtd_device(p->info); | ||
75 | } | 70 | } |
76 | 71 | ||
77 | static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) | 72 | static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) |
78 | { | 73 | { |
79 | int err = 0; | ||
80 | #if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE) | ||
81 | struct mtd_partition *parts; | 74 | struct mtd_partition *parts; |
82 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 75 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
83 | #endif | ||
84 | 76 | ||
85 | /* register the flash bank */ | 77 | /* register the flash bank */ |
86 | #if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE) | ||
87 | /* partition the flash bank */ | 78 | /* partition the flash bank */ |
88 | p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0); | 79 | p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0); |
89 | if (p->nr_parts > 0) | 80 | return mtd_device_register(p->info, parts, p->nr_parts); |
90 | err = add_mtd_partitions(p->info, parts, p->nr_parts); | ||
91 | #endif | ||
92 | if (p->nr_parts <= 0) | ||
93 | err = add_mtd_device(p->info); | ||
94 | |||
95 | return err; | ||
96 | } | 81 | } |
97 | 82 | ||
98 | static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) | 83 | static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) |
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c index 9639d83a9d6c..c00b9175ba9e 100644 --- a/drivers/mtd/maps/ixp2000.c +++ b/drivers/mtd/maps/ixp2000.c | |||
@@ -119,7 +119,7 @@ static int ixp2000_flash_remove(struct platform_device *dev) | |||
119 | return 0; | 119 | return 0; |
120 | 120 | ||
121 | if (info->mtd) { | 121 | if (info->mtd) { |
122 | del_mtd_partitions(info->mtd); | 122 | mtd_device_unregister(info->mtd); |
123 | map_destroy(info->mtd); | 123 | map_destroy(info->mtd); |
124 | } | 124 | } |
125 | if (info->map.map_priv_1) | 125 | if (info->map.map_priv_1) |
@@ -230,7 +230,7 @@ static int ixp2000_flash_probe(struct platform_device *dev) | |||
230 | 230 | ||
231 | err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); | 231 | err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); |
232 | if (err > 0) { | 232 | if (err > 0) { |
233 | err = add_mtd_partitions(info->mtd, info->partitions, err); | 233 | err = mtd_device_register(info->mtd, info->partitions, err); |
234 | if(err) | 234 | if(err) |
235 | dev_err(&dev->dev, "Could not parse partitions\n"); | 235 | dev_err(&dev->dev, "Could not parse partitions\n"); |
236 | } | 236 | } |
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 1f9fde0dad35..155b21942f47 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c | |||
@@ -162,7 +162,7 @@ static int ixp4xx_flash_remove(struct platform_device *dev) | |||
162 | return 0; | 162 | return 0; |
163 | 163 | ||
164 | if (info->mtd) { | 164 | if (info->mtd) { |
165 | del_mtd_partitions(info->mtd); | 165 | mtd_device_unregister(info->mtd); |
166 | map_destroy(info->mtd); | 166 | map_destroy(info->mtd); |
167 | } | 167 | } |
168 | if (info->map.virt) | 168 | if (info->map.virt) |
@@ -252,10 +252,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev) | |||
252 | /* Use the fast version */ | 252 | /* Use the fast version */ |
253 | info->map.write = ixp4xx_write16; | 253 | info->map.write = ixp4xx_write16; |
254 | 254 | ||
255 | #ifdef CONFIG_MTD_PARTITIONS | ||
256 | nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions, | 255 | nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions, |
257 | dev->resource->start); | 256 | dev->resource->start); |
258 | #endif | ||
259 | if (nr_parts > 0) { | 257 | if (nr_parts > 0) { |
260 | part_type = "dynamic"; | 258 | part_type = "dynamic"; |
261 | } else { | 259 | } else { |
@@ -263,18 +261,16 @@ static int ixp4xx_flash_probe(struct platform_device *dev) | |||
263 | nr_parts = plat->nr_parts; | 261 | nr_parts = plat->nr_parts; |
264 | part_type = "static"; | 262 | part_type = "static"; |
265 | } | 263 | } |
266 | if (nr_parts == 0) { | 264 | if (nr_parts == 0) |
267 | printk(KERN_NOTICE "IXP4xx flash: no partition info " | 265 | printk(KERN_NOTICE "IXP4xx flash: no partition info " |
268 | "available, registering whole flash\n"); | 266 | "available, registering whole flash\n"); |
269 | err = add_mtd_device(info->mtd); | 267 | else |
270 | } else { | ||
271 | printk(KERN_NOTICE "IXP4xx flash: using %s partition " | 268 | printk(KERN_NOTICE "IXP4xx flash: using %s partition " |
272 | "definition\n", part_type); | 269 | "definition\n", part_type); |
273 | err = add_mtd_partitions(info->mtd, info->partitions, nr_parts); | ||
274 | 270 | ||
275 | if(err) | 271 | err = mtd_device_register(info->mtd, info->partitions, nr_parts); |
276 | printk(KERN_ERR "Could not parse partitions\n"); | 272 | if (err) |
277 | } | 273 | printk(KERN_ERR "Could not parse partitions\n"); |
278 | 274 | ||
279 | if (err) | 275 | if (err) |
280 | goto Error; | 276 | goto Error; |
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c index 9e054503c4cf..dd0360ba2412 100644 --- a/drivers/mtd/maps/l440gx.c +++ b/drivers/mtd/maps/l440gx.c | |||
@@ -138,7 +138,7 @@ static int __init init_l440gx(void) | |||
138 | if (mymtd) { | 138 | if (mymtd) { |
139 | mymtd->owner = THIS_MODULE; | 139 | mymtd->owner = THIS_MODULE; |
140 | 140 | ||
141 | add_mtd_device(mymtd); | 141 | mtd_device_register(mymtd, NULL, 0); |
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
@@ -148,7 +148,7 @@ static int __init init_l440gx(void) | |||
148 | 148 | ||
149 | static void __exit cleanup_l440gx(void) | 149 | static void __exit cleanup_l440gx(void) |
150 | { | 150 | { |
151 | del_mtd_device(mymtd); | 151 | mtd_device_unregister(mymtd); |
152 | map_destroy(mymtd); | 152 | map_destroy(mymtd); |
153 | 153 | ||
154 | iounmap(l440gx_map.virt); | 154 | iounmap(l440gx_map.virt); |
diff --git a/drivers/mtd/maps/latch-addr-flash.c b/drivers/mtd/maps/latch-addr-flash.c index ee2548085334..5936c466e901 100644 --- a/drivers/mtd/maps/latch-addr-flash.c +++ b/drivers/mtd/maps/latch-addr-flash.c | |||
@@ -112,18 +112,9 @@ static int latch_addr_flash_remove(struct platform_device *dev) | |||
112 | latch_addr_data = dev->dev.platform_data; | 112 | latch_addr_data = dev->dev.platform_data; |
113 | 113 | ||
114 | if (info->mtd != NULL) { | 114 | if (info->mtd != NULL) { |
115 | if (mtd_has_partitions()) { | 115 | if (info->nr_parts) |
116 | if (info->nr_parts) { | 116 | kfree(info->parts); |
117 | del_mtd_partitions(info->mtd); | 117 | mtd_device_unregister(info->mtd); |
118 | kfree(info->parts); | ||
119 | } else if (latch_addr_data->nr_parts) { | ||
120 | del_mtd_partitions(info->mtd); | ||
121 | } else { | ||
122 | del_mtd_device(info->mtd); | ||
123 | } | ||
124 | } else { | ||
125 | del_mtd_device(info->mtd); | ||
126 | } | ||
127 | map_destroy(info->mtd); | 118 | map_destroy(info->mtd); |
128 | } | 119 | } |
129 | 120 | ||
@@ -215,23 +206,21 @@ static int __devinit latch_addr_flash_probe(struct platform_device *dev) | |||
215 | } | 206 | } |
216 | info->mtd->owner = THIS_MODULE; | 207 | info->mtd->owner = THIS_MODULE; |
217 | 208 | ||
218 | if (mtd_has_partitions()) { | 209 | err = parse_mtd_partitions(info->mtd, (const char **)part_probe_types, |
219 | 210 | &info->parts, 0); | |
220 | err = parse_mtd_partitions(info->mtd, | 211 | if (err > 0) { |
221 | (const char **)part_probe_types, | 212 | mtd_device_register(info->mtd, info->parts, err); |
222 | &info->parts, 0); | 213 | return 0; |
223 | if (err > 0) { | 214 | } |
224 | add_mtd_partitions(info->mtd, info->parts, err); | 215 | if (latch_addr_data->nr_parts) { |
225 | return 0; | 216 | pr_notice("Using latch-addr-flash partition information\n"); |
226 | } | 217 | mtd_device_register(info->mtd, |
227 | if (latch_addr_data->nr_parts) { | 218 | latch_addr_data->parts, |
228 | pr_notice("Using latch-addr-flash partition information\n"); | 219 | latch_addr_data->nr_parts); |
229 | add_mtd_partitions(info->mtd, latch_addr_data->parts, | 220 | return 0; |
230 | latch_addr_data->nr_parts); | ||
231 | return 0; | ||
232 | } | ||
233 | } | 221 | } |
234 | add_mtd_device(info->mtd); | 222 | |
223 | mtd_device_register(info->mtd, NULL, 0); | ||
235 | return 0; | 224 | return 0; |
236 | 225 | ||
237 | iounmap: | 226 | iounmap: |
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c index 0eb5a7c85380..93fa56c33003 100644 --- a/drivers/mtd/maps/mbx860.c +++ b/drivers/mtd/maps/mbx860.c | |||
@@ -69,8 +69,8 @@ static int __init init_mbx(void) | |||
69 | mymtd = do_map_probe("jedec_probe", &mbx_map); | 69 | mymtd = do_map_probe("jedec_probe", &mbx_map); |
70 | if (mymtd) { | 70 | if (mymtd) { |
71 | mymtd->owner = THIS_MODULE; | 71 | mymtd->owner = THIS_MODULE; |
72 | add_mtd_device(mymtd); | 72 | mtd_device_register(mymtd, NULL, 0); |
73 | add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); | 73 | mtd_device_register(mymtd, partition_info, NUM_PARTITIONS); |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
@@ -81,7 +81,7 @@ static int __init init_mbx(void) | |||
81 | static void __exit cleanup_mbx(void) | 81 | static void __exit cleanup_mbx(void) |
82 | { | 82 | { |
83 | if (mymtd) { | 83 | if (mymtd) { |
84 | del_mtd_device(mymtd); | 84 | mtd_device_unregister(mymtd); |
85 | map_destroy(mymtd); | 85 | map_destroy(mymtd); |
86 | } | 86 | } |
87 | if (mbx_map.virt) { | 87 | if (mbx_map.virt) { |
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c index c0cb319b2b70..81dc2598bc0a 100644 --- a/drivers/mtd/maps/netsc520.c +++ b/drivers/mtd/maps/netsc520.c | |||
@@ -116,14 +116,14 @@ static int __init init_netsc520(void) | |||
116 | } | 116 | } |
117 | 117 | ||
118 | mymtd->owner = THIS_MODULE; | 118 | mymtd->owner = THIS_MODULE; |
119 | add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS ); | 119 | mtd_device_register(mymtd, partition_info, NUM_PARTITIONS); |
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static void __exit cleanup_netsc520(void) | 123 | static void __exit cleanup_netsc520(void) |
124 | { | 124 | { |
125 | if (mymtd) { | 125 | if (mymtd) { |
126 | del_mtd_partitions(mymtd); | 126 | mtd_device_unregister(mymtd); |
127 | map_destroy(mymtd); | 127 | map_destroy(mymtd); |
128 | } | 128 | } |
129 | if (netsc520_map.virt) { | 129 | if (netsc520_map.virt) { |
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index a97133eb9d70..eadcfffc4f9c 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c | |||
@@ -383,13 +383,13 @@ static int __init nettel_init(void) | |||
383 | /* No BIOS regions when AMD boot */ | 383 | /* No BIOS regions when AMD boot */ |
384 | num_intel_partitions -= 2; | 384 | num_intel_partitions -= 2; |
385 | } | 385 | } |
386 | rc = add_mtd_partitions(intel_mtd, nettel_intel_partitions, | 386 | rc = mtd_device_register(intel_mtd, nettel_intel_partitions, |
387 | num_intel_partitions); | 387 | num_intel_partitions); |
388 | #endif | 388 | #endif |
389 | 389 | ||
390 | if (amd_mtd) { | 390 | if (amd_mtd) { |
391 | rc = add_mtd_partitions(amd_mtd, nettel_amd_partitions, | 391 | rc = mtd_device_register(amd_mtd, nettel_amd_partitions, |
392 | num_amd_partitions); | 392 | num_amd_partitions); |
393 | } | 393 | } |
394 | 394 | ||
395 | #ifdef CONFIG_MTD_CFI_INTELEXT | 395 | #ifdef CONFIG_MTD_CFI_INTELEXT |
@@ -419,7 +419,7 @@ static void __exit nettel_cleanup(void) | |||
419 | unregister_reboot_notifier(&nettel_notifier_block); | 419 | unregister_reboot_notifier(&nettel_notifier_block); |
420 | #endif | 420 | #endif |
421 | if (amd_mtd) { | 421 | if (amd_mtd) { |
422 | del_mtd_partitions(amd_mtd); | 422 | mtd_device_unregister(amd_mtd); |
423 | map_destroy(amd_mtd); | 423 | map_destroy(amd_mtd); |
424 | } | 424 | } |
425 | if (nettel_mmcrp) { | 425 | if (nettel_mmcrp) { |
@@ -432,7 +432,7 @@ static void __exit nettel_cleanup(void) | |||
432 | } | 432 | } |
433 | #ifdef CONFIG_MTD_CFI_INTELEXT | 433 | #ifdef CONFIG_MTD_CFI_INTELEXT |
434 | if (intel_mtd) { | 434 | if (intel_mtd) { |
435 | del_mtd_partitions(intel_mtd); | 435 | mtd_device_unregister(intel_mtd); |
436 | map_destroy(intel_mtd); | 436 | map_destroy(intel_mtd); |
437 | } | 437 | } |
438 | if (nettel_intel_map.virt) { | 438 | if (nettel_intel_map.virt) { |
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c index 23fe1786770f..807ac2a2e686 100644 --- a/drivers/mtd/maps/octagon-5066.c +++ b/drivers/mtd/maps/octagon-5066.c | |||
@@ -175,7 +175,7 @@ void cleanup_oct5066(void) | |||
175 | int i; | 175 | int i; |
176 | for (i=0; i<2; i++) { | 176 | for (i=0; i<2; i++) { |
177 | if (oct5066_mtd[i]) { | 177 | if (oct5066_mtd[i]) { |
178 | del_mtd_device(oct5066_mtd[i]); | 178 | mtd_device_unregister(oct5066_mtd[i]); |
179 | map_destroy(oct5066_mtd[i]); | 179 | map_destroy(oct5066_mtd[i]); |
180 | } | 180 | } |
181 | } | 181 | } |
@@ -220,7 +220,7 @@ static int __init init_oct5066(void) | |||
220 | oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]); | 220 | oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]); |
221 | if (oct5066_mtd[i]) { | 221 | if (oct5066_mtd[i]) { |
222 | oct5066_mtd[i]->owner = THIS_MODULE; | 222 | oct5066_mtd[i]->owner = THIS_MODULE; |
223 | add_mtd_device(oct5066_mtd[i]); | 223 | mtd_device_register(oct5066_mtd[i], NULL, 0); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 48f4cf5cb9d1..1d005a3e9b41 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c | |||
@@ -313,7 +313,7 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
313 | goto release; | 313 | goto release; |
314 | 314 | ||
315 | mtd->owner = THIS_MODULE; | 315 | mtd->owner = THIS_MODULE; |
316 | add_mtd_device(mtd); | 316 | mtd_device_register(mtd, NULL, 0); |
317 | 317 | ||
318 | pci_set_drvdata(dev, mtd); | 318 | pci_set_drvdata(dev, mtd); |
319 | 319 | ||
@@ -336,7 +336,7 @@ mtd_pci_remove(struct pci_dev *dev) | |||
336 | struct mtd_info *mtd = pci_get_drvdata(dev); | 336 | struct mtd_info *mtd = pci_get_drvdata(dev); |
337 | struct map_pci_info *map = mtd->priv; | 337 | struct map_pci_info *map = mtd->priv; |
338 | 338 | ||
339 | del_mtd_device(mtd); | 339 | mtd_device_unregister(mtd); |
340 | map_destroy(mtd); | 340 | map_destroy(mtd); |
341 | map->exit(dev, map); | 341 | map->exit(dev, map); |
342 | kfree(map); | 342 | kfree(map); |
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 33dc2829b01b..bbe168b65c26 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c | |||
@@ -630,7 +630,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) | |||
630 | dev->pcmcia_map.copy_to = pcmcia_copy_to; | 630 | dev->pcmcia_map.copy_to = pcmcia_copy_to; |
631 | } | 631 | } |
632 | 632 | ||
633 | if(add_mtd_device(mtd)) { | 633 | if (mtd_device_register(mtd, NULL, 0)) { |
634 | map_destroy(mtd); | 634 | map_destroy(mtd); |
635 | dev->mtd_info = NULL; | 635 | dev->mtd_info = NULL; |
636 | dev_err(&dev->p_dev->dev, | 636 | dev_err(&dev->p_dev->dev, |
@@ -669,7 +669,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link) | |||
669 | DEBUG(3, "link=0x%p", link); | 669 | DEBUG(3, "link=0x%p", link); |
670 | 670 | ||
671 | if(dev->mtd_info) { | 671 | if(dev->mtd_info) { |
672 | del_mtd_device(dev->mtd_info); | 672 | mtd_device_unregister(dev->mtd_info); |
673 | dev_info(&dev->p_dev->dev, "mtd%d: Removing\n", | 673 | dev_info(&dev->p_dev->dev, "mtd%d: Removing\n", |
674 | dev->mtd_info->index); | 674 | dev->mtd_info->index); |
675 | map_destroy(dev->mtd_info); | 675 | map_destroy(dev->mtd_info); |
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 1a9b94f0ee54..f64cee4a3bfb 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -27,10 +27,8 @@ struct physmap_flash_info { | |||
27 | struct mtd_info *mtd[MAX_RESOURCES]; | 27 | struct mtd_info *mtd[MAX_RESOURCES]; |
28 | struct mtd_info *cmtd; | 28 | struct mtd_info *cmtd; |
29 | struct map_info map[MAX_RESOURCES]; | 29 | struct map_info map[MAX_RESOURCES]; |
30 | #ifdef CONFIG_MTD_PARTITIONS | ||
31 | int nr_parts; | 30 | int nr_parts; |
32 | struct mtd_partition *parts; | 31 | struct mtd_partition *parts; |
33 | #endif | ||
34 | }; | 32 | }; |
35 | 33 | ||
36 | static int physmap_flash_remove(struct platform_device *dev) | 34 | static int physmap_flash_remove(struct platform_device *dev) |
@@ -47,18 +45,9 @@ static int physmap_flash_remove(struct platform_device *dev) | |||
47 | physmap_data = dev->dev.platform_data; | 45 | physmap_data = dev->dev.platform_data; |
48 | 46 | ||
49 | if (info->cmtd) { | 47 | if (info->cmtd) { |
50 | #ifdef CONFIG_MTD_PARTITIONS | 48 | mtd_device_unregister(info->cmtd); |
51 | if (info->nr_parts || physmap_data->nr_parts) { | 49 | if (info->nr_parts) |
52 | del_mtd_partitions(info->cmtd); | 50 | kfree(info->parts); |
53 | |||
54 | if (info->nr_parts) | ||
55 | kfree(info->parts); | ||
56 | } else { | ||
57 | del_mtd_device(info->cmtd); | ||
58 | } | ||
59 | #else | ||
60 | del_mtd_device(info->cmtd); | ||
61 | #endif | ||
62 | if (info->cmtd != info->mtd[0]) | 51 | if (info->cmtd != info->mtd[0]) |
63 | mtd_concat_destroy(info->cmtd); | 52 | mtd_concat_destroy(info->cmtd); |
64 | } | 53 | } |
@@ -92,10 +81,8 @@ static const char *rom_probe_types[] = { | |||
92 | "qinfo_probe", | 81 | "qinfo_probe", |
93 | "map_rom", | 82 | "map_rom", |
94 | NULL }; | 83 | NULL }; |
95 | #ifdef CONFIG_MTD_PARTITIONS | ||
96 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs", | 84 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs", |
97 | NULL }; | 85 | NULL }; |
98 | #endif | ||
99 | 86 | ||
100 | static int physmap_flash_probe(struct platform_device *dev) | 87 | static int physmap_flash_probe(struct platform_device *dev) |
101 | { | 88 | { |
@@ -188,24 +175,23 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
188 | if (err) | 175 | if (err) |
189 | goto err_out; | 176 | goto err_out; |
190 | 177 | ||
191 | #ifdef CONFIG_MTD_PARTITIONS | ||
192 | err = parse_mtd_partitions(info->cmtd, part_probe_types, | 178 | err = parse_mtd_partitions(info->cmtd, part_probe_types, |
193 | &info->parts, 0); | 179 | &info->parts, 0); |
194 | if (err > 0) { | 180 | if (err > 0) { |
195 | add_mtd_partitions(info->cmtd, info->parts, err); | 181 | mtd_device_register(info->cmtd, info->parts, err); |
196 | info->nr_parts = err; | 182 | info->nr_parts = err; |
197 | return 0; | 183 | return 0; |
198 | } | 184 | } |
199 | 185 | ||
200 | if (physmap_data->nr_parts) { | 186 | if (physmap_data->nr_parts) { |
201 | printk(KERN_NOTICE "Using physmap partition information\n"); | 187 | printk(KERN_NOTICE "Using physmap partition information\n"); |
202 | add_mtd_partitions(info->cmtd, physmap_data->parts, | 188 | mtd_device_register(info->cmtd, physmap_data->parts, |
203 | physmap_data->nr_parts); | 189 | physmap_data->nr_parts); |
204 | return 0; | 190 | return 0; |
205 | } | 191 | } |
206 | #endif | ||
207 | 192 | ||
208 | add_mtd_device(info->cmtd); | 193 | mtd_device_register(info->cmtd, NULL, 0); |
194 | |||
209 | return 0; | 195 | return 0; |
210 | 196 | ||
211 | err_out: | 197 | err_out: |
@@ -269,14 +255,12 @@ void physmap_configure(unsigned long addr, unsigned long size, | |||
269 | physmap_flash_data.set_vpp = set_vpp; | 255 | physmap_flash_data.set_vpp = set_vpp; |
270 | } | 256 | } |
271 | 257 | ||
272 | #ifdef CONFIG_MTD_PARTITIONS | ||
273 | void physmap_set_partitions(struct mtd_partition *parts, int num_parts) | 258 | void physmap_set_partitions(struct mtd_partition *parts, int num_parts) |
274 | { | 259 | { |
275 | physmap_flash_data.nr_parts = num_parts; | 260 | physmap_flash_data.nr_parts = num_parts; |
276 | physmap_flash_data.parts = parts; | 261 | physmap_flash_data.parts = parts; |
277 | } | 262 | } |
278 | #endif | 263 | #endif |
279 | #endif | ||
280 | 264 | ||
281 | static int __init physmap_init(void) | 265 | static int __init physmap_init(void) |
282 | { | 266 | { |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index c1d33464aee8..d251d1db129b 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -34,16 +34,12 @@ struct of_flash_list { | |||
34 | 34 | ||
35 | struct of_flash { | 35 | struct of_flash { |
36 | struct mtd_info *cmtd; | 36 | struct mtd_info *cmtd; |
37 | #ifdef CONFIG_MTD_PARTITIONS | ||
38 | struct mtd_partition *parts; | 37 | struct mtd_partition *parts; |
39 | #endif | ||
40 | int list_size; /* number of elements in of_flash_list */ | 38 | int list_size; /* number of elements in of_flash_list */ |
41 | struct of_flash_list list[0]; | 39 | struct of_flash_list list[0]; |
42 | }; | 40 | }; |
43 | 41 | ||
44 | #ifdef CONFIG_MTD_PARTITIONS | ||
45 | #define OF_FLASH_PARTS(info) ((info)->parts) | 42 | #define OF_FLASH_PARTS(info) ((info)->parts) |
46 | |||
47 | static int parse_obsolete_partitions(struct platform_device *dev, | 43 | static int parse_obsolete_partitions(struct platform_device *dev, |
48 | struct of_flash *info, | 44 | struct of_flash *info, |
49 | struct device_node *dp) | 45 | struct device_node *dp) |
@@ -89,10 +85,6 @@ static int parse_obsolete_partitions(struct platform_device *dev, | |||
89 | 85 | ||
90 | return nr_parts; | 86 | return nr_parts; |
91 | } | 87 | } |
92 | #else /* MTD_PARTITIONS */ | ||
93 | #define OF_FLASH_PARTS(info) (0) | ||
94 | #define parse_partitions(info, dev) (0) | ||
95 | #endif /* MTD_PARTITIONS */ | ||
96 | 88 | ||
97 | static int of_flash_remove(struct platform_device *dev) | 89 | static int of_flash_remove(struct platform_device *dev) |
98 | { | 90 | { |
@@ -105,17 +97,14 @@ static int of_flash_remove(struct platform_device *dev) | |||
105 | dev_set_drvdata(&dev->dev, NULL); | 97 | dev_set_drvdata(&dev->dev, NULL); |
106 | 98 | ||
107 | if (info->cmtd != info->list[0].mtd) { | 99 | if (info->cmtd != info->list[0].mtd) { |
108 | del_mtd_device(info->cmtd); | 100 | mtd_device_unregister(info->cmtd); |
109 | mtd_concat_destroy(info->cmtd); | 101 | mtd_concat_destroy(info->cmtd); |
110 | } | 102 | } |
111 | 103 | ||
112 | if (info->cmtd) { | 104 | if (info->cmtd) { |
113 | if (OF_FLASH_PARTS(info)) { | 105 | if (OF_FLASH_PARTS(info)) |
114 | del_mtd_partitions(info->cmtd); | ||
115 | kfree(OF_FLASH_PARTS(info)); | 106 | kfree(OF_FLASH_PARTS(info)); |
116 | } else { | 107 | mtd_device_unregister(info->cmtd); |
117 | del_mtd_device(info->cmtd); | ||
118 | } | ||
119 | } | 108 | } |
120 | 109 | ||
121 | for (i = 0; i < info->list_size; i++) { | 110 | for (i = 0; i < info->list_size; i++) { |
@@ -172,7 +161,6 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, | |||
172 | } | 161 | } |
173 | } | 162 | } |
174 | 163 | ||
175 | #ifdef CONFIG_MTD_PARTITIONS | ||
176 | /* When partitions are set we look for a linux,part-probe property which | 164 | /* When partitions are set we look for a linux,part-probe property which |
177 | specifies the list of partition probers to use. If none is given then the | 165 | specifies the list of partition probers to use. If none is given then the |
178 | default is use. These take precedence over other device tree | 166 | default is use. These take precedence over other device tree |
@@ -212,14 +200,11 @@ static void __devinit of_free_probes(const char **probes) | |||
212 | if (probes != part_probe_types_def) | 200 | if (probes != part_probe_types_def) |
213 | kfree(probes); | 201 | kfree(probes); |
214 | } | 202 | } |
215 | #endif | ||
216 | 203 | ||
217 | static struct of_device_id of_flash_match[]; | 204 | static struct of_device_id of_flash_match[]; |
218 | static int __devinit of_flash_probe(struct platform_device *dev) | 205 | static int __devinit of_flash_probe(struct platform_device *dev) |
219 | { | 206 | { |
220 | #ifdef CONFIG_MTD_PARTITIONS | ||
221 | const char **part_probe_types; | 207 | const char **part_probe_types; |
222 | #endif | ||
223 | const struct of_device_id *match; | 208 | const struct of_device_id *match; |
224 | struct device_node *dp = dev->dev.of_node; | 209 | struct device_node *dp = dev->dev.of_node; |
225 | struct resource res; | 210 | struct resource res; |
@@ -346,7 +331,6 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
346 | if (err) | 331 | if (err) |
347 | goto err_out; | 332 | goto err_out; |
348 | 333 | ||
349 | #ifdef CONFIG_MTD_PARTITIONS | ||
350 | part_probe_types = of_get_probes(dp); | 334 | part_probe_types = of_get_probes(dp); |
351 | err = parse_mtd_partitions(info->cmtd, part_probe_types, | 335 | err = parse_mtd_partitions(info->cmtd, part_probe_types, |
352 | &info->parts, 0); | 336 | &info->parts, 0); |
@@ -356,13 +340,11 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
356 | } | 340 | } |
357 | of_free_probes(part_probe_types); | 341 | of_free_probes(part_probe_types); |
358 | 342 | ||
359 | #ifdef CONFIG_MTD_OF_PARTS | ||
360 | if (err == 0) { | 343 | if (err == 0) { |
361 | err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts); | 344 | err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts); |
362 | if (err < 0) | 345 | if (err < 0) |
363 | goto err_out; | 346 | goto err_out; |
364 | } | 347 | } |
365 | #endif | ||
366 | 348 | ||
367 | if (err == 0) { | 349 | if (err == 0) { |
368 | err = parse_obsolete_partitions(dev, info, dp); | 350 | err = parse_obsolete_partitions(dev, info, dp); |
@@ -370,11 +352,7 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
370 | goto err_out; | 352 | goto err_out; |
371 | } | 353 | } |
372 | 354 | ||
373 | if (err > 0) | 355 | mtd_device_register(info->cmtd, info->parts, err); |
374 | add_mtd_partitions(info->cmtd, info->parts, err); | ||
375 | else | ||
376 | #endif | ||
377 | add_mtd_device(info->cmtd); | ||
378 | 356 | ||
379 | kfree(mtd_list); | 357 | kfree(mtd_list); |
380 | 358 | ||
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 76a76be5a7bd..9ca1eccba4bc 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c | |||
@@ -94,14 +94,11 @@ static int platram_remove(struct platform_device *pdev) | |||
94 | return 0; | 94 | return 0; |
95 | 95 | ||
96 | if (info->mtd) { | 96 | if (info->mtd) { |
97 | #ifdef CONFIG_MTD_PARTITIONS | 97 | mtd_device_unregister(info->mtd); |
98 | if (info->partitions) { | 98 | if (info->partitions) { |
99 | del_mtd_partitions(info->mtd); | ||
100 | if (info->free_partitions) | 99 | if (info->free_partitions) |
101 | kfree(info->partitions); | 100 | kfree(info->partitions); |
102 | } | 101 | } |
103 | #endif | ||
104 | del_mtd_device(info->mtd); | ||
105 | map_destroy(info->mtd); | 102 | map_destroy(info->mtd); |
106 | } | 103 | } |
107 | 104 | ||
@@ -231,7 +228,6 @@ static int platram_probe(struct platform_device *pdev) | |||
231 | /* check to see if there are any available partitions, or wether | 228 | /* check to see if there are any available partitions, or wether |
232 | * to add this device whole */ | 229 | * to add this device whole */ |
233 | 230 | ||
234 | #ifdef CONFIG_MTD_PARTITIONS | ||
235 | if (!pdata->nr_partitions) { | 231 | if (!pdata->nr_partitions) { |
236 | /* try to probe using the supplied probe type */ | 232 | /* try to probe using the supplied probe type */ |
237 | if (pdata->probes) { | 233 | if (pdata->probes) { |
@@ -239,24 +235,22 @@ static int platram_probe(struct platform_device *pdev) | |||
239 | &info->partitions, 0); | 235 | &info->partitions, 0); |
240 | info->free_partitions = 1; | 236 | info->free_partitions = 1; |
241 | if (err > 0) | 237 | if (err > 0) |
242 | err = add_mtd_partitions(info->mtd, | 238 | err = mtd_device_register(info->mtd, |
243 | info->partitions, err); | 239 | info->partitions, err); |
244 | } | 240 | } |
245 | } | 241 | } |
246 | /* use the static mapping */ | 242 | /* use the static mapping */ |
247 | else | 243 | else |
248 | err = add_mtd_partitions(info->mtd, pdata->partitions, | 244 | err = mtd_device_register(info->mtd, pdata->partitions, |
249 | pdata->nr_partitions); | 245 | pdata->nr_partitions); |
250 | #endif /* CONFIG_MTD_PARTITIONS */ | ||
251 | |||
252 | if (add_mtd_device(info->mtd)) { | ||
253 | dev_err(&pdev->dev, "add_mtd_device() failed\n"); | ||
254 | err = -ENOMEM; | ||
255 | } | ||
256 | |||
257 | if (!err) | 246 | if (!err) |
258 | dev_info(&pdev->dev, "registered mtd device\n"); | 247 | dev_info(&pdev->dev, "registered mtd device\n"); |
259 | 248 | ||
249 | /* add the whole device. */ | ||
250 | err = mtd_device_register(info->mtd, NULL, 0); | ||
251 | if (err) | ||
252 | dev_err(&pdev->dev, "failed to register the entire device\n"); | ||
253 | |||
260 | return err; | 254 | return err; |
261 | 255 | ||
262 | exit_free: | 256 | exit_free: |
diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c index 64aea6acd48e..744ca5cacc9b 100644 --- a/drivers/mtd/maps/pmcmsp-flash.c +++ b/drivers/mtd/maps/pmcmsp-flash.c | |||
@@ -173,7 +173,7 @@ static int __init init_msp_flash(void) | |||
173 | msp_flash[i] = do_map_probe("cfi_probe", &msp_maps[i]); | 173 | msp_flash[i] = do_map_probe("cfi_probe", &msp_maps[i]); |
174 | if (msp_flash[i]) { | 174 | if (msp_flash[i]) { |
175 | msp_flash[i]->owner = THIS_MODULE; | 175 | msp_flash[i]->owner = THIS_MODULE; |
176 | add_mtd_partitions(msp_flash[i], msp_parts[i], pcnt); | 176 | mtd_device_register(msp_flash[i], msp_parts[i], pcnt); |
177 | } else { | 177 | } else { |
178 | printk(KERN_ERR "map probe failed for flash\n"); | 178 | printk(KERN_ERR "map probe failed for flash\n"); |
179 | ret = -ENXIO; | 179 | ret = -ENXIO; |
@@ -188,7 +188,7 @@ static int __init init_msp_flash(void) | |||
188 | 188 | ||
189 | cleanup_loop: | 189 | cleanup_loop: |
190 | while (i--) { | 190 | while (i--) { |
191 | del_mtd_partitions(msp_flash[i]); | 191 | mtd_device_unregister(msp_flash[i]); |
192 | map_destroy(msp_flash[i]); | 192 | map_destroy(msp_flash[i]); |
193 | kfree(msp_maps[i].name); | 193 | kfree(msp_maps[i].name); |
194 | iounmap(msp_maps[i].virt); | 194 | iounmap(msp_maps[i].virt); |
@@ -207,7 +207,7 @@ static void __exit cleanup_msp_flash(void) | |||
207 | int i; | 207 | int i; |
208 | 208 | ||
209 | for (i = 0; i < fcnt; i++) { | 209 | for (i = 0; i < fcnt; i++) { |
210 | del_mtd_partitions(msp_flash[i]); | 210 | mtd_device_unregister(msp_flash[i]); |
211 | map_destroy(msp_flash[i]); | 211 | map_destroy(msp_flash[i]); |
212 | iounmap((void *)msp_maps[i].virt); | 212 | iounmap((void *)msp_maps[i].virt); |
213 | 213 | ||
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index d8ae634d347e..f59d62f74d44 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
@@ -104,23 +104,18 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) | |||
104 | } | 104 | } |
105 | info->mtd->owner = THIS_MODULE; | 105 | info->mtd->owner = THIS_MODULE; |
106 | 106 | ||
107 | #ifdef CONFIG_MTD_PARTITIONS | ||
108 | ret = parse_mtd_partitions(info->mtd, probes, &parts, 0); | 107 | ret = parse_mtd_partitions(info->mtd, probes, &parts, 0); |
109 | 108 | ||
110 | if (ret > 0) { | 109 | if (ret > 0) { |
111 | info->nr_parts = ret; | 110 | info->nr_parts = ret; |
112 | info->parts = parts; | 111 | info->parts = parts; |
113 | } | 112 | } |
114 | #endif | ||
115 | 113 | ||
116 | if (info->nr_parts) { | 114 | if (!info->nr_parts) |
117 | add_mtd_partitions(info->mtd, info->parts, | ||
118 | info->nr_parts); | ||
119 | } else { | ||
120 | printk("Registering %s as whole device\n", | 115 | printk("Registering %s as whole device\n", |
121 | info->map.name); | 116 | info->map.name); |
122 | add_mtd_device(info->mtd); | 117 | |
123 | } | 118 | mtd_device_register(info->mtd, info->parts, info->nr_parts); |
124 | 119 | ||
125 | platform_set_drvdata(pdev, info); | 120 | platform_set_drvdata(pdev, info); |
126 | return 0; | 121 | return 0; |
@@ -132,12 +127,7 @@ static int __devexit pxa2xx_flash_remove(struct platform_device *dev) | |||
132 | 127 | ||
133 | platform_set_drvdata(dev, NULL); | 128 | platform_set_drvdata(dev, NULL); |
134 | 129 | ||
135 | #ifdef CONFIG_MTD_PARTITIONS | 130 | mtd_device_unregister(info->mtd); |
136 | if (info->nr_parts) | ||
137 | del_mtd_partitions(info->mtd); | ||
138 | else | ||
139 | #endif | ||
140 | del_mtd_device(info->mtd); | ||
141 | 131 | ||
142 | map_destroy(info->mtd); | 132 | map_destroy(info->mtd); |
143 | iounmap(info->map.virt); | 133 | iounmap(info->map.virt); |
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c index 83ed64512c5e..761fb459d2c7 100644 --- a/drivers/mtd/maps/rbtx4939-flash.c +++ b/drivers/mtd/maps/rbtx4939-flash.c | |||
@@ -25,10 +25,8 @@ | |||
25 | struct rbtx4939_flash_info { | 25 | struct rbtx4939_flash_info { |
26 | struct mtd_info *mtd; | 26 | struct mtd_info *mtd; |
27 | struct map_info map; | 27 | struct map_info map; |
28 | #ifdef CONFIG_MTD_PARTITIONS | ||
29 | int nr_parts; | 28 | int nr_parts; |
30 | struct mtd_partition *parts; | 29 | struct mtd_partition *parts; |
31 | #endif | ||
32 | }; | 30 | }; |
33 | 31 | ||
34 | static int rbtx4939_flash_remove(struct platform_device *dev) | 32 | static int rbtx4939_flash_remove(struct platform_device *dev) |
@@ -41,28 +39,18 @@ static int rbtx4939_flash_remove(struct platform_device *dev) | |||
41 | platform_set_drvdata(dev, NULL); | 39 | platform_set_drvdata(dev, NULL); |
42 | 40 | ||
43 | if (info->mtd) { | 41 | if (info->mtd) { |
44 | #ifdef CONFIG_MTD_PARTITIONS | ||
45 | struct rbtx4939_flash_data *pdata = dev->dev.platform_data; | 42 | struct rbtx4939_flash_data *pdata = dev->dev.platform_data; |
46 | 43 | ||
47 | if (info->nr_parts) { | 44 | if (info->nr_parts) |
48 | del_mtd_partitions(info->mtd); | ||
49 | kfree(info->parts); | 45 | kfree(info->parts); |
50 | } else if (pdata->nr_parts) | 46 | mtd_device_unregister(info->mtd); |
51 | del_mtd_partitions(info->mtd); | ||
52 | else | ||
53 | del_mtd_device(info->mtd); | ||
54 | #else | ||
55 | del_mtd_device(info->mtd); | ||
56 | #endif | ||
57 | map_destroy(info->mtd); | 47 | map_destroy(info->mtd); |
58 | } | 48 | } |
59 | return 0; | 49 | return 0; |
60 | } | 50 | } |
61 | 51 | ||
62 | static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | 52 | static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; |
63 | #ifdef CONFIG_MTD_PARTITIONS | ||
64 | static const char *part_probe_types[] = { "cmdlinepart", NULL }; | 53 | static const char *part_probe_types[] = { "cmdlinepart", NULL }; |
65 | #endif | ||
66 | 54 | ||
67 | static int rbtx4939_flash_probe(struct platform_device *dev) | 55 | static int rbtx4939_flash_probe(struct platform_device *dev) |
68 | { | 56 | { |
@@ -120,23 +108,21 @@ static int rbtx4939_flash_probe(struct platform_device *dev) | |||
120 | if (err) | 108 | if (err) |
121 | goto err_out; | 109 | goto err_out; |
122 | 110 | ||
123 | #ifdef CONFIG_MTD_PARTITIONS | ||
124 | err = parse_mtd_partitions(info->mtd, part_probe_types, | 111 | err = parse_mtd_partitions(info->mtd, part_probe_types, |
125 | &info->parts, 0); | 112 | &info->parts, 0); |
126 | if (err > 0) { | 113 | if (err > 0) { |
127 | add_mtd_partitions(info->mtd, info->parts, err); | 114 | mtd_device_register(info->mtd, info->parts, err); |
128 | info->nr_parts = err; | 115 | info->nr_parts = err; |
129 | return 0; | 116 | return 0; |
130 | } | 117 | } |
131 | 118 | ||
132 | if (pdata->nr_parts) { | 119 | if (pdata->nr_parts) { |
133 | pr_notice("Using rbtx4939 partition information\n"); | 120 | pr_notice("Using rbtx4939 partition information\n"); |
134 | add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); | 121 | mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts); |
135 | return 0; | 122 | return 0; |
136 | } | 123 | } |
137 | #endif | ||
138 | 124 | ||
139 | add_mtd_device(info->mtd); | 125 | mtd_device_register(info->mtd, NULL, 0); |
140 | return 0; | 126 | return 0; |
141 | 127 | ||
142 | err_out: | 128 | err_out: |
diff --git a/drivers/mtd/maps/rpxlite.c b/drivers/mtd/maps/rpxlite.c index 3e3ef53d4fd4..ed88225bf667 100644 --- a/drivers/mtd/maps/rpxlite.c +++ b/drivers/mtd/maps/rpxlite.c | |||
@@ -36,7 +36,7 @@ static int __init init_rpxlite(void) | |||
36 | mymtd = do_map_probe("cfi_probe", &rpxlite_map); | 36 | mymtd = do_map_probe("cfi_probe", &rpxlite_map); |
37 | if (mymtd) { | 37 | if (mymtd) { |
38 | mymtd->owner = THIS_MODULE; | 38 | mymtd->owner = THIS_MODULE; |
39 | add_mtd_device(mymtd); | 39 | mtd_device_register(mymtd, NULL, 0); |
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
@@ -47,7 +47,7 @@ static int __init init_rpxlite(void) | |||
47 | static void __exit cleanup_rpxlite(void) | 47 | static void __exit cleanup_rpxlite(void) |
48 | { | 48 | { |
49 | if (mymtd) { | 49 | if (mymtd) { |
50 | del_mtd_device(mymtd); | 50 | mtd_device_unregister(mymtd); |
51 | map_destroy(mymtd); | 51 | map_destroy(mymtd); |
52 | } | 52 | } |
53 | if (rpxlite_map.virt) { | 53 | if (rpxlite_map.virt) { |
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index da875908ea8e..a9b5e0e5c4c5 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
@@ -226,12 +226,7 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla | |||
226 | int i; | 226 | int i; |
227 | 227 | ||
228 | if (info->mtd) { | 228 | if (info->mtd) { |
229 | if (info->nr_parts == 0) | 229 | mtd_device_unregister(info->mtd); |
230 | del_mtd_device(info->mtd); | ||
231 | #ifdef CONFIG_MTD_PARTITIONS | ||
232 | else | ||
233 | del_mtd_partitions(info->mtd); | ||
234 | #endif | ||
235 | if (info->mtd != info->subdev[0].mtd) | 230 | if (info->mtd != info->subdev[0].mtd) |
236 | mtd_concat_destroy(info->mtd); | 231 | mtd_concat_destroy(info->mtd); |
237 | } | 232 | } |
@@ -363,28 +358,24 @@ static int __devinit sa1100_mtd_probe(struct platform_device *pdev) | |||
363 | /* | 358 | /* |
364 | * Partition selection stuff. | 359 | * Partition selection stuff. |
365 | */ | 360 | */ |
366 | #ifdef CONFIG_MTD_PARTITIONS | ||
367 | nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0); | 361 | nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0); |
368 | if (nr_parts > 0) { | 362 | if (nr_parts > 0) { |
369 | info->parts = parts; | 363 | info->parts = parts; |
370 | part_type = "dynamic"; | 364 | part_type = "dynamic"; |
371 | } else | 365 | } else { |
372 | #endif | ||
373 | { | ||
374 | parts = plat->parts; | 366 | parts = plat->parts; |
375 | nr_parts = plat->nr_parts; | 367 | nr_parts = plat->nr_parts; |
376 | part_type = "static"; | 368 | part_type = "static"; |
377 | } | 369 | } |
378 | 370 | ||
379 | if (nr_parts == 0) { | 371 | if (nr_parts == 0) |
380 | printk(KERN_NOTICE "SA1100 flash: no partition info " | 372 | printk(KERN_NOTICE "SA1100 flash: no partition info " |
381 | "available, registering whole flash\n"); | 373 | "available, registering whole flash\n"); |
382 | add_mtd_device(info->mtd); | 374 | else |
383 | } else { | ||
384 | printk(KERN_NOTICE "SA1100 flash: using %s partition " | 375 | printk(KERN_NOTICE "SA1100 flash: using %s partition " |
385 | "definition\n", part_type); | 376 | "definition\n", part_type); |
386 | add_mtd_partitions(info->mtd, parts, nr_parts); | 377 | |
387 | } | 378 | mtd_device_register(info->mtd, parts, nr_parts); |
388 | 379 | ||
389 | info->nr_parts = nr_parts; | 380 | info->nr_parts = nr_parts; |
390 | 381 | ||
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c index 04b2781fc627..556a2dfe94c5 100644 --- a/drivers/mtd/maps/sbc_gxx.c +++ b/drivers/mtd/maps/sbc_gxx.c | |||
@@ -182,7 +182,7 @@ static struct mtd_info *all_mtd; | |||
182 | static void cleanup_sbc_gxx(void) | 182 | static void cleanup_sbc_gxx(void) |
183 | { | 183 | { |
184 | if( all_mtd ) { | 184 | if( all_mtd ) { |
185 | del_mtd_partitions( all_mtd ); | 185 | mtd_device_unregister(all_mtd); |
186 | map_destroy( all_mtd ); | 186 | map_destroy( all_mtd ); |
187 | } | 187 | } |
188 | 188 | ||
@@ -223,7 +223,7 @@ static int __init init_sbc_gxx(void) | |||
223 | all_mtd->owner = THIS_MODULE; | 223 | all_mtd->owner = THIS_MODULE; |
224 | 224 | ||
225 | /* Create MTD devices for each partition. */ | 225 | /* Create MTD devices for each partition. */ |
226 | add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS ); | 226 | mtd_device_register(all_mtd, partition_info, NUM_PARTITIONS); |
227 | 227 | ||
228 | return 0; | 228 | return 0; |
229 | } | 229 | } |
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index 4d8aaaf4bb76..8fead8e46bce 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c | |||
@@ -266,10 +266,10 @@ static int __init init_sc520cdp(void) | |||
266 | /* Combine the two flash banks into a single MTD device & register it: */ | 266 | /* Combine the two flash banks into a single MTD device & register it: */ |
267 | merged_mtd = mtd_concat_create(mymtd, 2, "SC520CDP Flash Banks #0 and #1"); | 267 | merged_mtd = mtd_concat_create(mymtd, 2, "SC520CDP Flash Banks #0 and #1"); |
268 | if(merged_mtd) | 268 | if(merged_mtd) |
269 | add_mtd_device(merged_mtd); | 269 | mtd_device_register(merged_mtd, NULL, 0); |
270 | } | 270 | } |
271 | if(devices_found == 3) /* register the third (DIL-Flash) device */ | 271 | if(devices_found == 3) /* register the third (DIL-Flash) device */ |
272 | add_mtd_device(mymtd[2]); | 272 | mtd_device_register(mymtd[2], NULL, 0); |
273 | return(devices_found ? 0 : -ENXIO); | 273 | return(devices_found ? 0 : -ENXIO); |
274 | } | 274 | } |
275 | 275 | ||
@@ -278,11 +278,11 @@ static void __exit cleanup_sc520cdp(void) | |||
278 | int i; | 278 | int i; |
279 | 279 | ||
280 | if (merged_mtd) { | 280 | if (merged_mtd) { |
281 | del_mtd_device(merged_mtd); | 281 | mtd_device_unregister(merged_mtd); |
282 | mtd_concat_destroy(merged_mtd); | 282 | mtd_concat_destroy(merged_mtd); |
283 | } | 283 | } |
284 | if (mymtd[2]) | 284 | if (mymtd[2]) |
285 | del_mtd_device(mymtd[2]); | 285 | mtd_device_unregister(mymtd[2]); |
286 | 286 | ||
287 | for (i = 0; i < NUM_FLASH_BANKS; i++) { | 287 | for (i = 0; i < NUM_FLASH_BANKS; i++) { |
288 | if (mymtd[i]) | 288 | if (mymtd[i]) |
diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c index 7e329f09a548..d88c8426bb0f 100644 --- a/drivers/mtd/maps/scb2_flash.c +++ b/drivers/mtd/maps/scb2_flash.c | |||
@@ -180,7 +180,7 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
180 | 180 | ||
181 | scb2_mtd->owner = THIS_MODULE; | 181 | scb2_mtd->owner = THIS_MODULE; |
182 | if (scb2_fixup_mtd(scb2_mtd) < 0) { | 182 | if (scb2_fixup_mtd(scb2_mtd) < 0) { |
183 | del_mtd_device(scb2_mtd); | 183 | mtd_device_unregister(scb2_mtd); |
184 | map_destroy(scb2_mtd); | 184 | map_destroy(scb2_mtd); |
185 | iounmap(scb2_ioaddr); | 185 | iounmap(scb2_ioaddr); |
186 | if (!region_fail) | 186 | if (!region_fail) |
@@ -192,7 +192,7 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
192 | (unsigned long long)scb2_mtd->size, | 192 | (unsigned long long)scb2_mtd->size, |
193 | (unsigned long long)(SCB2_WINDOW - scb2_mtd->size)); | 193 | (unsigned long long)(SCB2_WINDOW - scb2_mtd->size)); |
194 | 194 | ||
195 | add_mtd_device(scb2_mtd); | 195 | mtd_device_register(scb2_mtd, NULL, 0); |
196 | 196 | ||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
@@ -207,7 +207,7 @@ scb2_flash_remove(struct pci_dev *dev) | |||
207 | if (scb2_mtd->lock) | 207 | if (scb2_mtd->lock) |
208 | scb2_mtd->lock(scb2_mtd, 0, scb2_mtd->size); | 208 | scb2_mtd->lock(scb2_mtd, 0, scb2_mtd->size); |
209 | 209 | ||
210 | del_mtd_device(scb2_mtd); | 210 | mtd_device_unregister(scb2_mtd); |
211 | map_destroy(scb2_mtd); | 211 | map_destroy(scb2_mtd); |
212 | 212 | ||
213 | iounmap(scb2_ioaddr); | 213 | iounmap(scb2_ioaddr); |
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 027e628a4f1d..f1c1f737d0d7 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c | |||
@@ -44,7 +44,6 @@ static struct resource docmem = { | |||
44 | 44 | ||
45 | static struct mtd_info *mymtd; | 45 | static struct mtd_info *mymtd; |
46 | 46 | ||
47 | #ifdef CONFIG_MTD_PARTITIONS | ||
48 | static struct mtd_partition partition_info[] = { | 47 | static struct mtd_partition partition_info[] = { |
49 | { | 48 | { |
50 | .name = "DOCCS Boot kernel", | 49 | .name = "DOCCS Boot kernel", |
@@ -68,8 +67,6 @@ static struct mtd_partition partition_info[] = { | |||
68 | }, | 67 | }, |
69 | }; | 68 | }; |
70 | #define NUM_PARTITIONS ARRAY_SIZE(partition_info) | 69 | #define NUM_PARTITIONS ARRAY_SIZE(partition_info) |
71 | #endif | ||
72 | |||
73 | 70 | ||
74 | static struct map_info scx200_docflash_map = { | 71 | static struct map_info scx200_docflash_map = { |
75 | .name = "NatSemi SCx200 DOCCS Flash", | 72 | .name = "NatSemi SCx200 DOCCS Flash", |
@@ -198,24 +195,17 @@ static int __init init_scx200_docflash(void) | |||
198 | 195 | ||
199 | mymtd->owner = THIS_MODULE; | 196 | mymtd->owner = THIS_MODULE; |
200 | 197 | ||
201 | #ifdef CONFIG_MTD_PARTITIONS | ||
202 | partition_info[3].offset = mymtd->size-partition_info[3].size; | 198 | partition_info[3].offset = mymtd->size-partition_info[3].size; |
203 | partition_info[2].size = partition_info[3].offset-partition_info[2].offset; | 199 | partition_info[2].size = partition_info[3].offset-partition_info[2].offset; |
204 | add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); | 200 | mtd_device_register(mymtd, partition_info, NUM_PARTITIONS); |
205 | #else | 201 | |
206 | add_mtd_device(mymtd); | ||
207 | #endif | ||
208 | return 0; | 202 | return 0; |
209 | } | 203 | } |
210 | 204 | ||
211 | static void __exit cleanup_scx200_docflash(void) | 205 | static void __exit cleanup_scx200_docflash(void) |
212 | { | 206 | { |
213 | if (mymtd) { | 207 | if (mymtd) { |
214 | #ifdef CONFIG_MTD_PARTITIONS | 208 | mtd_device_unregister(mymtd); |
215 | del_mtd_partitions(mymtd); | ||
216 | #else | ||
217 | del_mtd_device(mymtd); | ||
218 | #endif | ||
219 | map_destroy(mymtd); | 209 | map_destroy(mymtd); |
220 | } | 210 | } |
221 | if (scx200_docflash_map.virt) { | 211 | if (scx200_docflash_map.virt) { |
diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c index 0eb41d9c6786..cbf6bade9354 100644 --- a/drivers/mtd/maps/solutionengine.c +++ b/drivers/mtd/maps/solutionengine.c | |||
@@ -89,7 +89,7 @@ static int __init init_soleng_maps(void) | |||
89 | eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map); | 89 | eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map); |
90 | if (eprom_mtd) { | 90 | if (eprom_mtd) { |
91 | eprom_mtd->owner = THIS_MODULE; | 91 | eprom_mtd->owner = THIS_MODULE; |
92 | add_mtd_device(eprom_mtd); | 92 | mtd_device_register(eprom_mtd, NULL, 0); |
93 | } | 93 | } |
94 | 94 | ||
95 | nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); | 95 | nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); |
@@ -104,9 +104,9 @@ static int __init init_soleng_maps(void) | |||
104 | #endif /* CONFIG_MTD_SUPERH_RESERVE */ | 104 | #endif /* CONFIG_MTD_SUPERH_RESERVE */ |
105 | 105 | ||
106 | if (nr_parts > 0) | 106 | if (nr_parts > 0) |
107 | add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); | 107 | mtd_device_register(flash_mtd, parsed_parts, nr_parts); |
108 | else | 108 | else |
109 | add_mtd_device(flash_mtd); | 109 | mtd_device_register(flash_mtd, NULL, 0); |
110 | 110 | ||
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
@@ -114,14 +114,14 @@ static int __init init_soleng_maps(void) | |||
114 | static void __exit cleanup_soleng_maps(void) | 114 | static void __exit cleanup_soleng_maps(void) |
115 | { | 115 | { |
116 | if (eprom_mtd) { | 116 | if (eprom_mtd) { |
117 | del_mtd_device(eprom_mtd); | 117 | mtd_device_unregister(eprom_mtd); |
118 | map_destroy(eprom_mtd); | 118 | map_destroy(eprom_mtd); |
119 | } | 119 | } |
120 | 120 | ||
121 | if (parsed_parts) | 121 | if (parsed_parts) |
122 | del_mtd_partitions(flash_mtd); | 122 | mtd_device_unregister(flash_mtd); |
123 | else | 123 | else |
124 | del_mtd_device(flash_mtd); | 124 | mtd_device_unregister(flash_mtd); |
125 | map_destroy(flash_mtd); | 125 | map_destroy(flash_mtd); |
126 | } | 126 | } |
127 | 127 | ||
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 3f1cb328a574..2d66234f57cb 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c | |||
@@ -101,7 +101,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp) | |||
101 | 101 | ||
102 | up->mtd->owner = THIS_MODULE; | 102 | up->mtd->owner = THIS_MODULE; |
103 | 103 | ||
104 | add_mtd_device(up->mtd); | 104 | mtd_device_register(up->mtd, NULL, 0); |
105 | 105 | ||
106 | dev_set_drvdata(&op->dev, up); | 106 | dev_set_drvdata(&op->dev, up); |
107 | 107 | ||
@@ -126,7 +126,7 @@ static int __devexit uflash_remove(struct platform_device *op) | |||
126 | struct uflash_dev *up = dev_get_drvdata(&op->dev); | 126 | struct uflash_dev *up = dev_get_drvdata(&op->dev); |
127 | 127 | ||
128 | if (up->mtd) { | 128 | if (up->mtd) { |
129 | del_mtd_device(up->mtd); | 129 | mtd_device_unregister(up->mtd); |
130 | map_destroy(up->mtd); | 130 | map_destroy(up->mtd); |
131 | } | 131 | } |
132 | if (up->map.virt) { | 132 | if (up->map.virt) { |
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index 0718dfb3ee64..d78587990e7e 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c | |||
@@ -62,7 +62,6 @@ static void __iomem *start_scan_addr; | |||
62 | * "struct map_desc *_io_desc" for the corresponding machine. | 62 | * "struct map_desc *_io_desc" for the corresponding machine. |
63 | */ | 63 | */ |
64 | 64 | ||
65 | #ifdef CONFIG_MTD_PARTITIONS | ||
66 | /* Currently, TQM8xxL has up to 8MiB flash */ | 65 | /* Currently, TQM8xxL has up to 8MiB flash */ |
67 | static unsigned long tqm8xxl_max_flash_size = 0x00800000; | 66 | static unsigned long tqm8xxl_max_flash_size = 0x00800000; |
68 | 67 | ||
@@ -107,7 +106,6 @@ static struct mtd_partition tqm8xxl_fs_partitions[] = { | |||
107 | //.size = MTDPART_SIZ_FULL, | 106 | //.size = MTDPART_SIZ_FULL, |
108 | } | 107 | } |
109 | }; | 108 | }; |
110 | #endif | ||
111 | 109 | ||
112 | static int __init init_tqm_mtd(void) | 110 | static int __init init_tqm_mtd(void) |
113 | { | 111 | { |
@@ -188,7 +186,6 @@ static int __init init_tqm_mtd(void) | |||
188 | goto error_mem; | 186 | goto error_mem; |
189 | } | 187 | } |
190 | 188 | ||
191 | #ifdef CONFIG_MTD_PARTITIONS | ||
192 | /* | 189 | /* |
193 | * Select Static partition definitions | 190 | * Select Static partition definitions |
194 | */ | 191 | */ |
@@ -201,21 +198,14 @@ static int __init init_tqm_mtd(void) | |||
201 | part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions); | 198 | part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions); |
202 | 199 | ||
203 | for(idx = 0; idx < num_banks ; idx++) { | 200 | for(idx = 0; idx < num_banks ; idx++) { |
204 | if (part_banks[idx].nums == 0) { | 201 | if (part_banks[idx].nums == 0) |
205 | printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx); | 202 | printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx); |
206 | add_mtd_device(mtd_banks[idx]); | 203 | else |
207 | } else { | ||
208 | printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n", | 204 | printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n", |
209 | idx, part_banks[idx].type); | 205 | idx, part_banks[idx].type); |
210 | add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part, | 206 | mtd_device_register(mtd_banks[idx], part_banks[idx].mtd_part, |
211 | part_banks[idx].nums); | 207 | part_banks[idx].nums); |
212 | } | ||
213 | } | 208 | } |
214 | #else | ||
215 | printk(KERN_NOTICE "TQM flash: registering %d whole flash banks at once\n", num_banks); | ||
216 | for(idx = 0 ; idx < num_banks ; idx++) | ||
217 | add_mtd_device(mtd_banks[idx]); | ||
218 | #endif | ||
219 | return 0; | 209 | return 0; |
220 | error_mem: | 210 | error_mem: |
221 | for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { | 211 | for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { |
@@ -237,7 +227,7 @@ static void __exit cleanup_tqm_mtd(void) | |||
237 | for(idx = 0 ; idx < num_banks ; idx++) { | 227 | for(idx = 0 ; idx < num_banks ; idx++) { |
238 | /* destroy mtd_info previously allocated */ | 228 | /* destroy mtd_info previously allocated */ |
239 | if (mtd_banks[idx]) { | 229 | if (mtd_banks[idx]) { |
240 | del_mtd_partitions(mtd_banks[idx]); | 230 | mtd_device_unregister(mtd_banks[idx]); |
241 | map_destroy(mtd_banks[idx]); | 231 | map_destroy(mtd_banks[idx]); |
242 | } | 232 | } |
243 | /* release map_info not used anymore */ | 233 | /* release map_info not used anymore */ |
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c index e02dfa9d4ddd..d1d671daf235 100644 --- a/drivers/mtd/maps/ts5500_flash.c +++ b/drivers/mtd/maps/ts5500_flash.c | |||
@@ -89,7 +89,7 @@ static int __init init_ts5500_map(void) | |||
89 | } | 89 | } |
90 | 90 | ||
91 | mymtd->owner = THIS_MODULE; | 91 | mymtd->owner = THIS_MODULE; |
92 | add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS); | 92 | mtd_device_register(mymtd, ts5500_partitions, NUM_PARTITIONS); |
93 | 93 | ||
94 | return 0; | 94 | return 0; |
95 | 95 | ||
@@ -102,7 +102,7 @@ err2: | |||
102 | static void __exit cleanup_ts5500_map(void) | 102 | static void __exit cleanup_ts5500_map(void) |
103 | { | 103 | { |
104 | if (mymtd) { | 104 | if (mymtd) { |
105 | del_mtd_partitions(mymtd); | 105 | mtd_device_unregister(mymtd); |
106 | map_destroy(mymtd); | 106 | map_destroy(mymtd); |
107 | } | 107 | } |
108 | 108 | ||
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c index 77a8bfc02577..1de390e1c2fb 100644 --- a/drivers/mtd/maps/tsunami_flash.c +++ b/drivers/mtd/maps/tsunami_flash.c | |||
@@ -76,7 +76,7 @@ static void __exit cleanup_tsunami_flash(void) | |||
76 | struct mtd_info *mtd; | 76 | struct mtd_info *mtd; |
77 | mtd = tsunami_flash_mtd; | 77 | mtd = tsunami_flash_mtd; |
78 | if (mtd) { | 78 | if (mtd) { |
79 | del_mtd_device(mtd); | 79 | mtd_device_unregister(mtd); |
80 | map_destroy(mtd); | 80 | map_destroy(mtd); |
81 | } | 81 | } |
82 | tsunami_flash_mtd = 0; | 82 | tsunami_flash_mtd = 0; |
@@ -97,7 +97,7 @@ static int __init init_tsunami_flash(void) | |||
97 | } | 97 | } |
98 | if (tsunami_flash_mtd) { | 98 | if (tsunami_flash_mtd) { |
99 | tsunami_flash_mtd->owner = THIS_MODULE; | 99 | tsunami_flash_mtd->owner = THIS_MODULE; |
100 | add_mtd_device(tsunami_flash_mtd); | 100 | mtd_device_register(tsunami_flash_mtd, NULL, 0); |
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | return -ENXIO; | 103 | return -ENXIO; |
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 35009294b435..6793074f3f40 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c | |||
@@ -89,11 +89,7 @@ static int __init uclinux_mtd_init(void) | |||
89 | mtd->priv = mapp; | 89 | mtd->priv = mapp; |
90 | 90 | ||
91 | uclinux_ram_mtdinfo = mtd; | 91 | uclinux_ram_mtdinfo = mtd; |
92 | #ifdef CONFIG_MTD_PARTITIONS | 92 | mtd_device_register(mtd, uclinux_romfs, NUM_PARTITIONS); |
93 | add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS); | ||
94 | #else | ||
95 | add_mtd_device(mtd); | ||
96 | #endif | ||
97 | 93 | ||
98 | return(0); | 94 | return(0); |
99 | } | 95 | } |
@@ -103,11 +99,7 @@ static int __init uclinux_mtd_init(void) | |||
103 | static void __exit uclinux_mtd_cleanup(void) | 99 | static void __exit uclinux_mtd_cleanup(void) |
104 | { | 100 | { |
105 | if (uclinux_ram_mtdinfo) { | 101 | if (uclinux_ram_mtdinfo) { |
106 | #ifdef CONFIG_MTD_PARTITIONS | 102 | mtd_device_unregister(uclinux_ram_mtdinfo); |
107 | del_mtd_partitions(uclinux_ram_mtdinfo); | ||
108 | #else | ||
109 | del_mtd_device(uclinux_ram_mtdinfo); | ||
110 | #endif | ||
111 | map_destroy(uclinux_ram_mtdinfo); | 103 | map_destroy(uclinux_ram_mtdinfo); |
112 | uclinux_ram_mtdinfo = NULL; | 104 | uclinux_ram_mtdinfo = NULL; |
113 | } | 105 | } |
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c index 6adaa6acc193..5e68de73eabc 100644 --- a/drivers/mtd/maps/vmax301.c +++ b/drivers/mtd/maps/vmax301.c | |||
@@ -138,7 +138,7 @@ static void __exit cleanup_vmax301(void) | |||
138 | 138 | ||
139 | for (i=0; i<2; i++) { | 139 | for (i=0; i<2; i++) { |
140 | if (vmax_mtd[i]) { | 140 | if (vmax_mtd[i]) { |
141 | del_mtd_device(vmax_mtd[i]); | 141 | mtd_device_unregister(vmax_mtd[i]); |
142 | map_destroy(vmax_mtd[i]); | 142 | map_destroy(vmax_mtd[i]); |
143 | } | 143 | } |
144 | } | 144 | } |
@@ -176,7 +176,7 @@ static int __init init_vmax301(void) | |||
176 | vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]); | 176 | vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]); |
177 | if (vmax_mtd[i]) { | 177 | if (vmax_mtd[i]) { |
178 | vmax_mtd[i]->owner = THIS_MODULE; | 178 | vmax_mtd[i]->owner = THIS_MODULE; |
179 | add_mtd_device(vmax_mtd[i]); | 179 | mtd_device_register(vmax_mtd[i], NULL, 0); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 4afc167731ef..3a04b078576a 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c | |||
@@ -563,7 +563,7 @@ static void vmu_queryblocks(struct mapleq *mq) | |||
563 | goto fail_cache_create; | 563 | goto fail_cache_create; |
564 | part_cur->pcache = pcache; | 564 | part_cur->pcache = pcache; |
565 | 565 | ||
566 | error = add_mtd_device(mtd_cur); | 566 | error = mtd_device_register(mtd_cur, NULL, 0); |
567 | if (error) | 567 | if (error) |
568 | goto fail_mtd_register; | 568 | goto fail_mtd_register; |
569 | 569 | ||
@@ -709,7 +709,7 @@ static void __devexit vmu_disconnect(struct maple_device *mdev) | |||
709 | for (x = 0; x < card->partitions; x++) { | 709 | for (x = 0; x < card->partitions; x++) { |
710 | mpart = ((card->mtd)[x]).priv; | 710 | mpart = ((card->mtd)[x]).priv; |
711 | mpart->mdev = NULL; | 711 | mpart->mdev = NULL; |
712 | del_mtd_device(&((card->mtd)[x])); | 712 | mtd_device_unregister(&((card->mtd)[x])); |
713 | kfree(((card->parts)[x]).name); | 713 | kfree(((card->parts)[x]).name); |
714 | } | 714 | } |
715 | kfree(card->parts); | 715 | kfree(card->parts); |
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c index 933a2b6598b4..901ce968efae 100644 --- a/drivers/mtd/maps/wr_sbc82xx_flash.c +++ b/drivers/mtd/maps/wr_sbc82xx_flash.c | |||
@@ -132,17 +132,20 @@ static int __init init_sbc82xx_flash(void) | |||
132 | nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes, | 132 | nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes, |
133 | &sbcmtd_parts[i], 0); | 133 | &sbcmtd_parts[i], 0); |
134 | if (nr_parts > 0) { | 134 | if (nr_parts > 0) { |
135 | add_mtd_partitions (sbcmtd[i], sbcmtd_parts[i], nr_parts); | 135 | mtd_device_register(sbcmtd[i], sbcmtd_parts[i], |
136 | nr_parts); | ||
136 | continue; | 137 | continue; |
137 | } | 138 | } |
138 | 139 | ||
139 | /* No partitioning detected. Use default */ | 140 | /* No partitioning detected. Use default */ |
140 | if (i == 2) { | 141 | if (i == 2) { |
141 | add_mtd_device(sbcmtd[i]); | 142 | mtd_device_register(sbcmtd[i], NULL, 0); |
142 | } else if (i == bigflash) { | 143 | } else if (i == bigflash) { |
143 | add_mtd_partitions (sbcmtd[i], bigflash_parts, ARRAY_SIZE(bigflash_parts)); | 144 | mtd_device_register(sbcmtd[i], bigflash_parts, |
145 | ARRAY_SIZE(bigflash_parts)); | ||
144 | } else { | 146 | } else { |
145 | add_mtd_partitions (sbcmtd[i], smallflash_parts, ARRAY_SIZE(smallflash_parts)); | 147 | mtd_device_register(sbcmtd[i], smallflash_parts, |
148 | ARRAY_SIZE(smallflash_parts)); | ||
146 | } | 149 | } |
147 | } | 150 | } |
148 | return 0; | 151 | return 0; |
@@ -157,9 +160,9 @@ static void __exit cleanup_sbc82xx_flash(void) | |||
157 | continue; | 160 | continue; |
158 | 161 | ||
159 | if (i<2 || sbcmtd_parts[i]) | 162 | if (i<2 || sbcmtd_parts[i]) |
160 | del_mtd_partitions(sbcmtd[i]); | 163 | mtd_device_unregister(sbcmtd[i]); |
161 | else | 164 | else |
162 | del_mtd_device(sbcmtd[i]); | 165 | mtd_device_unregister(sbcmtd[i]); |
163 | 166 | ||
164 | kfree(sbcmtd_parts[i]); | 167 | kfree(sbcmtd_parts[i]); |
165 | map_destroy(sbcmtd[i]); | 168 | map_destroy(sbcmtd[i]); |
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index a534e1f0c348..ca385697446e 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c | |||
@@ -221,15 +221,33 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) | |||
221 | kref_get(&dev->ref); | 221 | kref_get(&dev->ref); |
222 | __module_get(dev->tr->owner); | 222 | __module_get(dev->tr->owner); |
223 | 223 | ||
224 | if (dev->mtd) { | 224 | if (!dev->mtd) |
225 | ret = dev->tr->open ? dev->tr->open(dev) : 0; | 225 | goto unlock; |
226 | __get_mtd_device(dev->mtd); | 226 | |
227 | if (dev->tr->open) { | ||
228 | ret = dev->tr->open(dev); | ||
229 | if (ret) | ||
230 | goto error_put; | ||
227 | } | 231 | } |
228 | 232 | ||
233 | ret = __get_mtd_device(dev->mtd); | ||
234 | if (ret) | ||
235 | goto error_release; | ||
236 | |||
229 | unlock: | 237 | unlock: |
230 | mutex_unlock(&dev->lock); | 238 | mutex_unlock(&dev->lock); |
231 | blktrans_dev_put(dev); | 239 | blktrans_dev_put(dev); |
232 | return ret; | 240 | return ret; |
241 | |||
242 | error_release: | ||
243 | if (dev->tr->release) | ||
244 | dev->tr->release(dev); | ||
245 | error_put: | ||
246 | module_put(dev->tr->owner); | ||
247 | kref_put(&dev->ref, blktrans_dev_release); | ||
248 | mutex_unlock(&dev->lock); | ||
249 | blktrans_dev_put(dev); | ||
250 | return ret; | ||
233 | } | 251 | } |
234 | 252 | ||
235 | static int blktrans_release(struct gendisk *disk, fmode_t mode) | 253 | static int blktrans_release(struct gendisk *disk, fmode_t mode) |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 4c36ef66a46b..3f92731a5b9e 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -166,10 +166,23 @@ static int mtd_close(struct inode *inode, struct file *file) | |||
166 | return 0; | 166 | return 0; |
167 | } /* mtd_close */ | 167 | } /* mtd_close */ |
168 | 168 | ||
169 | /* FIXME: This _really_ needs to die. In 2.5, we should lock the | 169 | /* Back in June 2001, dwmw2 wrote: |
170 | userspace buffer down and use it directly with readv/writev. | 170 | * |
171 | */ | 171 | * FIXME: This _really_ needs to die. In 2.5, we should lock the |
172 | #define MAX_KMALLOC_SIZE 0x20000 | 172 | * userspace buffer down and use it directly with readv/writev. |
173 | * | ||
174 | * The implementation below, using mtd_kmalloc_up_to, mitigates | ||
175 | * allocation failures when the system is under low-memory situations | ||
176 | * or if memory is highly fragmented at the cost of reducing the | ||
177 | * performance of the requested transfer due to a smaller buffer size. | ||
178 | * | ||
179 | * A more complex but more memory-efficient implementation based on | ||
180 | * get_user_pages and iovecs to cover extents of those pages is a | ||
181 | * longer-term goal, as intimated by dwmw2 above. However, for the | ||
182 | * write case, this requires yet more complex head and tail transfer | ||
183 | * handling when those head and tail offsets and sizes are such that | ||
184 | * alignment requirements are not met in the NAND subdriver. | ||
185 | */ | ||
173 | 186 | ||
174 | static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) | 187 | static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) |
175 | { | 188 | { |
@@ -179,6 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
179 | size_t total_retlen=0; | 192 | size_t total_retlen=0; |
180 | int ret=0; | 193 | int ret=0; |
181 | int len; | 194 | int len; |
195 | size_t size = count; | ||
182 | char *kbuf; | 196 | char *kbuf; |
183 | 197 | ||
184 | DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); | 198 | DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); |
@@ -189,23 +203,12 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
189 | if (!count) | 203 | if (!count) |
190 | return 0; | 204 | return 0; |
191 | 205 | ||
192 | /* FIXME: Use kiovec in 2.5 to lock down the user's buffers | 206 | kbuf = mtd_kmalloc_up_to(mtd, &size); |
193 | and pass them directly to the MTD functions */ | ||
194 | |||
195 | if (count > MAX_KMALLOC_SIZE) | ||
196 | kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL); | ||
197 | else | ||
198 | kbuf=kmalloc(count, GFP_KERNEL); | ||
199 | |||
200 | if (!kbuf) | 207 | if (!kbuf) |
201 | return -ENOMEM; | 208 | return -ENOMEM; |
202 | 209 | ||
203 | while (count) { | 210 | while (count) { |
204 | 211 | len = min_t(size_t, count, size); | |
205 | if (count > MAX_KMALLOC_SIZE) | ||
206 | len = MAX_KMALLOC_SIZE; | ||
207 | else | ||
208 | len = count; | ||
209 | 212 | ||
210 | switch (mfi->mode) { | 213 | switch (mfi->mode) { |
211 | case MTD_MODE_OTP_FACTORY: | 214 | case MTD_MODE_OTP_FACTORY: |
@@ -268,6 +271,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count | |||
268 | { | 271 | { |
269 | struct mtd_file_info *mfi = file->private_data; | 272 | struct mtd_file_info *mfi = file->private_data; |
270 | struct mtd_info *mtd = mfi->mtd; | 273 | struct mtd_info *mtd = mfi->mtd; |
274 | size_t size = count; | ||
271 | char *kbuf; | 275 | char *kbuf; |
272 | size_t retlen; | 276 | size_t retlen; |
273 | size_t total_retlen=0; | 277 | size_t total_retlen=0; |
@@ -285,20 +289,12 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count | |||
285 | if (!count) | 289 | if (!count) |
286 | return 0; | 290 | return 0; |
287 | 291 | ||
288 | if (count > MAX_KMALLOC_SIZE) | 292 | kbuf = mtd_kmalloc_up_to(mtd, &size); |
289 | kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL); | ||
290 | else | ||
291 | kbuf=kmalloc(count, GFP_KERNEL); | ||
292 | |||
293 | if (!kbuf) | 293 | if (!kbuf) |
294 | return -ENOMEM; | 294 | return -ENOMEM; |
295 | 295 | ||
296 | while (count) { | 296 | while (count) { |
297 | 297 | len = min_t(size_t, count, size); | |
298 | if (count > MAX_KMALLOC_SIZE) | ||
299 | len = MAX_KMALLOC_SIZE; | ||
300 | else | ||
301 | len = count; | ||
302 | 298 | ||
303 | if (copy_from_user(kbuf, buf, len)) { | 299 | if (copy_from_user(kbuf, buf, len)) { |
304 | kfree(kbuf); | 300 | kfree(kbuf); |
@@ -512,7 +508,6 @@ static int shrink_ecclayout(const struct nand_ecclayout *from, | |||
512 | return 0; | 508 | return 0; |
513 | } | 509 | } |
514 | 510 | ||
515 | #ifdef CONFIG_MTD_PARTITIONS | ||
516 | static int mtd_blkpg_ioctl(struct mtd_info *mtd, | 511 | static int mtd_blkpg_ioctl(struct mtd_info *mtd, |
517 | struct blkpg_ioctl_arg __user *arg) | 512 | struct blkpg_ioctl_arg __user *arg) |
518 | { | 513 | { |
@@ -548,8 +543,6 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd, | |||
548 | return -EINVAL; | 543 | return -EINVAL; |
549 | } | 544 | } |
550 | } | 545 | } |
551 | #endif | ||
552 | |||
553 | 546 | ||
554 | static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) | 547 | static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) |
555 | { | 548 | { |
@@ -941,7 +934,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) | |||
941 | break; | 934 | break; |
942 | } | 935 | } |
943 | 936 | ||
944 | #ifdef CONFIG_MTD_PARTITIONS | ||
945 | case BLKPG: | 937 | case BLKPG: |
946 | { | 938 | { |
947 | ret = mtd_blkpg_ioctl(mtd, | 939 | ret = mtd_blkpg_ioctl(mtd, |
@@ -955,7 +947,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) | |||
955 | ret = 0; | 947 | ret = 0; |
956 | break; | 948 | break; |
957 | } | 949 | } |
958 | #endif | ||
959 | 950 | ||
960 | default: | 951 | default: |
961 | ret = -ENOTTY; | 952 | ret = -ENOTTY; |
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 5060e608ea5d..e601672a5305 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c | |||
@@ -319,7 +319,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) | |||
319 | if (!(mtd->flags & MTD_WRITEABLE)) | 319 | if (!(mtd->flags & MTD_WRITEABLE)) |
320 | return -EROFS; | 320 | return -EROFS; |
321 | 321 | ||
322 | ops->retlen = 0; | 322 | ops->retlen = ops->oobretlen = 0; |
323 | 323 | ||
324 | for (i = 0; i < concat->num_subdev; i++) { | 324 | for (i = 0; i < concat->num_subdev; i++) { |
325 | struct mtd_info *subdev = concat->subdev[i]; | 325 | struct mtd_info *subdev = concat->subdev[i]; |
@@ -334,7 +334,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) | |||
334 | devops.len = subdev->size - to; | 334 | devops.len = subdev->size - to; |
335 | 335 | ||
336 | err = subdev->write_oob(subdev, to, &devops); | 336 | err = subdev->write_oob(subdev, to, &devops); |
337 | ops->retlen += devops.retlen; | 337 | ops->retlen += devops.oobretlen; |
338 | if (err) | 338 | if (err) |
339 | return err; | 339 | return err; |
340 | 340 | ||
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index da69bc8a5a7d..c510aff289a8 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/ptrace.h> | 26 | #include <linux/ptrace.h> |
27 | #include <linux/seq_file.h> | ||
27 | #include <linux/string.h> | 28 | #include <linux/string.h> |
28 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
29 | #include <linux/major.h> | 30 | #include <linux/major.h> |
@@ -37,6 +38,7 @@ | |||
37 | #include <linux/gfp.h> | 38 | #include <linux/gfp.h> |
38 | 39 | ||
39 | #include <linux/mtd/mtd.h> | 40 | #include <linux/mtd/mtd.h> |
41 | #include <linux/mtd/partitions.h> | ||
40 | 42 | ||
41 | #include "mtdcore.h" | 43 | #include "mtdcore.h" |
42 | /* | 44 | /* |
@@ -391,7 +393,7 @@ fail_locked: | |||
391 | * if the requested device does not appear to be present in the list. | 393 | * if the requested device does not appear to be present in the list. |
392 | */ | 394 | */ |
393 | 395 | ||
394 | int del_mtd_device (struct mtd_info *mtd) | 396 | int del_mtd_device(struct mtd_info *mtd) |
395 | { | 397 | { |
396 | int ret; | 398 | int ret; |
397 | struct mtd_notifier *not; | 399 | struct mtd_notifier *not; |
@@ -427,6 +429,50 @@ out_error: | |||
427 | } | 429 | } |
428 | 430 | ||
429 | /** | 431 | /** |
432 | * mtd_device_register - register an MTD device. | ||
433 | * | ||
434 | * @master: the MTD device to register | ||
435 | * @parts: the partitions to register - only valid if nr_parts > 0 | ||
436 | * @nr_parts: the number of partitions in parts. If zero then the full MTD | ||
437 | * device is registered | ||
438 | * | ||
439 | * Register an MTD device with the system and optionally, a number of | ||
440 | * partitions. If nr_parts is 0 then the whole device is registered, otherwise | ||
441 | * only the partitions are registered. To register both the full device *and* | ||
442 | * the partitions, call mtd_device_register() twice, once with nr_parts == 0 | ||
443 | * and once equal to the number of partitions. | ||
444 | */ | ||
445 | int mtd_device_register(struct mtd_info *master, | ||
446 | const struct mtd_partition *parts, | ||
447 | int nr_parts) | ||
448 | { | ||
449 | return parts ? add_mtd_partitions(master, parts, nr_parts) : | ||
450 | add_mtd_device(master); | ||
451 | } | ||
452 | EXPORT_SYMBOL_GPL(mtd_device_register); | ||
453 | |||
454 | /** | ||
455 | * mtd_device_unregister - unregister an existing MTD device. | ||
456 | * | ||
457 | * @master: the MTD device to unregister. This will unregister both the master | ||
458 | * and any partitions if registered. | ||
459 | */ | ||
460 | int mtd_device_unregister(struct mtd_info *master) | ||
461 | { | ||
462 | int err; | ||
463 | |||
464 | err = del_mtd_partitions(master); | ||
465 | if (err) | ||
466 | return err; | ||
467 | |||
468 | if (!device_is_registered(&master->dev)) | ||
469 | return 0; | ||
470 | |||
471 | return del_mtd_device(master); | ||
472 | } | ||
473 | EXPORT_SYMBOL_GPL(mtd_device_unregister); | ||
474 | |||
475 | /** | ||
430 | * register_mtd_user - register a 'user' of MTD devices. | 476 | * register_mtd_user - register a 'user' of MTD devices. |
431 | * @new: pointer to notifier info structure | 477 | * @new: pointer to notifier info structure |
432 | * | 478 | * |
@@ -443,7 +489,7 @@ void register_mtd_user (struct mtd_notifier *new) | |||
443 | 489 | ||
444 | list_add(&new->list, &mtd_notifiers); | 490 | list_add(&new->list, &mtd_notifiers); |
445 | 491 | ||
446 | __module_get(THIS_MODULE); | 492 | __module_get(THIS_MODULE); |
447 | 493 | ||
448 | mtd_for_each_device(mtd) | 494 | mtd_for_each_device(mtd) |
449 | new->add(mtd); | 495 | new->add(mtd); |
@@ -532,7 +578,6 @@ int __get_mtd_device(struct mtd_info *mtd) | |||
532 | return -ENODEV; | 578 | return -ENODEV; |
533 | 579 | ||
534 | if (mtd->get_device) { | 580 | if (mtd->get_device) { |
535 | |||
536 | err = mtd->get_device(mtd); | 581 | err = mtd->get_device(mtd); |
537 | 582 | ||
538 | if (err) { | 583 | if (err) { |
@@ -570,21 +615,13 @@ struct mtd_info *get_mtd_device_nm(const char *name) | |||
570 | if (!mtd) | 615 | if (!mtd) |
571 | goto out_unlock; | 616 | goto out_unlock; |
572 | 617 | ||
573 | if (!try_module_get(mtd->owner)) | 618 | err = __get_mtd_device(mtd); |
619 | if (err) | ||
574 | goto out_unlock; | 620 | goto out_unlock; |
575 | 621 | ||
576 | if (mtd->get_device) { | ||
577 | err = mtd->get_device(mtd); | ||
578 | if (err) | ||
579 | goto out_put; | ||
580 | } | ||
581 | |||
582 | mtd->usecount++; | ||
583 | mutex_unlock(&mtd_table_mutex); | 622 | mutex_unlock(&mtd_table_mutex); |
584 | return mtd; | 623 | return mtd; |
585 | 624 | ||
586 | out_put: | ||
587 | module_put(mtd->owner); | ||
588 | out_unlock: | 625 | out_unlock: |
589 | mutex_unlock(&mtd_table_mutex); | 626 | mutex_unlock(&mtd_table_mutex); |
590 | return ERR_PTR(err); | 627 | return ERR_PTR(err); |
@@ -638,8 +675,54 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | |||
638 | return ret; | 675 | return ret; |
639 | } | 676 | } |
640 | 677 | ||
641 | EXPORT_SYMBOL_GPL(add_mtd_device); | 678 | /** |
642 | EXPORT_SYMBOL_GPL(del_mtd_device); | 679 | * mtd_kmalloc_up_to - allocate a contiguous buffer up to the specified size |
680 | * @size: A pointer to the ideal or maximum size of the allocation. Points | ||
681 | * to the actual allocation size on success. | ||
682 | * | ||
683 | * This routine attempts to allocate a contiguous kernel buffer up to | ||
684 | * the specified size, backing off the size of the request exponentially | ||
685 | * until the request succeeds or until the allocation size falls below | ||
686 | * the system page size. This attempts to make sure it does not adversely | ||
687 | * impact system performance, so when allocating more than one page, we | ||
688 | * ask the memory allocator to avoid re-trying, swapping, writing back | ||
689 | * or performing I/O. | ||
690 | * | ||
691 | * Note, this function also makes sure that the allocated buffer is aligned to | ||
692 | * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value. | ||
693 | * | ||
694 | * This is called, for example by mtd_{read,write} and jffs2_scan_medium, | ||
695 | * to handle smaller (i.e. degraded) buffer allocations under low- or | ||
696 | * fragmented-memory situations where such reduced allocations, from a | ||
697 | * requested ideal, are allowed. | ||
698 | * | ||
699 | * Returns a pointer to the allocated buffer on success; otherwise, NULL. | ||
700 | */ | ||
701 | void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) | ||
702 | { | ||
703 | gfp_t flags = __GFP_NOWARN | __GFP_WAIT | | ||
704 | __GFP_NORETRY | __GFP_NO_KSWAPD; | ||
705 | size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); | ||
706 | void *kbuf; | ||
707 | |||
708 | *size = min_t(size_t, *size, KMALLOC_MAX_SIZE); | ||
709 | |||
710 | while (*size > min_alloc) { | ||
711 | kbuf = kmalloc(*size, flags); | ||
712 | if (kbuf) | ||
713 | return kbuf; | ||
714 | |||
715 | *size >>= 1; | ||
716 | *size = ALIGN(*size, mtd->writesize); | ||
717 | } | ||
718 | |||
719 | /* | ||
720 | * For the last resort allocation allow 'kmalloc()' to do all sorts of | ||
721 | * things (write-back, dropping caches, etc) by using GFP_KERNEL. | ||
722 | */ | ||
723 | return kmalloc(*size, GFP_KERNEL); | ||
724 | } | ||
725 | |||
643 | EXPORT_SYMBOL_GPL(get_mtd_device); | 726 | EXPORT_SYMBOL_GPL(get_mtd_device); |
644 | EXPORT_SYMBOL_GPL(get_mtd_device_nm); | 727 | EXPORT_SYMBOL_GPL(get_mtd_device_nm); |
645 | EXPORT_SYMBOL_GPL(__get_mtd_device); | 728 | EXPORT_SYMBOL_GPL(__get_mtd_device); |
@@ -648,6 +731,7 @@ EXPORT_SYMBOL_GPL(__put_mtd_device); | |||
648 | EXPORT_SYMBOL_GPL(register_mtd_user); | 731 | EXPORT_SYMBOL_GPL(register_mtd_user); |
649 | EXPORT_SYMBOL_GPL(unregister_mtd_user); | 732 | EXPORT_SYMBOL_GPL(unregister_mtd_user); |
650 | EXPORT_SYMBOL_GPL(default_mtd_writev); | 733 | EXPORT_SYMBOL_GPL(default_mtd_writev); |
734 | EXPORT_SYMBOL_GPL(mtd_kmalloc_up_to); | ||
651 | 735 | ||
652 | #ifdef CONFIG_PROC_FS | 736 | #ifdef CONFIG_PROC_FS |
653 | 737 | ||
@@ -656,44 +740,32 @@ EXPORT_SYMBOL_GPL(default_mtd_writev); | |||
656 | 740 | ||
657 | static struct proc_dir_entry *proc_mtd; | 741 | static struct proc_dir_entry *proc_mtd; |
658 | 742 | ||
659 | static inline int mtd_proc_info(char *buf, struct mtd_info *this) | 743 | static int mtd_proc_show(struct seq_file *m, void *v) |
660 | { | ||
661 | return sprintf(buf, "mtd%d: %8.8llx %8.8x \"%s\"\n", this->index, | ||
662 | (unsigned long long)this->size, | ||
663 | this->erasesize, this->name); | ||
664 | } | ||
665 | |||
666 | static int mtd_read_proc (char *page, char **start, off_t off, int count, | ||
667 | int *eof, void *data_unused) | ||
668 | { | 744 | { |
669 | struct mtd_info *mtd; | 745 | struct mtd_info *mtd; |
670 | int len, l; | ||
671 | off_t begin = 0; | ||
672 | 746 | ||
747 | seq_puts(m, "dev: size erasesize name\n"); | ||
673 | mutex_lock(&mtd_table_mutex); | 748 | mutex_lock(&mtd_table_mutex); |
674 | |||
675 | len = sprintf(page, "dev: size erasesize name\n"); | ||
676 | mtd_for_each_device(mtd) { | 749 | mtd_for_each_device(mtd) { |
677 | l = mtd_proc_info(page + len, mtd); | 750 | seq_printf(m, "mtd%d: %8.8llx %8.8x \"%s\"\n", |
678 | len += l; | 751 | mtd->index, (unsigned long long)mtd->size, |
679 | if (len+begin > off+count) | 752 | mtd->erasesize, mtd->name); |
680 | goto done; | 753 | } |
681 | if (len+begin < off) { | ||
682 | begin += len; | ||
683 | len = 0; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | *eof = 1; | ||
688 | |||
689 | done: | ||
690 | mutex_unlock(&mtd_table_mutex); | 754 | mutex_unlock(&mtd_table_mutex); |
691 | if (off >= len+begin) | 755 | return 0; |
692 | return 0; | 756 | } |
693 | *start = page + (off-begin); | 757 | |
694 | return ((count < begin+len-off) ? count : begin+len-off); | 758 | static int mtd_proc_open(struct inode *inode, struct file *file) |
759 | { | ||
760 | return single_open(file, mtd_proc_show, NULL); | ||
695 | } | 761 | } |
696 | 762 | ||
763 | static const struct file_operations mtd_proc_ops = { | ||
764 | .open = mtd_proc_open, | ||
765 | .read = seq_read, | ||
766 | .llseek = seq_lseek, | ||
767 | .release = single_release, | ||
768 | }; | ||
697 | #endif /* CONFIG_PROC_FS */ | 769 | #endif /* CONFIG_PROC_FS */ |
698 | 770 | ||
699 | /*====================================================================*/ | 771 | /*====================================================================*/ |
@@ -734,8 +806,7 @@ static int __init init_mtd(void) | |||
734 | goto err_bdi3; | 806 | goto err_bdi3; |
735 | 807 | ||
736 | #ifdef CONFIG_PROC_FS | 808 | #ifdef CONFIG_PROC_FS |
737 | if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) | 809 | proc_mtd = proc_create("mtd", 0, NULL, &mtd_proc_ops); |
738 | proc_mtd->read_proc = mtd_read_proc; | ||
739 | #endif /* CONFIG_PROC_FS */ | 810 | #endif /* CONFIG_PROC_FS */ |
740 | return 0; | 811 | return 0; |
741 | 812 | ||
@@ -753,7 +824,7 @@ err_reg: | |||
753 | static void __exit cleanup_mtd(void) | 824 | static void __exit cleanup_mtd(void) |
754 | { | 825 | { |
755 | #ifdef CONFIG_PROC_FS | 826 | #ifdef CONFIG_PROC_FS |
756 | if (proc_mtd) | 827 | if (proc_mtd) |
757 | remove_proc_entry( "mtd", NULL); | 828 | remove_proc_entry( "mtd", NULL); |
758 | #endif /* CONFIG_PROC_FS */ | 829 | #endif /* CONFIG_PROC_FS */ |
759 | class_unregister(&mtd_class); | 830 | class_unregister(&mtd_class); |
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 6a64fdebc898..0ed6126b4c1f 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h | |||
@@ -10,6 +10,12 @@ | |||
10 | extern struct mutex mtd_table_mutex; | 10 | extern struct mutex mtd_table_mutex; |
11 | extern struct mtd_info *__mtd_next_device(int i); | 11 | extern struct mtd_info *__mtd_next_device(int i); |
12 | 12 | ||
13 | extern int add_mtd_device(struct mtd_info *mtd); | ||
14 | extern int del_mtd_device(struct mtd_info *mtd); | ||
15 | extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, | ||
16 | int); | ||
17 | extern int del_mtd_partitions(struct mtd_info *); | ||
18 | |||
13 | #define mtd_for_each_device(mtd) \ | 19 | #define mtd_for_each_device(mtd) \ |
14 | for ((mtd) = __mtd_next_device(0); \ | 20 | for ((mtd) = __mtd_next_device(0); \ |
15 | (mtd) != NULL; \ | 21 | (mtd) != NULL; \ |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 0a4760174782..630be3e7da04 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/mtd/partitions.h> | 31 | #include <linux/mtd/partitions.h> |
32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
33 | 33 | ||
34 | #include "mtdcore.h" | ||
35 | |||
34 | /* Our partition linked list */ | 36 | /* Our partition linked list */ |
35 | static LIST_HEAD(mtd_partitions); | 37 | static LIST_HEAD(mtd_partitions); |
36 | static DEFINE_MUTEX(mtd_partitions_mutex); | 38 | static DEFINE_MUTEX(mtd_partitions_mutex); |
@@ -376,7 +378,6 @@ int del_mtd_partitions(struct mtd_info *master) | |||
376 | 378 | ||
377 | return err; | 379 | return err; |
378 | } | 380 | } |
379 | EXPORT_SYMBOL(del_mtd_partitions); | ||
380 | 381 | ||
381 | static struct mtd_part *allocate_partition(struct mtd_info *master, | 382 | static struct mtd_part *allocate_partition(struct mtd_info *master, |
382 | const struct mtd_partition *part, int partno, | 383 | const struct mtd_partition *part, int partno, |
@@ -671,7 +672,6 @@ int add_mtd_partitions(struct mtd_info *master, | |||
671 | 672 | ||
672 | return 0; | 673 | return 0; |
673 | } | 674 | } |
674 | EXPORT_SYMBOL(add_mtd_partitions); | ||
675 | 675 | ||
676 | static DEFINE_SPINLOCK(part_parser_lock); | 676 | static DEFINE_SPINLOCK(part_parser_lock); |
677 | static LIST_HEAD(part_parsers); | 677 | static LIST_HEAD(part_parsers); |
@@ -722,11 +722,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, | |||
722 | parser = get_partition_parser(*types); | 722 | parser = get_partition_parser(*types); |
723 | if (!parser && !request_module("%s", *types)) | 723 | if (!parser && !request_module("%s", *types)) |
724 | parser = get_partition_parser(*types); | 724 | parser = get_partition_parser(*types); |
725 | if (!parser) { | 725 | if (!parser) |
726 | printk(KERN_NOTICE "%s partition parsing not available\n", | ||
727 | *types); | ||
728 | continue; | 726 | continue; |
729 | } | ||
730 | ret = (*parser->parse_fn)(master, pparts, origin); | 727 | ret = (*parser->parse_fn)(master, pparts, origin); |
731 | if (ret > 0) { | 728 | if (ret > 0) { |
732 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", | 729 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", |
diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index fed215c4cfa1..fd7885327611 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c | |||
@@ -1450,7 +1450,13 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) | |||
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | oinfo = mtd->ecclayout; | 1452 | oinfo = mtd->ecclayout; |
1453 | if (!mtd->oobsize || !oinfo || oinfo->oobavail < MTDSWAP_OOBSIZE) { | 1453 | if (!oinfo) { |
1454 | printk(KERN_ERR "%s: mtd%d does not have OOB\n", | ||
1455 | MTDSWAP_PREFIX, mtd->index); | ||
1456 | return; | ||
1457 | } | ||
1458 | |||
1459 | if (!mtd->oobsize || oinfo->oobavail < MTDSWAP_OOBSIZE) { | ||
1454 | printk(KERN_ERR "%s: Not enough free bytes in OOB, " | 1460 | printk(KERN_ERR "%s: Not enough free bytes in OOB, " |
1455 | "%d available, %zu needed.\n", | 1461 | "%d available, %zu needed.\n", |
1456 | MTDSWAP_PREFIX, oinfo->oobavail, MTDSWAP_OOBSIZE); | 1462 | MTDSWAP_PREFIX, oinfo->oobavail, MTDSWAP_OOBSIZE); |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index edec457d361d..4c3425235adc 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -92,7 +92,7 @@ config MTD_NAND_EDB7312 | |||
92 | 92 | ||
93 | config MTD_NAND_H1900 | 93 | config MTD_NAND_H1900 |
94 | tristate "iPAQ H1900 flash" | 94 | tristate "iPAQ H1900 flash" |
95 | depends on ARCH_PXA && MTD_PARTITIONS | 95 | depends on ARCH_PXA |
96 | help | 96 | help |
97 | This enables the driver for the iPAQ h1900 flash. | 97 | This enables the driver for the iPAQ h1900 flash. |
98 | 98 | ||
@@ -419,7 +419,6 @@ config MTD_NAND_TMIO | |||
419 | 419 | ||
420 | config MTD_NAND_NANDSIM | 420 | config MTD_NAND_NANDSIM |
421 | tristate "Support for NAND Flash Simulator" | 421 | tristate "Support for NAND Flash Simulator" |
422 | depends on MTD_PARTITIONS | ||
423 | help | 422 | help |
424 | The simulator may simulate various NAND flash chips for the | 423 | The simulator may simulate various NAND flash chips for the |
425 | MTD nand layer. | 424 | MTD nand layer. |
@@ -513,7 +512,7 @@ config MTD_NAND_SOCRATES | |||
513 | 512 | ||
514 | config MTD_NAND_NUC900 | 513 | config MTD_NAND_NUC900 |
515 | tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards." | 514 | tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards." |
516 | depends on ARCH_W90X900 && MTD_PARTITIONS | 515 | depends on ARCH_W90X900 |
517 | help | 516 | help |
518 | This enables the driver for the NAND Flash on evaluation board based | 517 | This enables the driver for the NAND Flash on evaluation board based |
519 | on w90p910 / NUC9xx. | 518 | on w90p910 / NUC9xx. |
diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c index 8691e0482ed2..eb40ea829ab2 100644 --- a/drivers/mtd/nand/alauda.c +++ b/drivers/mtd/nand/alauda.c | |||
@@ -120,7 +120,7 @@ static void alauda_delete(struct kref *kref) | |||
120 | struct alauda *al = container_of(kref, struct alauda, kref); | 120 | struct alauda *al = container_of(kref, struct alauda, kref); |
121 | 121 | ||
122 | if (al->mtd) { | 122 | if (al->mtd) { |
123 | del_mtd_device(al->mtd); | 123 | mtd_device_unregister(al->mtd); |
124 | kfree(al->mtd); | 124 | kfree(al->mtd); |
125 | } | 125 | } |
126 | usb_put_dev(al->dev); | 126 | usb_put_dev(al->dev); |
@@ -592,7 +592,7 @@ static int alauda_init_media(struct alauda *al) | |||
592 | mtd->priv = al; | 592 | mtd->priv = al; |
593 | mtd->owner = THIS_MODULE; | 593 | mtd->owner = THIS_MODULE; |
594 | 594 | ||
595 | err = add_mtd_device(mtd); | 595 | err = mtd_device_register(mtd, NULL, 0); |
596 | if (err) { | 596 | if (err) { |
597 | err = -ENFILE; | 597 | err = -ENFILE; |
598 | goto error; | 598 | goto error; |
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index bc65bf71e1a2..78017eb9318e 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -235,8 +235,8 @@ static int __devinit ams_delta_init(struct platform_device *pdev) | |||
235 | } | 235 | } |
236 | 236 | ||
237 | /* Register the partitions */ | 237 | /* Register the partitions */ |
238 | add_mtd_partitions(ams_delta_mtd, partition_info, | 238 | mtd_device_register(ams_delta_mtd, partition_info, |
239 | ARRAY_SIZE(partition_info)); | 239 | ARRAY_SIZE(partition_info)); |
240 | 240 | ||
241 | goto out; | 241 | goto out; |
242 | 242 | ||
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 950646aa4c4b..b300705d41cb 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mtd/nand.h> | 30 | #include <linux/mtd/nand.h> |
31 | #include <linux/mtd/partitions.h> | 31 | #include <linux/mtd/partitions.h> |
32 | 32 | ||
33 | #include <linux/dmaengine.h> | ||
33 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
34 | #include <linux/io.h> | 35 | #include <linux/io.h> |
35 | 36 | ||
@@ -494,11 +495,8 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
494 | struct resource *regs; | 495 | struct resource *regs; |
495 | struct resource *mem; | 496 | struct resource *mem; |
496 | int res; | 497 | int res; |
497 | |||
498 | #ifdef CONFIG_MTD_PARTITIONS | ||
499 | struct mtd_partition *partitions = NULL; | 498 | struct mtd_partition *partitions = NULL; |
500 | int num_partitions = 0; | 499 | int num_partitions = 0; |
501 | #endif | ||
502 | 500 | ||
503 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 501 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
504 | if (!mem) { | 502 | if (!mem) { |
@@ -656,7 +654,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
656 | goto err_scan_tail; | 654 | goto err_scan_tail; |
657 | } | 655 | } |
658 | 656 | ||
659 | #ifdef CONFIG_MTD_PARTITIONS | ||
660 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 657 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
661 | mtd->name = "atmel_nand"; | 658 | mtd->name = "atmel_nand"; |
662 | num_partitions = parse_mtd_partitions(mtd, part_probes, | 659 | num_partitions = parse_mtd_partitions(mtd, part_probes, |
@@ -672,17 +669,11 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
672 | goto err_no_partitions; | 669 | goto err_no_partitions; |
673 | } | 670 | } |
674 | 671 | ||
675 | res = add_mtd_partitions(mtd, partitions, num_partitions); | 672 | res = mtd_device_register(mtd, partitions, num_partitions); |
676 | #else | ||
677 | res = add_mtd_device(mtd); | ||
678 | #endif | ||
679 | |||
680 | if (!res) | 673 | if (!res) |
681 | return res; | 674 | return res; |
682 | 675 | ||
683 | #ifdef CONFIG_MTD_PARTITIONS | ||
684 | err_no_partitions: | 676 | err_no_partitions: |
685 | #endif | ||
686 | nand_release(mtd); | 677 | nand_release(mtd); |
687 | err_scan_tail: | 678 | err_scan_tail: |
688 | err_scan_ident: | 679 | err_scan_ident: |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 5d513b54a7d7..e7767eef4505 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -581,7 +581,8 @@ static int __init au1xxx_nand_init(void) | |||
581 | } | 581 | } |
582 | 582 | ||
583 | /* Register the partitions */ | 583 | /* Register the partitions */ |
584 | add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info)); | 584 | mtd_device_register(au1550_mtd, partition_info, |
585 | ARRAY_SIZE(partition_info)); | ||
585 | 586 | ||
586 | return 0; | 587 | return 0; |
587 | 588 | ||
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c index 0911cf03db80..eddc9a224985 100644 --- a/drivers/mtd/nand/autcpu12.c +++ b/drivers/mtd/nand/autcpu12.c | |||
@@ -185,20 +185,20 @@ static int __init autcpu12_init(void) | |||
185 | /* Register the partitions */ | 185 | /* Register the partitions */ |
186 | switch (autcpu12_mtd->size) { | 186 | switch (autcpu12_mtd->size) { |
187 | case SZ_16M: | 187 | case SZ_16M: |
188 | add_mtd_partitions(autcpu12_mtd, partition_info16k, | 188 | mtd_device_register(autcpu12_mtd, partition_info16k, |
189 | NUM_PARTITIONS16K); | 189 | NUM_PARTITIONS16K); |
190 | break; | 190 | break; |
191 | case SZ_32M: | 191 | case SZ_32M: |
192 | add_mtd_partitions(autcpu12_mtd, partition_info32k, | 192 | mtd_device_register(autcpu12_mtd, partition_info32k, |
193 | NUM_PARTITIONS32K); | 193 | NUM_PARTITIONS32K); |
194 | break; | 194 | break; |
195 | case SZ_64M: | 195 | case SZ_64M: |
196 | add_mtd_partitions(autcpu12_mtd, partition_info64k, | 196 | mtd_device_register(autcpu12_mtd, partition_info64k, |
197 | NUM_PARTITIONS64K); | 197 | NUM_PARTITIONS64K); |
198 | break; | 198 | break; |
199 | case SZ_128M: | 199 | case SZ_128M: |
200 | add_mtd_partitions(autcpu12_mtd, partition_info128k, | 200 | mtd_device_register(autcpu12_mtd, partition_info128k, |
201 | NUM_PARTITIONS128K); | 201 | NUM_PARTITIONS128K); |
202 | break; | 202 | break; |
203 | default: | 203 | default: |
204 | printk("Unsupported SmartMedia device\n"); | 204 | printk("Unsupported SmartMedia device\n"); |
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index dfe262c726fb..9ec280738a9a 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c | |||
@@ -52,9 +52,7 @@ | |||
52 | static const __devinitconst char gBanner[] = KERN_INFO \ | 52 | static const __devinitconst char gBanner[] = KERN_INFO \ |
53 | "BCM UMI MTD NAND Driver: 1.00\n"; | 53 | "BCM UMI MTD NAND Driver: 1.00\n"; |
54 | 54 | ||
55 | #ifdef CONFIG_MTD_PARTITIONS | ||
56 | const char *part_probes[] = { "cmdlinepart", NULL }; | 55 | const char *part_probes[] = { "cmdlinepart", NULL }; |
57 | #endif | ||
58 | 56 | ||
59 | #if NAND_ECC_BCH | 57 | #if NAND_ECC_BCH |
60 | static uint8_t scan_ff_pattern[] = { 0xff }; | 58 | static uint8_t scan_ff_pattern[] = { 0xff }; |
@@ -509,7 +507,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) | |||
509 | kfree(board_mtd); | 507 | kfree(board_mtd); |
510 | return -EIO; | 508 | return -EIO; |
511 | } | 509 | } |
512 | add_mtd_partitions(board_mtd, partition_info, nr_partitions); | 510 | mtd_device_register(board_mtd, partition_info, nr_partitions); |
513 | } | 511 | } |
514 | 512 | ||
515 | /* Return happy */ | 513 | /* Return happy */ |
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 79947bea4d57..dd899cb5d366 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
@@ -659,15 +659,10 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) | |||
659 | static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) | 659 | static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) |
660 | { | 660 | { |
661 | struct mtd_info *mtd = &info->mtd; | 661 | struct mtd_info *mtd = &info->mtd; |
662 | |||
663 | #ifdef CONFIG_MTD_PARTITIONS | ||
664 | struct mtd_partition *parts = info->platform->partitions; | 662 | struct mtd_partition *parts = info->platform->partitions; |
665 | int nr = info->platform->nr_partitions; | 663 | int nr = info->platform->nr_partitions; |
666 | 664 | ||
667 | return add_mtd_partitions(mtd, parts, nr); | 665 | return mtd_device_register(mtd, parts, nr); |
668 | #else | ||
669 | return add_mtd_device(mtd); | ||
670 | #endif | ||
671 | } | 666 | } |
672 | 667 | ||
673 | static int __devexit bf5xx_nand_remove(struct platform_device *pdev) | 668 | static int __devexit bf5xx_nand_remove(struct platform_device *pdev) |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index e06c8983978e..87ebb4e5b0c3 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -90,9 +90,7 @@ static unsigned int numtimings; | |||
90 | static int timing[3]; | 90 | static int timing[3]; |
91 | module_param_array(timing, int, &numtimings, 0644); | 91 | module_param_array(timing, int, &numtimings, 0644); |
92 | 92 | ||
93 | #ifdef CONFIG_MTD_PARTITIONS | ||
94 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; | 93 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; |
95 | #endif | ||
96 | 94 | ||
97 | /* Hrm. Why isn't this already conditional on something in the struct device? */ | 95 | /* Hrm. Why isn't this already conditional on something in the struct device? */ |
98 | #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) | 96 | #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) |
@@ -632,10 +630,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
632 | struct cafe_priv *cafe; | 630 | struct cafe_priv *cafe; |
633 | uint32_t ctrl; | 631 | uint32_t ctrl; |
634 | int err = 0; | 632 | int err = 0; |
635 | #ifdef CONFIG_MTD_PARTITIONS | ||
636 | struct mtd_partition *parts; | 633 | struct mtd_partition *parts; |
637 | int nr_parts; | 634 | int nr_parts; |
638 | #endif | ||
639 | 635 | ||
640 | /* Very old versions shared the same PCI ident for all three | 636 | /* Very old versions shared the same PCI ident for all three |
641 | functions on the chip. Verify the class too... */ | 637 | functions on the chip. Verify the class too... */ |
@@ -804,9 +800,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
804 | pci_set_drvdata(pdev, mtd); | 800 | pci_set_drvdata(pdev, mtd); |
805 | 801 | ||
806 | /* We register the whole device first, separate from the partitions */ | 802 | /* We register the whole device first, separate from the partitions */ |
807 | add_mtd_device(mtd); | 803 | mtd_device_register(mtd, NULL, 0); |
808 | 804 | ||
809 | #ifdef CONFIG_MTD_PARTITIONS | ||
810 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 805 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
811 | mtd->name = "cafe_nand"; | 806 | mtd->name = "cafe_nand"; |
812 | #endif | 807 | #endif |
@@ -814,9 +809,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
814 | if (nr_parts > 0) { | 809 | if (nr_parts > 0) { |
815 | cafe->parts = parts; | 810 | cafe->parts = parts; |
816 | dev_info(&cafe->pdev->dev, "%d partitions found\n", nr_parts); | 811 | dev_info(&cafe->pdev->dev, "%d partitions found\n", nr_parts); |
817 | add_mtd_partitions(mtd, parts, nr_parts); | 812 | mtd_device_register(mtd, parts, nr_parts); |
818 | } | 813 | } |
819 | #endif | ||
820 | goto out; | 814 | goto out; |
821 | 815 | ||
822 | out_irq: | 816 | out_irq: |
@@ -838,7 +832,6 @@ static void __devexit cafe_nand_remove(struct pci_dev *pdev) | |||
838 | struct mtd_info *mtd = pci_get_drvdata(pdev); | 832 | struct mtd_info *mtd = pci_get_drvdata(pdev); |
839 | struct cafe_priv *cafe = mtd->priv; | 833 | struct cafe_priv *cafe = mtd->priv; |
840 | 834 | ||
841 | del_mtd_device(mtd); | ||
842 | /* Disable NAND IRQ in global IRQ mask register */ | 835 | /* Disable NAND IRQ in global IRQ mask register */ |
843 | cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); | 836 | cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); |
844 | free_irq(pdev->irq, mtd); | 837 | free_irq(pdev->irq, mtd); |
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 6e6495278258..6fc043a30d1e 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c | |||
@@ -238,7 +238,7 @@ static int __init cmx270_init(void) | |||
238 | 238 | ||
239 | /* Register the partitions */ | 239 | /* Register the partitions */ |
240 | pr_notice("Using %s partition definition\n", part_type); | 240 | pr_notice("Using %s partition definition\n", part_type); |
241 | ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb); | 241 | ret = mtd_device_register(cmx270_nand_mtd, mtd_parts, mtd_parts_nb); |
242 | if (ret) | 242 | if (ret) |
243 | goto err_scan; | 243 | goto err_scan; |
244 | 244 | ||
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 71c35a0b9826..f59ad1f2d5db 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
@@ -277,22 +277,15 @@ static int is_geode(void) | |||
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | |||
281 | #ifdef CONFIG_MTD_PARTITIONS | ||
282 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 280 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
283 | #endif | ||
284 | |||
285 | 281 | ||
286 | static int __init cs553x_init(void) | 282 | static int __init cs553x_init(void) |
287 | { | 283 | { |
288 | int err = -ENXIO; | 284 | int err = -ENXIO; |
289 | int i; | 285 | int i; |
290 | uint64_t val; | 286 | uint64_t val; |
291 | |||
292 | #ifdef CONFIG_MTD_PARTITIONS | ||
293 | int mtd_parts_nb = 0; | 287 | int mtd_parts_nb = 0; |
294 | struct mtd_partition *mtd_parts = NULL; | 288 | struct mtd_partition *mtd_parts = NULL; |
295 | #endif | ||
296 | 289 | ||
297 | /* If the CPU isn't a Geode GX or LX, abort */ | 290 | /* If the CPU isn't a Geode GX or LX, abort */ |
298 | if (!is_geode()) | 291 | if (!is_geode()) |
@@ -324,17 +317,11 @@ static int __init cs553x_init(void) | |||
324 | if (cs553x_mtd[i]) { | 317 | if (cs553x_mtd[i]) { |
325 | 318 | ||
326 | /* If any devices registered, return success. Else the last error. */ | 319 | /* If any devices registered, return success. Else the last error. */ |
327 | #ifdef CONFIG_MTD_PARTITIONS | ||
328 | mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0); | 320 | mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0); |
329 | if (mtd_parts_nb > 0) { | 321 | if (mtd_parts_nb > 0) |
330 | printk(KERN_NOTICE "Using command line partition definition\n"); | 322 | printk(KERN_NOTICE "Using command line partition definition\n"); |
331 | add_mtd_partitions(cs553x_mtd[i], mtd_parts, mtd_parts_nb); | 323 | mtd_device_register(cs553x_mtd[i], mtd_parts, |
332 | } else { | 324 | mtd_parts_nb); |
333 | add_mtd_device(cs553x_mtd[i]); | ||
334 | } | ||
335 | #else | ||
336 | add_mtd_device(cs553x_mtd[i]); | ||
337 | #endif | ||
338 | err = 0; | 325 | err = 0; |
339 | } | 326 | } |
340 | } | 327 | } |
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index aff3468867ac..1f34951ae1a7 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -530,6 +530,8 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
530 | int ret; | 530 | int ret; |
531 | uint32_t val; | 531 | uint32_t val; |
532 | nand_ecc_modes_t ecc_mode; | 532 | nand_ecc_modes_t ecc_mode; |
533 | struct mtd_partition *mtd_parts = NULL; | ||
534 | int mtd_parts_nb = 0; | ||
533 | 535 | ||
534 | /* insist on board-specific configuration */ | 536 | /* insist on board-specific configuration */ |
535 | if (!pdata) | 537 | if (!pdata) |
@@ -749,41 +751,33 @@ syndrome_done: | |||
749 | if (ret < 0) | 751 | if (ret < 0) |
750 | goto err_scan; | 752 | goto err_scan; |
751 | 753 | ||
752 | if (mtd_has_partitions()) { | 754 | if (mtd_has_cmdlinepart()) { |
753 | struct mtd_partition *mtd_parts = NULL; | 755 | static const char *probes[] __initconst = { |
754 | int mtd_parts_nb = 0; | 756 | "cmdlinepart", NULL |
757 | }; | ||
755 | 758 | ||
756 | if (mtd_has_cmdlinepart()) { | 759 | mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes, |
757 | static const char *probes[] __initconst = | 760 | &mtd_parts, 0); |
758 | { "cmdlinepart", NULL }; | 761 | } |
759 | |||
760 | mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes, | ||
761 | &mtd_parts, 0); | ||
762 | } | ||
763 | |||
764 | if (mtd_parts_nb <= 0) { | ||
765 | mtd_parts = pdata->parts; | ||
766 | mtd_parts_nb = pdata->nr_parts; | ||
767 | } | ||
768 | 762 | ||
769 | /* Register any partitions */ | 763 | if (mtd_parts_nb <= 0) { |
770 | if (mtd_parts_nb > 0) { | 764 | mtd_parts = pdata->parts; |
771 | ret = add_mtd_partitions(&info->mtd, | 765 | mtd_parts_nb = pdata->nr_parts; |
772 | mtd_parts, mtd_parts_nb); | 766 | } |
773 | if (ret == 0) | ||
774 | info->partitioned = true; | ||
775 | } | ||
776 | 767 | ||
777 | } else if (pdata->nr_parts) { | 768 | /* Register any partitions */ |
778 | dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n", | 769 | if (mtd_parts_nb > 0) { |
779 | pdata->nr_parts, info->mtd.name); | 770 | ret = mtd_device_register(&info->mtd, mtd_parts, |
771 | mtd_parts_nb); | ||
772 | if (ret == 0) | ||
773 | info->partitioned = true; | ||
780 | } | 774 | } |
781 | 775 | ||
782 | /* If there's no partition info, just package the whole chip | 776 | /* If there's no partition info, just package the whole chip |
783 | * as a single MTD device. | 777 | * as a single MTD device. |
784 | */ | 778 | */ |
785 | if (!info->partitioned) | 779 | if (!info->partitioned) |
786 | ret = add_mtd_device(&info->mtd) ? -ENODEV : 0; | 780 | ret = mtd_device_register(&info->mtd, NULL, 0) ? -ENODEV : 0; |
787 | 781 | ||
788 | if (ret < 0) | 782 | if (ret < 0) |
789 | goto err_scan; | 783 | goto err_scan; |
@@ -824,10 +818,7 @@ static int __exit nand_davinci_remove(struct platform_device *pdev) | |||
824 | struct davinci_nand_info *info = platform_get_drvdata(pdev); | 818 | struct davinci_nand_info *info = platform_get_drvdata(pdev); |
825 | int status; | 819 | int status; |
826 | 820 | ||
827 | if (mtd_has_partitions() && info->partitioned) | 821 | status = mtd_device_unregister(&info->mtd); |
828 | status = del_mtd_partitions(&info->mtd); | ||
829 | else | ||
830 | status = del_mtd_device(&info->mtd); | ||
831 | 822 | ||
832 | spin_lock_irq(&davinci_nand_lock); | 823 | spin_lock_irq(&davinci_nand_lock); |
833 | if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME) | 824 | if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME) |
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 4633f094c510..d5276218945f 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/wait.h> | 23 | #include <linux/wait.h> |
23 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -44,16 +45,16 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting." | |||
44 | 45 | ||
45 | /* We define a macro here that combines all interrupts this driver uses into | 46 | /* We define a macro here that combines all interrupts this driver uses into |
46 | * a single constant value, for convenience. */ | 47 | * a single constant value, for convenience. */ |
47 | #define DENALI_IRQ_ALL (INTR_STATUS0__DMA_CMD_COMP | \ | 48 | #define DENALI_IRQ_ALL (INTR_STATUS__DMA_CMD_COMP | \ |
48 | INTR_STATUS0__ECC_TRANSACTION_DONE | \ | 49 | INTR_STATUS__ECC_TRANSACTION_DONE | \ |
49 | INTR_STATUS0__ECC_ERR | \ | 50 | INTR_STATUS__ECC_ERR | \ |
50 | INTR_STATUS0__PROGRAM_FAIL | \ | 51 | INTR_STATUS__PROGRAM_FAIL | \ |
51 | INTR_STATUS0__LOAD_COMP | \ | 52 | INTR_STATUS__LOAD_COMP | \ |
52 | INTR_STATUS0__PROGRAM_COMP | \ | 53 | INTR_STATUS__PROGRAM_COMP | \ |
53 | INTR_STATUS0__TIME_OUT | \ | 54 | INTR_STATUS__TIME_OUT | \ |
54 | INTR_STATUS0__ERASE_FAIL | \ | 55 | INTR_STATUS__ERASE_FAIL | \ |
55 | INTR_STATUS0__RST_COMP | \ | 56 | INTR_STATUS__RST_COMP | \ |
56 | INTR_STATUS0__ERASE_COMP) | 57 | INTR_STATUS__ERASE_COMP) |
57 | 58 | ||
58 | /* indicates whether or not the internal value for the flash bank is | 59 | /* indicates whether or not the internal value for the flash bank is |
59 | * valid or not */ | 60 | * valid or not */ |
@@ -95,30 +96,6 @@ static const struct pci_device_id denali_pci_ids[] = { | |||
95 | { /* end: all zeroes */ } | 96 | { /* end: all zeroes */ } |
96 | }; | 97 | }; |
97 | 98 | ||
98 | |||
99 | /* these are static lookup tables that give us easy access to | ||
100 | * registers in the NAND controller. | ||
101 | */ | ||
102 | static const uint32_t intr_status_addresses[4] = {INTR_STATUS0, | ||
103 | INTR_STATUS1, | ||
104 | INTR_STATUS2, | ||
105 | INTR_STATUS3}; | ||
106 | |||
107 | static const uint32_t device_reset_banks[4] = {DEVICE_RESET__BANK0, | ||
108 | DEVICE_RESET__BANK1, | ||
109 | DEVICE_RESET__BANK2, | ||
110 | DEVICE_RESET__BANK3}; | ||
111 | |||
112 | static const uint32_t operation_timeout[4] = {INTR_STATUS0__TIME_OUT, | ||
113 | INTR_STATUS1__TIME_OUT, | ||
114 | INTR_STATUS2__TIME_OUT, | ||
115 | INTR_STATUS3__TIME_OUT}; | ||
116 | |||
117 | static const uint32_t reset_complete[4] = {INTR_STATUS0__RST_COMP, | ||
118 | INTR_STATUS1__RST_COMP, | ||
119 | INTR_STATUS2__RST_COMP, | ||
120 | INTR_STATUS3__RST_COMP}; | ||
121 | |||
122 | /* forward declarations */ | 99 | /* forward declarations */ |
123 | static void clear_interrupts(struct denali_nand_info *denali); | 100 | static void clear_interrupts(struct denali_nand_info *denali); |
124 | static uint32_t wait_for_irq(struct denali_nand_info *denali, | 101 | static uint32_t wait_for_irq(struct denali_nand_info *denali, |
@@ -180,19 +157,17 @@ static void read_status(struct denali_nand_info *denali) | |||
180 | static void reset_bank(struct denali_nand_info *denali) | 157 | static void reset_bank(struct denali_nand_info *denali) |
181 | { | 158 | { |
182 | uint32_t irq_status = 0; | 159 | uint32_t irq_status = 0; |
183 | uint32_t irq_mask = reset_complete[denali->flash_bank] | | 160 | uint32_t irq_mask = INTR_STATUS__RST_COMP | |
184 | operation_timeout[denali->flash_bank]; | 161 | INTR_STATUS__TIME_OUT; |
185 | int bank = 0; | ||
186 | 162 | ||
187 | clear_interrupts(denali); | 163 | clear_interrupts(denali); |
188 | 164 | ||
189 | bank = device_reset_banks[denali->flash_bank]; | 165 | iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET); |
190 | iowrite32(bank, denali->flash_reg + DEVICE_RESET); | ||
191 | 166 | ||
192 | irq_status = wait_for_irq(denali, irq_mask); | 167 | irq_status = wait_for_irq(denali, irq_mask); |
193 | 168 | ||
194 | if (irq_status & operation_timeout[denali->flash_bank]) | 169 | if (irq_status & INTR_STATUS__TIME_OUT) |
195 | dev_err(&denali->dev->dev, "reset bank failed.\n"); | 170 | dev_err(denali->dev, "reset bank failed.\n"); |
196 | } | 171 | } |
197 | 172 | ||
198 | /* Reset the flash controller */ | 173 | /* Reset the flash controller */ |
@@ -200,29 +175,28 @@ static uint16_t denali_nand_reset(struct denali_nand_info *denali) | |||
200 | { | 175 | { |
201 | uint32_t i; | 176 | uint32_t i; |
202 | 177 | ||
203 | dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n", | 178 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", |
204 | __FILE__, __LINE__, __func__); | 179 | __FILE__, __LINE__, __func__); |
205 | 180 | ||
206 | for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) | 181 | for (i = 0 ; i < denali->max_banks; i++) |
207 | iowrite32(reset_complete[i] | operation_timeout[i], | 182 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, |
208 | denali->flash_reg + intr_status_addresses[i]); | 183 | denali->flash_reg + INTR_STATUS(i)); |
209 | 184 | ||
210 | for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) { | 185 | for (i = 0 ; i < denali->max_banks; i++) { |
211 | iowrite32(device_reset_banks[i], | 186 | iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); |
212 | denali->flash_reg + DEVICE_RESET); | ||
213 | while (!(ioread32(denali->flash_reg + | 187 | while (!(ioread32(denali->flash_reg + |
214 | intr_status_addresses[i]) & | 188 | INTR_STATUS(i)) & |
215 | (reset_complete[i] | operation_timeout[i]))) | 189 | (INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT))) |
216 | cpu_relax(); | 190 | cpu_relax(); |
217 | if (ioread32(denali->flash_reg + intr_status_addresses[i]) & | 191 | if (ioread32(denali->flash_reg + INTR_STATUS(i)) & |
218 | operation_timeout[i]) | 192 | INTR_STATUS__TIME_OUT) |
219 | dev_dbg(&denali->dev->dev, | 193 | dev_dbg(denali->dev, |
220 | "NAND Reset operation timed out on bank %d\n", i); | 194 | "NAND Reset operation timed out on bank %d\n", i); |
221 | } | 195 | } |
222 | 196 | ||
223 | for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) | 197 | for (i = 0; i < denali->max_banks; i++) |
224 | iowrite32(reset_complete[i] | operation_timeout[i], | 198 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, |
225 | denali->flash_reg + intr_status_addresses[i]); | 199 | denali->flash_reg + INTR_STATUS(i)); |
226 | 200 | ||
227 | return PASS; | 201 | return PASS; |
228 | } | 202 | } |
@@ -254,7 +228,7 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali, | |||
254 | uint16_t acc_clks; | 228 | uint16_t acc_clks; |
255 | uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt; | 229 | uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt; |
256 | 230 | ||
257 | dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n", | 231 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", |
258 | __FILE__, __LINE__, __func__); | 232 | __FILE__, __LINE__, __func__); |
259 | 233 | ||
260 | en_lo = CEIL_DIV(Trp[mode], CLK_X); | 234 | en_lo = CEIL_DIV(Trp[mode], CLK_X); |
@@ -291,7 +265,7 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali, | |||
291 | acc_clks++; | 265 | acc_clks++; |
292 | 266 | ||
293 | if ((data_invalid - acc_clks * CLK_X) < 2) | 267 | if ((data_invalid - acc_clks * CLK_X) < 2) |
294 | dev_warn(&denali->dev->dev, "%s, Line %d: Warning!\n", | 268 | dev_warn(denali->dev, "%s, Line %d: Warning!\n", |
295 | __FILE__, __LINE__); | 269 | __FILE__, __LINE__); |
296 | 270 | ||
297 | addr_2_data = CEIL_DIV(Tadl[mode], CLK_X); | 271 | addr_2_data = CEIL_DIV(Tadl[mode], CLK_X); |
@@ -419,7 +393,7 @@ static void get_hynix_nand_para(struct denali_nand_info *denali, | |||
419 | #endif | 393 | #endif |
420 | break; | 394 | break; |
421 | default: | 395 | default: |
422 | dev_warn(&denali->dev->dev, | 396 | dev_warn(denali->dev, |
423 | "Spectra: Unknown Hynix NAND (Device ID: 0x%x)." | 397 | "Spectra: Unknown Hynix NAND (Device ID: 0x%x)." |
424 | "Will use default parameter values instead.\n", | 398 | "Will use default parameter values instead.\n", |
425 | device_id); | 399 | device_id); |
@@ -431,17 +405,17 @@ static void get_hynix_nand_para(struct denali_nand_info *denali, | |||
431 | */ | 405 | */ |
432 | static void find_valid_banks(struct denali_nand_info *denali) | 406 | static void find_valid_banks(struct denali_nand_info *denali) |
433 | { | 407 | { |
434 | uint32_t id[LLD_MAX_FLASH_BANKS]; | 408 | uint32_t id[denali->max_banks]; |
435 | int i; | 409 | int i; |
436 | 410 | ||
437 | denali->total_used_banks = 1; | 411 | denali->total_used_banks = 1; |
438 | for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) { | 412 | for (i = 0; i < denali->max_banks; i++) { |
439 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90); | 413 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90); |
440 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0); | 414 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0); |
441 | index_addr_read_data(denali, | 415 | index_addr_read_data(denali, |
442 | (uint32_t)(MODE_11 | (i << 24) | 2), &id[i]); | 416 | (uint32_t)(MODE_11 | (i << 24) | 2), &id[i]); |
443 | 417 | ||
444 | dev_dbg(&denali->dev->dev, | 418 | dev_dbg(denali->dev, |
445 | "Return 1st ID for bank[%d]: %x\n", i, id[i]); | 419 | "Return 1st ID for bank[%d]: %x\n", i, id[i]); |
446 | 420 | ||
447 | if (i == 0) { | 421 | if (i == 0) { |
@@ -461,16 +435,27 @@ static void find_valid_banks(struct denali_nand_info *denali) | |||
461 | * Multichip support is not enabled. | 435 | * Multichip support is not enabled. |
462 | */ | 436 | */ |
463 | if (denali->total_used_banks != 1) { | 437 | if (denali->total_used_banks != 1) { |
464 | dev_err(&denali->dev->dev, | 438 | dev_err(denali->dev, |
465 | "Sorry, Intel CE4100 only supports " | 439 | "Sorry, Intel CE4100 only supports " |
466 | "a single NAND device.\n"); | 440 | "a single NAND device.\n"); |
467 | BUG(); | 441 | BUG(); |
468 | } | 442 | } |
469 | } | 443 | } |
470 | dev_dbg(&denali->dev->dev, | 444 | dev_dbg(denali->dev, |
471 | "denali->total_used_banks: %d\n", denali->total_used_banks); | 445 | "denali->total_used_banks: %d\n", denali->total_used_banks); |
472 | } | 446 | } |
473 | 447 | ||
448 | /* | ||
449 | * Use the configuration feature register to determine the maximum number of | ||
450 | * banks that the hardware supports. | ||
451 | */ | ||
452 | static void detect_max_banks(struct denali_nand_info *denali) | ||
453 | { | ||
454 | uint32_t features = ioread32(denali->flash_reg + FEATURES); | ||
455 | |||
456 | denali->max_banks = 2 << (features & FEATURES__N_BANKS); | ||
457 | } | ||
458 | |||
474 | static void detect_partition_feature(struct denali_nand_info *denali) | 459 | static void detect_partition_feature(struct denali_nand_info *denali) |
475 | { | 460 | { |
476 | /* For MRST platform, denali->fwblks represent the | 461 | /* For MRST platform, denali->fwblks represent the |
@@ -480,15 +465,15 @@ static void detect_partition_feature(struct denali_nand_info *denali) | |||
480 | * blocks it can't touch. | 465 | * blocks it can't touch. |
481 | * */ | 466 | * */ |
482 | if (ioread32(denali->flash_reg + FEATURES) & FEATURES__PARTITION) { | 467 | if (ioread32(denali->flash_reg + FEATURES) & FEATURES__PARTITION) { |
483 | if ((ioread32(denali->flash_reg + PERM_SRC_ID_1) & | 468 | if ((ioread32(denali->flash_reg + PERM_SRC_ID(1)) & |
484 | PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) { | 469 | PERM_SRC_ID__SRCID) == SPECTRA_PARTITION_ID) { |
485 | denali->fwblks = | 470 | denali->fwblks = |
486 | ((ioread32(denali->flash_reg + MIN_MAX_BANK_1) & | 471 | ((ioread32(denali->flash_reg + MIN_MAX_BANK(1)) & |
487 | MIN_MAX_BANK_1__MIN_VALUE) * | 472 | MIN_MAX_BANK__MIN_VALUE) * |
488 | denali->blksperchip) | 473 | denali->blksperchip) |
489 | + | 474 | + |
490 | (ioread32(denali->flash_reg + MIN_BLK_ADDR_1) & | 475 | (ioread32(denali->flash_reg + MIN_BLK_ADDR(1)) & |
491 | MIN_BLK_ADDR_1__VALUE); | 476 | MIN_BLK_ADDR__VALUE); |
492 | } else | 477 | } else |
493 | denali->fwblks = SPECTRA_START_BLOCK; | 478 | denali->fwblks = SPECTRA_START_BLOCK; |
494 | } else | 479 | } else |
@@ -501,7 +486,7 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | |||
501 | uint32_t id_bytes[5], addr; | 486 | uint32_t id_bytes[5], addr; |
502 | uint8_t i, maf_id, device_id; | 487 | uint8_t i, maf_id, device_id; |
503 | 488 | ||
504 | dev_dbg(&denali->dev->dev, | 489 | dev_dbg(denali->dev, |
505 | "%s, Line %d, Function: %s\n", | 490 | "%s, Line %d, Function: %s\n", |
506 | __FILE__, __LINE__, __func__); | 491 | __FILE__, __LINE__, __func__); |
507 | 492 | ||
@@ -530,7 +515,7 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | |||
530 | get_hynix_nand_para(denali, device_id); | 515 | get_hynix_nand_para(denali, device_id); |
531 | } | 516 | } |
532 | 517 | ||
533 | dev_info(&denali->dev->dev, | 518 | dev_info(denali->dev, |
534 | "Dump timing register values:" | 519 | "Dump timing register values:" |
535 | "acc_clks: %d, re_2_we: %d, re_2_re: %d\n" | 520 | "acc_clks: %d, re_2_we: %d, re_2_re: %d\n" |
536 | "we_2_re: %d, addr_2_data: %d, rdwr_en_lo_cnt: %d\n" | 521 | "we_2_re: %d, addr_2_data: %d, rdwr_en_lo_cnt: %d\n" |
@@ -560,7 +545,7 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | |||
560 | static void denali_set_intr_modes(struct denali_nand_info *denali, | 545 | static void denali_set_intr_modes(struct denali_nand_info *denali, |
561 | uint16_t INT_ENABLE) | 546 | uint16_t INT_ENABLE) |
562 | { | 547 | { |
563 | dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n", | 548 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", |
564 | __FILE__, __LINE__, __func__); | 549 | __FILE__, __LINE__, __func__); |
565 | 550 | ||
566 | if (INT_ENABLE) | 551 | if (INT_ENABLE) |
@@ -580,6 +565,7 @@ static inline bool is_flash_bank_valid(int flash_bank) | |||
580 | static void denali_irq_init(struct denali_nand_info *denali) | 565 | static void denali_irq_init(struct denali_nand_info *denali) |
581 | { | 566 | { |
582 | uint32_t int_mask = 0; | 567 | uint32_t int_mask = 0; |
568 | int i; | ||
583 | 569 | ||
584 | /* Disable global interrupts */ | 570 | /* Disable global interrupts */ |
585 | denali_set_intr_modes(denali, false); | 571 | denali_set_intr_modes(denali, false); |
@@ -587,10 +573,8 @@ static void denali_irq_init(struct denali_nand_info *denali) | |||
587 | int_mask = DENALI_IRQ_ALL; | 573 | int_mask = DENALI_IRQ_ALL; |
588 | 574 | ||
589 | /* Clear all status bits */ | 575 | /* Clear all status bits */ |
590 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS0); | 576 | for (i = 0; i < denali->max_banks; ++i) |
591 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS1); | 577 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i)); |
592 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS2); | ||
593 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS3); | ||
594 | 578 | ||
595 | denali_irq_enable(denali, int_mask); | 579 | denali_irq_enable(denali, int_mask); |
596 | } | 580 | } |
@@ -604,10 +588,10 @@ static void denali_irq_cleanup(int irqnum, struct denali_nand_info *denali) | |||
604 | static void denali_irq_enable(struct denali_nand_info *denali, | 588 | static void denali_irq_enable(struct denali_nand_info *denali, |
605 | uint32_t int_mask) | 589 | uint32_t int_mask) |
606 | { | 590 | { |
607 | iowrite32(int_mask, denali->flash_reg + INTR_EN0); | 591 | int i; |
608 | iowrite32(int_mask, denali->flash_reg + INTR_EN1); | 592 | |
609 | iowrite32(int_mask, denali->flash_reg + INTR_EN2); | 593 | for (i = 0; i < denali->max_banks; ++i) |
610 | iowrite32(int_mask, denali->flash_reg + INTR_EN3); | 594 | iowrite32(int_mask, denali->flash_reg + INTR_EN(i)); |
611 | } | 595 | } |
612 | 596 | ||
613 | /* This function only returns when an interrupt that this driver cares about | 597 | /* This function only returns when an interrupt that this driver cares about |
@@ -624,7 +608,7 @@ static inline void clear_interrupt(struct denali_nand_info *denali, | |||
624 | { | 608 | { |
625 | uint32_t intr_status_reg = 0; | 609 | uint32_t intr_status_reg = 0; |
626 | 610 | ||
627 | intr_status_reg = intr_status_addresses[denali->flash_bank]; | 611 | intr_status_reg = INTR_STATUS(denali->flash_bank); |
628 | 612 | ||
629 | iowrite32(irq_mask, denali->flash_reg + intr_status_reg); | 613 | iowrite32(irq_mask, denali->flash_reg + intr_status_reg); |
630 | } | 614 | } |
@@ -645,7 +629,7 @@ static uint32_t read_interrupt_status(struct denali_nand_info *denali) | |||
645 | { | 629 | { |
646 | uint32_t intr_status_reg = 0; | 630 | uint32_t intr_status_reg = 0; |
647 | 631 | ||
648 | intr_status_reg = intr_status_addresses[denali->flash_bank]; | 632 | intr_status_reg = INTR_STATUS(denali->flash_bank); |
649 | 633 | ||
650 | return ioread32(denali->flash_reg + intr_status_reg); | 634 | return ioread32(denali->flash_reg + intr_status_reg); |
651 | } | 635 | } |
@@ -754,7 +738,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, | |||
754 | irq_mask = 0; | 738 | irq_mask = 0; |
755 | 739 | ||
756 | if (op == DENALI_READ) | 740 | if (op == DENALI_READ) |
757 | irq_mask = INTR_STATUS0__LOAD_COMP; | 741 | irq_mask = INTR_STATUS__LOAD_COMP; |
758 | else if (op == DENALI_WRITE) | 742 | else if (op == DENALI_WRITE) |
759 | irq_mask = 0; | 743 | irq_mask = 0; |
760 | else | 744 | else |
@@ -800,7 +784,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, | |||
800 | irq_status = wait_for_irq(denali, irq_mask); | 784 | irq_status = wait_for_irq(denali, irq_mask); |
801 | 785 | ||
802 | if (irq_status == 0) { | 786 | if (irq_status == 0) { |
803 | dev_err(&denali->dev->dev, | 787 | dev_err(denali->dev, |
804 | "cmd, page, addr on timeout " | 788 | "cmd, page, addr on timeout " |
805 | "(0x%x, 0x%x, 0x%x)\n", | 789 | "(0x%x, 0x%x, 0x%x)\n", |
806 | cmd, denali->page, addr); | 790 | cmd, denali->page, addr); |
@@ -861,8 +845,8 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
861 | { | 845 | { |
862 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 846 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
863 | uint32_t irq_status = 0; | 847 | uint32_t irq_status = 0; |
864 | uint32_t irq_mask = INTR_STATUS0__PROGRAM_COMP | | 848 | uint32_t irq_mask = INTR_STATUS__PROGRAM_COMP | |
865 | INTR_STATUS0__PROGRAM_FAIL; | 849 | INTR_STATUS__PROGRAM_FAIL; |
866 | int status = 0; | 850 | int status = 0; |
867 | 851 | ||
868 | denali->page = page; | 852 | denali->page = page; |
@@ -875,11 +859,11 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
875 | irq_status = wait_for_irq(denali, irq_mask); | 859 | irq_status = wait_for_irq(denali, irq_mask); |
876 | 860 | ||
877 | if (irq_status == 0) { | 861 | if (irq_status == 0) { |
878 | dev_err(&denali->dev->dev, "OOB write failed\n"); | 862 | dev_err(denali->dev, "OOB write failed\n"); |
879 | status = -EIO; | 863 | status = -EIO; |
880 | } | 864 | } |
881 | } else { | 865 | } else { |
882 | dev_err(&denali->dev->dev, "unable to send pipeline command\n"); | 866 | dev_err(denali->dev, "unable to send pipeline command\n"); |
883 | status = -EIO; | 867 | status = -EIO; |
884 | } | 868 | } |
885 | return status; | 869 | return status; |
@@ -889,7 +873,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
889 | static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) | 873 | static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) |
890 | { | 874 | { |
891 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 875 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
892 | uint32_t irq_mask = INTR_STATUS0__LOAD_COMP, | 876 | uint32_t irq_mask = INTR_STATUS__LOAD_COMP, |
893 | irq_status = 0, addr = 0x0, cmd = 0x0; | 877 | irq_status = 0, addr = 0x0, cmd = 0x0; |
894 | 878 | ||
895 | denali->page = page; | 879 | denali->page = page; |
@@ -904,7 +888,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
904 | irq_status = wait_for_irq(denali, irq_mask); | 888 | irq_status = wait_for_irq(denali, irq_mask); |
905 | 889 | ||
906 | if (irq_status == 0) | 890 | if (irq_status == 0) |
907 | dev_err(&denali->dev->dev, "page on OOB timeout %d\n", | 891 | dev_err(denali->dev, "page on OOB timeout %d\n", |
908 | denali->page); | 892 | denali->page); |
909 | 893 | ||
910 | /* We set the device back to MAIN_ACCESS here as I observed | 894 | /* We set the device back to MAIN_ACCESS here as I observed |
@@ -944,7 +928,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
944 | { | 928 | { |
945 | bool check_erased_page = false; | 929 | bool check_erased_page = false; |
946 | 930 | ||
947 | if (irq_status & INTR_STATUS0__ECC_ERR) { | 931 | if (irq_status & INTR_STATUS__ECC_ERR) { |
948 | /* read the ECC errors. we'll ignore them for now */ | 932 | /* read the ECC errors. we'll ignore them for now */ |
949 | uint32_t err_address = 0, err_correction_info = 0; | 933 | uint32_t err_address = 0, err_correction_info = 0; |
950 | uint32_t err_byte = 0, err_sector = 0, err_device = 0; | 934 | uint32_t err_byte = 0, err_sector = 0, err_device = 0; |
@@ -995,7 +979,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
995 | * for a while for this interrupt | 979 | * for a while for this interrupt |
996 | * */ | 980 | * */ |
997 | while (!(read_interrupt_status(denali) & | 981 | while (!(read_interrupt_status(denali) & |
998 | INTR_STATUS0__ECC_TRANSACTION_DONE)) | 982 | INTR_STATUS__ECC_TRANSACTION_DONE)) |
999 | cpu_relax(); | 983 | cpu_relax(); |
1000 | clear_interrupts(denali); | 984 | clear_interrupts(denali); |
1001 | denali_set_intr_modes(denali, true); | 985 | denali_set_intr_modes(denali, true); |
@@ -1045,14 +1029,13 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1045 | const uint8_t *buf, bool raw_xfer) | 1029 | const uint8_t *buf, bool raw_xfer) |
1046 | { | 1030 | { |
1047 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1031 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1048 | struct pci_dev *pci_dev = denali->dev; | ||
1049 | 1032 | ||
1050 | dma_addr_t addr = denali->buf.dma_buf; | 1033 | dma_addr_t addr = denali->buf.dma_buf; |
1051 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; | 1034 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; |
1052 | 1035 | ||
1053 | uint32_t irq_status = 0; | 1036 | uint32_t irq_status = 0; |
1054 | uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP | | 1037 | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP | |
1055 | INTR_STATUS0__PROGRAM_FAIL; | 1038 | INTR_STATUS__PROGRAM_FAIL; |
1056 | 1039 | ||
1057 | /* if it is a raw xfer, we want to disable ecc, and send | 1040 | /* if it is a raw xfer, we want to disable ecc, and send |
1058 | * the spare area. | 1041 | * the spare area. |
@@ -1071,7 +1054,7 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1071 | mtd->oobsize); | 1054 | mtd->oobsize); |
1072 | } | 1055 | } |
1073 | 1056 | ||
1074 | pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_TODEVICE); | 1057 | dma_sync_single_for_device(denali->dev, addr, size, DMA_TO_DEVICE); |
1075 | 1058 | ||
1076 | clear_interrupts(denali); | 1059 | clear_interrupts(denali); |
1077 | denali_enable_dma(denali, true); | 1060 | denali_enable_dma(denali, true); |
@@ -1082,16 +1065,16 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1082 | irq_status = wait_for_irq(denali, irq_mask); | 1065 | irq_status = wait_for_irq(denali, irq_mask); |
1083 | 1066 | ||
1084 | if (irq_status == 0) { | 1067 | if (irq_status == 0) { |
1085 | dev_err(&denali->dev->dev, | 1068 | dev_err(denali->dev, |
1086 | "timeout on write_page (type = %d)\n", | 1069 | "timeout on write_page (type = %d)\n", |
1087 | raw_xfer); | 1070 | raw_xfer); |
1088 | denali->status = | 1071 | denali->status = |
1089 | (irq_status & INTR_STATUS0__PROGRAM_FAIL) ? | 1072 | (irq_status & INTR_STATUS__PROGRAM_FAIL) ? |
1090 | NAND_STATUS_FAIL : PASS; | 1073 | NAND_STATUS_FAIL : PASS; |
1091 | } | 1074 | } |
1092 | 1075 | ||
1093 | denali_enable_dma(denali, false); | 1076 | denali_enable_dma(denali, false); |
1094 | pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_TODEVICE); | 1077 | dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE); |
1095 | } | 1078 | } |
1096 | 1079 | ||
1097 | /* NAND core entry points */ | 1080 | /* NAND core entry points */ |
@@ -1139,18 +1122,17 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1139 | uint8_t *buf, int page) | 1122 | uint8_t *buf, int page) |
1140 | { | 1123 | { |
1141 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1124 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1142 | struct pci_dev *pci_dev = denali->dev; | ||
1143 | 1125 | ||
1144 | dma_addr_t addr = denali->buf.dma_buf; | 1126 | dma_addr_t addr = denali->buf.dma_buf; |
1145 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; | 1127 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; |
1146 | 1128 | ||
1147 | uint32_t irq_status = 0; | 1129 | uint32_t irq_status = 0; |
1148 | uint32_t irq_mask = INTR_STATUS0__ECC_TRANSACTION_DONE | | 1130 | uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE | |
1149 | INTR_STATUS0__ECC_ERR; | 1131 | INTR_STATUS__ECC_ERR; |
1150 | bool check_erased_page = false; | 1132 | bool check_erased_page = false; |
1151 | 1133 | ||
1152 | if (page != denali->page) { | 1134 | if (page != denali->page) { |
1153 | dev_err(&denali->dev->dev, "IN %s: page %d is not" | 1135 | dev_err(denali->dev, "IN %s: page %d is not" |
1154 | " equal to denali->page %d, investigate!!", | 1136 | " equal to denali->page %d, investigate!!", |
1155 | __func__, page, denali->page); | 1137 | __func__, page, denali->page); |
1156 | BUG(); | 1138 | BUG(); |
@@ -1159,7 +1141,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1159 | setup_ecc_for_xfer(denali, true, false); | 1141 | setup_ecc_for_xfer(denali, true, false); |
1160 | 1142 | ||
1161 | denali_enable_dma(denali, true); | 1143 | denali_enable_dma(denali, true); |
1162 | pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_FROMDEVICE); | 1144 | dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE); |
1163 | 1145 | ||
1164 | clear_interrupts(denali); | 1146 | clear_interrupts(denali); |
1165 | denali_setup_dma(denali, DENALI_READ); | 1147 | denali_setup_dma(denali, DENALI_READ); |
@@ -1167,7 +1149,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1167 | /* wait for operation to complete */ | 1149 | /* wait for operation to complete */ |
1168 | irq_status = wait_for_irq(denali, irq_mask); | 1150 | irq_status = wait_for_irq(denali, irq_mask); |
1169 | 1151 | ||
1170 | pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE); | 1152 | dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE); |
1171 | 1153 | ||
1172 | memcpy(buf, denali->buf.buf, mtd->writesize); | 1154 | memcpy(buf, denali->buf.buf, mtd->writesize); |
1173 | 1155 | ||
@@ -1192,16 +1174,15 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1192 | uint8_t *buf, int page) | 1174 | uint8_t *buf, int page) |
1193 | { | 1175 | { |
1194 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1176 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1195 | struct pci_dev *pci_dev = denali->dev; | ||
1196 | 1177 | ||
1197 | dma_addr_t addr = denali->buf.dma_buf; | 1178 | dma_addr_t addr = denali->buf.dma_buf; |
1198 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; | 1179 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; |
1199 | 1180 | ||
1200 | uint32_t irq_status = 0; | 1181 | uint32_t irq_status = 0; |
1201 | uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP; | 1182 | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP; |
1202 | 1183 | ||
1203 | if (page != denali->page) { | 1184 | if (page != denali->page) { |
1204 | dev_err(&denali->dev->dev, "IN %s: page %d is not" | 1185 | dev_err(denali->dev, "IN %s: page %d is not" |
1205 | " equal to denali->page %d, investigate!!", | 1186 | " equal to denali->page %d, investigate!!", |
1206 | __func__, page, denali->page); | 1187 | __func__, page, denali->page); |
1207 | BUG(); | 1188 | BUG(); |
@@ -1210,7 +1191,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1210 | setup_ecc_for_xfer(denali, false, true); | 1191 | setup_ecc_for_xfer(denali, false, true); |
1211 | denali_enable_dma(denali, true); | 1192 | denali_enable_dma(denali, true); |
1212 | 1193 | ||
1213 | pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_FROMDEVICE); | 1194 | dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE); |
1214 | 1195 | ||
1215 | clear_interrupts(denali); | 1196 | clear_interrupts(denali); |
1216 | denali_setup_dma(denali, DENALI_READ); | 1197 | denali_setup_dma(denali, DENALI_READ); |
@@ -1218,7 +1199,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1218 | /* wait for operation to complete */ | 1199 | /* wait for operation to complete */ |
1219 | irq_status = wait_for_irq(denali, irq_mask); | 1200 | irq_status = wait_for_irq(denali, irq_mask); |
1220 | 1201 | ||
1221 | pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE); | 1202 | dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE); |
1222 | 1203 | ||
1223 | denali_enable_dma(denali, false); | 1204 | denali_enable_dma(denali, false); |
1224 | 1205 | ||
@@ -1271,10 +1252,10 @@ static void denali_erase(struct mtd_info *mtd, int page) | |||
1271 | index_addr(denali, (uint32_t)cmd, 0x1); | 1252 | index_addr(denali, (uint32_t)cmd, 0x1); |
1272 | 1253 | ||
1273 | /* wait for erase to complete or failure to occur */ | 1254 | /* wait for erase to complete or failure to occur */ |
1274 | irq_status = wait_for_irq(denali, INTR_STATUS0__ERASE_COMP | | 1255 | irq_status = wait_for_irq(denali, INTR_STATUS__ERASE_COMP | |
1275 | INTR_STATUS0__ERASE_FAIL); | 1256 | INTR_STATUS__ERASE_FAIL); |
1276 | 1257 | ||
1277 | denali->status = (irq_status & INTR_STATUS0__ERASE_FAIL) ? | 1258 | denali->status = (irq_status & INTR_STATUS__ERASE_FAIL) ? |
1278 | NAND_STATUS_FAIL : PASS; | 1259 | NAND_STATUS_FAIL : PASS; |
1279 | } | 1260 | } |
1280 | 1261 | ||
@@ -1330,7 +1311,7 @@ static int denali_ecc_calculate(struct mtd_info *mtd, const uint8_t *data, | |||
1330 | uint8_t *ecc_code) | 1311 | uint8_t *ecc_code) |
1331 | { | 1312 | { |
1332 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1313 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1333 | dev_err(&denali->dev->dev, | 1314 | dev_err(denali->dev, |
1334 | "denali_ecc_calculate called unexpectedly\n"); | 1315 | "denali_ecc_calculate called unexpectedly\n"); |
1335 | BUG(); | 1316 | BUG(); |
1336 | return -EIO; | 1317 | return -EIO; |
@@ -1340,7 +1321,7 @@ static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data, | |||
1340 | uint8_t *read_ecc, uint8_t *calc_ecc) | 1321 | uint8_t *read_ecc, uint8_t *calc_ecc) |
1341 | { | 1322 | { |
1342 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1323 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1343 | dev_err(&denali->dev->dev, | 1324 | dev_err(denali->dev, |
1344 | "denali_ecc_correct called unexpectedly\n"); | 1325 | "denali_ecc_correct called unexpectedly\n"); |
1345 | BUG(); | 1326 | BUG(); |
1346 | return -EIO; | 1327 | return -EIO; |
@@ -1349,7 +1330,7 @@ static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data, | |||
1349 | static void denali_ecc_hwctl(struct mtd_info *mtd, int mode) | 1330 | static void denali_ecc_hwctl(struct mtd_info *mtd, int mode) |
1350 | { | 1331 | { |
1351 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1332 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1352 | dev_err(&denali->dev->dev, | 1333 | dev_err(denali->dev, |
1353 | "denali_ecc_hwctl called unexpectedly\n"); | 1334 | "denali_ecc_hwctl called unexpectedly\n"); |
1354 | BUG(); | 1335 | BUG(); |
1355 | } | 1336 | } |
@@ -1375,6 +1356,7 @@ static void denali_hw_init(struct denali_nand_info *denali) | |||
1375 | /* Should set value for these registers when init */ | 1356 | /* Should set value for these registers when init */ |
1376 | iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES); | 1357 | iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES); |
1377 | iowrite32(1, denali->flash_reg + ECC_ENABLE); | 1358 | iowrite32(1, denali->flash_reg + ECC_ENABLE); |
1359 | detect_max_banks(denali); | ||
1378 | denali_nand_timing_set(denali); | 1360 | denali_nand_timing_set(denali); |
1379 | denali_irq_init(denali); | 1361 | denali_irq_init(denali); |
1380 | } | 1362 | } |
@@ -1484,24 +1466,22 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1484 | } | 1466 | } |
1485 | 1467 | ||
1486 | /* Is 32-bit DMA supported? */ | 1468 | /* Is 32-bit DMA supported? */ |
1487 | ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32)); | 1469 | ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); |
1488 | |||
1489 | if (ret) { | 1470 | if (ret) { |
1490 | printk(KERN_ERR "Spectra: no usable DMA configuration\n"); | 1471 | printk(KERN_ERR "Spectra: no usable DMA configuration\n"); |
1491 | goto failed_enable_dev; | 1472 | goto failed_enable_dev; |
1492 | } | 1473 | } |
1493 | denali->buf.dma_buf = | 1474 | denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf, |
1494 | pci_map_single(dev, denali->buf.buf, | 1475 | DENALI_BUF_SIZE, |
1495 | DENALI_BUF_SIZE, | 1476 | DMA_BIDIRECTIONAL); |
1496 | PCI_DMA_BIDIRECTIONAL); | ||
1497 | 1477 | ||
1498 | if (pci_dma_mapping_error(dev, denali->buf.dma_buf)) { | 1478 | if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) { |
1499 | dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n"); | 1479 | dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n"); |
1500 | goto failed_enable_dev; | 1480 | goto failed_enable_dev; |
1501 | } | 1481 | } |
1502 | 1482 | ||
1503 | pci_set_master(dev); | 1483 | pci_set_master(dev); |
1504 | denali->dev = dev; | 1484 | denali->dev = &dev->dev; |
1505 | denali->mtd.dev.parent = &dev->dev; | 1485 | denali->mtd.dev.parent = &dev->dev; |
1506 | 1486 | ||
1507 | ret = pci_request_regions(dev, DENALI_NAND_NAME); | 1487 | ret = pci_request_regions(dev, DENALI_NAND_NAME); |
@@ -1554,7 +1534,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1554 | /* scan for NAND devices attached to the controller | 1534 | /* scan for NAND devices attached to the controller |
1555 | * this is the first stage in a two step process to register | 1535 | * this is the first stage in a two step process to register |
1556 | * with the nand subsystem */ | 1536 | * with the nand subsystem */ |
1557 | if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL)) { | 1537 | if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) { |
1558 | ret = -ENXIO; | 1538 | ret = -ENXIO; |
1559 | goto failed_req_irq; | 1539 | goto failed_req_irq; |
1560 | } | 1540 | } |
@@ -1664,7 +1644,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1664 | goto failed_req_irq; | 1644 | goto failed_req_irq; |
1665 | } | 1645 | } |
1666 | 1646 | ||
1667 | ret = add_mtd_device(&denali->mtd); | 1647 | ret = mtd_device_register(&denali->mtd, NULL, 0); |
1668 | if (ret) { | 1648 | if (ret) { |
1669 | dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n", | 1649 | dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n", |
1670 | ret); | 1650 | ret); |
@@ -1681,8 +1661,8 @@ failed_remap_reg: | |||
1681 | failed_req_regions: | 1661 | failed_req_regions: |
1682 | pci_release_regions(dev); | 1662 | pci_release_regions(dev); |
1683 | failed_dma_map: | 1663 | failed_dma_map: |
1684 | pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | 1664 | dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, |
1685 | PCI_DMA_BIDIRECTIONAL); | 1665 | DMA_BIDIRECTIONAL); |
1686 | failed_enable_dev: | 1666 | failed_enable_dev: |
1687 | pci_disable_device(dev); | 1667 | pci_disable_device(dev); |
1688 | failed_alloc_memery: | 1668 | failed_alloc_memery: |
@@ -1696,7 +1676,7 @@ static void denali_pci_remove(struct pci_dev *dev) | |||
1696 | struct denali_nand_info *denali = pci_get_drvdata(dev); | 1676 | struct denali_nand_info *denali = pci_get_drvdata(dev); |
1697 | 1677 | ||
1698 | nand_release(&denali->mtd); | 1678 | nand_release(&denali->mtd); |
1699 | del_mtd_device(&denali->mtd); | 1679 | mtd_device_unregister(&denali->mtd); |
1700 | 1680 | ||
1701 | denali_irq_cleanup(dev->irq, denali); | 1681 | denali_irq_cleanup(dev->irq, denali); |
1702 | 1682 | ||
@@ -1704,8 +1684,8 @@ static void denali_pci_remove(struct pci_dev *dev) | |||
1704 | iounmap(denali->flash_mem); | 1684 | iounmap(denali->flash_mem); |
1705 | pci_release_regions(dev); | 1685 | pci_release_regions(dev); |
1706 | pci_disable_device(dev); | 1686 | pci_disable_device(dev); |
1707 | pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | 1687 | dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, |
1708 | PCI_DMA_BIDIRECTIONAL); | 1688 | DMA_BIDIRECTIONAL); |
1709 | pci_set_drvdata(dev, NULL); | 1689 | pci_set_drvdata(dev, NULL); |
1710 | kfree(denali); | 1690 | kfree(denali); |
1711 | } | 1691 | } |
@@ -1721,8 +1701,7 @@ static struct pci_driver denali_pci_driver = { | |||
1721 | 1701 | ||
1722 | static int __devinit denali_init(void) | 1702 | static int __devinit denali_init(void) |
1723 | { | 1703 | { |
1724 | printk(KERN_INFO "Spectra MTD driver built on %s @ %s\n", | 1704 | printk(KERN_INFO "Spectra MTD driver\n"); |
1725 | __DATE__, __TIME__); | ||
1726 | return pci_register_driver(&denali_pci_driver); | 1705 | return pci_register_driver(&denali_pci_driver); |
1727 | } | 1706 | } |
1728 | 1707 | ||
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index 3918bcb1561e..fabb9d56b39e 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h | |||
@@ -211,185 +211,46 @@ | |||
211 | #define TRANSFER_MODE 0x400 | 211 | #define TRANSFER_MODE 0x400 |
212 | #define TRANSFER_MODE__VALUE 0x0003 | 212 | #define TRANSFER_MODE__VALUE 0x0003 |
213 | 213 | ||
214 | #define INTR_STATUS0 0x410 | 214 | #define INTR_STATUS(__bank) (0x410 + ((__bank) * 0x50)) |
215 | #define INTR_STATUS0__ECC_TRANSACTION_DONE 0x0001 | 215 | #define INTR_EN(__bank) (0x420 + ((__bank) * 0x50)) |
216 | #define INTR_STATUS0__ECC_ERR 0x0002 | 216 | |
217 | #define INTR_STATUS0__DMA_CMD_COMP 0x0004 | 217 | #define INTR_STATUS__ECC_TRANSACTION_DONE 0x0001 |
218 | #define INTR_STATUS0__TIME_OUT 0x0008 | 218 | #define INTR_STATUS__ECC_ERR 0x0002 |
219 | #define INTR_STATUS0__PROGRAM_FAIL 0x0010 | 219 | #define INTR_STATUS__DMA_CMD_COMP 0x0004 |
220 | #define INTR_STATUS0__ERASE_FAIL 0x0020 | 220 | #define INTR_STATUS__TIME_OUT 0x0008 |
221 | #define INTR_STATUS0__LOAD_COMP 0x0040 | 221 | #define INTR_STATUS__PROGRAM_FAIL 0x0010 |
222 | #define INTR_STATUS0__PROGRAM_COMP 0x0080 | 222 | #define INTR_STATUS__ERASE_FAIL 0x0020 |
223 | #define INTR_STATUS0__ERASE_COMP 0x0100 | 223 | #define INTR_STATUS__LOAD_COMP 0x0040 |
224 | #define INTR_STATUS0__PIPE_CPYBCK_CMD_COMP 0x0200 | 224 | #define INTR_STATUS__PROGRAM_COMP 0x0080 |
225 | #define INTR_STATUS0__LOCKED_BLK 0x0400 | 225 | #define INTR_STATUS__ERASE_COMP 0x0100 |
226 | #define INTR_STATUS0__UNSUP_CMD 0x0800 | 226 | #define INTR_STATUS__PIPE_CPYBCK_CMD_COMP 0x0200 |
227 | #define INTR_STATUS0__INT_ACT 0x1000 | 227 | #define INTR_STATUS__LOCKED_BLK 0x0400 |
228 | #define INTR_STATUS0__RST_COMP 0x2000 | 228 | #define INTR_STATUS__UNSUP_CMD 0x0800 |
229 | #define INTR_STATUS0__PIPE_CMD_ERR 0x4000 | 229 | #define INTR_STATUS__INT_ACT 0x1000 |
230 | #define INTR_STATUS0__PAGE_XFER_INC 0x8000 | 230 | #define INTR_STATUS__RST_COMP 0x2000 |
231 | 231 | #define INTR_STATUS__PIPE_CMD_ERR 0x4000 | |
232 | #define INTR_EN0 0x420 | 232 | #define INTR_STATUS__PAGE_XFER_INC 0x8000 |
233 | #define INTR_EN0__ECC_TRANSACTION_DONE 0x0001 | 233 | |
234 | #define INTR_EN0__ECC_ERR 0x0002 | 234 | #define INTR_EN__ECC_TRANSACTION_DONE 0x0001 |
235 | #define INTR_EN0__DMA_CMD_COMP 0x0004 | 235 | #define INTR_EN__ECC_ERR 0x0002 |
236 | #define INTR_EN0__TIME_OUT 0x0008 | 236 | #define INTR_EN__DMA_CMD_COMP 0x0004 |
237 | #define INTR_EN0__PROGRAM_FAIL 0x0010 | 237 | #define INTR_EN__TIME_OUT 0x0008 |
238 | #define INTR_EN0__ERASE_FAIL 0x0020 | 238 | #define INTR_EN__PROGRAM_FAIL 0x0010 |
239 | #define INTR_EN0__LOAD_COMP 0x0040 | 239 | #define INTR_EN__ERASE_FAIL 0x0020 |
240 | #define INTR_EN0__PROGRAM_COMP 0x0080 | 240 | #define INTR_EN__LOAD_COMP 0x0040 |
241 | #define INTR_EN0__ERASE_COMP 0x0100 | 241 | #define INTR_EN__PROGRAM_COMP 0x0080 |
242 | #define INTR_EN0__PIPE_CPYBCK_CMD_COMP 0x0200 | 242 | #define INTR_EN__ERASE_COMP 0x0100 |
243 | #define INTR_EN0__LOCKED_BLK 0x0400 | 243 | #define INTR_EN__PIPE_CPYBCK_CMD_COMP 0x0200 |
244 | #define INTR_EN0__UNSUP_CMD 0x0800 | 244 | #define INTR_EN__LOCKED_BLK 0x0400 |
245 | #define INTR_EN0__INT_ACT 0x1000 | 245 | #define INTR_EN__UNSUP_CMD 0x0800 |
246 | #define INTR_EN0__RST_COMP 0x2000 | 246 | #define INTR_EN__INT_ACT 0x1000 |
247 | #define INTR_EN0__PIPE_CMD_ERR 0x4000 | 247 | #define INTR_EN__RST_COMP 0x2000 |
248 | #define INTR_EN0__PAGE_XFER_INC 0x8000 | 248 | #define INTR_EN__PIPE_CMD_ERR 0x4000 |
249 | 249 | #define INTR_EN__PAGE_XFER_INC 0x8000 | |
250 | #define PAGE_CNT0 0x430 | 250 | |
251 | #define PAGE_CNT0__VALUE 0x00ff | 251 | #define PAGE_CNT(__bank) (0x430 + ((__bank) * 0x50)) |
252 | 252 | #define ERR_PAGE_ADDR(__bank) (0x440 + ((__bank) * 0x50)) | |
253 | #define ERR_PAGE_ADDR0 0x440 | 253 | #define ERR_BLOCK_ADDR(__bank) (0x450 + ((__bank) * 0x50)) |
254 | #define ERR_PAGE_ADDR0__VALUE 0xffff | ||
255 | |||
256 | #define ERR_BLOCK_ADDR0 0x450 | ||
257 | #define ERR_BLOCK_ADDR0__VALUE 0xffff | ||
258 | |||
259 | #define INTR_STATUS1 0x460 | ||
260 | #define INTR_STATUS1__ECC_TRANSACTION_DONE 0x0001 | ||
261 | #define INTR_STATUS1__ECC_ERR 0x0002 | ||
262 | #define INTR_STATUS1__DMA_CMD_COMP 0x0004 | ||
263 | #define INTR_STATUS1__TIME_OUT 0x0008 | ||
264 | #define INTR_STATUS1__PROGRAM_FAIL 0x0010 | ||
265 | #define INTR_STATUS1__ERASE_FAIL 0x0020 | ||
266 | #define INTR_STATUS1__LOAD_COMP 0x0040 | ||
267 | #define INTR_STATUS1__PROGRAM_COMP 0x0080 | ||
268 | #define INTR_STATUS1__ERASE_COMP 0x0100 | ||
269 | #define INTR_STATUS1__PIPE_CPYBCK_CMD_COMP 0x0200 | ||
270 | #define INTR_STATUS1__LOCKED_BLK 0x0400 | ||
271 | #define INTR_STATUS1__UNSUP_CMD 0x0800 | ||
272 | #define INTR_STATUS1__INT_ACT 0x1000 | ||
273 | #define INTR_STATUS1__RST_COMP 0x2000 | ||
274 | #define INTR_STATUS1__PIPE_CMD_ERR 0x4000 | ||
275 | #define INTR_STATUS1__PAGE_XFER_INC 0x8000 | ||
276 | |||
277 | #define INTR_EN1 0x470 | ||
278 | #define INTR_EN1__ECC_TRANSACTION_DONE 0x0001 | ||
279 | #define INTR_EN1__ECC_ERR 0x0002 | ||
280 | #define INTR_EN1__DMA_CMD_COMP 0x0004 | ||
281 | #define INTR_EN1__TIME_OUT 0x0008 | ||
282 | #define INTR_EN1__PROGRAM_FAIL 0x0010 | ||
283 | #define INTR_EN1__ERASE_FAIL 0x0020 | ||
284 | #define INTR_EN1__LOAD_COMP 0x0040 | ||
285 | #define INTR_EN1__PROGRAM_COMP 0x0080 | ||
286 | #define INTR_EN1__ERASE_COMP 0x0100 | ||
287 | #define INTR_EN1__PIPE_CPYBCK_CMD_COMP 0x0200 | ||
288 | #define INTR_EN1__LOCKED_BLK 0x0400 | ||
289 | #define INTR_EN1__UNSUP_CMD 0x0800 | ||
290 | #define INTR_EN1__INT_ACT 0x1000 | ||
291 | #define INTR_EN1__RST_COMP 0x2000 | ||
292 | #define INTR_EN1__PIPE_CMD_ERR 0x4000 | ||
293 | #define INTR_EN1__PAGE_XFER_INC 0x8000 | ||
294 | |||
295 | #define PAGE_CNT1 0x480 | ||
296 | #define PAGE_CNT1__VALUE 0x00ff | ||
297 | |||
298 | #define ERR_PAGE_ADDR1 0x490 | ||
299 | #define ERR_PAGE_ADDR1__VALUE 0xffff | ||
300 | |||
301 | #define ERR_BLOCK_ADDR1 0x4a0 | ||
302 | #define ERR_BLOCK_ADDR1__VALUE 0xffff | ||
303 | |||
304 | #define INTR_STATUS2 0x4b0 | ||
305 | #define INTR_STATUS2__ECC_TRANSACTION_DONE 0x0001 | ||
306 | #define INTR_STATUS2__ECC_ERR 0x0002 | ||
307 | #define INTR_STATUS2__DMA_CMD_COMP 0x0004 | ||
308 | #define INTR_STATUS2__TIME_OUT 0x0008 | ||
309 | #define INTR_STATUS2__PROGRAM_FAIL 0x0010 | ||
310 | #define INTR_STATUS2__ERASE_FAIL 0x0020 | ||
311 | #define INTR_STATUS2__LOAD_COMP 0x0040 | ||
312 | #define INTR_STATUS2__PROGRAM_COMP 0x0080 | ||
313 | #define INTR_STATUS2__ERASE_COMP 0x0100 | ||
314 | #define INTR_STATUS2__PIPE_CPYBCK_CMD_COMP 0x0200 | ||
315 | #define INTR_STATUS2__LOCKED_BLK 0x0400 | ||
316 | #define INTR_STATUS2__UNSUP_CMD 0x0800 | ||
317 | #define INTR_STATUS2__INT_ACT 0x1000 | ||
318 | #define INTR_STATUS2__RST_COMP 0x2000 | ||
319 | #define INTR_STATUS2__PIPE_CMD_ERR 0x4000 | ||
320 | #define INTR_STATUS2__PAGE_XFER_INC 0x8000 | ||
321 | |||
322 | #define INTR_EN2 0x4c0 | ||
323 | #define INTR_EN2__ECC_TRANSACTION_DONE 0x0001 | ||
324 | #define INTR_EN2__ECC_ERR 0x0002 | ||
325 | #define INTR_EN2__DMA_CMD_COMP 0x0004 | ||
326 | #define INTR_EN2__TIME_OUT 0x0008 | ||
327 | #define INTR_EN2__PROGRAM_FAIL 0x0010 | ||
328 | #define INTR_EN2__ERASE_FAIL 0x0020 | ||
329 | #define INTR_EN2__LOAD_COMP 0x0040 | ||
330 | #define INTR_EN2__PROGRAM_COMP 0x0080 | ||
331 | #define INTR_EN2__ERASE_COMP 0x0100 | ||
332 | #define INTR_EN2__PIPE_CPYBCK_CMD_COMP 0x0200 | ||
333 | #define INTR_EN2__LOCKED_BLK 0x0400 | ||
334 | #define INTR_EN2__UNSUP_CMD 0x0800 | ||
335 | #define INTR_EN2__INT_ACT 0x1000 | ||
336 | #define INTR_EN2__RST_COMP 0x2000 | ||
337 | #define INTR_EN2__PIPE_CMD_ERR 0x4000 | ||
338 | #define INTR_EN2__PAGE_XFER_INC 0x8000 | ||
339 | |||
340 | #define PAGE_CNT2 0x4d0 | ||
341 | #define PAGE_CNT2__VALUE 0x00ff | ||
342 | |||
343 | #define ERR_PAGE_ADDR2 0x4e0 | ||
344 | #define ERR_PAGE_ADDR2__VALUE 0xffff | ||
345 | |||
346 | #define ERR_BLOCK_ADDR2 0x4f0 | ||
347 | #define ERR_BLOCK_ADDR2__VALUE 0xffff | ||
348 | |||
349 | #define INTR_STATUS3 0x500 | ||
350 | #define INTR_STATUS3__ECC_TRANSACTION_DONE 0x0001 | ||
351 | #define INTR_STATUS3__ECC_ERR 0x0002 | ||
352 | #define INTR_STATUS3__DMA_CMD_COMP 0x0004 | ||
353 | #define INTR_STATUS3__TIME_OUT 0x0008 | ||
354 | #define INTR_STATUS3__PROGRAM_FAIL 0x0010 | ||
355 | #define INTR_STATUS3__ERASE_FAIL 0x0020 | ||
356 | #define INTR_STATUS3__LOAD_COMP 0x0040 | ||
357 | #define INTR_STATUS3__PROGRAM_COMP 0x0080 | ||
358 | #define INTR_STATUS3__ERASE_COMP 0x0100 | ||
359 | #define INTR_STATUS3__PIPE_CPYBCK_CMD_COMP 0x0200 | ||
360 | #define INTR_STATUS3__LOCKED_BLK 0x0400 | ||
361 | #define INTR_STATUS3__UNSUP_CMD 0x0800 | ||
362 | #define INTR_STATUS3__INT_ACT 0x1000 | ||
363 | #define INTR_STATUS3__RST_COMP 0x2000 | ||
364 | #define INTR_STATUS3__PIPE_CMD_ERR 0x4000 | ||
365 | #define INTR_STATUS3__PAGE_XFER_INC 0x8000 | ||
366 | |||
367 | #define INTR_EN3 0x510 | ||
368 | #define INTR_EN3__ECC_TRANSACTION_DONE 0x0001 | ||
369 | #define INTR_EN3__ECC_ERR 0x0002 | ||
370 | #define INTR_EN3__DMA_CMD_COMP 0x0004 | ||
371 | #define INTR_EN3__TIME_OUT 0x0008 | ||
372 | #define INTR_EN3__PROGRAM_FAIL 0x0010 | ||
373 | #define INTR_EN3__ERASE_FAIL 0x0020 | ||
374 | #define INTR_EN3__LOAD_COMP 0x0040 | ||
375 | #define INTR_EN3__PROGRAM_COMP 0x0080 | ||
376 | #define INTR_EN3__ERASE_COMP 0x0100 | ||
377 | #define INTR_EN3__PIPE_CPYBCK_CMD_COMP 0x0200 | ||
378 | #define INTR_EN3__LOCKED_BLK 0x0400 | ||
379 | #define INTR_EN3__UNSUP_CMD 0x0800 | ||
380 | #define INTR_EN3__INT_ACT 0x1000 | ||
381 | #define INTR_EN3__RST_COMP 0x2000 | ||
382 | #define INTR_EN3__PIPE_CMD_ERR 0x4000 | ||
383 | #define INTR_EN3__PAGE_XFER_INC 0x8000 | ||
384 | |||
385 | #define PAGE_CNT3 0x520 | ||
386 | #define PAGE_CNT3__VALUE 0x00ff | ||
387 | |||
388 | #define ERR_PAGE_ADDR3 0x530 | ||
389 | #define ERR_PAGE_ADDR3__VALUE 0xffff | ||
390 | |||
391 | #define ERR_BLOCK_ADDR3 0x540 | ||
392 | #define ERR_BLOCK_ADDR3__VALUE 0xffff | ||
393 | 254 | ||
394 | #define DATA_INTR 0x550 | 255 | #define DATA_INTR 0x550 |
395 | #define DATA_INTR__WRITE_SPACE_AV 0x0001 | 256 | #define DATA_INTR__WRITE_SPACE_AV 0x0001 |
@@ -484,141 +345,23 @@ | |||
484 | #define PTN_INTR_EN__ACCESS_ERROR_BANK3 0x0010 | 345 | #define PTN_INTR_EN__ACCESS_ERROR_BANK3 0x0010 |
485 | #define PTN_INTR_EN__REG_ACCESS_ERROR 0x0020 | 346 | #define PTN_INTR_EN__REG_ACCESS_ERROR 0x0020 |
486 | 347 | ||
487 | #define PERM_SRC_ID_0 0x830 | 348 | #define PERM_SRC_ID(__bank) (0x830 + ((__bank) * 0x40)) |
488 | #define PERM_SRC_ID_0__SRCID 0x00ff | 349 | #define PERM_SRC_ID__SRCID 0x00ff |
489 | #define PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE 0x0800 | 350 | #define PERM_SRC_ID__DIRECT_ACCESS_ACTIVE 0x0800 |
490 | #define PERM_SRC_ID_0__WRITE_ACTIVE 0x2000 | 351 | #define PERM_SRC_ID__WRITE_ACTIVE 0x2000 |
491 | #define PERM_SRC_ID_0__READ_ACTIVE 0x4000 | 352 | #define PERM_SRC_ID__READ_ACTIVE 0x4000 |
492 | #define PERM_SRC_ID_0__PARTITION_VALID 0x8000 | 353 | #define PERM_SRC_ID__PARTITION_VALID 0x8000 |
493 | 354 | ||
494 | #define MIN_BLK_ADDR_0 0x840 | 355 | #define MIN_BLK_ADDR(__bank) (0x840 + ((__bank) * 0x40)) |
495 | #define MIN_BLK_ADDR_0__VALUE 0xffff | 356 | #define MIN_BLK_ADDR__VALUE 0xffff |
496 | 357 | ||
497 | #define MAX_BLK_ADDR_0 0x850 | 358 | #define MAX_BLK_ADDR(__bank) (0x850 + ((__bank) * 0x40)) |
498 | #define MAX_BLK_ADDR_0__VALUE 0xffff | 359 | #define MAX_BLK_ADDR__VALUE 0xffff |
499 | 360 | ||
500 | #define MIN_MAX_BANK_0 0x860 | 361 | #define MIN_MAX_BANK(__bank) (0x860 + ((__bank) * 0x40)) |
501 | #define MIN_MAX_BANK_0__MIN_VALUE 0x0003 | 362 | #define MIN_MAX_BANK__MIN_VALUE 0x0003 |
502 | #define MIN_MAX_BANK_0__MAX_VALUE 0x000c | 363 | #define MIN_MAX_BANK__MAX_VALUE 0x000c |
503 | |||
504 | #define PERM_SRC_ID_1 0x870 | ||
505 | #define PERM_SRC_ID_1__SRCID 0x00ff | ||
506 | #define PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE 0x0800 | ||
507 | #define PERM_SRC_ID_1__WRITE_ACTIVE 0x2000 | ||
508 | #define PERM_SRC_ID_1__READ_ACTIVE 0x4000 | ||
509 | #define PERM_SRC_ID_1__PARTITION_VALID 0x8000 | ||
510 | |||
511 | #define MIN_BLK_ADDR_1 0x880 | ||
512 | #define MIN_BLK_ADDR_1__VALUE 0xffff | ||
513 | |||
514 | #define MAX_BLK_ADDR_1 0x890 | ||
515 | #define MAX_BLK_ADDR_1__VALUE 0xffff | ||
516 | |||
517 | #define MIN_MAX_BANK_1 0x8a0 | ||
518 | #define MIN_MAX_BANK_1__MIN_VALUE 0x0003 | ||
519 | #define MIN_MAX_BANK_1__MAX_VALUE 0x000c | ||
520 | |||
521 | #define PERM_SRC_ID_2 0x8b0 | ||
522 | #define PERM_SRC_ID_2__SRCID 0x00ff | ||
523 | #define PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE 0x0800 | ||
524 | #define PERM_SRC_ID_2__WRITE_ACTIVE 0x2000 | ||
525 | #define PERM_SRC_ID_2__READ_ACTIVE 0x4000 | ||
526 | #define PERM_SRC_ID_2__PARTITION_VALID 0x8000 | ||
527 | |||
528 | #define MIN_BLK_ADDR_2 0x8c0 | ||
529 | #define MIN_BLK_ADDR_2__VALUE 0xffff | ||
530 | |||
531 | #define MAX_BLK_ADDR_2 0x8d0 | ||
532 | #define MAX_BLK_ADDR_2__VALUE 0xffff | ||
533 | |||
534 | #define MIN_MAX_BANK_2 0x8e0 | ||
535 | #define MIN_MAX_BANK_2__MIN_VALUE 0x0003 | ||
536 | #define MIN_MAX_BANK_2__MAX_VALUE 0x000c | ||
537 | |||
538 | #define PERM_SRC_ID_3 0x8f0 | ||
539 | #define PERM_SRC_ID_3__SRCID 0x00ff | ||
540 | #define PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE 0x0800 | ||
541 | #define PERM_SRC_ID_3__WRITE_ACTIVE 0x2000 | ||
542 | #define PERM_SRC_ID_3__READ_ACTIVE 0x4000 | ||
543 | #define PERM_SRC_ID_3__PARTITION_VALID 0x8000 | ||
544 | |||
545 | #define MIN_BLK_ADDR_3 0x900 | ||
546 | #define MIN_BLK_ADDR_3__VALUE 0xffff | ||
547 | |||
548 | #define MAX_BLK_ADDR_3 0x910 | ||
549 | #define MAX_BLK_ADDR_3__VALUE 0xffff | ||
550 | |||
551 | #define MIN_MAX_BANK_3 0x920 | ||
552 | #define MIN_MAX_BANK_3__MIN_VALUE 0x0003 | ||
553 | #define MIN_MAX_BANK_3__MAX_VALUE 0x000c | ||
554 | |||
555 | #define PERM_SRC_ID_4 0x930 | ||
556 | #define PERM_SRC_ID_4__SRCID 0x00ff | ||
557 | #define PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE 0x0800 | ||
558 | #define PERM_SRC_ID_4__WRITE_ACTIVE 0x2000 | ||
559 | #define PERM_SRC_ID_4__READ_ACTIVE 0x4000 | ||
560 | #define PERM_SRC_ID_4__PARTITION_VALID 0x8000 | ||
561 | |||
562 | #define MIN_BLK_ADDR_4 0x940 | ||
563 | #define MIN_BLK_ADDR_4__VALUE 0xffff | ||
564 | |||
565 | #define MAX_BLK_ADDR_4 0x950 | ||
566 | #define MAX_BLK_ADDR_4__VALUE 0xffff | ||
567 | |||
568 | #define MIN_MAX_BANK_4 0x960 | ||
569 | #define MIN_MAX_BANK_4__MIN_VALUE 0x0003 | ||
570 | #define MIN_MAX_BANK_4__MAX_VALUE 0x000c | ||
571 | |||
572 | #define PERM_SRC_ID_5 0x970 | ||
573 | #define PERM_SRC_ID_5__SRCID 0x00ff | ||
574 | #define PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE 0x0800 | ||
575 | #define PERM_SRC_ID_5__WRITE_ACTIVE 0x2000 | ||
576 | #define PERM_SRC_ID_5__READ_ACTIVE 0x4000 | ||
577 | #define PERM_SRC_ID_5__PARTITION_VALID 0x8000 | ||
578 | |||
579 | #define MIN_BLK_ADDR_5 0x980 | ||
580 | #define MIN_BLK_ADDR_5__VALUE 0xffff | ||
581 | |||
582 | #define MAX_BLK_ADDR_5 0x990 | ||
583 | #define MAX_BLK_ADDR_5__VALUE 0xffff | ||
584 | |||
585 | #define MIN_MAX_BANK_5 0x9a0 | ||
586 | #define MIN_MAX_BANK_5__MIN_VALUE 0x0003 | ||
587 | #define MIN_MAX_BANK_5__MAX_VALUE 0x000c | ||
588 | |||
589 | #define PERM_SRC_ID_6 0x9b0 | ||
590 | #define PERM_SRC_ID_6__SRCID 0x00ff | ||
591 | #define PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE 0x0800 | ||
592 | #define PERM_SRC_ID_6__WRITE_ACTIVE 0x2000 | ||
593 | #define PERM_SRC_ID_6__READ_ACTIVE 0x4000 | ||
594 | #define PERM_SRC_ID_6__PARTITION_VALID 0x8000 | ||
595 | |||
596 | #define MIN_BLK_ADDR_6 0x9c0 | ||
597 | #define MIN_BLK_ADDR_6__VALUE 0xffff | ||
598 | |||
599 | #define MAX_BLK_ADDR_6 0x9d0 | ||
600 | #define MAX_BLK_ADDR_6__VALUE 0xffff | ||
601 | |||
602 | #define MIN_MAX_BANK_6 0x9e0 | ||
603 | #define MIN_MAX_BANK_6__MIN_VALUE 0x0003 | ||
604 | #define MIN_MAX_BANK_6__MAX_VALUE 0x000c | ||
605 | |||
606 | #define PERM_SRC_ID_7 0x9f0 | ||
607 | #define PERM_SRC_ID_7__SRCID 0x00ff | ||
608 | #define PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE 0x0800 | ||
609 | #define PERM_SRC_ID_7__WRITE_ACTIVE 0x2000 | ||
610 | #define PERM_SRC_ID_7__READ_ACTIVE 0x4000 | ||
611 | #define PERM_SRC_ID_7__PARTITION_VALID 0x8000 | ||
612 | 364 | ||
613 | #define MIN_BLK_ADDR_7 0xa00 | ||
614 | #define MIN_BLK_ADDR_7__VALUE 0xffff | ||
615 | |||
616 | #define MAX_BLK_ADDR_7 0xa10 | ||
617 | #define MAX_BLK_ADDR_7__VALUE 0xffff | ||
618 | |||
619 | #define MIN_MAX_BANK_7 0xa20 | ||
620 | #define MIN_MAX_BANK_7__MIN_VALUE 0x0003 | ||
621 | #define MIN_MAX_BANK_7__MAX_VALUE 0x000c | ||
622 | 365 | ||
623 | /* ffsdefs.h */ | 366 | /* ffsdefs.h */ |
624 | #define CLEAR 0 /*use this to clear a field instead of "fail"*/ | 367 | #define CLEAR 0 /*use this to clear a field instead of "fail"*/ |
@@ -711,7 +454,6 @@ | |||
711 | #define READ_WRITE_ENABLE_HIGH_COUNT 22 | 454 | #define READ_WRITE_ENABLE_HIGH_COUNT 22 |
712 | 455 | ||
713 | #define ECC_SECTOR_SIZE 512 | 456 | #define ECC_SECTOR_SIZE 512 |
714 | #define LLD_MAX_FLASH_BANKS 4 | ||
715 | 457 | ||
716 | #define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) | 458 | #define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) |
717 | 459 | ||
@@ -732,7 +474,7 @@ struct denali_nand_info { | |||
732 | int status; | 474 | int status; |
733 | int platform; | 475 | int platform; |
734 | struct nand_buf buf; | 476 | struct nand_buf buf; |
735 | struct pci_dev *dev; | 477 | struct device *dev; |
736 | int total_used_banks; | 478 | int total_used_banks; |
737 | uint32_t block; /* stored for future use */ | 479 | uint32_t block; /* stored for future use */ |
738 | uint16_t page; | 480 | uint16_t page; |
@@ -751,6 +493,7 @@ struct denali_nand_info { | |||
751 | uint32_t totalblks; | 493 | uint32_t totalblks; |
752 | uint32_t blksperchip; | 494 | uint32_t blksperchip; |
753 | uint32_t bbtskipbytes; | 495 | uint32_t bbtskipbytes; |
496 | uint32_t max_banks; | ||
754 | }; | 497 | }; |
755 | 498 | ||
756 | #endif /*_LLD_NAND_*/ | 499 | #endif /*_LLD_NAND_*/ |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 657b9f4b6f9b..7837728d02ff 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -1360,11 +1360,9 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd) | |||
1360 | At least as nand_bbt.c is currently written. */ | 1360 | At least as nand_bbt.c is currently written. */ |
1361 | if ((ret = nand_scan_bbt(mtd, NULL))) | 1361 | if ((ret = nand_scan_bbt(mtd, NULL))) |
1362 | return ret; | 1362 | return ret; |
1363 | add_mtd_device(mtd); | 1363 | mtd_device_register(mtd, NULL, 0); |
1364 | #ifdef CONFIG_MTD_PARTITIONS | ||
1365 | if (!no_autopart) | 1364 | if (!no_autopart) |
1366 | add_mtd_partitions(mtd, parts, numparts); | 1365 | mtd_device_register(mtd, parts, numparts); |
1367 | #endif | ||
1368 | return 0; | 1366 | return 0; |
1369 | } | 1367 | } |
1370 | 1368 | ||
@@ -1419,11 +1417,9 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) | |||
1419 | autopartitioning, but I want to give it more thought. */ | 1417 | autopartitioning, but I want to give it more thought. */ |
1420 | if (!numparts) | 1418 | if (!numparts) |
1421 | return -EIO; | 1419 | return -EIO; |
1422 | add_mtd_device(mtd); | 1420 | mtd_device_register(mtd, NULL, 0); |
1423 | #ifdef CONFIG_MTD_PARTITIONS | ||
1424 | if (!no_autopart) | 1421 | if (!no_autopart) |
1425 | add_mtd_partitions(mtd, parts, numparts); | 1422 | mtd_device_register(mtd, parts, numparts); |
1426 | #endif | ||
1427 | return 0; | 1423 | return 0; |
1428 | } | 1424 | } |
1429 | 1425 | ||
@@ -1678,9 +1674,9 @@ static int __init doc_probe(unsigned long physadr) | |||
1678 | /* DBB note: i believe nand_release is necessary here, as | 1674 | /* DBB note: i believe nand_release is necessary here, as |
1679 | buffers may have been allocated in nand_base. Check with | 1675 | buffers may have been allocated in nand_base. Check with |
1680 | Thomas. FIX ME! */ | 1676 | Thomas. FIX ME! */ |
1681 | /* nand_release will call del_mtd_device, but we haven't yet | 1677 | /* nand_release will call mtd_device_unregister, but we |
1682 | added it. This is handled without incident by | 1678 | haven't yet added it. This is handled without incident by |
1683 | del_mtd_device, as far as I can tell. */ | 1679 | mtd_device_unregister, as far as I can tell. */ |
1684 | nand_release(mtd); | 1680 | nand_release(mtd); |
1685 | kfree(mtd); | 1681 | kfree(mtd); |
1686 | goto fail; | 1682 | goto fail; |
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c index 86366bfba9f8..8400d0f6dada 100644 --- a/drivers/mtd/nand/edb7312.c +++ b/drivers/mtd/nand/edb7312.c | |||
@@ -55,7 +55,6 @@ static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE; | |||
55 | static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR; | 55 | static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR; |
56 | static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR; | 56 | static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR; |
57 | 57 | ||
58 | #ifdef CONFIG_MTD_PARTITIONS | ||
59 | /* | 58 | /* |
60 | * Define static partitions for flash device | 59 | * Define static partitions for flash device |
61 | */ | 60 | */ |
@@ -67,8 +66,6 @@ static struct mtd_partition partition_info[] = { | |||
67 | 66 | ||
68 | #define NUM_PARTITIONS 1 | 67 | #define NUM_PARTITIONS 1 |
69 | 68 | ||
70 | #endif | ||
71 | |||
72 | /* | 69 | /* |
73 | * hardware specific access to control-lines | 70 | * hardware specific access to control-lines |
74 | * | 71 | * |
@@ -101,9 +98,7 @@ static int ep7312_device_ready(struct mtd_info *mtd) | |||
101 | return 1; | 98 | return 1; |
102 | } | 99 | } |
103 | 100 | ||
104 | #ifdef CONFIG_MTD_PARTITIONS | ||
105 | const char *part_probes[] = { "cmdlinepart", NULL }; | 101 | const char *part_probes[] = { "cmdlinepart", NULL }; |
106 | #endif | ||
107 | 102 | ||
108 | /* | 103 | /* |
109 | * Main initialization routine | 104 | * Main initialization routine |
@@ -162,14 +157,12 @@ static int __init ep7312_init(void) | |||
162 | kfree(ep7312_mtd); | 157 | kfree(ep7312_mtd); |
163 | return -ENXIO; | 158 | return -ENXIO; |
164 | } | 159 | } |
165 | #ifdef CONFIG_MTD_PARTITIONS | ||
166 | ep7312_mtd->name = "edb7312-nand"; | 160 | ep7312_mtd->name = "edb7312-nand"; |
167 | mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0); | 161 | mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0); |
168 | if (mtd_parts_nb > 0) | 162 | if (mtd_parts_nb > 0) |
169 | part_type = "command line"; | 163 | part_type = "command line"; |
170 | else | 164 | else |
171 | mtd_parts_nb = 0; | 165 | mtd_parts_nb = 0; |
172 | #endif | ||
173 | if (mtd_parts_nb == 0) { | 166 | if (mtd_parts_nb == 0) { |
174 | mtd_parts = partition_info; | 167 | mtd_parts = partition_info; |
175 | mtd_parts_nb = NUM_PARTITIONS; | 168 | mtd_parts_nb = NUM_PARTITIONS; |
@@ -178,7 +171,7 @@ static int __init ep7312_init(void) | |||
178 | 171 | ||
179 | /* Register the partitions */ | 172 | /* Register the partitions */ |
180 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 173 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
181 | add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); | 174 | mtd_device_register(ep7312_mtd, mtd_parts, mtd_parts_nb); |
182 | 175 | ||
183 | /* Return happy */ | 176 | /* Return happy */ |
184 | return 0; | 177 | return 0; |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 537e380b8dcb..0bb254c7d2b1 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -841,12 +841,9 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev) | |||
841 | struct fsl_elbc_mtd *priv; | 841 | struct fsl_elbc_mtd *priv; |
842 | struct resource res; | 842 | struct resource res; |
843 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl; | 843 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl; |
844 | |||
845 | #ifdef CONFIG_MTD_PARTITIONS | ||
846 | static const char *part_probe_types[] | 844 | static const char *part_probe_types[] |
847 | = { "cmdlinepart", "RedBoot", NULL }; | 845 | = { "cmdlinepart", "RedBoot", NULL }; |
848 | struct mtd_partition *parts; | 846 | struct mtd_partition *parts; |
849 | #endif | ||
850 | int ret; | 847 | int ret; |
851 | int bank; | 848 | int bank; |
852 | struct device *dev; | 849 | struct device *dev; |
@@ -935,26 +932,19 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev) | |||
935 | if (ret) | 932 | if (ret) |
936 | goto err; | 933 | goto err; |
937 | 934 | ||
938 | #ifdef CONFIG_MTD_PARTITIONS | ||
939 | /* First look for RedBoot table or partitions on the command | 935 | /* First look for RedBoot table or partitions on the command |
940 | * line, these take precedence over device tree information */ | 936 | * line, these take precedence over device tree information */ |
941 | ret = parse_mtd_partitions(&priv->mtd, part_probe_types, &parts, 0); | 937 | ret = parse_mtd_partitions(&priv->mtd, part_probe_types, &parts, 0); |
942 | if (ret < 0) | 938 | if (ret < 0) |
943 | goto err; | 939 | goto err; |
944 | 940 | ||
945 | #ifdef CONFIG_MTD_OF_PARTS | ||
946 | if (ret == 0) { | 941 | if (ret == 0) { |
947 | ret = of_mtd_parse_partitions(priv->dev, node, &parts); | 942 | ret = of_mtd_parse_partitions(priv->dev, node, &parts); |
948 | if (ret < 0) | 943 | if (ret < 0) |
949 | goto err; | 944 | goto err; |
950 | } | 945 | } |
951 | #endif | ||
952 | 946 | ||
953 | if (ret > 0) | 947 | mtd_device_register(&priv->mtd, parts, ret); |
954 | add_mtd_partitions(&priv->mtd, parts, ret); | ||
955 | else | ||
956 | #endif | ||
957 | add_mtd_device(&priv->mtd); | ||
958 | 948 | ||
959 | printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", | 949 | printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", |
960 | (unsigned long long)res.start, priv->bank); | 950 | (unsigned long long)res.start, priv->bank); |
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 073ee026a17c..23752fd5bc59 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
@@ -33,10 +33,7 @@ struct fsl_upm_nand { | |||
33 | struct mtd_info mtd; | 33 | struct mtd_info mtd; |
34 | struct nand_chip chip; | 34 | struct nand_chip chip; |
35 | int last_ctrl; | 35 | int last_ctrl; |
36 | #ifdef CONFIG_MTD_PARTITIONS | ||
37 | struct mtd_partition *parts; | 36 | struct mtd_partition *parts; |
38 | #endif | ||
39 | |||
40 | struct fsl_upm upm; | 37 | struct fsl_upm upm; |
41 | uint8_t upm_addr_offset; | 38 | uint8_t upm_addr_offset; |
42 | uint8_t upm_cmd_offset; | 39 | uint8_t upm_cmd_offset; |
@@ -161,9 +158,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | |||
161 | { | 158 | { |
162 | int ret; | 159 | int ret; |
163 | struct device_node *flash_np; | 160 | struct device_node *flash_np; |
164 | #ifdef CONFIG_MTD_PARTITIONS | ||
165 | static const char *part_types[] = { "cmdlinepart", NULL, }; | 161 | static const char *part_types[] = { "cmdlinepart", NULL, }; |
166 | #endif | ||
167 | 162 | ||
168 | fun->chip.IO_ADDR_R = fun->io_base; | 163 | fun->chip.IO_ADDR_R = fun->io_base; |
169 | fun->chip.IO_ADDR_W = fun->io_base; | 164 | fun->chip.IO_ADDR_W = fun->io_base; |
@@ -197,7 +192,6 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | |||
197 | if (ret) | 192 | if (ret) |
198 | goto err; | 193 | goto err; |
199 | 194 | ||
200 | #ifdef CONFIG_MTD_PARTITIONS | ||
201 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); | 195 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); |
202 | 196 | ||
203 | #ifdef CONFIG_MTD_OF_PARTS | 197 | #ifdef CONFIG_MTD_OF_PARTS |
@@ -207,11 +201,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | |||
207 | goto err; | 201 | goto err; |
208 | } | 202 | } |
209 | #endif | 203 | #endif |
210 | if (ret > 0) | 204 | ret = mtd_device_register(&fun->mtd, fun->parts, ret); |
211 | ret = add_mtd_partitions(&fun->mtd, fun->parts, ret); | ||
212 | else | ||
213 | #endif | ||
214 | ret = add_mtd_device(&fun->mtd); | ||
215 | err: | 205 | err: |
216 | of_node_put(flash_np); | 206 | of_node_put(flash_np); |
217 | return ret; | 207 | return ret; |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 0d45ef3883e8..e9b275ac381c 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -120,8 +120,6 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = { | |||
120 | } | 120 | } |
121 | }; | 121 | }; |
122 | 122 | ||
123 | |||
124 | #ifdef CONFIG_MTD_PARTITIONS | ||
125 | /* | 123 | /* |
126 | * Default partition tables to be used if the partition information not | 124 | * Default partition tables to be used if the partition information not |
127 | * provided through platform data. | 125 | * provided through platform data. |
@@ -182,7 +180,6 @@ static struct mtd_partition partition_info_128KB_blk[] = { | |||
182 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 180 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
183 | const char *part_probes[] = { "cmdlinepart", NULL }; | 181 | const char *part_probes[] = { "cmdlinepart", NULL }; |
184 | #endif | 182 | #endif |
185 | #endif | ||
186 | 183 | ||
187 | /** | 184 | /** |
188 | * struct fsmc_nand_data - structure for FSMC NAND device state | 185 | * struct fsmc_nand_data - structure for FSMC NAND device state |
@@ -719,7 +716,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
719 | * platform data, | 716 | * platform data, |
720 | * default partition information present in driver. | 717 | * default partition information present in driver. |
721 | */ | 718 | */ |
722 | #ifdef CONFIG_MTD_PARTITIONS | ||
723 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 719 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
724 | /* | 720 | /* |
725 | * Check if partition info passed via command line | 721 | * Check if partition info passed via command line |
@@ -777,19 +773,10 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
777 | } | 773 | } |
778 | #endif | 774 | #endif |
779 | 775 | ||
780 | if (host->partitions) { | 776 | ret = mtd_device_register(&host->mtd, host->partitions, |
781 | ret = add_mtd_partitions(&host->mtd, host->partitions, | 777 | host->nr_partitions); |
782 | host->nr_partitions); | 778 | if (ret) |
783 | if (ret) | ||
784 | goto err_probe; | ||
785 | } | ||
786 | #else | ||
787 | dev_info(&pdev->dev, "Registering %s as whole device\n", mtd->name); | ||
788 | if (!add_mtd_device(mtd)) { | ||
789 | ret = -ENXIO; | ||
790 | goto err_probe; | 779 | goto err_probe; |
791 | } | ||
792 | #endif | ||
793 | 780 | ||
794 | platform_set_drvdata(pdev, host); | 781 | platform_set_drvdata(pdev, host); |
795 | dev_info(&pdev->dev, "FSMC NAND driver registration successful\n"); | 782 | dev_info(&pdev->dev, "FSMC NAND driver registration successful\n"); |
@@ -835,11 +822,7 @@ static int fsmc_nand_remove(struct platform_device *pdev) | |||
835 | platform_set_drvdata(pdev, NULL); | 822 | platform_set_drvdata(pdev, NULL); |
836 | 823 | ||
837 | if (host) { | 824 | if (host) { |
838 | #ifdef CONFIG_MTD_PARTITIONS | 825 | mtd_device_unregister(&host->mtd); |
839 | del_mtd_partitions(&host->mtd); | ||
840 | #else | ||
841 | del_mtd_device(&host->mtd); | ||
842 | #endif | ||
843 | clk_disable(host->clk); | 826 | clk_disable(host->clk); |
844 | clk_put(host->clk); | 827 | clk_put(host->clk); |
845 | 828 | ||
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 0cde618bcc1e..2c2060b2800e 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
@@ -316,8 +316,8 @@ static int __devinit gpio_nand_probe(struct platform_device *dev) | |||
316 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, | 316 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, |
317 | gpiomtd->mtd_info.size); | 317 | gpiomtd->mtd_info.size); |
318 | 318 | ||
319 | add_mtd_partitions(&gpiomtd->mtd_info, gpiomtd->plat.parts, | 319 | mtd_device_register(&gpiomtd->mtd_info, gpiomtd->plat.parts, |
320 | gpiomtd->plat.num_parts); | 320 | gpiomtd->plat.num_parts); |
321 | platform_set_drvdata(dev, gpiomtd); | 321 | platform_set_drvdata(dev, gpiomtd); |
322 | 322 | ||
323 | return 0; | 323 | return 0; |
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c index f8ce79b446ed..02a03e67109c 100644 --- a/drivers/mtd/nand/h1910.c +++ b/drivers/mtd/nand/h1910.c | |||
@@ -38,7 +38,6 @@ static struct mtd_info *h1910_nand_mtd = NULL; | |||
38 | * Module stuff | 38 | * Module stuff |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #ifdef CONFIG_MTD_PARTITIONS | ||
42 | /* | 41 | /* |
43 | * Define static partitions for flash device | 42 | * Define static partitions for flash device |
44 | */ | 43 | */ |
@@ -50,8 +49,6 @@ static struct mtd_partition partition_info[] = { | |||
50 | 49 | ||
51 | #define NUM_PARTITIONS 1 | 50 | #define NUM_PARTITIONS 1 |
52 | 51 | ||
53 | #endif | ||
54 | |||
55 | /* | 52 | /* |
56 | * hardware specific access to control-lines | 53 | * hardware specific access to control-lines |
57 | * | 54 | * |
@@ -154,7 +151,7 @@ static int __init h1910_init(void) | |||
154 | 151 | ||
155 | /* Register the partitions */ | 152 | /* Register the partitions */ |
156 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 153 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
157 | add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); | 154 | mtd_device_register(h1910_nand_mtd, mtd_parts, mtd_parts_nb); |
158 | 155 | ||
159 | /* Return happy */ | 156 | /* Return happy */ |
160 | return 0; | 157 | return 0; |
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index cea38a5d4ac5..6e813daed068 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c | |||
@@ -299,10 +299,8 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) | |||
299 | struct nand_chip *chip; | 299 | struct nand_chip *chip; |
300 | struct mtd_info *mtd; | 300 | struct mtd_info *mtd; |
301 | struct jz_nand_platform_data *pdata = pdev->dev.platform_data; | 301 | struct jz_nand_platform_data *pdata = pdev->dev.platform_data; |
302 | #ifdef CONFIG_MTD_PARTITIONS | ||
303 | struct mtd_partition *partition_info; | 302 | struct mtd_partition *partition_info; |
304 | int num_partitions = 0; | 303 | int num_partitions = 0; |
305 | #endif | ||
306 | 304 | ||
307 | nand = kzalloc(sizeof(*nand), GFP_KERNEL); | 305 | nand = kzalloc(sizeof(*nand), GFP_KERNEL); |
308 | if (!nand) { | 306 | if (!nand) { |
@@ -375,7 +373,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) | |||
375 | goto err_gpio_free; | 373 | goto err_gpio_free; |
376 | } | 374 | } |
377 | 375 | ||
378 | #ifdef CONFIG_MTD_PARTITIONS | ||
379 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 376 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
380 | num_partitions = parse_mtd_partitions(mtd, part_probes, | 377 | num_partitions = parse_mtd_partitions(mtd, part_probes, |
381 | &partition_info, 0); | 378 | &partition_info, 0); |
@@ -384,12 +381,7 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) | |||
384 | num_partitions = pdata->num_partitions; | 381 | num_partitions = pdata->num_partitions; |
385 | partition_info = pdata->partitions; | 382 | partition_info = pdata->partitions; |
386 | } | 383 | } |
387 | 384 | ret = mtd_device_register(mtd, partition_info, num_partitions); | |
388 | if (num_partitions > 0) | ||
389 | ret = add_mtd_partitions(mtd, partition_info, num_partitions); | ||
390 | else | ||
391 | #endif | ||
392 | ret = add_mtd_device(mtd); | ||
393 | 385 | ||
394 | if (ret) { | 386 | if (ret) { |
395 | dev_err(&pdev->dev, "Failed to add mtd device\n"); | 387 | dev_err(&pdev->dev, "Failed to add mtd device\n"); |
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 0b81b5b499d1..2f7c930872f9 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c | |||
@@ -131,9 +131,7 @@ struct mpc5121_nfc_prv { | |||
131 | 131 | ||
132 | static void mpc5121_nfc_done(struct mtd_info *mtd); | 132 | static void mpc5121_nfc_done(struct mtd_info *mtd); |
133 | 133 | ||
134 | #ifdef CONFIG_MTD_PARTITIONS | ||
135 | static const char *mpc5121_nfc_pprobes[] = { "cmdlinepart", NULL }; | 134 | static const char *mpc5121_nfc_pprobes[] = { "cmdlinepart", NULL }; |
136 | #endif | ||
137 | 135 | ||
138 | /* Read NFC register */ | 136 | /* Read NFC register */ |
139 | static inline u16 nfc_read(struct mtd_info *mtd, uint reg) | 137 | static inline u16 nfc_read(struct mtd_info *mtd, uint reg) |
@@ -658,9 +656,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op) | |||
658 | struct mpc5121_nfc_prv *prv; | 656 | struct mpc5121_nfc_prv *prv; |
659 | struct resource res; | 657 | struct resource res; |
660 | struct mtd_info *mtd; | 658 | struct mtd_info *mtd; |
661 | #ifdef CONFIG_MTD_PARTITIONS | ||
662 | struct mtd_partition *parts; | 659 | struct mtd_partition *parts; |
663 | #endif | ||
664 | struct nand_chip *chip; | 660 | struct nand_chip *chip; |
665 | unsigned long regs_paddr, regs_size; | 661 | unsigned long regs_paddr, regs_size; |
666 | const __be32 *chips_no; | 662 | const __be32 *chips_no; |
@@ -841,7 +837,6 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op) | |||
841 | dev_set_drvdata(dev, mtd); | 837 | dev_set_drvdata(dev, mtd); |
842 | 838 | ||
843 | /* Register device in MTD */ | 839 | /* Register device in MTD */ |
844 | #ifdef CONFIG_MTD_PARTITIONS | ||
845 | retval = parse_mtd_partitions(mtd, mpc5121_nfc_pprobes, &parts, 0); | 840 | retval = parse_mtd_partitions(mtd, mpc5121_nfc_pprobes, &parts, 0); |
846 | #ifdef CONFIG_MTD_OF_PARTS | 841 | #ifdef CONFIG_MTD_OF_PARTS |
847 | if (retval == 0) | 842 | if (retval == 0) |
@@ -854,12 +849,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op) | |||
854 | goto error; | 849 | goto error; |
855 | } | 850 | } |
856 | 851 | ||
857 | if (retval > 0) | 852 | retval = mtd_device_register(mtd, parts, retval); |
858 | retval = add_mtd_partitions(mtd, parts, retval); | ||
859 | else | ||
860 | #endif | ||
861 | retval = add_mtd_device(mtd); | ||
862 | |||
863 | if (retval) { | 853 | if (retval) { |
864 | dev_err(dev, "Error adding MTD device!\n"); | 854 | dev_err(dev, "Error adding MTD device!\n"); |
865 | devm_free_irq(dev, prv->irq, mtd); | 855 | devm_free_irq(dev, prv->irq, mtd); |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 42a95fb41504..90df34c4d26c 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -56,8 +56,14 @@ | |||
56 | #define NFC_V1_V2_WRPROT (host->regs + 0x12) | 56 | #define NFC_V1_V2_WRPROT (host->regs + 0x12) |
57 | #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14) | 57 | #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14) |
58 | #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16) | 58 | #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16) |
59 | #define NFC_V21_UNLOCKSTART_BLKADDR (host->regs + 0x20) | 59 | #define NFC_V21_UNLOCKSTART_BLKADDR0 (host->regs + 0x20) |
60 | #define NFC_V21_UNLOCKEND_BLKADDR (host->regs + 0x22) | 60 | #define NFC_V21_UNLOCKSTART_BLKADDR1 (host->regs + 0x24) |
61 | #define NFC_V21_UNLOCKSTART_BLKADDR2 (host->regs + 0x28) | ||
62 | #define NFC_V21_UNLOCKSTART_BLKADDR3 (host->regs + 0x2c) | ||
63 | #define NFC_V21_UNLOCKEND_BLKADDR0 (host->regs + 0x22) | ||
64 | #define NFC_V21_UNLOCKEND_BLKADDR1 (host->regs + 0x26) | ||
65 | #define NFC_V21_UNLOCKEND_BLKADDR2 (host->regs + 0x2a) | ||
66 | #define NFC_V21_UNLOCKEND_BLKADDR3 (host->regs + 0x2e) | ||
61 | #define NFC_V1_V2_NF_WRPRST (host->regs + 0x18) | 67 | #define NFC_V1_V2_NF_WRPRST (host->regs + 0x18) |
62 | #define NFC_V1_V2_CONFIG1 (host->regs + 0x1a) | 68 | #define NFC_V1_V2_CONFIG1 (host->regs + 0x1a) |
63 | #define NFC_V1_V2_CONFIG2 (host->regs + 0x1c) | 69 | #define NFC_V1_V2_CONFIG2 (host->regs + 0x1c) |
@@ -152,6 +158,7 @@ struct mxc_nand_host { | |||
152 | int clk_act; | 158 | int clk_act; |
153 | int irq; | 159 | int irq; |
154 | int eccsize; | 160 | int eccsize; |
161 | int active_cs; | ||
155 | 162 | ||
156 | struct completion op_completion; | 163 | struct completion op_completion; |
157 | 164 | ||
@@ -236,9 +243,7 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = { | |||
236 | } | 243 | } |
237 | }; | 244 | }; |
238 | 245 | ||
239 | #ifdef CONFIG_MTD_PARTITIONS | ||
240 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; | 246 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; |
241 | #endif | ||
242 | 247 | ||
243 | static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) | 248 | static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) |
244 | { | 249 | { |
@@ -445,7 +450,7 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops) | |||
445 | for (i = 0; i < bufs; i++) { | 450 | for (i = 0; i < bufs; i++) { |
446 | 451 | ||
447 | /* NANDFC buffer 0 is used for page read/write */ | 452 | /* NANDFC buffer 0 is used for page read/write */ |
448 | writew(i, NFC_V1_V2_BUF_ADDR); | 453 | writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); |
449 | 454 | ||
450 | writew(ops, NFC_V1_V2_CONFIG2); | 455 | writew(ops, NFC_V1_V2_CONFIG2); |
451 | 456 | ||
@@ -470,7 +475,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) | |||
470 | struct nand_chip *this = &host->nand; | 475 | struct nand_chip *this = &host->nand; |
471 | 476 | ||
472 | /* NANDFC buffer 0 is used for device ID output */ | 477 | /* NANDFC buffer 0 is used for device ID output */ |
473 | writew(0x0, NFC_V1_V2_BUF_ADDR); | 478 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); |
474 | 479 | ||
475 | writew(NFC_ID, NFC_V1_V2_CONFIG2); | 480 | writew(NFC_ID, NFC_V1_V2_CONFIG2); |
476 | 481 | ||
@@ -505,7 +510,7 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host) | |||
505 | uint32_t store; | 510 | uint32_t store; |
506 | uint16_t ret; | 511 | uint16_t ret; |
507 | 512 | ||
508 | writew(0x0, NFC_V1_V2_BUF_ADDR); | 513 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); |
509 | 514 | ||
510 | /* | 515 | /* |
511 | * The device status is stored in main_area0. To | 516 | * The device status is stored in main_area0. To |
@@ -686,24 +691,24 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) | |||
686 | struct nand_chip *nand_chip = mtd->priv; | 691 | struct nand_chip *nand_chip = mtd->priv; |
687 | struct mxc_nand_host *host = nand_chip->priv; | 692 | struct mxc_nand_host *host = nand_chip->priv; |
688 | 693 | ||
689 | switch (chip) { | 694 | if (chip == -1) { |
690 | case -1: | ||
691 | /* Disable the NFC clock */ | 695 | /* Disable the NFC clock */ |
692 | if (host->clk_act) { | 696 | if (host->clk_act) { |
693 | clk_disable(host->clk); | 697 | clk_disable(host->clk); |
694 | host->clk_act = 0; | 698 | host->clk_act = 0; |
695 | } | 699 | } |
696 | break; | 700 | return; |
697 | case 0: | 701 | } |
702 | |||
703 | if (!host->clk_act) { | ||
698 | /* Enable the NFC clock */ | 704 | /* Enable the NFC clock */ |
699 | if (!host->clk_act) { | 705 | clk_enable(host->clk); |
700 | clk_enable(host->clk); | 706 | host->clk_act = 1; |
701 | host->clk_act = 1; | 707 | } |
702 | } | ||
703 | break; | ||
704 | 708 | ||
705 | default: | 709 | if (nfc_is_v21()) { |
706 | break; | 710 | host->active_cs = chip; |
711 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); | ||
707 | } | 712 | } |
708 | } | 713 | } |
709 | 714 | ||
@@ -834,8 +839,14 @@ static void preset_v1_v2(struct mtd_info *mtd) | |||
834 | 839 | ||
835 | /* Blocks to be unlocked */ | 840 | /* Blocks to be unlocked */ |
836 | if (nfc_is_v21()) { | 841 | if (nfc_is_v21()) { |
837 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR); | 842 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0); |
838 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR); | 843 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1); |
844 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2); | ||
845 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3); | ||
846 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0); | ||
847 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1); | ||
848 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2); | ||
849 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3); | ||
839 | } else if (nfc_is_v1()) { | 850 | } else if (nfc_is_v1()) { |
840 | writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); | 851 | writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); |
841 | writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR); | 852 | writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR); |
@@ -1200,7 +1211,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) | |||
1200 | irq_control_v1_v2(host, 1); | 1211 | irq_control_v1_v2(host, 1); |
1201 | 1212 | ||
1202 | /* first scan to find the device and get the page size */ | 1213 | /* first scan to find the device and get the page size */ |
1203 | if (nand_scan_ident(mtd, 1, NULL)) { | 1214 | if (nand_scan_ident(mtd, nfc_is_v21() ? 4 : 1, NULL)) { |
1204 | err = -ENXIO; | 1215 | err = -ENXIO; |
1205 | goto escan; | 1216 | goto escan; |
1206 | } | 1217 | } |
@@ -1220,18 +1231,15 @@ static int __init mxcnd_probe(struct platform_device *pdev) | |||
1220 | } | 1231 | } |
1221 | 1232 | ||
1222 | /* Register the partitions */ | 1233 | /* Register the partitions */ |
1223 | #ifdef CONFIG_MTD_PARTITIONS | ||
1224 | nr_parts = | 1234 | nr_parts = |
1225 | parse_mtd_partitions(mtd, part_probes, &host->parts, 0); | 1235 | parse_mtd_partitions(mtd, part_probes, &host->parts, 0); |
1226 | if (nr_parts > 0) | 1236 | if (nr_parts > 0) |
1227 | add_mtd_partitions(mtd, host->parts, nr_parts); | 1237 | mtd_device_register(mtd, host->parts, nr_parts); |
1228 | else if (pdata->parts) | 1238 | else if (pdata->parts) |
1229 | add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); | 1239 | mtd_device_register(mtd, pdata->parts, pdata->nr_parts); |
1230 | else | 1240 | else { |
1231 | #endif | ||
1232 | { | ||
1233 | pr_info("Registering %s as whole device\n", mtd->name); | 1241 | pr_info("Registering %s as whole device\n", mtd->name); |
1234 | add_mtd_device(mtd); | 1242 | mtd_device_register(mtd, NULL, 0); |
1235 | } | 1243 | } |
1236 | 1244 | ||
1237 | platform_set_drvdata(pdev, host); | 1245 | platform_set_drvdata(pdev, host); |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index c54a4cbac6bc..a46e9bb847bd 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -47,10 +47,7 @@ | |||
47 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
48 | #include <linux/leds.h> | 48 | #include <linux/leds.h> |
49 | #include <linux/io.h> | 49 | #include <linux/io.h> |
50 | |||
51 | #ifdef CONFIG_MTD_PARTITIONS | ||
52 | #include <linux/mtd/partitions.h> | 50 | #include <linux/mtd/partitions.h> |
53 | #endif | ||
54 | 51 | ||
55 | /* Define default oob placement schemes for large and small page devices */ | 52 | /* Define default oob placement schemes for large and small page devices */ |
56 | static struct nand_ecclayout nand_oob_8 = { | 53 | static struct nand_ecclayout nand_oob_8 = { |
@@ -976,9 +973,6 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
976 | ret = __nand_unlock(mtd, ofs, len, 0); | 973 | ret = __nand_unlock(mtd, ofs, len, 0); |
977 | 974 | ||
978 | out: | 975 | out: |
979 | /* de-select the NAND device */ | ||
980 | chip->select_chip(mtd, -1); | ||
981 | |||
982 | nand_release_device(mtd); | 976 | nand_release_device(mtd); |
983 | 977 | ||
984 | return ret; | 978 | return ret; |
@@ -1046,9 +1040,6 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
1046 | ret = __nand_unlock(mtd, ofs, len, 0x1); | 1040 | ret = __nand_unlock(mtd, ofs, len, 0x1); |
1047 | 1041 | ||
1048 | out: | 1042 | out: |
1049 | /* de-select the NAND device */ | ||
1050 | chip->select_chip(mtd, -1); | ||
1051 | |||
1052 | nand_release_device(mtd); | 1043 | nand_release_device(mtd); |
1053 | 1044 | ||
1054 | return ret; | 1045 | return ret; |
@@ -3112,6 +3103,8 @@ ident_done: | |||
3112 | chip->chip_shift += 32 - 1; | 3103 | chip->chip_shift += 32 - 1; |
3113 | } | 3104 | } |
3114 | 3105 | ||
3106 | chip->badblockbits = 8; | ||
3107 | |||
3115 | /* Set the bad block position */ | 3108 | /* Set the bad block position */ |
3116 | if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) | 3109 | if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) |
3117 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; | 3110 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; |
@@ -3539,12 +3532,7 @@ void nand_release(struct mtd_info *mtd) | |||
3539 | if (chip->ecc.mode == NAND_ECC_SOFT_BCH) | 3532 | if (chip->ecc.mode == NAND_ECC_SOFT_BCH) |
3540 | nand_bch_free((struct nand_bch_control *)chip->ecc.priv); | 3533 | nand_bch_free((struct nand_bch_control *)chip->ecc.priv); |
3541 | 3534 | ||
3542 | #ifdef CONFIG_MTD_PARTITIONS | 3535 | mtd_device_unregister(mtd); |
3543 | /* Deregister partitions */ | ||
3544 | del_mtd_partitions(mtd); | ||
3545 | #endif | ||
3546 | /* Deregister the device */ | ||
3547 | del_mtd_device(mtd); | ||
3548 | 3536 | ||
3549 | /* Free bad block table memory */ | 3537 | /* Free bad block table memory */ |
3550 | kfree(chip->bbt); | 3538 | kfree(chip->bbt); |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index af46428286fe..ccbeaa1e4a8e 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -1276,20 +1276,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | |||
1276 | * while scanning a device for factory marked good / bad blocks. */ | 1276 | * while scanning a device for factory marked good / bad blocks. */ |
1277 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | 1277 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; |
1278 | 1278 | ||
1279 | static struct nand_bbt_descr smallpage_flashbased = { | ||
1280 | .options = NAND_BBT_SCAN2NDPAGE, | ||
1281 | .offs = NAND_SMALL_BADBLOCK_POS, | ||
1282 | .len = 1, | ||
1283 | .pattern = scan_ff_pattern | ||
1284 | }; | ||
1285 | |||
1286 | static struct nand_bbt_descr largepage_flashbased = { | ||
1287 | .options = NAND_BBT_SCAN2NDPAGE, | ||
1288 | .offs = NAND_LARGE_BADBLOCK_POS, | ||
1289 | .len = 2, | ||
1290 | .pattern = scan_ff_pattern | ||
1291 | }; | ||
1292 | |||
1293 | static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; | 1279 | static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; |
1294 | 1280 | ||
1295 | static struct nand_bbt_descr agand_flashbased = { | 1281 | static struct nand_bbt_descr agand_flashbased = { |
@@ -1355,10 +1341,6 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { | |||
1355 | * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when | 1341 | * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when |
1356 | * passed to this function. | 1342 | * passed to this function. |
1357 | * | 1343 | * |
1358 | * TODO: Handle other flags, replace other static structs | ||
1359 | * (e.g. handle NAND_BBT_FLASH for flash-based BBT, | ||
1360 | * replace smallpage_flashbased) | ||
1361 | * | ||
1362 | */ | 1344 | */ |
1363 | static int nand_create_default_bbt_descr(struct nand_chip *this) | 1345 | static int nand_create_default_bbt_descr(struct nand_chip *this) |
1364 | { | 1346 | { |
@@ -1422,15 +1404,14 @@ int nand_default_bbt(struct mtd_info *mtd) | |||
1422 | this->bbt_md = &bbt_mirror_descr; | 1404 | this->bbt_md = &bbt_mirror_descr; |
1423 | } | 1405 | } |
1424 | } | 1406 | } |
1425 | if (!this->badblock_pattern) { | ||
1426 | this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased; | ||
1427 | } | ||
1428 | } else { | 1407 | } else { |
1429 | this->bbt_td = NULL; | 1408 | this->bbt_td = NULL; |
1430 | this->bbt_md = NULL; | 1409 | this->bbt_md = NULL; |
1431 | if (!this->badblock_pattern) | ||
1432 | nand_create_default_bbt_descr(this); | ||
1433 | } | 1410 | } |
1411 | |||
1412 | if (!this->badblock_pattern) | ||
1413 | nand_create_default_bbt_descr(this); | ||
1414 | |||
1434 | return nand_scan_bbt(mtd, this->badblock_pattern); | 1415 | return nand_scan_bbt(mtd, this->badblock_pattern); |
1435 | } | 1416 | } |
1436 | 1417 | ||
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 893d95bfea48..357e8c5252a8 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -2383,7 +2383,9 @@ static int __init ns_init_module(void) | |||
2383 | goto err_exit; | 2383 | goto err_exit; |
2384 | 2384 | ||
2385 | /* Register NAND partitions */ | 2385 | /* Register NAND partitions */ |
2386 | if ((retval = add_mtd_partitions(nsmtd, &nand->partitions[0], nand->nbparts)) != 0) | 2386 | retval = mtd_device_register(nsmtd, &nand->partitions[0], |
2387 | nand->nbparts); | ||
2388 | if (retval != 0) | ||
2387 | goto err_exit; | 2389 | goto err_exit; |
2388 | 2390 | ||
2389 | return 0; | 2391 | return 0; |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index bbe6d451290d..ea2dea8a9c88 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/of_platform.h> | 33 | #include <linux/of_platform.h> |
34 | #include <asm/io.h> | 34 | #include <asm/io.h> |
35 | 35 | ||
36 | #define NDFC_MAX_CS 4 | ||
36 | 37 | ||
37 | struct ndfc_controller { | 38 | struct ndfc_controller { |
38 | struct platform_device *ofdev; | 39 | struct platform_device *ofdev; |
@@ -41,17 +42,16 @@ struct ndfc_controller { | |||
41 | struct nand_chip chip; | 42 | struct nand_chip chip; |
42 | int chip_select; | 43 | int chip_select; |
43 | struct nand_hw_control ndfc_control; | 44 | struct nand_hw_control ndfc_control; |
44 | #ifdef CONFIG_MTD_PARTITIONS | ||
45 | struct mtd_partition *parts; | 45 | struct mtd_partition *parts; |
46 | #endif | ||
47 | }; | 46 | }; |
48 | 47 | ||
49 | static struct ndfc_controller ndfc_ctrl; | 48 | static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS]; |
50 | 49 | ||
51 | static void ndfc_select_chip(struct mtd_info *mtd, int chip) | 50 | static void ndfc_select_chip(struct mtd_info *mtd, int chip) |
52 | { | 51 | { |
53 | uint32_t ccr; | 52 | uint32_t ccr; |
54 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 53 | struct nand_chip *nchip = mtd->priv; |
54 | struct ndfc_controller *ndfc = nchip->priv; | ||
55 | 55 | ||
56 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); | 56 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); |
57 | if (chip >= 0) { | 57 | if (chip >= 0) { |
@@ -64,7 +64,8 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) | |||
64 | 64 | ||
65 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 65 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
66 | { | 66 | { |
67 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 67 | struct nand_chip *chip = mtd->priv; |
68 | struct ndfc_controller *ndfc = chip->priv; | ||
68 | 69 | ||
69 | if (cmd == NAND_CMD_NONE) | 70 | if (cmd == NAND_CMD_NONE) |
70 | return; | 71 | return; |
@@ -77,7 +78,8 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
77 | 78 | ||
78 | static int ndfc_ready(struct mtd_info *mtd) | 79 | static int ndfc_ready(struct mtd_info *mtd) |
79 | { | 80 | { |
80 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 81 | struct nand_chip *chip = mtd->priv; |
82 | struct ndfc_controller *ndfc = chip->priv; | ||
81 | 83 | ||
82 | return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; | 84 | return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; |
83 | } | 85 | } |
@@ -85,7 +87,8 @@ static int ndfc_ready(struct mtd_info *mtd) | |||
85 | static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) | 87 | static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) |
86 | { | 88 | { |
87 | uint32_t ccr; | 89 | uint32_t ccr; |
88 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 90 | struct nand_chip *chip = mtd->priv; |
91 | struct ndfc_controller *ndfc = chip->priv; | ||
89 | 92 | ||
90 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); | 93 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); |
91 | ccr |= NDFC_CCR_RESET_ECC; | 94 | ccr |= NDFC_CCR_RESET_ECC; |
@@ -96,7 +99,8 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) | |||
96 | static int ndfc_calculate_ecc(struct mtd_info *mtd, | 99 | static int ndfc_calculate_ecc(struct mtd_info *mtd, |
97 | const u_char *dat, u_char *ecc_code) | 100 | const u_char *dat, u_char *ecc_code) |
98 | { | 101 | { |
99 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 102 | struct nand_chip *chip = mtd->priv; |
103 | struct ndfc_controller *ndfc = chip->priv; | ||
100 | uint32_t ecc; | 104 | uint32_t ecc; |
101 | uint8_t *p = (uint8_t *)&ecc; | 105 | uint8_t *p = (uint8_t *)&ecc; |
102 | 106 | ||
@@ -119,7 +123,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, | |||
119 | */ | 123 | */ |
120 | static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 124 | static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
121 | { | 125 | { |
122 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 126 | struct nand_chip *chip = mtd->priv; |
127 | struct ndfc_controller *ndfc = chip->priv; | ||
123 | uint32_t *p = (uint32_t *) buf; | 128 | uint32_t *p = (uint32_t *) buf; |
124 | 129 | ||
125 | for(;len > 0; len -= 4) | 130 | for(;len > 0; len -= 4) |
@@ -128,7 +133,8 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
128 | 133 | ||
129 | static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 134 | static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
130 | { | 135 | { |
131 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 136 | struct nand_chip *chip = mtd->priv; |
137 | struct ndfc_controller *ndfc = chip->priv; | ||
132 | uint32_t *p = (uint32_t *) buf; | 138 | uint32_t *p = (uint32_t *) buf; |
133 | 139 | ||
134 | for(;len > 0; len -= 4) | 140 | for(;len > 0; len -= 4) |
@@ -137,7 +143,8 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
137 | 143 | ||
138 | static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 144 | static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
139 | { | 145 | { |
140 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 146 | struct nand_chip *chip = mtd->priv; |
147 | struct ndfc_controller *ndfc = chip->priv; | ||
141 | uint32_t *p = (uint32_t *) buf; | 148 | uint32_t *p = (uint32_t *) buf; |
142 | 149 | ||
143 | for(;len > 0; len -= 4) | 150 | for(;len > 0; len -= 4) |
@@ -152,13 +159,11 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
152 | static int ndfc_chip_init(struct ndfc_controller *ndfc, | 159 | static int ndfc_chip_init(struct ndfc_controller *ndfc, |
153 | struct device_node *node) | 160 | struct device_node *node) |
154 | { | 161 | { |
155 | #ifdef CONFIG_MTD_PARTITIONS | ||
156 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 162 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
157 | static const char *part_types[] = { "cmdlinepart", NULL }; | 163 | static const char *part_types[] = { "cmdlinepart", NULL }; |
158 | #else | 164 | #else |
159 | static const char *part_types[] = { NULL }; | 165 | static const char *part_types[] = { NULL }; |
160 | #endif | 166 | #endif |
161 | #endif | ||
162 | struct device_node *flash_np; | 167 | struct device_node *flash_np; |
163 | struct nand_chip *chip = &ndfc->chip; | 168 | struct nand_chip *chip = &ndfc->chip; |
164 | int ret; | 169 | int ret; |
@@ -179,6 +184,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, | |||
179 | chip->ecc.mode = NAND_ECC_HW; | 184 | chip->ecc.mode = NAND_ECC_HW; |
180 | chip->ecc.size = 256; | 185 | chip->ecc.size = 256; |
181 | chip->ecc.bytes = 3; | 186 | chip->ecc.bytes = 3; |
187 | chip->priv = ndfc; | ||
182 | 188 | ||
183 | ndfc->mtd.priv = chip; | 189 | ndfc->mtd.priv = chip; |
184 | ndfc->mtd.owner = THIS_MODULE; | 190 | ndfc->mtd.owner = THIS_MODULE; |
@@ -198,25 +204,18 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, | |||
198 | if (ret) | 204 | if (ret) |
199 | goto err; | 205 | goto err; |
200 | 206 | ||
201 | #ifdef CONFIG_MTD_PARTITIONS | ||
202 | ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0); | 207 | ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0); |
203 | if (ret < 0) | 208 | if (ret < 0) |
204 | goto err; | 209 | goto err; |
205 | 210 | ||
206 | #ifdef CONFIG_MTD_OF_PARTS | ||
207 | if (ret == 0) { | 211 | if (ret == 0) { |
208 | ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np, | 212 | ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np, |
209 | &ndfc->parts); | 213 | &ndfc->parts); |
210 | if (ret < 0) | 214 | if (ret < 0) |
211 | goto err; | 215 | goto err; |
212 | } | 216 | } |
213 | #endif | ||
214 | 217 | ||
215 | if (ret > 0) | 218 | ret = mtd_device_register(&ndfc->mtd, ndfc->parts, ret); |
216 | ret = add_mtd_partitions(&ndfc->mtd, ndfc->parts, ret); | ||
217 | else | ||
218 | #endif | ||
219 | ret = add_mtd_device(&ndfc->mtd); | ||
220 | 219 | ||
221 | err: | 220 | err: |
222 | of_node_put(flash_np); | 221 | of_node_put(flash_np); |
@@ -227,15 +226,10 @@ err: | |||
227 | 226 | ||
228 | static int __devinit ndfc_probe(struct platform_device *ofdev) | 227 | static int __devinit ndfc_probe(struct platform_device *ofdev) |
229 | { | 228 | { |
230 | struct ndfc_controller *ndfc = &ndfc_ctrl; | 229 | struct ndfc_controller *ndfc; |
231 | const __be32 *reg; | 230 | const __be32 *reg; |
232 | u32 ccr; | 231 | u32 ccr; |
233 | int err, len; | 232 | int err, len, cs; |
234 | |||
235 | spin_lock_init(&ndfc->ndfc_control.lock); | ||
236 | init_waitqueue_head(&ndfc->ndfc_control.wq); | ||
237 | ndfc->ofdev = ofdev; | ||
238 | dev_set_drvdata(&ofdev->dev, ndfc); | ||
239 | 233 | ||
240 | /* Read the reg property to get the chip select */ | 234 | /* Read the reg property to get the chip select */ |
241 | reg = of_get_property(ofdev->dev.of_node, "reg", &len); | 235 | reg = of_get_property(ofdev->dev.of_node, "reg", &len); |
@@ -243,7 +237,20 @@ static int __devinit ndfc_probe(struct platform_device *ofdev) | |||
243 | dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); | 237 | dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); |
244 | return -ENOENT; | 238 | return -ENOENT; |
245 | } | 239 | } |
246 | ndfc->chip_select = be32_to_cpu(reg[0]); | 240 | |
241 | cs = be32_to_cpu(reg[0]); | ||
242 | if (cs >= NDFC_MAX_CS) { | ||
243 | dev_err(&ofdev->dev, "invalid CS number (%d)\n", cs); | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | ndfc = &ndfc_ctrl[cs]; | ||
248 | ndfc->chip_select = cs; | ||
249 | |||
250 | spin_lock_init(&ndfc->ndfc_control.lock); | ||
251 | init_waitqueue_head(&ndfc->ndfc_control.wq); | ||
252 | ndfc->ofdev = ofdev; | ||
253 | dev_set_drvdata(&ofdev->dev, ndfc); | ||
247 | 254 | ||
248 | ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); | 255 | ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); |
249 | if (!ndfc->ndfcbase) { | 256 | if (!ndfc->ndfcbase) { |
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c index a045a4a581b6..b6a5c86ab31e 100644 --- a/drivers/mtd/nand/nomadik_nand.c +++ b/drivers/mtd/nand/nomadik_nand.c | |||
@@ -158,12 +158,7 @@ static int nomadik_nand_probe(struct platform_device *pdev) | |||
158 | goto err_unmap; | 158 | goto err_unmap; |
159 | } | 159 | } |
160 | 160 | ||
161 | #ifdef CONFIG_MTD_PARTITIONS | 161 | mtd_device_register(&host->mtd, pdata->parts, pdata->nparts); |
162 | add_mtd_partitions(&host->mtd, pdata->parts, pdata->nparts); | ||
163 | #else | ||
164 | pr_info("Registering %s as whole device\n", mtd->name); | ||
165 | add_mtd_device(mtd); | ||
166 | #endif | ||
167 | 162 | ||
168 | platform_set_drvdata(pdev, host); | 163 | platform_set_drvdata(pdev, host); |
169 | return 0; | 164 | return 0; |
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 6eddf7361ed7..9c30a0b03171 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
@@ -321,8 +321,8 @@ static int __devinit nuc900_nand_probe(struct platform_device *pdev) | |||
321 | goto fail3; | 321 | goto fail3; |
322 | } | 322 | } |
323 | 323 | ||
324 | add_mtd_partitions(&(nuc900_nand->mtd), partitions, | 324 | mtd_device_register(&(nuc900_nand->mtd), partitions, |
325 | ARRAY_SIZE(partitions)); | 325 | ARRAY_SIZE(partitions)); |
326 | 326 | ||
327 | platform_set_drvdata(pdev, nuc900_nand); | 327 | platform_set_drvdata(pdev, nuc900_nand); |
328 | 328 | ||
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index da9a351c9d79..0db2c0e7656a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -94,9 +94,7 @@ | |||
94 | #define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) | 94 | #define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) |
95 | #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) | 95 | #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) |
96 | 96 | ||
97 | #ifdef CONFIG_MTD_PARTITIONS | ||
98 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 97 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
99 | #endif | ||
100 | 98 | ||
101 | /* oob info generated runtime depending on ecc algorithm and layout selected */ | 99 | /* oob info generated runtime depending on ecc algorithm and layout selected */ |
102 | static struct nand_ecclayout omap_oobinfo; | 100 | static struct nand_ecclayout omap_oobinfo; |
@@ -263,11 +261,10 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
263 | if (ret) { | 261 | if (ret) { |
264 | /* PFPW engine is busy, use cpu copy method */ | 262 | /* PFPW engine is busy, use cpu copy method */ |
265 | if (info->nand.options & NAND_BUSWIDTH_16) | 263 | if (info->nand.options & NAND_BUSWIDTH_16) |
266 | omap_read_buf16(mtd, buf, len); | 264 | omap_read_buf16(mtd, (u_char *)p, len); |
267 | else | 265 | else |
268 | omap_read_buf8(mtd, buf, len); | 266 | omap_read_buf8(mtd, (u_char *)p, len); |
269 | } else { | 267 | } else { |
270 | p = (u32 *) buf; | ||
271 | do { | 268 | do { |
272 | r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); | 269 | r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); |
273 | r_count = r_count >> 2; | 270 | r_count = r_count >> 2; |
@@ -293,7 +290,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
293 | struct omap_nand_info, mtd); | 290 | struct omap_nand_info, mtd); |
294 | uint32_t w_count = 0; | 291 | uint32_t w_count = 0; |
295 | int i = 0, ret = 0; | 292 | int i = 0, ret = 0; |
296 | u16 *p; | 293 | u16 *p = (u16 *)buf; |
297 | unsigned long tim, limit; | 294 | unsigned long tim, limit; |
298 | 295 | ||
299 | /* take care of subpage writes */ | 296 | /* take care of subpage writes */ |
@@ -309,11 +306,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
309 | if (ret) { | 306 | if (ret) { |
310 | /* PFPW engine is busy, use cpu copy method */ | 307 | /* PFPW engine is busy, use cpu copy method */ |
311 | if (info->nand.options & NAND_BUSWIDTH_16) | 308 | if (info->nand.options & NAND_BUSWIDTH_16) |
312 | omap_write_buf16(mtd, buf, len); | 309 | omap_write_buf16(mtd, (u_char *)p, len); |
313 | else | 310 | else |
314 | omap_write_buf8(mtd, buf, len); | 311 | omap_write_buf8(mtd, (u_char *)p, len); |
315 | } else { | 312 | } else { |
316 | p = (u16 *) buf; | ||
317 | while (len) { | 313 | while (len) { |
318 | w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); | 314 | w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); |
319 | w_count = w_count >> 1; | 315 | w_count = w_count >> 1; |
@@ -1073,9 +1069,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1073 | /* DIP switches on some boards change between 8 and 16 bit | 1069 | /* DIP switches on some boards change between 8 and 16 bit |
1074 | * bus widths for flash. Try the other width if the first try fails. | 1070 | * bus widths for flash. Try the other width if the first try fails. |
1075 | */ | 1071 | */ |
1076 | if (nand_scan(&info->mtd, 1)) { | 1072 | if (nand_scan_ident(&info->mtd, 1, NULL)) { |
1077 | info->nand.options ^= NAND_BUSWIDTH_16; | 1073 | info->nand.options ^= NAND_BUSWIDTH_16; |
1078 | if (nand_scan(&info->mtd, 1)) { | 1074 | if (nand_scan_ident(&info->mtd, 1, NULL)) { |
1079 | err = -ENXIO; | 1075 | err = -ENXIO; |
1080 | goto out_release_mem_region; | 1076 | goto out_release_mem_region; |
1081 | } | 1077 | } |
@@ -1101,15 +1097,19 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1101 | info->nand.ecc.layout = &omap_oobinfo; | 1097 | info->nand.ecc.layout = &omap_oobinfo; |
1102 | } | 1098 | } |
1103 | 1099 | ||
1104 | #ifdef CONFIG_MTD_PARTITIONS | 1100 | /* second phase scan */ |
1101 | if (nand_scan_tail(&info->mtd)) { | ||
1102 | err = -ENXIO; | ||
1103 | goto out_release_mem_region; | ||
1104 | } | ||
1105 | |||
1105 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); | 1106 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); |
1106 | if (err > 0) | 1107 | if (err > 0) |
1107 | add_mtd_partitions(&info->mtd, info->parts, err); | 1108 | mtd_device_register(&info->mtd, info->parts, err); |
1108 | else if (pdata->parts) | 1109 | else if (pdata->parts) |
1109 | add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); | 1110 | mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts); |
1110 | else | 1111 | else |
1111 | #endif | 1112 | mtd_device_register(&info->mtd, NULL, 0); |
1112 | add_mtd_device(&info->mtd); | ||
1113 | 1113 | ||
1114 | platform_set_drvdata(pdev, &info->mtd); | 1114 | platform_set_drvdata(pdev, &info->mtd); |
1115 | 1115 | ||
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index da6e75343052..7794d0680f91 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -21,9 +21,7 @@ | |||
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | #include <plat/orion_nand.h> | 22 | #include <plat/orion_nand.h> |
23 | 23 | ||
24 | #ifdef CONFIG_MTD_CMDLINE_PARTS | ||
25 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 24 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
26 | #endif | ||
27 | 25 | ||
28 | static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 26 | static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
29 | { | 27 | { |
@@ -83,10 +81,8 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
83 | struct resource *res; | 81 | struct resource *res; |
84 | void __iomem *io_base; | 82 | void __iomem *io_base; |
85 | int ret = 0; | 83 | int ret = 0; |
86 | #ifdef CONFIG_MTD_PARTITIONS | ||
87 | struct mtd_partition *partitions = NULL; | 84 | struct mtd_partition *partitions = NULL; |
88 | int num_part = 0; | 85 | int num_part = 0; |
89 | #endif | ||
90 | 86 | ||
91 | nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL); | 87 | nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL); |
92 | if (!nc) { | 88 | if (!nc) { |
@@ -136,7 +132,6 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
136 | goto no_dev; | 132 | goto no_dev; |
137 | } | 133 | } |
138 | 134 | ||
139 | #ifdef CONFIG_MTD_PARTITIONS | ||
140 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 135 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
141 | mtd->name = "orion_nand"; | 136 | mtd->name = "orion_nand"; |
142 | num_part = parse_mtd_partitions(mtd, part_probes, &partitions, 0); | 137 | num_part = parse_mtd_partitions(mtd, part_probes, &partitions, 0); |
@@ -147,14 +142,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
147 | partitions = board->parts; | 142 | partitions = board->parts; |
148 | } | 143 | } |
149 | 144 | ||
150 | if (partitions && num_part > 0) | 145 | ret = mtd_device_register(mtd, partitions, num_part); |
151 | ret = add_mtd_partitions(mtd, partitions, num_part); | ||
152 | else | ||
153 | ret = add_mtd_device(mtd); | ||
154 | #else | ||
155 | ret = add_mtd_device(mtd); | ||
156 | #endif | ||
157 | |||
158 | if (ret) { | 146 | if (ret) { |
159 | nand_release(mtd); | 147 | nand_release(mtd); |
160 | goto no_dev; | 148 | goto no_dev; |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 20bfe5f15afd..b1aa41b8a4eb 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
@@ -163,7 +163,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev) | |||
163 | goto out_lpc; | 163 | goto out_lpc; |
164 | } | 164 | } |
165 | 165 | ||
166 | if (add_mtd_device(pasemi_nand_mtd)) { | 166 | if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) { |
167 | printk(KERN_ERR "pasemi_nand: Unable to register MTD device\n"); | 167 | printk(KERN_ERR "pasemi_nand: Unable to register MTD device\n"); |
168 | err = -ENODEV; | 168 | err = -ENODEV; |
169 | goto out_lpc; | 169 | goto out_lpc; |
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index caf5a736340a..633c04bf76f6 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c | |||
@@ -21,10 +21,8 @@ struct plat_nand_data { | |||
21 | struct nand_chip chip; | 21 | struct nand_chip chip; |
22 | struct mtd_info mtd; | 22 | struct mtd_info mtd; |
23 | void __iomem *io_base; | 23 | void __iomem *io_base; |
24 | #ifdef CONFIG_MTD_PARTITIONS | ||
25 | int nr_parts; | 24 | int nr_parts; |
26 | struct mtd_partition *parts; | 25 | struct mtd_partition *parts; |
27 | #endif | ||
28 | }; | 26 | }; |
29 | 27 | ||
30 | /* | 28 | /* |
@@ -101,13 +99,12 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) | |||
101 | goto out; | 99 | goto out; |
102 | } | 100 | } |
103 | 101 | ||
104 | #ifdef CONFIG_MTD_PARTITIONS | ||
105 | if (pdata->chip.part_probe_types) { | 102 | if (pdata->chip.part_probe_types) { |
106 | err = parse_mtd_partitions(&data->mtd, | 103 | err = parse_mtd_partitions(&data->mtd, |
107 | pdata->chip.part_probe_types, | 104 | pdata->chip.part_probe_types, |
108 | &data->parts, 0); | 105 | &data->parts, 0); |
109 | if (err > 0) { | 106 | if (err > 0) { |
110 | add_mtd_partitions(&data->mtd, data->parts, err); | 107 | mtd_device_register(&data->mtd, data->parts, err); |
111 | return 0; | 108 | return 0; |
112 | } | 109 | } |
113 | } | 110 | } |
@@ -115,11 +112,10 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) | |||
115 | pdata->chip.set_parts(data->mtd.size, &pdata->chip); | 112 | pdata->chip.set_parts(data->mtd.size, &pdata->chip); |
116 | if (pdata->chip.partitions) { | 113 | if (pdata->chip.partitions) { |
117 | data->parts = pdata->chip.partitions; | 114 | data->parts = pdata->chip.partitions; |
118 | err = add_mtd_partitions(&data->mtd, data->parts, | 115 | err = mtd_device_register(&data->mtd, data->parts, |
119 | pdata->chip.nr_partitions); | 116 | pdata->chip.nr_partitions); |
120 | } else | 117 | } else |
121 | #endif | 118 | err = mtd_device_register(&data->mtd, NULL, 0); |
122 | err = add_mtd_device(&data->mtd); | ||
123 | 119 | ||
124 | if (!err) | 120 | if (!err) |
125 | return err; | 121 | return err; |
@@ -149,10 +145,8 @@ static int __devexit plat_nand_remove(struct platform_device *pdev) | |||
149 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 145 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
150 | 146 | ||
151 | nand_release(&data->mtd); | 147 | nand_release(&data->mtd); |
152 | #ifdef CONFIG_MTD_PARTITIONS | ||
153 | if (data->parts && data->parts != pdata->chip.partitions) | 148 | if (data->parts && data->parts != pdata->chip.partitions) |
154 | kfree(data->parts); | 149 | kfree(data->parts); |
155 | #endif | ||
156 | if (pdata->ctrl.remove) | 150 | if (pdata->ctrl.remove) |
157 | pdata->ctrl.remove(pdev); | 151 | pdata->ctrl.remove(pdev); |
158 | iounmap(data->io_base); | 152 | iounmap(data->io_base); |
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c index cc8658431851..3bbb796b451c 100644 --- a/drivers/mtd/nand/ppchameleonevb.c +++ b/drivers/mtd/nand/ppchameleonevb.c | |||
@@ -73,7 +73,6 @@ __setup("ppchameleon_fio_pbase=", ppchameleon_fio_pbase); | |||
73 | __setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase); | 73 | __setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase); |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #ifdef CONFIG_MTD_PARTITIONS | ||
77 | /* | 76 | /* |
78 | * Define static partitions for flash devices | 77 | * Define static partitions for flash devices |
79 | */ | 78 | */ |
@@ -101,7 +100,6 @@ static struct mtd_partition partition_info_evb[] = { | |||
101 | #define NUM_PARTITIONS 1 | 100 | #define NUM_PARTITIONS 1 |
102 | 101 | ||
103 | extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id); | 102 | extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id); |
104 | #endif | ||
105 | 103 | ||
106 | /* | 104 | /* |
107 | * hardware specific access to control-lines | 105 | * hardware specific access to control-lines |
@@ -189,10 +187,8 @@ static int ppchameleonevb_device_ready(struct mtd_info *minfo) | |||
189 | } | 187 | } |
190 | #endif | 188 | #endif |
191 | 189 | ||
192 | #ifdef CONFIG_MTD_PARTITIONS | ||
193 | const char *part_probes[] = { "cmdlinepart", NULL }; | 190 | const char *part_probes[] = { "cmdlinepart", NULL }; |
194 | const char *part_probes_evb[] = { "cmdlinepart", NULL }; | 191 | const char *part_probes_evb[] = { "cmdlinepart", NULL }; |
195 | #endif | ||
196 | 192 | ||
197 | /* | 193 | /* |
198 | * Main initialization routine | 194 | * Main initialization routine |
@@ -284,14 +280,13 @@ static int __init ppchameleonevb_init(void) | |||
284 | this->chip_delay = NAND_SMALL_DELAY_US; | 280 | this->chip_delay = NAND_SMALL_DELAY_US; |
285 | #endif | 281 | #endif |
286 | 282 | ||
287 | #ifdef CONFIG_MTD_PARTITIONS | ||
288 | ppchameleon_mtd->name = "ppchameleon-nand"; | 283 | ppchameleon_mtd->name = "ppchameleon-nand"; |
289 | mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0); | 284 | mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0); |
290 | if (mtd_parts_nb > 0) | 285 | if (mtd_parts_nb > 0) |
291 | part_type = "command line"; | 286 | part_type = "command line"; |
292 | else | 287 | else |
293 | mtd_parts_nb = 0; | 288 | mtd_parts_nb = 0; |
294 | #endif | 289 | |
295 | if (mtd_parts_nb == 0) { | 290 | if (mtd_parts_nb == 0) { |
296 | if (ppchameleon_mtd->size == NAND_SMALL_SIZE) | 291 | if (ppchameleon_mtd->size == NAND_SMALL_SIZE) |
297 | mtd_parts = partition_info_me; | 292 | mtd_parts = partition_info_me; |
@@ -303,7 +298,7 @@ static int __init ppchameleonevb_init(void) | |||
303 | 298 | ||
304 | /* Register the partitions */ | 299 | /* Register the partitions */ |
305 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 300 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
306 | add_mtd_partitions(ppchameleon_mtd, mtd_parts, mtd_parts_nb); | 301 | mtd_device_register(ppchameleon_mtd, mtd_parts, mtd_parts_nb); |
307 | 302 | ||
308 | nand_evb_init: | 303 | nand_evb_init: |
309 | /**************************** | 304 | /**************************** |
@@ -385,14 +380,14 @@ static int __init ppchameleonevb_init(void) | |||
385 | iounmap(ppchameleon_fio_base); | 380 | iounmap(ppchameleon_fio_base); |
386 | return -ENXIO; | 381 | return -ENXIO; |
387 | } | 382 | } |
388 | #ifdef CONFIG_MTD_PARTITIONS | 383 | |
389 | ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; | 384 | ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; |
390 | mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0); | 385 | mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0); |
391 | if (mtd_parts_nb > 0) | 386 | if (mtd_parts_nb > 0) |
392 | part_type = "command line"; | 387 | part_type = "command line"; |
393 | else | 388 | else |
394 | mtd_parts_nb = 0; | 389 | mtd_parts_nb = 0; |
395 | #endif | 390 | |
396 | if (mtd_parts_nb == 0) { | 391 | if (mtd_parts_nb == 0) { |
397 | mtd_parts = partition_info_evb; | 392 | mtd_parts = partition_info_evb; |
398 | mtd_parts_nb = NUM_PARTITIONS; | 393 | mtd_parts_nb = NUM_PARTITIONS; |
@@ -401,7 +396,7 @@ static int __init ppchameleonevb_init(void) | |||
401 | 396 | ||
402 | /* Register the partitions */ | 397 | /* Register the partitions */ |
403 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); | 398 | printk(KERN_NOTICE "Using %s partition definition\n", part_type); |
404 | add_mtd_partitions(ppchameleonevb_mtd, mtd_parts, mtd_parts_nb); | 399 | mtd_device_register(ppchameleonevb_mtd, mtd_parts, mtd_parts_nb); |
405 | 400 | ||
406 | /* Return happy */ | 401 | /* Return happy */ |
407 | return 0; | 402 | return 0; |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index ff0701276d65..1fb3b3a80581 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -1119,10 +1119,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1119 | clk_put(info->clk); | 1119 | clk_put(info->clk); |
1120 | 1120 | ||
1121 | if (mtd) { | 1121 | if (mtd) { |
1122 | del_mtd_device(mtd); | 1122 | mtd_device_unregister(mtd); |
1123 | #ifdef CONFIG_MTD_PARTITIONS | ||
1124 | del_mtd_partitions(mtd); | ||
1125 | #endif | ||
1126 | kfree(mtd); | 1123 | kfree(mtd); |
1127 | } | 1124 | } |
1128 | return 0; | 1125 | return 0; |
@@ -1149,7 +1146,6 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1149 | return -ENODEV; | 1146 | return -ENODEV; |
1150 | } | 1147 | } |
1151 | 1148 | ||
1152 | #ifdef CONFIG_MTD_PARTITIONS | ||
1153 | if (mtd_has_cmdlinepart()) { | 1149 | if (mtd_has_cmdlinepart()) { |
1154 | const char *probes[] = { "cmdlinepart", NULL }; | 1150 | const char *probes[] = { "cmdlinepart", NULL }; |
1155 | struct mtd_partition *parts; | 1151 | struct mtd_partition *parts; |
@@ -1158,13 +1154,10 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1158 | nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0); | 1154 | nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0); |
1159 | 1155 | ||
1160 | if (nr_parts) | 1156 | if (nr_parts) |
1161 | return add_mtd_partitions(info->mtd, parts, nr_parts); | 1157 | return mtd_device_register(info->mtd, parts, nr_parts); |
1162 | } | 1158 | } |
1163 | 1159 | ||
1164 | return add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); | 1160 | return mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts); |
1165 | #else | ||
1166 | return 0; | ||
1167 | #endif | ||
1168 | } | 1161 | } |
1169 | 1162 | ||
1170 | #ifdef CONFIG_PM | 1163 | #ifdef CONFIG_PM |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 67440b5beef8..c9f9127ff770 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -580,7 +580,8 @@ static int __init rtc_from4_init(void) | |||
580 | #endif | 580 | #endif |
581 | 581 | ||
582 | /* Register the partitions */ | 582 | /* Register the partitions */ |
583 | ret = add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); | 583 | ret = mtd_device_register(rtc_from4_mtd, partition_info, |
584 | NUM_PARTITIONS); | ||
584 | if (ret) | 585 | if (ret) |
585 | goto err_3; | 586 | goto err_3; |
586 | 587 | ||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 33d832dddfdd..4405468f196b 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -55,7 +55,7 @@ static int hardware_ecc = 0; | |||
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP | 57 | #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP |
58 | static int clock_stop = 1; | 58 | static const int clock_stop = 1; |
59 | #else | 59 | #else |
60 | static const int clock_stop = 0; | 60 | static const int clock_stop = 0; |
61 | #endif | 61 | #endif |
@@ -96,6 +96,12 @@ enum s3c_cpu_type { | |||
96 | TYPE_S3C2440, | 96 | TYPE_S3C2440, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | enum s3c_nand_clk_state { | ||
100 | CLOCK_DISABLE = 0, | ||
101 | CLOCK_ENABLE, | ||
102 | CLOCK_SUSPEND, | ||
103 | }; | ||
104 | |||
99 | /* overview of the s3c2410 nand state */ | 105 | /* overview of the s3c2410 nand state */ |
100 | 106 | ||
101 | /** | 107 | /** |
@@ -111,6 +117,7 @@ enum s3c_cpu_type { | |||
111 | * @mtd_count: The number of MTDs created from this controller. | 117 | * @mtd_count: The number of MTDs created from this controller. |
112 | * @save_sel: The contents of @sel_reg to be saved over suspend. | 118 | * @save_sel: The contents of @sel_reg to be saved over suspend. |
113 | * @clk_rate: The clock rate from @clk. | 119 | * @clk_rate: The clock rate from @clk. |
120 | * @clk_state: The current clock state. | ||
114 | * @cpu_type: The exact type of this controller. | 121 | * @cpu_type: The exact type of this controller. |
115 | */ | 122 | */ |
116 | struct s3c2410_nand_info { | 123 | struct s3c2410_nand_info { |
@@ -129,6 +136,7 @@ struct s3c2410_nand_info { | |||
129 | int mtd_count; | 136 | int mtd_count; |
130 | unsigned long save_sel; | 137 | unsigned long save_sel; |
131 | unsigned long clk_rate; | 138 | unsigned long clk_rate; |
139 | enum s3c_nand_clk_state clk_state; | ||
132 | 140 | ||
133 | enum s3c_cpu_type cpu_type; | 141 | enum s3c_cpu_type cpu_type; |
134 | 142 | ||
@@ -159,11 +167,33 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev) | |||
159 | return dev->dev.platform_data; | 167 | return dev->dev.platform_data; |
160 | } | 168 | } |
161 | 169 | ||
162 | static inline int allow_clk_stop(struct s3c2410_nand_info *info) | 170 | static inline int allow_clk_suspend(struct s3c2410_nand_info *info) |
163 | { | 171 | { |
164 | return clock_stop; | 172 | return clock_stop; |
165 | } | 173 | } |
166 | 174 | ||
175 | /** | ||
176 | * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock. | ||
177 | * @info: The controller instance. | ||
178 | * @new_state: State to which clock should be set. | ||
179 | */ | ||
180 | static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info, | ||
181 | enum s3c_nand_clk_state new_state) | ||
182 | { | ||
183 | if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND) | ||
184 | return; | ||
185 | |||
186 | if (info->clk_state == CLOCK_ENABLE) { | ||
187 | if (new_state != CLOCK_ENABLE) | ||
188 | clk_disable(info->clk); | ||
189 | } else { | ||
190 | if (new_state == CLOCK_ENABLE) | ||
191 | clk_enable(info->clk); | ||
192 | } | ||
193 | |||
194 | info->clk_state = new_state; | ||
195 | } | ||
196 | |||
167 | /* timing calculations */ | 197 | /* timing calculations */ |
168 | 198 | ||
169 | #define NS_IN_KHZ 1000000 | 199 | #define NS_IN_KHZ 1000000 |
@@ -333,8 +363,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
333 | nmtd = this->priv; | 363 | nmtd = this->priv; |
334 | info = nmtd->info; | 364 | info = nmtd->info; |
335 | 365 | ||
336 | if (chip != -1 && allow_clk_stop(info)) | 366 | if (chip != -1) |
337 | clk_enable(info->clk); | 367 | s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); |
338 | 368 | ||
339 | cur = readl(info->sel_reg); | 369 | cur = readl(info->sel_reg); |
340 | 370 | ||
@@ -356,8 +386,8 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
356 | 386 | ||
357 | writel(cur, info->sel_reg); | 387 | writel(cur, info->sel_reg); |
358 | 388 | ||
359 | if (chip == -1 && allow_clk_stop(info)) | 389 | if (chip == -1) |
360 | clk_disable(info->clk); | 390 | s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); |
361 | } | 391 | } |
362 | 392 | ||
363 | /* s3c2410_nand_hwcontrol | 393 | /* s3c2410_nand_hwcontrol |
@@ -694,8 +724,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) | |||
694 | /* free the common resources */ | 724 | /* free the common resources */ |
695 | 725 | ||
696 | if (info->clk != NULL && !IS_ERR(info->clk)) { | 726 | if (info->clk != NULL && !IS_ERR(info->clk)) { |
697 | if (!allow_clk_stop(info)) | 727 | s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); |
698 | clk_disable(info->clk); | ||
699 | clk_put(info->clk); | 728 | clk_put(info->clk); |
700 | } | 729 | } |
701 | 730 | ||
@@ -715,7 +744,6 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) | |||
715 | return 0; | 744 | return 0; |
716 | } | 745 | } |
717 | 746 | ||
718 | #ifdef CONFIG_MTD_PARTITIONS | ||
719 | const char *part_probes[] = { "cmdlinepart", NULL }; | 747 | const char *part_probes[] = { "cmdlinepart", NULL }; |
720 | static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | 748 | static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, |
721 | struct s3c2410_nand_mtd *mtd, | 749 | struct s3c2410_nand_mtd *mtd, |
@@ -725,7 +753,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | |||
725 | int nr_part = 0; | 753 | int nr_part = 0; |
726 | 754 | ||
727 | if (set == NULL) | 755 | if (set == NULL) |
728 | return add_mtd_device(&mtd->mtd); | 756 | return mtd_device_register(&mtd->mtd, NULL, 0); |
729 | 757 | ||
730 | mtd->mtd.name = set->name; | 758 | mtd->mtd.name = set->name; |
731 | nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0); | 759 | nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0); |
@@ -735,19 +763,8 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | |||
735 | part_info = set->partitions; | 763 | part_info = set->partitions; |
736 | } | 764 | } |
737 | 765 | ||
738 | if (nr_part > 0 && part_info) | 766 | return mtd_device_register(&mtd->mtd, part_info, nr_part); |
739 | return add_mtd_partitions(&mtd->mtd, part_info, nr_part); | ||
740 | |||
741 | return add_mtd_device(&mtd->mtd); | ||
742 | } | ||
743 | #else | ||
744 | static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | ||
745 | struct s3c2410_nand_mtd *mtd, | ||
746 | struct s3c2410_nand_set *set) | ||
747 | { | ||
748 | return add_mtd_device(&mtd->mtd); | ||
749 | } | 767 | } |
750 | #endif | ||
751 | 768 | ||
752 | /** | 769 | /** |
753 | * s3c2410_nand_init_chip - initialise a single instance of an chip | 770 | * s3c2410_nand_init_chip - initialise a single instance of an chip |
@@ -947,7 +964,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
947 | goto exit_error; | 964 | goto exit_error; |
948 | } | 965 | } |
949 | 966 | ||
950 | clk_enable(info->clk); | 967 | s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); |
951 | 968 | ||
952 | /* allocate and map the resource */ | 969 | /* allocate and map the resource */ |
953 | 970 | ||
@@ -1026,9 +1043,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
1026 | goto exit_error; | 1043 | goto exit_error; |
1027 | } | 1044 | } |
1028 | 1045 | ||
1029 | if (allow_clk_stop(info)) { | 1046 | if (allow_clk_suspend(info)) { |
1030 | dev_info(&pdev->dev, "clock idle support enabled\n"); | 1047 | dev_info(&pdev->dev, "clock idle support enabled\n"); |
1031 | clk_disable(info->clk); | 1048 | s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); |
1032 | } | 1049 | } |
1033 | 1050 | ||
1034 | pr_debug("initialised ok\n"); | 1051 | pr_debug("initialised ok\n"); |
@@ -1059,8 +1076,7 @@ static int s3c24xx_nand_suspend(struct platform_device *dev, pm_message_t pm) | |||
1059 | 1076 | ||
1060 | writel(info->save_sel | info->sel_bit, info->sel_reg); | 1077 | writel(info->save_sel | info->sel_bit, info->sel_reg); |
1061 | 1078 | ||
1062 | if (!allow_clk_stop(info)) | 1079 | s3c2410_nand_clk_set_state(info, CLOCK_DISABLE); |
1063 | clk_disable(info->clk); | ||
1064 | } | 1080 | } |
1065 | 1081 | ||
1066 | return 0; | 1082 | return 0; |
@@ -1072,7 +1088,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) | |||
1072 | unsigned long sel; | 1088 | unsigned long sel; |
1073 | 1089 | ||
1074 | if (info) { | 1090 | if (info) { |
1075 | clk_enable(info->clk); | 1091 | s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); |
1076 | s3c2410_nand_inithw(info); | 1092 | s3c2410_nand_inithw(info); |
1077 | 1093 | ||
1078 | /* Restore the state of the nFCE line. */ | 1094 | /* Restore the state of the nFCE line. */ |
@@ -1082,8 +1098,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) | |||
1082 | sel |= info->save_sel & info->sel_bit; | 1098 | sel |= info->save_sel & info->sel_bit; |
1083 | writel(sel, info->sel_reg); | 1099 | writel(sel, info->sel_reg); |
1084 | 1100 | ||
1085 | if (allow_clk_stop(info)) | 1101 | s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND); |
1086 | clk_disable(info->clk); | ||
1087 | } | 1102 | } |
1088 | 1103 | ||
1089 | return 0; | 1104 | return 0; |
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 81bbb5ee148d..93b1f74321c2 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
@@ -867,7 +867,7 @@ static int __devinit flctl_probe(struct platform_device *pdev) | |||
867 | if (ret) | 867 | if (ret) |
868 | goto err; | 868 | goto err; |
869 | 869 | ||
870 | add_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts); | 870 | mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); |
871 | 871 | ||
872 | return 0; | 872 | return 0; |
873 | 873 | ||
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 54ec7542a7b7..19e24ed089ea 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -103,9 +103,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, | |||
103 | return readb(sharpsl->io + ECCCNTR) != 0; | 103 | return readb(sharpsl->io + ECCCNTR) != 0; |
104 | } | 104 | } |
105 | 105 | ||
106 | #ifdef CONFIG_MTD_PARTITIONS | ||
107 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 106 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
108 | #endif | ||
109 | 107 | ||
110 | /* | 108 | /* |
111 | * Main initialization routine | 109 | * Main initialization routine |
@@ -113,10 +111,8 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; | |||
113 | static int __devinit sharpsl_nand_probe(struct platform_device *pdev) | 111 | static int __devinit sharpsl_nand_probe(struct platform_device *pdev) |
114 | { | 112 | { |
115 | struct nand_chip *this; | 113 | struct nand_chip *this; |
116 | #ifdef CONFIG_MTD_PARTITIONS | ||
117 | struct mtd_partition *sharpsl_partition_info; | 114 | struct mtd_partition *sharpsl_partition_info; |
118 | int nr_partitions; | 115 | int nr_partitions; |
119 | #endif | ||
120 | struct resource *r; | 116 | struct resource *r; |
121 | int err = 0; | 117 | int err = 0; |
122 | struct sharpsl_nand *sharpsl; | 118 | struct sharpsl_nand *sharpsl; |
@@ -188,18 +184,14 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev) | |||
188 | 184 | ||
189 | /* Register the partitions */ | 185 | /* Register the partitions */ |
190 | sharpsl->mtd.name = "sharpsl-nand"; | 186 | sharpsl->mtd.name = "sharpsl-nand"; |
191 | #ifdef CONFIG_MTD_PARTITIONS | ||
192 | nr_partitions = parse_mtd_partitions(&sharpsl->mtd, part_probes, &sharpsl_partition_info, 0); | 187 | nr_partitions = parse_mtd_partitions(&sharpsl->mtd, part_probes, &sharpsl_partition_info, 0); |
193 | if (nr_partitions <= 0) { | 188 | if (nr_partitions <= 0) { |
194 | nr_partitions = data->nr_partitions; | 189 | nr_partitions = data->nr_partitions; |
195 | sharpsl_partition_info = data->partitions; | 190 | sharpsl_partition_info = data->partitions; |
196 | } | 191 | } |
197 | 192 | ||
198 | if (nr_partitions > 0) | 193 | err = mtd_device_register(&sharpsl->mtd, sharpsl_partition_info, |
199 | err = add_mtd_partitions(&sharpsl->mtd, sharpsl_partition_info, nr_partitions); | 194 | nr_partitions); |
200 | else | ||
201 | #endif | ||
202 | err = add_mtd_device(&sharpsl->mtd); | ||
203 | if (err) | 195 | if (err) |
204 | goto err_add; | 196 | goto err_add; |
205 | 197 | ||
diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/sm_common.c index 57cc80cd01a3..b6332e83b289 100644 --- a/drivers/mtd/nand/sm_common.c +++ b/drivers/mtd/nand/sm_common.c | |||
@@ -139,7 +139,7 @@ int sm_register_device(struct mtd_info *mtd, int smartmedia) | |||
139 | if (ret) | 139 | if (ret) |
140 | return ret; | 140 | return ret; |
141 | 141 | ||
142 | return add_mtd_device(mtd); | 142 | return mtd_device_register(mtd, NULL, 0); |
143 | } | 143 | } |
144 | EXPORT_SYMBOL_GPL(sm_register_device); | 144 | EXPORT_SYMBOL_GPL(sm_register_device); |
145 | 145 | ||
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index a853548986f0..ca2d0555729e 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c | |||
@@ -155,9 +155,7 @@ static int socrates_nand_device_ready(struct mtd_info *mtd) | |||
155 | return 1; | 155 | return 1; |
156 | } | 156 | } |
157 | 157 | ||
158 | #ifdef CONFIG_MTD_PARTITIONS | ||
159 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 158 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
160 | #endif | ||
161 | 159 | ||
162 | /* | 160 | /* |
163 | * Probe for the NAND device. | 161 | * Probe for the NAND device. |
@@ -168,11 +166,8 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev) | |||
168 | struct mtd_info *mtd; | 166 | struct mtd_info *mtd; |
169 | struct nand_chip *nand_chip; | 167 | struct nand_chip *nand_chip; |
170 | int res; | 168 | int res; |
171 | |||
172 | #ifdef CONFIG_MTD_PARTITIONS | ||
173 | struct mtd_partition *partitions = NULL; | 169 | struct mtd_partition *partitions = NULL; |
174 | int num_partitions = 0; | 170 | int num_partitions = 0; |
175 | #endif | ||
176 | 171 | ||
177 | /* Allocate memory for the device structure (and zero it) */ | 172 | /* Allocate memory for the device structure (and zero it) */ |
178 | host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL); | 173 | host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL); |
@@ -230,7 +225,6 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev) | |||
230 | goto out; | 225 | goto out; |
231 | } | 226 | } |
232 | 227 | ||
233 | #ifdef CONFIG_MTD_PARTITIONS | ||
234 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 228 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
235 | num_partitions = parse_mtd_partitions(mtd, part_probes, | 229 | num_partitions = parse_mtd_partitions(mtd, part_probes, |
236 | &partitions, 0); | 230 | &partitions, 0); |
@@ -240,7 +234,6 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev) | |||
240 | } | 234 | } |
241 | #endif | 235 | #endif |
242 | 236 | ||
243 | #ifdef CONFIG_MTD_OF_PARTS | ||
244 | if (num_partitions == 0) { | 237 | if (num_partitions == 0) { |
245 | num_partitions = of_mtd_parse_partitions(&ofdev->dev, | 238 | num_partitions = of_mtd_parse_partitions(&ofdev->dev, |
246 | ofdev->dev.of_node, | 239 | ofdev->dev.of_node, |
@@ -250,19 +243,12 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev) | |||
250 | goto release; | 243 | goto release; |
251 | } | 244 | } |
252 | } | 245 | } |
253 | #endif | ||
254 | if (partitions && (num_partitions > 0)) | ||
255 | res = add_mtd_partitions(mtd, partitions, num_partitions); | ||
256 | else | ||
257 | #endif | ||
258 | res = add_mtd_device(mtd); | ||
259 | 246 | ||
247 | res = mtd_device_register(mtd, partitions, num_partitions); | ||
260 | if (!res) | 248 | if (!res) |
261 | return res; | 249 | return res; |
262 | 250 | ||
263 | #ifdef CONFIG_MTD_PARTITIONS | ||
264 | release: | 251 | release: |
265 | #endif | ||
266 | nand_release(mtd); | 252 | nand_release(mtd); |
267 | 253 | ||
268 | out: | 254 | out: |
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c index 0cc6d0acb8fe..bef76cd7c24c 100644 --- a/drivers/mtd/nand/spia.c +++ b/drivers/mtd/nand/spia.c | |||
@@ -149,7 +149,7 @@ static int __init spia_init(void) | |||
149 | } | 149 | } |
150 | 150 | ||
151 | /* Register the partitions */ | 151 | /* Register the partitions */ |
152 | add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS); | 152 | mtd_device_register(spia_mtd, partition_info, NUM_PARTITIONS); |
153 | 153 | ||
154 | /* Return happy */ | 154 | /* Return happy */ |
155 | return 0; | 155 | return 0; |
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index c004e474631b..11e8371b5683 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c | |||
@@ -381,10 +381,8 @@ static int tmio_probe(struct platform_device *dev) | |||
381 | struct tmio_nand *tmio; | 381 | struct tmio_nand *tmio; |
382 | struct mtd_info *mtd; | 382 | struct mtd_info *mtd; |
383 | struct nand_chip *nand_chip; | 383 | struct nand_chip *nand_chip; |
384 | #ifdef CONFIG_MTD_PARTITIONS | ||
385 | struct mtd_partition *parts; | 384 | struct mtd_partition *parts; |
386 | int nbparts = 0; | 385 | int nbparts = 0; |
387 | #endif | ||
388 | int retval; | 386 | int retval; |
389 | 387 | ||
390 | if (data == NULL) | 388 | if (data == NULL) |
@@ -463,7 +461,6 @@ static int tmio_probe(struct platform_device *dev) | |||
463 | goto err_scan; | 461 | goto err_scan; |
464 | } | 462 | } |
465 | /* Register the partitions */ | 463 | /* Register the partitions */ |
466 | #ifdef CONFIG_MTD_PARTITIONS | ||
467 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 464 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
468 | nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0); | 465 | nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0); |
469 | #endif | 466 | #endif |
@@ -472,12 +469,7 @@ static int tmio_probe(struct platform_device *dev) | |||
472 | nbparts = data->num_partitions; | 469 | nbparts = data->num_partitions; |
473 | } | 470 | } |
474 | 471 | ||
475 | if (nbparts) | 472 | retval = mtd_device_register(mtd, parts, nbparts); |
476 | retval = add_mtd_partitions(mtd, parts, nbparts); | ||
477 | else | ||
478 | #endif | ||
479 | retval = add_mtd_device(mtd); | ||
480 | |||
481 | if (!retval) | 473 | if (!retval) |
482 | return retval; | 474 | return retval; |
483 | 475 | ||
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index ca270a4881a4..bfba4e39a6c5 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c | |||
@@ -74,9 +74,7 @@ struct txx9ndfmc_drvdata { | |||
74 | unsigned char hold; /* in gbusclock */ | 74 | unsigned char hold; /* in gbusclock */ |
75 | unsigned char spw; /* in gbusclock */ | 75 | unsigned char spw; /* in gbusclock */ |
76 | struct nand_hw_control hw_control; | 76 | struct nand_hw_control hw_control; |
77 | #ifdef CONFIG_MTD_PARTITIONS | ||
78 | struct mtd_partition *parts[MAX_TXX9NDFMC_DEV]; | 77 | struct mtd_partition *parts[MAX_TXX9NDFMC_DEV]; |
79 | #endif | ||
80 | }; | 78 | }; |
81 | 79 | ||
82 | static struct platform_device *mtd_to_platdev(struct mtd_info *mtd) | 80 | static struct platform_device *mtd_to_platdev(struct mtd_info *mtd) |
@@ -289,9 +287,7 @@ static int txx9ndfmc_nand_scan(struct mtd_info *mtd) | |||
289 | static int __init txx9ndfmc_probe(struct platform_device *dev) | 287 | static int __init txx9ndfmc_probe(struct platform_device *dev) |
290 | { | 288 | { |
291 | struct txx9ndfmc_platform_data *plat = dev->dev.platform_data; | 289 | struct txx9ndfmc_platform_data *plat = dev->dev.platform_data; |
292 | #ifdef CONFIG_MTD_PARTITIONS | ||
293 | static const char *probes[] = { "cmdlinepart", NULL }; | 290 | static const char *probes[] = { "cmdlinepart", NULL }; |
294 | #endif | ||
295 | int hold, spw; | 291 | int hold, spw; |
296 | int i; | 292 | int i; |
297 | struct txx9ndfmc_drvdata *drvdata; | 293 | struct txx9ndfmc_drvdata *drvdata; |
@@ -337,9 +333,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) | |||
337 | struct txx9ndfmc_priv *txx9_priv; | 333 | struct txx9ndfmc_priv *txx9_priv; |
338 | struct nand_chip *chip; | 334 | struct nand_chip *chip; |
339 | struct mtd_info *mtd; | 335 | struct mtd_info *mtd; |
340 | #ifdef CONFIG_MTD_PARTITIONS | ||
341 | int nr_parts; | 336 | int nr_parts; |
342 | #endif | ||
343 | 337 | ||
344 | if (!(plat->ch_mask & (1 << i))) | 338 | if (!(plat->ch_mask & (1 << i))) |
345 | continue; | 339 | continue; |
@@ -399,13 +393,9 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) | |||
399 | } | 393 | } |
400 | mtd->name = txx9_priv->mtdname; | 394 | mtd->name = txx9_priv->mtdname; |
401 | 395 | ||
402 | #ifdef CONFIG_MTD_PARTITIONS | ||
403 | nr_parts = parse_mtd_partitions(mtd, probes, | 396 | nr_parts = parse_mtd_partitions(mtd, probes, |
404 | &drvdata->parts[i], 0); | 397 | &drvdata->parts[i], 0); |
405 | if (nr_parts > 0) | 398 | mtd_device_register(mtd, drvdata->parts[i], nr_parts); |
406 | add_mtd_partitions(mtd, drvdata->parts[i], nr_parts); | ||
407 | #endif | ||
408 | add_mtd_device(mtd); | ||
409 | drvdata->mtds[i] = mtd; | 399 | drvdata->mtds[i] = mtd; |
410 | } | 400 | } |
411 | 401 | ||
@@ -431,9 +421,7 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev) | |||
431 | txx9_priv = chip->priv; | 421 | txx9_priv = chip->priv; |
432 | 422 | ||
433 | nand_release(mtd); | 423 | nand_release(mtd); |
434 | #ifdef CONFIG_MTD_PARTITIONS | ||
435 | kfree(drvdata->parts[i]); | 424 | kfree(drvdata->parts[i]); |
436 | #endif | ||
437 | kfree(txx9_priv->mtdname); | 425 | kfree(txx9_priv->mtdname); |
438 | kfree(txx9_priv); | 426 | kfree(txx9_priv); |
439 | } | 427 | } |
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig index 4f426195f8db..772ad2966619 100644 --- a/drivers/mtd/onenand/Kconfig +++ b/drivers/mtd/onenand/Kconfig | |||
@@ -1,7 +1,6 @@ | |||
1 | menuconfig MTD_ONENAND | 1 | menuconfig MTD_ONENAND |
2 | tristate "OneNAND Device Support" | 2 | tristate "OneNAND Device Support" |
3 | depends on MTD | 3 | depends on MTD |
4 | select MTD_PARTITIONS | ||
5 | help | 4 | help |
6 | This enables support for accessing all type of OneNAND flash | 5 | This enables support for accessing all type of OneNAND flash |
7 | devices. For further information see | 6 | devices. For further information see |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index ac08750748a3..2d70d354d846 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
@@ -30,9 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | #define DRIVER_NAME "onenand-flash" | 31 | #define DRIVER_NAME "onenand-flash" |
32 | 32 | ||
33 | #ifdef CONFIG_MTD_PARTITIONS | ||
34 | static const char *part_probes[] = { "cmdlinepart", NULL, }; | 33 | static const char *part_probes[] = { "cmdlinepart", NULL, }; |
35 | #endif | ||
36 | 34 | ||
37 | struct onenand_info { | 35 | struct onenand_info { |
38 | struct mtd_info mtd; | 36 | struct mtd_info mtd; |
@@ -75,15 +73,13 @@ static int __devinit generic_onenand_probe(struct platform_device *pdev) | |||
75 | goto out_iounmap; | 73 | goto out_iounmap; |
76 | } | 74 | } |
77 | 75 | ||
78 | #ifdef CONFIG_MTD_PARTITIONS | ||
79 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); | 76 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); |
80 | if (err > 0) | 77 | if (err > 0) |
81 | add_mtd_partitions(&info->mtd, info->parts, err); | 78 | mtd_device_register(&info->mtd, info->parts, err); |
82 | else if (err <= 0 && pdata && pdata->parts) | 79 | else if (err <= 0 && pdata && pdata->parts) |
83 | add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); | 80 | mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts); |
84 | else | 81 | else |
85 | #endif | 82 | err = mtd_device_register(&info->mtd, NULL, 0); |
86 | err = add_mtd_device(&info->mtd); | ||
87 | 83 | ||
88 | platform_set_drvdata(pdev, info); | 84 | platform_set_drvdata(pdev, info); |
89 | 85 | ||
@@ -108,11 +104,7 @@ static int __devexit generic_onenand_remove(struct platform_device *pdev) | |||
108 | platform_set_drvdata(pdev, NULL); | 104 | platform_set_drvdata(pdev, NULL); |
109 | 105 | ||
110 | if (info) { | 106 | if (info) { |
111 | if (info->parts) | 107 | mtd_device_unregister(&info->mtd); |
112 | del_mtd_partitions(&info->mtd); | ||
113 | else | ||
114 | del_mtd_device(&info->mtd); | ||
115 | |||
116 | onenand_release(&info->mtd); | 108 | onenand_release(&info->mtd); |
117 | release_mem_region(res->start, size); | 109 | release_mem_region(res->start, size); |
118 | iounmap(info->onenand.base); | 110 | iounmap(info->onenand.base); |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 1fcb41adab07..a916dec29215 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
@@ -67,9 +67,7 @@ struct omap2_onenand { | |||
67 | struct regulator *regulator; | 67 | struct regulator *regulator; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #ifdef CONFIG_MTD_PARTITIONS | ||
71 | static const char *part_probes[] = { "cmdlinepart", NULL, }; | 70 | static const char *part_probes[] = { "cmdlinepart", NULL, }; |
72 | #endif | ||
73 | 71 | ||
74 | static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data) | 72 | static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data) |
75 | { | 73 | { |
@@ -755,15 +753,13 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) | |||
755 | if ((r = onenand_scan(&c->mtd, 1)) < 0) | 753 | if ((r = onenand_scan(&c->mtd, 1)) < 0) |
756 | goto err_release_regulator; | 754 | goto err_release_regulator; |
757 | 755 | ||
758 | #ifdef CONFIG_MTD_PARTITIONS | ||
759 | r = parse_mtd_partitions(&c->mtd, part_probes, &c->parts, 0); | 756 | r = parse_mtd_partitions(&c->mtd, part_probes, &c->parts, 0); |
760 | if (r > 0) | 757 | if (r > 0) |
761 | r = add_mtd_partitions(&c->mtd, c->parts, r); | 758 | r = mtd_device_register(&c->mtd, c->parts, r); |
762 | else if (pdata->parts != NULL) | 759 | else if (pdata->parts != NULL) |
763 | r = add_mtd_partitions(&c->mtd, pdata->parts, pdata->nr_parts); | 760 | r = mtd_device_register(&c->mtd, pdata->parts, pdata->nr_parts); |
764 | else | 761 | else |
765 | #endif | 762 | r = mtd_device_register(&c->mtd, NULL, 0); |
766 | r = add_mtd_device(&c->mtd); | ||
767 | if (r) | 763 | if (r) |
768 | goto err_release_onenand; | 764 | goto err_release_onenand; |
769 | 765 | ||
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 56a8b2005bda..ac9e959802a7 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -65,11 +65,11 @@ MODULE_PARM_DESC(otp, "Corresponding behaviour of OneNAND in OTP" | |||
65 | " : 2 -> 1st Block lock" | 65 | " : 2 -> 1st Block lock" |
66 | " : 3 -> BOTH OTP Block and 1st Block lock"); | 66 | " : 3 -> BOTH OTP Block and 1st Block lock"); |
67 | 67 | ||
68 | /** | 68 | /* |
69 | * onenand_oob_128 - oob info for Flex-Onenand with 4KB page | 69 | * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page |
70 | * For now, we expose only 64 out of 80 ecc bytes | 70 | * For now, we expose only 64 out of 80 ecc bytes |
71 | */ | 71 | */ |
72 | static struct nand_ecclayout onenand_oob_128 = { | 72 | static struct nand_ecclayout flexonenand_oob_128 = { |
73 | .eccbytes = 64, | 73 | .eccbytes = 64, |
74 | .eccpos = { | 74 | .eccpos = { |
75 | 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | 75 | 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
@@ -86,6 +86,35 @@ static struct nand_ecclayout onenand_oob_128 = { | |||
86 | } | 86 | } |
87 | }; | 87 | }; |
88 | 88 | ||
89 | /* | ||
90 | * onenand_oob_128 - oob info for OneNAND with 4KB page | ||
91 | * | ||
92 | * Based on specification: | ||
93 | * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010 | ||
94 | * | ||
95 | * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout) | ||
96 | * | ||
97 | * oobfree uses the spare area fields marked as | ||
98 | * "Managed by internal ECC logic for Logical Sector Number area" | ||
99 | */ | ||
100 | static struct nand_ecclayout onenand_oob_128 = { | ||
101 | .eccbytes = 64, | ||
102 | .eccpos = { | ||
103 | 7, 8, 9, 10, 11, 12, 13, 14, 15, | ||
104 | 23, 24, 25, 26, 27, 28, 29, 30, 31, | ||
105 | 39, 40, 41, 42, 43, 44, 45, 46, 47, | ||
106 | 55, 56, 57, 58, 59, 60, 61, 62, 63, | ||
107 | 71, 72, 73, 74, 75, 76, 77, 78, 79, | ||
108 | 87, 88, 89, 90, 91, 92, 93, 94, 95, | ||
109 | 103, 104, 105, 106, 107, 108, 109, 110, 111, | ||
110 | 119 | ||
111 | }, | ||
112 | .oobfree = { | ||
113 | {2, 3}, {18, 3}, {34, 3}, {50, 3}, | ||
114 | {66, 3}, {82, 3}, {98, 3}, {114, 3} | ||
115 | } | ||
116 | }; | ||
117 | |||
89 | /** | 118 | /** |
90 | * onenand_oob_64 - oob info for large (2KB) page | 119 | * onenand_oob_64 - oob info for large (2KB) page |
91 | */ | 120 | */ |
@@ -2424,7 +2453,7 @@ static int onenand_block_by_block_erase(struct mtd_info *mtd, | |||
2424 | len -= block_size; | 2453 | len -= block_size; |
2425 | addr += block_size; | 2454 | addr += block_size; |
2426 | 2455 | ||
2427 | if (addr == region_end) { | 2456 | if (region && addr == region_end) { |
2428 | if (!len) | 2457 | if (!len) |
2429 | break; | 2458 | break; |
2430 | region++; | 2459 | region++; |
@@ -4018,8 +4047,13 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
4018 | */ | 4047 | */ |
4019 | switch (mtd->oobsize) { | 4048 | switch (mtd->oobsize) { |
4020 | case 128: | 4049 | case 128: |
4021 | this->ecclayout = &onenand_oob_128; | 4050 | if (FLEXONENAND(this)) { |
4022 | mtd->subpage_sft = 0; | 4051 | this->ecclayout = &flexonenand_oob_128; |
4052 | mtd->subpage_sft = 0; | ||
4053 | } else { | ||
4054 | this->ecclayout = &onenand_oob_128; | ||
4055 | mtd->subpage_sft = 2; | ||
4056 | } | ||
4023 | break; | 4057 | break; |
4024 | case 64: | 4058 | case 64: |
4025 | this->ecclayout = &onenand_oob_64; | 4059 | this->ecclayout = &onenand_oob_64; |
@@ -4108,12 +4142,8 @@ void onenand_release(struct mtd_info *mtd) | |||
4108 | { | 4142 | { |
4109 | struct onenand_chip *this = mtd->priv; | 4143 | struct onenand_chip *this = mtd->priv; |
4110 | 4144 | ||
4111 | #ifdef CONFIG_MTD_PARTITIONS | ||
4112 | /* Deregister partitions */ | 4145 | /* Deregister partitions */ |
4113 | del_mtd_partitions (mtd); | 4146 | mtd_device_unregister(mtd); |
4114 | #endif | ||
4115 | /* Deregister the device */ | ||
4116 | del_mtd_device (mtd); | ||
4117 | 4147 | ||
4118 | /* Free bad block table memory, if allocated */ | 4148 | /* Free bad block table memory, if allocated */ |
4119 | if (this->bbm) { | 4149 | if (this->bbm) { |
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c index 5ef3bd547772..85399e3accda 100644 --- a/drivers/mtd/onenand/onenand_sim.c +++ b/drivers/mtd/onenand/onenand_sim.c | |||
@@ -539,7 +539,8 @@ static int __init onenand_sim_init(void) | |||
539 | return -ENXIO; | 539 | return -ENXIO; |
540 | } | 540 | } |
541 | 541 | ||
542 | add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions)); | 542 | mtd_device_register(&info->mtd, info->parts, |
543 | ARRAY_SIZE(os_partitions)); | ||
543 | 544 | ||
544 | return 0; | 545 | return 0; |
545 | } | 546 | } |
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index a4c74a9ba430..3306b5b3c736 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c | |||
@@ -147,9 +147,7 @@ struct s3c_onenand { | |||
147 | struct resource *dma_res; | 147 | struct resource *dma_res; |
148 | unsigned long phys_base; | 148 | unsigned long phys_base; |
149 | struct completion complete; | 149 | struct completion complete; |
150 | #ifdef CONFIG_MTD_PARTITIONS | ||
151 | struct mtd_partition *parts; | 150 | struct mtd_partition *parts; |
152 | #endif | ||
153 | }; | 151 | }; |
154 | 152 | ||
155 | #define CMD_MAP_00(dev, addr) (dev->cmd_map(MAP_00, ((addr) << 1))) | 153 | #define CMD_MAP_00(dev, addr) (dev->cmd_map(MAP_00, ((addr) << 1))) |
@@ -159,9 +157,7 @@ struct s3c_onenand { | |||
159 | 157 | ||
160 | static struct s3c_onenand *onenand; | 158 | static struct s3c_onenand *onenand; |
161 | 159 | ||
162 | #ifdef CONFIG_MTD_PARTITIONS | ||
163 | static const char *part_probes[] = { "cmdlinepart", NULL, }; | 160 | static const char *part_probes[] = { "cmdlinepart", NULL, }; |
164 | #endif | ||
165 | 161 | ||
166 | static inline int s3c_read_reg(int offset) | 162 | static inline int s3c_read_reg(int offset) |
167 | { | 163 | { |
@@ -1021,15 +1017,13 @@ static int s3c_onenand_probe(struct platform_device *pdev) | |||
1021 | if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ) | 1017 | if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ) |
1022 | dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n"); | 1018 | dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n"); |
1023 | 1019 | ||
1024 | #ifdef CONFIG_MTD_PARTITIONS | ||
1025 | err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0); | 1020 | err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0); |
1026 | if (err > 0) | 1021 | if (err > 0) |
1027 | add_mtd_partitions(mtd, onenand->parts, err); | 1022 | mtd_device_register(mtd, onenand->parts, err); |
1028 | else if (err <= 0 && pdata && pdata->parts) | 1023 | else if (err <= 0 && pdata && pdata->parts) |
1029 | add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); | 1024 | mtd_device_register(mtd, pdata->parts, pdata->nr_parts); |
1030 | else | 1025 | else |
1031 | #endif | 1026 | err = mtd_device_register(mtd, NULL, 0); |
1032 | err = add_mtd_device(mtd); | ||
1033 | 1027 | ||
1034 | platform_set_drvdata(pdev, mtd); | 1028 | platform_set_drvdata(pdev, mtd); |
1035 | 1029 | ||
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 9aa81584c8a2..941bc3c05d6e 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c | |||
@@ -365,7 +365,7 @@ static int gluebi_create(struct ubi_device_info *di, | |||
365 | vi->vol_id); | 365 | vi->vol_id); |
366 | mutex_unlock(&devices_mutex); | 366 | mutex_unlock(&devices_mutex); |
367 | 367 | ||
368 | if (add_mtd_device(mtd)) { | 368 | if (mtd_device_register(mtd, NULL, 0)) { |
369 | err_msg("cannot add MTD device"); | 369 | err_msg("cannot add MTD device"); |
370 | kfree(mtd->name); | 370 | kfree(mtd->name); |
371 | kfree(gluebi); | 371 | kfree(gluebi); |
@@ -407,7 +407,7 @@ static int gluebi_remove(struct ubi_volume_info *vi) | |||
407 | return err; | 407 | return err; |
408 | 408 | ||
409 | mtd = &gluebi->mtd; | 409 | mtd = &gluebi->mtd; |
410 | err = del_mtd_device(mtd); | 410 | err = mtd_device_unregister(mtd); |
411 | if (err) { | 411 | if (err) { |
412 | err_msg("cannot remove fake MTD device %d, UBI device %d, " | 412 | err_msg("cannot remove fake MTD device %d, UBI device %d, " |
413 | "volume %d, error %d", mtd->index, gluebi->ubi_num, | 413 | "volume %d, error %d", mtd->index, gluebi->ubi_num, |
@@ -524,7 +524,7 @@ static void __exit ubi_gluebi_exit(void) | |||
524 | int err; | 524 | int err; |
525 | struct mtd_info *mtd = &gluebi->mtd; | 525 | struct mtd_info *mtd = &gluebi->mtd; |
526 | 526 | ||
527 | err = del_mtd_device(mtd); | 527 | err = mtd_device_unregister(mtd); |
528 | if (err) | 528 | if (err) |
529 | err_msg("error %d while removing gluebi MTD device %d, " | 529 | err_msg("error %d while removing gluebi MTD device %d, " |
530 | "UBI device %d, volume %d - ignoring", err, | 530 | "UBI device %d, volume %d - ignoring", err, |
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index e646bfce2d84..b6304486f244 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c | |||
@@ -216,7 +216,7 @@ static void efx_mtd_remove_partition(struct efx_mtd_partition *part) | |||
216 | int rc; | 216 | int rc; |
217 | 217 | ||
218 | for (;;) { | 218 | for (;;) { |
219 | rc = del_mtd_device(&part->mtd); | 219 | rc = mtd_device_unregister(&part->mtd); |
220 | if (rc != -EBUSY) | 220 | if (rc != -EBUSY) |
221 | break; | 221 | break; |
222 | ssleep(1); | 222 | ssleep(1); |
@@ -268,7 +268,7 @@ static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd) | |||
268 | part->mtd.write = efx_mtd->ops->write; | 268 | part->mtd.write = efx_mtd->ops->write; |
269 | part->mtd.sync = efx_mtd_sync; | 269 | part->mtd.sync = efx_mtd_sync; |
270 | 270 | ||
271 | if (add_mtd_device(&part->mtd)) | 271 | if (mtd_device_register(&part->mtd, NULL, 0)) |
272 | goto fail; | 272 | goto fail; |
273 | } | 273 | } |
274 | 274 | ||
@@ -280,7 +280,7 @@ fail: | |||
280 | --part; | 280 | --part; |
281 | efx_mtd_remove_partition(part); | 281 | efx_mtd_remove_partition(part); |
282 | } | 282 | } |
283 | /* add_mtd_device() returns 1 if the MTD table is full */ | 283 | /* mtd_device_register() returns 1 if the MTD table is full */ |
284 | return -ENOMEM; | 284 | return -ENOMEM; |
285 | } | 285 | } |
286 | 286 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0cb0b0632672..f6853247a620 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -609,7 +609,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
609 | * before it gets out of hand. Naturally, this wastes entries. */ | 609 | * before it gets out of hand. Naturally, this wastes entries. */ |
610 | if (capacity < 2+MAX_SKB_FRAGS) { | 610 | if (capacity < 2+MAX_SKB_FRAGS) { |
611 | netif_stop_queue(dev); | 611 | netif_stop_queue(dev); |
612 | if (unlikely(!virtqueue_enable_cb(vi->svq))) { | 612 | if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) { |
613 | /* More just got used, free them then recheck. */ | 613 | /* More just got used, free them then recheck. */ |
614 | capacity += free_old_xmit_skbs(vi); | 614 | capacity += free_old_xmit_skbs(vi); |
615 | if (capacity >= 2+MAX_SKB_FRAGS) { | 615 | if (capacity >= 2+MAX_SKB_FRAGS) { |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 8b63a691a9ed..65200af29c52 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -670,7 +670,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
670 | 670 | ||
671 | pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); | 671 | pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); |
672 | 672 | ||
673 | if (depth != 1 || | 673 | if (depth != 1 || !data || |
674 | (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) | 674 | (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) |
675 | return 0; | 675 | return 0; |
676 | 676 | ||
@@ -679,16 +679,16 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
679 | /* Retrieve command line */ | 679 | /* Retrieve command line */ |
680 | p = of_get_flat_dt_prop(node, "bootargs", &l); | 680 | p = of_get_flat_dt_prop(node, "bootargs", &l); |
681 | if (p != NULL && l > 0) | 681 | if (p != NULL && l > 0) |
682 | strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); | 682 | strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); |
683 | 683 | ||
684 | #ifdef CONFIG_CMDLINE | 684 | #ifdef CONFIG_CMDLINE |
685 | #ifndef CONFIG_CMDLINE_FORCE | 685 | #ifndef CONFIG_CMDLINE_FORCE |
686 | if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) | 686 | if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) |
687 | #endif | 687 | #endif |
688 | strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | 688 | strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); |
689 | #endif /* CONFIG_CMDLINE */ | 689 | #endif /* CONFIG_CMDLINE */ |
690 | 690 | ||
691 | pr_debug("Command line is: %s\n", cmd_line); | 691 | pr_debug("Command line is: %s\n", (char*)data); |
692 | 692 | ||
693 | /* break now */ | 693 | /* break now */ |
694 | return 1; | 694 | return 1; |
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h index 4e70749f8d16..a8d5bb3cba89 100644 --- a/drivers/oprofile/event_buffer.h +++ b/drivers/oprofile/event_buffer.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #define EVENT_BUFFER_H | 11 | #define EVENT_BUFFER_H |
12 | 12 | ||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <asm/mutex.h> | 14 | #include <linux/mutex.h> |
15 | 15 | ||
16 | int alloc_event_buffer(void); | 16 | int alloc_event_buffer(void); |
17 | 17 | ||
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index f9bda64fcd1b..dccd8636095c 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <asm/mutex.h> | 17 | #include <linux/mutex.h> |
18 | 18 | ||
19 | #include "oprof.h" | 19 | #include "oprof.h" |
20 | #include "event_buffer.h" | 20 | #include "event_buffer.h" |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 12e02bf92c4a..3dc9befa5aec 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -698,12 +698,7 @@ int __init detect_intel_iommu(void) | |||
698 | { | 698 | { |
699 | #ifdef CONFIG_INTR_REMAP | 699 | #ifdef CONFIG_INTR_REMAP |
700 | struct acpi_table_dmar *dmar; | 700 | struct acpi_table_dmar *dmar; |
701 | /* | 701 | |
702 | * for now we will disable dma-remapping when interrupt | ||
703 | * remapping is enabled. | ||
704 | * When support for queued invalidation for IOTLB invalidation | ||
705 | * is added, we will not need this any more. | ||
706 | */ | ||
707 | dmar = (struct acpi_table_dmar *) dmar_tbl; | 702 | dmar = (struct acpi_table_dmar *) dmar_tbl; |
708 | if (ret && cpu_has_x2apic && dmar->flags & 0x1) | 703 | if (ret && cpu_has_x2apic && dmar->flags & 0x1) |
709 | printk(KERN_INFO | 704 | printk(KERN_INFO |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 6af6b628175b..59f17acf7f68 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #define ROOT_SIZE VTD_PAGE_SIZE | 47 | #define ROOT_SIZE VTD_PAGE_SIZE |
48 | #define CONTEXT_SIZE VTD_PAGE_SIZE | 48 | #define CONTEXT_SIZE VTD_PAGE_SIZE |
49 | 49 | ||
50 | #define IS_BRIDGE_HOST_DEVICE(pdev) \ | ||
51 | ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
50 | #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | 52 | #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) |
51 | #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) | 53 | #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) |
52 | #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) | 54 | #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) |
@@ -116,6 +118,11 @@ static inline unsigned long align_to_level(unsigned long pfn, int level) | |||
116 | return (pfn + level_size(level) - 1) & level_mask(level); | 118 | return (pfn + level_size(level) - 1) & level_mask(level); |
117 | } | 119 | } |
118 | 120 | ||
121 | static inline unsigned long lvl_to_nr_pages(unsigned int lvl) | ||
122 | { | ||
123 | return 1 << ((lvl - 1) * LEVEL_STRIDE); | ||
124 | } | ||
125 | |||
119 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things | 126 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things |
120 | are never going to work. */ | 127 | are never going to work. */ |
121 | static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) | 128 | static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) |
@@ -143,6 +150,12 @@ static void __init check_tylersburg_isoch(void); | |||
143 | static int rwbf_quirk; | 150 | static int rwbf_quirk; |
144 | 151 | ||
145 | /* | 152 | /* |
153 | * set to 1 to panic kernel if can't successfully enable VT-d | ||
154 | * (used when kernel is launched w/ TXT) | ||
155 | */ | ||
156 | static int force_on = 0; | ||
157 | |||
158 | /* | ||
146 | * 0: Present | 159 | * 0: Present |
147 | * 1-11: Reserved | 160 | * 1-11: Reserved |
148 | * 12-63: Context Ptr (12 - (haw-1)) | 161 | * 12-63: Context Ptr (12 - (haw-1)) |
@@ -338,6 +351,9 @@ struct dmar_domain { | |||
338 | int iommu_coherency;/* indicate coherency of iommu access */ | 351 | int iommu_coherency;/* indicate coherency of iommu access */ |
339 | int iommu_snooping; /* indicate snooping control feature*/ | 352 | int iommu_snooping; /* indicate snooping control feature*/ |
340 | int iommu_count; /* reference count of iommu */ | 353 | int iommu_count; /* reference count of iommu */ |
354 | int iommu_superpage;/* Level of superpages supported: | ||
355 | 0 == 4KiB (no superpages), 1 == 2MiB, | ||
356 | 2 == 1GiB, 3 == 512GiB, 4 == 1TiB */ | ||
341 | spinlock_t iommu_lock; /* protect iommu set in domain */ | 357 | spinlock_t iommu_lock; /* protect iommu set in domain */ |
342 | u64 max_addr; /* maximum mapped address */ | 358 | u64 max_addr; /* maximum mapped address */ |
343 | }; | 359 | }; |
@@ -387,6 +403,7 @@ int dmar_disabled = 1; | |||
387 | static int dmar_map_gfx = 1; | 403 | static int dmar_map_gfx = 1; |
388 | static int dmar_forcedac; | 404 | static int dmar_forcedac; |
389 | static int intel_iommu_strict; | 405 | static int intel_iommu_strict; |
406 | static int intel_iommu_superpage = 1; | ||
390 | 407 | ||
391 | #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1)) | 408 | #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1)) |
392 | static DEFINE_SPINLOCK(device_domain_lock); | 409 | static DEFINE_SPINLOCK(device_domain_lock); |
@@ -417,6 +434,10 @@ static int __init intel_iommu_setup(char *str) | |||
417 | printk(KERN_INFO | 434 | printk(KERN_INFO |
418 | "Intel-IOMMU: disable batched IOTLB flush\n"); | 435 | "Intel-IOMMU: disable batched IOTLB flush\n"); |
419 | intel_iommu_strict = 1; | 436 | intel_iommu_strict = 1; |
437 | } else if (!strncmp(str, "sp_off", 6)) { | ||
438 | printk(KERN_INFO | ||
439 | "Intel-IOMMU: disable supported super page\n"); | ||
440 | intel_iommu_superpage = 0; | ||
420 | } | 441 | } |
421 | 442 | ||
422 | str += strcspn(str, ","); | 443 | str += strcspn(str, ","); |
@@ -555,11 +576,32 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain) | |||
555 | } | 576 | } |
556 | } | 577 | } |
557 | 578 | ||
579 | static void domain_update_iommu_superpage(struct dmar_domain *domain) | ||
580 | { | ||
581 | int i, mask = 0xf; | ||
582 | |||
583 | if (!intel_iommu_superpage) { | ||
584 | domain->iommu_superpage = 0; | ||
585 | return; | ||
586 | } | ||
587 | |||
588 | domain->iommu_superpage = 4; /* 1TiB */ | ||
589 | |||
590 | for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { | ||
591 | mask |= cap_super_page_val(g_iommus[i]->cap); | ||
592 | if (!mask) { | ||
593 | break; | ||
594 | } | ||
595 | } | ||
596 | domain->iommu_superpage = fls(mask); | ||
597 | } | ||
598 | |||
558 | /* Some capabilities may be different across iommus */ | 599 | /* Some capabilities may be different across iommus */ |
559 | static void domain_update_iommu_cap(struct dmar_domain *domain) | 600 | static void domain_update_iommu_cap(struct dmar_domain *domain) |
560 | { | 601 | { |
561 | domain_update_iommu_coherency(domain); | 602 | domain_update_iommu_coherency(domain); |
562 | domain_update_iommu_snooping(domain); | 603 | domain_update_iommu_snooping(domain); |
604 | domain_update_iommu_superpage(domain); | ||
563 | } | 605 | } |
564 | 606 | ||
565 | static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) | 607 | static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) |
@@ -689,23 +731,31 @@ out: | |||
689 | } | 731 | } |
690 | 732 | ||
691 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | 733 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
692 | unsigned long pfn) | 734 | unsigned long pfn, int large_level) |
693 | { | 735 | { |
694 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; | 736 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
695 | struct dma_pte *parent, *pte = NULL; | 737 | struct dma_pte *parent, *pte = NULL; |
696 | int level = agaw_to_level(domain->agaw); | 738 | int level = agaw_to_level(domain->agaw); |
697 | int offset; | 739 | int offset, target_level; |
698 | 740 | ||
699 | BUG_ON(!domain->pgd); | 741 | BUG_ON(!domain->pgd); |
700 | BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); | 742 | BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); |
701 | parent = domain->pgd; | 743 | parent = domain->pgd; |
702 | 744 | ||
745 | /* Search pte */ | ||
746 | if (!large_level) | ||
747 | target_level = 1; | ||
748 | else | ||
749 | target_level = large_level; | ||
750 | |||
703 | while (level > 0) { | 751 | while (level > 0) { |
704 | void *tmp_page; | 752 | void *tmp_page; |
705 | 753 | ||
706 | offset = pfn_level_offset(pfn, level); | 754 | offset = pfn_level_offset(pfn, level); |
707 | pte = &parent[offset]; | 755 | pte = &parent[offset]; |
708 | if (level == 1) | 756 | if (!large_level && (pte->val & DMA_PTE_LARGE_PAGE)) |
757 | break; | ||
758 | if (level == target_level) | ||
709 | break; | 759 | break; |
710 | 760 | ||
711 | if (!dma_pte_present(pte)) { | 761 | if (!dma_pte_present(pte)) { |
@@ -733,10 +783,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | |||
733 | return pte; | 783 | return pte; |
734 | } | 784 | } |
735 | 785 | ||
786 | |||
736 | /* return address's pte at specific level */ | 787 | /* return address's pte at specific level */ |
737 | static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, | 788 | static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, |
738 | unsigned long pfn, | 789 | unsigned long pfn, |
739 | int level) | 790 | int level, int *large_page) |
740 | { | 791 | { |
741 | struct dma_pte *parent, *pte = NULL; | 792 | struct dma_pte *parent, *pte = NULL; |
742 | int total = agaw_to_level(domain->agaw); | 793 | int total = agaw_to_level(domain->agaw); |
@@ -749,8 +800,16 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, | |||
749 | if (level == total) | 800 | if (level == total) |
750 | return pte; | 801 | return pte; |
751 | 802 | ||
752 | if (!dma_pte_present(pte)) | 803 | if (!dma_pte_present(pte)) { |
804 | *large_page = total; | ||
753 | break; | 805 | break; |
806 | } | ||
807 | |||
808 | if (pte->val & DMA_PTE_LARGE_PAGE) { | ||
809 | *large_page = total; | ||
810 | return pte; | ||
811 | } | ||
812 | |||
754 | parent = phys_to_virt(dma_pte_addr(pte)); | 813 | parent = phys_to_virt(dma_pte_addr(pte)); |
755 | total--; | 814 | total--; |
756 | } | 815 | } |
@@ -763,6 +822,7 @@ static void dma_pte_clear_range(struct dmar_domain *domain, | |||
763 | unsigned long last_pfn) | 822 | unsigned long last_pfn) |
764 | { | 823 | { |
765 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; | 824 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
825 | unsigned int large_page = 1; | ||
766 | struct dma_pte *first_pte, *pte; | 826 | struct dma_pte *first_pte, *pte; |
767 | 827 | ||
768 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); | 828 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); |
@@ -771,14 +831,15 @@ static void dma_pte_clear_range(struct dmar_domain *domain, | |||
771 | 831 | ||
772 | /* we don't need lock here; nobody else touches the iova range */ | 832 | /* we don't need lock here; nobody else touches the iova range */ |
773 | do { | 833 | do { |
774 | first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1); | 834 | large_page = 1; |
835 | first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page); | ||
775 | if (!pte) { | 836 | if (!pte) { |
776 | start_pfn = align_to_level(start_pfn + 1, 2); | 837 | start_pfn = align_to_level(start_pfn + 1, large_page + 1); |
777 | continue; | 838 | continue; |
778 | } | 839 | } |
779 | do { | 840 | do { |
780 | dma_clear_pte(pte); | 841 | dma_clear_pte(pte); |
781 | start_pfn++; | 842 | start_pfn += lvl_to_nr_pages(large_page); |
782 | pte++; | 843 | pte++; |
783 | } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); | 844 | } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); |
784 | 845 | ||
@@ -798,6 +859,7 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, | |||
798 | int total = agaw_to_level(domain->agaw); | 859 | int total = agaw_to_level(domain->agaw); |
799 | int level; | 860 | int level; |
800 | unsigned long tmp; | 861 | unsigned long tmp; |
862 | int large_page = 2; | ||
801 | 863 | ||
802 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); | 864 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); |
803 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); | 865 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); |
@@ -813,7 +875,10 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, | |||
813 | return; | 875 | return; |
814 | 876 | ||
815 | do { | 877 | do { |
816 | first_pte = pte = dma_pfn_level_pte(domain, tmp, level); | 878 | large_page = level; |
879 | first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page); | ||
880 | if (large_page > level) | ||
881 | level = large_page + 1; | ||
817 | if (!pte) { | 882 | if (!pte) { |
818 | tmp = align_to_level(tmp + 1, level + 1); | 883 | tmp = align_to_level(tmp + 1, level + 1); |
819 | continue; | 884 | continue; |
@@ -1397,6 +1462,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1397 | else | 1462 | else |
1398 | domain->iommu_snooping = 0; | 1463 | domain->iommu_snooping = 0; |
1399 | 1464 | ||
1465 | domain->iommu_superpage = fls(cap_super_page_val(iommu->cap)); | ||
1400 | domain->iommu_count = 1; | 1466 | domain->iommu_count = 1; |
1401 | domain->nid = iommu->node; | 1467 | domain->nid = iommu->node; |
1402 | 1468 | ||
@@ -1417,6 +1483,10 @@ static void domain_exit(struct dmar_domain *domain) | |||
1417 | if (!domain) | 1483 | if (!domain) |
1418 | return; | 1484 | return; |
1419 | 1485 | ||
1486 | /* Flush any lazy unmaps that may reference this domain */ | ||
1487 | if (!intel_iommu_strict) | ||
1488 | flush_unmaps_timeout(0); | ||
1489 | |||
1420 | domain_remove_dev_info(domain); | 1490 | domain_remove_dev_info(domain); |
1421 | /* destroy iovas */ | 1491 | /* destroy iovas */ |
1422 | put_iova_domain(&domain->iovad); | 1492 | put_iova_domain(&domain->iovad); |
@@ -1648,6 +1718,34 @@ static inline unsigned long aligned_nrpages(unsigned long host_addr, | |||
1648 | return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; | 1718 | return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; |
1649 | } | 1719 | } |
1650 | 1720 | ||
1721 | /* Return largest possible superpage level for a given mapping */ | ||
1722 | static inline int hardware_largepage_caps(struct dmar_domain *domain, | ||
1723 | unsigned long iov_pfn, | ||
1724 | unsigned long phy_pfn, | ||
1725 | unsigned long pages) | ||
1726 | { | ||
1727 | int support, level = 1; | ||
1728 | unsigned long pfnmerge; | ||
1729 | |||
1730 | support = domain->iommu_superpage; | ||
1731 | |||
1732 | /* To use a large page, the virtual *and* physical addresses | ||
1733 | must be aligned to 2MiB/1GiB/etc. Lower bits set in either | ||
1734 | of them will mean we have to use smaller pages. So just | ||
1735 | merge them and check both at once. */ | ||
1736 | pfnmerge = iov_pfn | phy_pfn; | ||
1737 | |||
1738 | while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) { | ||
1739 | pages >>= VTD_STRIDE_SHIFT; | ||
1740 | if (!pages) | ||
1741 | break; | ||
1742 | pfnmerge >>= VTD_STRIDE_SHIFT; | ||
1743 | level++; | ||
1744 | support--; | ||
1745 | } | ||
1746 | return level; | ||
1747 | } | ||
1748 | |||
1651 | static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | 1749 | static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, |
1652 | struct scatterlist *sg, unsigned long phys_pfn, | 1750 | struct scatterlist *sg, unsigned long phys_pfn, |
1653 | unsigned long nr_pages, int prot) | 1751 | unsigned long nr_pages, int prot) |
@@ -1656,6 +1754,8 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1656 | phys_addr_t uninitialized_var(pteval); | 1754 | phys_addr_t uninitialized_var(pteval); |
1657 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; | 1755 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
1658 | unsigned long sg_res; | 1756 | unsigned long sg_res; |
1757 | unsigned int largepage_lvl = 0; | ||
1758 | unsigned long lvl_pages = 0; | ||
1659 | 1759 | ||
1660 | BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); | 1760 | BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); |
1661 | 1761 | ||
@@ -1671,7 +1771,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1671 | pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; | 1771 | pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; |
1672 | } | 1772 | } |
1673 | 1773 | ||
1674 | while (nr_pages--) { | 1774 | while (nr_pages > 0) { |
1675 | uint64_t tmp; | 1775 | uint64_t tmp; |
1676 | 1776 | ||
1677 | if (!sg_res) { | 1777 | if (!sg_res) { |
@@ -1679,11 +1779,21 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1679 | sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; | 1779 | sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; |
1680 | sg->dma_length = sg->length; | 1780 | sg->dma_length = sg->length; |
1681 | pteval = page_to_phys(sg_page(sg)) | prot; | 1781 | pteval = page_to_phys(sg_page(sg)) | prot; |
1782 | phys_pfn = pteval >> VTD_PAGE_SHIFT; | ||
1682 | } | 1783 | } |
1784 | |||
1683 | if (!pte) { | 1785 | if (!pte) { |
1684 | first_pte = pte = pfn_to_dma_pte(domain, iov_pfn); | 1786 | largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res); |
1787 | |||
1788 | first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, largepage_lvl); | ||
1685 | if (!pte) | 1789 | if (!pte) |
1686 | return -ENOMEM; | 1790 | return -ENOMEM; |
1791 | /* It is large page*/ | ||
1792 | if (largepage_lvl > 1) | ||
1793 | pteval |= DMA_PTE_LARGE_PAGE; | ||
1794 | else | ||
1795 | pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE; | ||
1796 | |||
1687 | } | 1797 | } |
1688 | /* We don't need lock here, nobody else | 1798 | /* We don't need lock here, nobody else |
1689 | * touches the iova range | 1799 | * touches the iova range |
@@ -1699,16 +1809,38 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1699 | } | 1809 | } |
1700 | WARN_ON(1); | 1810 | WARN_ON(1); |
1701 | } | 1811 | } |
1812 | |||
1813 | lvl_pages = lvl_to_nr_pages(largepage_lvl); | ||
1814 | |||
1815 | BUG_ON(nr_pages < lvl_pages); | ||
1816 | BUG_ON(sg_res < lvl_pages); | ||
1817 | |||
1818 | nr_pages -= lvl_pages; | ||
1819 | iov_pfn += lvl_pages; | ||
1820 | phys_pfn += lvl_pages; | ||
1821 | pteval += lvl_pages * VTD_PAGE_SIZE; | ||
1822 | sg_res -= lvl_pages; | ||
1823 | |||
1824 | /* If the next PTE would be the first in a new page, then we | ||
1825 | need to flush the cache on the entries we've just written. | ||
1826 | And then we'll need to recalculate 'pte', so clear it and | ||
1827 | let it get set again in the if (!pte) block above. | ||
1828 | |||
1829 | If we're done (!nr_pages) we need to flush the cache too. | ||
1830 | |||
1831 | Also if we've been setting superpages, we may need to | ||
1832 | recalculate 'pte' and switch back to smaller pages for the | ||
1833 | end of the mapping, if the trailing size is not enough to | ||
1834 | use another superpage (i.e. sg_res < lvl_pages). */ | ||
1702 | pte++; | 1835 | pte++; |
1703 | if (!nr_pages || first_pte_in_page(pte)) { | 1836 | if (!nr_pages || first_pte_in_page(pte) || |
1837 | (largepage_lvl > 1 && sg_res < lvl_pages)) { | ||
1704 | domain_flush_cache(domain, first_pte, | 1838 | domain_flush_cache(domain, first_pte, |
1705 | (void *)pte - (void *)first_pte); | 1839 | (void *)pte - (void *)first_pte); |
1706 | pte = NULL; | 1840 | pte = NULL; |
1707 | } | 1841 | } |
1708 | iov_pfn++; | 1842 | |
1709 | pteval += VTD_PAGE_SIZE; | 1843 | if (!sg_res && nr_pages) |
1710 | sg_res--; | ||
1711 | if (!sg_res) | ||
1712 | sg = sg_next(sg); | 1844 | sg = sg_next(sg); |
1713 | } | 1845 | } |
1714 | return 0; | 1846 | return 0; |
@@ -2016,7 +2148,7 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, | |||
2016 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) | 2148 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) |
2017 | return 0; | 2149 | return 0; |
2018 | return iommu_prepare_identity_map(pdev, rmrr->base_address, | 2150 | return iommu_prepare_identity_map(pdev, rmrr->base_address, |
2019 | rmrr->end_address + 1); | 2151 | rmrr->end_address); |
2020 | } | 2152 | } |
2021 | 2153 | ||
2022 | #ifdef CONFIG_DMAR_FLOPPY_WA | 2154 | #ifdef CONFIG_DMAR_FLOPPY_WA |
@@ -2030,7 +2162,7 @@ static inline void iommu_prepare_isa(void) | |||
2030 | return; | 2162 | return; |
2031 | 2163 | ||
2032 | printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); | 2164 | printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); |
2033 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); | 2165 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1); |
2034 | 2166 | ||
2035 | if (ret) | 2167 | if (ret) |
2036 | printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " | 2168 | printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " |
@@ -2106,10 +2238,10 @@ static int identity_mapping(struct pci_dev *pdev) | |||
2106 | if (likely(!iommu_identity_mapping)) | 2238 | if (likely(!iommu_identity_mapping)) |
2107 | return 0; | 2239 | return 0; |
2108 | 2240 | ||
2241 | info = pdev->dev.archdata.iommu; | ||
2242 | if (info && info != DUMMY_DEVICE_DOMAIN_INFO) | ||
2243 | return (info->domain == si_domain); | ||
2109 | 2244 | ||
2110 | list_for_each_entry(info, &si_domain->devices, link) | ||
2111 | if (info->dev == pdev) | ||
2112 | return 1; | ||
2113 | return 0; | 2245 | return 0; |
2114 | } | 2246 | } |
2115 | 2247 | ||
@@ -2187,8 +2319,19 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | |||
2187 | * Assume that they will -- if they turn out not to be, then we can | 2319 | * Assume that they will -- if they turn out not to be, then we can |
2188 | * take them out of the 1:1 domain later. | 2320 | * take them out of the 1:1 domain later. |
2189 | */ | 2321 | */ |
2190 | if (!startup) | 2322 | if (!startup) { |
2191 | return pdev->dma_mask > DMA_BIT_MASK(32); | 2323 | /* |
2324 | * If the device's dma_mask is less than the system's memory | ||
2325 | * size then this is not a candidate for identity mapping. | ||
2326 | */ | ||
2327 | u64 dma_mask = pdev->dma_mask; | ||
2328 | |||
2329 | if (pdev->dev.coherent_dma_mask && | ||
2330 | pdev->dev.coherent_dma_mask < dma_mask) | ||
2331 | dma_mask = pdev->dev.coherent_dma_mask; | ||
2332 | |||
2333 | return dma_mask >= dma_get_required_mask(&pdev->dev); | ||
2334 | } | ||
2192 | 2335 | ||
2193 | return 1; | 2336 | return 1; |
2194 | } | 2337 | } |
@@ -2203,6 +2346,9 @@ static int __init iommu_prepare_static_identity_mapping(int hw) | |||
2203 | return -EFAULT; | 2346 | return -EFAULT; |
2204 | 2347 | ||
2205 | for_each_pci_dev(pdev) { | 2348 | for_each_pci_dev(pdev) { |
2349 | /* Skip Host/PCI Bridge devices */ | ||
2350 | if (IS_BRIDGE_HOST_DEVICE(pdev)) | ||
2351 | continue; | ||
2206 | if (iommu_should_identity_map(pdev, 1)) { | 2352 | if (iommu_should_identity_map(pdev, 1)) { |
2207 | printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", | 2353 | printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", |
2208 | hw ? "hardware" : "software", pci_name(pdev)); | 2354 | hw ? "hardware" : "software", pci_name(pdev)); |
@@ -2218,7 +2364,7 @@ static int __init iommu_prepare_static_identity_mapping(int hw) | |||
2218 | return 0; | 2364 | return 0; |
2219 | } | 2365 | } |
2220 | 2366 | ||
2221 | static int __init init_dmars(int force_on) | 2367 | static int __init init_dmars(void) |
2222 | { | 2368 | { |
2223 | struct dmar_drhd_unit *drhd; | 2369 | struct dmar_drhd_unit *drhd; |
2224 | struct dmar_rmrr_unit *rmrr; | 2370 | struct dmar_rmrr_unit *rmrr; |
@@ -2592,8 +2738,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
2592 | iommu = domain_get_iommu(domain); | 2738 | iommu = domain_get_iommu(domain); |
2593 | size = aligned_nrpages(paddr, size); | 2739 | size = aligned_nrpages(paddr, size); |
2594 | 2740 | ||
2595 | iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), | 2741 | iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask); |
2596 | pdev->dma_mask); | ||
2597 | if (!iova) | 2742 | if (!iova) |
2598 | goto error; | 2743 | goto error; |
2599 | 2744 | ||
@@ -3118,7 +3263,17 @@ static int init_iommu_hw(void) | |||
3118 | if (iommu->qi) | 3263 | if (iommu->qi) |
3119 | dmar_reenable_qi(iommu); | 3264 | dmar_reenable_qi(iommu); |
3120 | 3265 | ||
3121 | for_each_active_iommu(iommu, drhd) { | 3266 | for_each_iommu(iommu, drhd) { |
3267 | if (drhd->ignored) { | ||
3268 | /* | ||
3269 | * we always have to disable PMRs or DMA may fail on | ||
3270 | * this device | ||
3271 | */ | ||
3272 | if (force_on) | ||
3273 | iommu_disable_protect_mem_regions(iommu); | ||
3274 | continue; | ||
3275 | } | ||
3276 | |||
3122 | iommu_flush_write_buffer(iommu); | 3277 | iommu_flush_write_buffer(iommu); |
3123 | 3278 | ||
3124 | iommu_set_root_entry(iommu); | 3279 | iommu_set_root_entry(iommu); |
@@ -3127,7 +3282,8 @@ static int init_iommu_hw(void) | |||
3127 | DMA_CCMD_GLOBAL_INVL); | 3282 | DMA_CCMD_GLOBAL_INVL); |
3128 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, | 3283 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, |
3129 | DMA_TLB_GLOBAL_FLUSH); | 3284 | DMA_TLB_GLOBAL_FLUSH); |
3130 | iommu_enable_translation(iommu); | 3285 | if (iommu_enable_translation(iommu)) |
3286 | return 1; | ||
3131 | iommu_disable_protect_mem_regions(iommu); | 3287 | iommu_disable_protect_mem_regions(iommu); |
3132 | } | 3288 | } |
3133 | 3289 | ||
@@ -3194,7 +3350,10 @@ static void iommu_resume(void) | |||
3194 | unsigned long flag; | 3350 | unsigned long flag; |
3195 | 3351 | ||
3196 | if (init_iommu_hw()) { | 3352 | if (init_iommu_hw()) { |
3197 | WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); | 3353 | if (force_on) |
3354 | panic("tboot: IOMMU setup failed, DMAR can not resume!\n"); | ||
3355 | else | ||
3356 | WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); | ||
3198 | return; | 3357 | return; |
3199 | } | 3358 | } |
3200 | 3359 | ||
@@ -3271,7 +3430,6 @@ static struct notifier_block device_nb = { | |||
3271 | int __init intel_iommu_init(void) | 3430 | int __init intel_iommu_init(void) |
3272 | { | 3431 | { |
3273 | int ret = 0; | 3432 | int ret = 0; |
3274 | int force_on = 0; | ||
3275 | 3433 | ||
3276 | /* VT-d is required for a TXT/tboot launch, so enforce that */ | 3434 | /* VT-d is required for a TXT/tboot launch, so enforce that */ |
3277 | force_on = tboot_force_iommu(); | 3435 | force_on = tboot_force_iommu(); |
@@ -3309,7 +3467,7 @@ int __init intel_iommu_init(void) | |||
3309 | 3467 | ||
3310 | init_no_remapping_devices(); | 3468 | init_no_remapping_devices(); |
3311 | 3469 | ||
3312 | ret = init_dmars(force_on); | 3470 | ret = init_dmars(); |
3313 | if (ret) { | 3471 | if (ret) { |
3314 | if (force_on) | 3472 | if (force_on) |
3315 | panic("tboot: Failed to initialize DMARs\n"); | 3473 | panic("tboot: Failed to initialize DMARs\n"); |
@@ -3380,8 +3538,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
3380 | spin_lock_irqsave(&device_domain_lock, flags); | 3538 | spin_lock_irqsave(&device_domain_lock, flags); |
3381 | list_for_each_safe(entry, tmp, &domain->devices) { | 3539 | list_for_each_safe(entry, tmp, &domain->devices) { |
3382 | info = list_entry(entry, struct device_domain_info, link); | 3540 | info = list_entry(entry, struct device_domain_info, link); |
3383 | /* No need to compare PCI domain; it has to be the same */ | 3541 | if (info->segment == pci_domain_nr(pdev->bus) && |
3384 | if (info->bus == pdev->bus->number && | 3542 | info->bus == pdev->bus->number && |
3385 | info->devfn == pdev->devfn) { | 3543 | info->devfn == pdev->devfn) { |
3386 | list_del(&info->link); | 3544 | list_del(&info->link); |
3387 | list_del(&info->global); | 3545 | list_del(&info->global); |
@@ -3419,10 +3577,13 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
3419 | domain_update_iommu_cap(domain); | 3577 | domain_update_iommu_cap(domain); |
3420 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); | 3578 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); |
3421 | 3579 | ||
3422 | spin_lock_irqsave(&iommu->lock, tmp_flags); | 3580 | if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && |
3423 | clear_bit(domain->id, iommu->domain_ids); | 3581 | !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) { |
3424 | iommu->domains[domain->id] = NULL; | 3582 | spin_lock_irqsave(&iommu->lock, tmp_flags); |
3425 | spin_unlock_irqrestore(&iommu->lock, tmp_flags); | 3583 | clear_bit(domain->id, iommu->domain_ids); |
3584 | iommu->domains[domain->id] = NULL; | ||
3585 | spin_unlock_irqrestore(&iommu->lock, tmp_flags); | ||
3586 | } | ||
3426 | } | 3587 | } |
3427 | 3588 | ||
3428 | spin_unlock_irqrestore(&device_domain_lock, flags); | 3589 | spin_unlock_irqrestore(&device_domain_lock, flags); |
@@ -3505,6 +3666,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) | |||
3505 | domain->iommu_count = 0; | 3666 | domain->iommu_count = 0; |
3506 | domain->iommu_coherency = 0; | 3667 | domain->iommu_coherency = 0; |
3507 | domain->iommu_snooping = 0; | 3668 | domain->iommu_snooping = 0; |
3669 | domain->iommu_superpage = 0; | ||
3508 | domain->max_addr = 0; | 3670 | domain->max_addr = 0; |
3509 | domain->nid = -1; | 3671 | domain->nid = -1; |
3510 | 3672 | ||
@@ -3720,7 +3882,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | |||
3720 | struct dma_pte *pte; | 3882 | struct dma_pte *pte; |
3721 | u64 phys = 0; | 3883 | u64 phys = 0; |
3722 | 3884 | ||
3723 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT); | 3885 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, 0); |
3724 | if (pte) | 3886 | if (pte) |
3725 | phys = dma_pte_addr(pte); | 3887 | phys = dma_pte_addr(pte); |
3726 | 3888 | ||
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c index 9606e599a475..c5c274ab5c5a 100644 --- a/drivers/pci/iova.c +++ b/drivers/pci/iova.c | |||
@@ -63,8 +63,16 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free) | |||
63 | curr = iovad->cached32_node; | 63 | curr = iovad->cached32_node; |
64 | cached_iova = container_of(curr, struct iova, node); | 64 | cached_iova = container_of(curr, struct iova, node); |
65 | 65 | ||
66 | if (free->pfn_lo >= cached_iova->pfn_lo) | 66 | if (free->pfn_lo >= cached_iova->pfn_lo) { |
67 | iovad->cached32_node = rb_next(&free->node); | 67 | struct rb_node *node = rb_next(&free->node); |
68 | struct iova *iova = container_of(node, struct iova, node); | ||
69 | |||
70 | /* only cache if it's below 32bit pfn */ | ||
71 | if (node && iova->pfn_lo < iovad->dma_32bit_pfn) | ||
72 | iovad->cached32_node = node; | ||
73 | else | ||
74 | iovad->cached32_node = NULL; | ||
75 | } | ||
68 | } | 76 | } |
69 | 77 | ||
70 | /* Computes the padding size required, to make the | 78 | /* Computes the padding size required, to make the |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 7c3b18e78cee..d36f41ea8cbf 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -195,6 +195,8 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) | |||
195 | return PCI_D2; | 195 | return PCI_D2; |
196 | case ACPI_STATE_D3: | 196 | case ACPI_STATE_D3: |
197 | return PCI_D3hot; | 197 | return PCI_D3hot; |
198 | case ACPI_STATE_D3_COLD: | ||
199 | return PCI_D3cold; | ||
198 | } | 200 | } |
199 | return PCI_POWER_ERROR; | 201 | return PCI_POWER_ERROR; |
200 | } | 202 | } |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 5cb999b50f95..45e0191c35dd 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -39,7 +39,7 @@ config ACER_WMI | |||
39 | 39 | ||
40 | config ACERHDF | 40 | config ACERHDF |
41 | tristate "Acer Aspire One temperature and fan driver" | 41 | tristate "Acer Aspire One temperature and fan driver" |
42 | depends on THERMAL && THERMAL_HWMON && ACPI | 42 | depends on THERMAL && ACPI |
43 | ---help--- | 43 | ---help--- |
44 | This is a driver for Acer Aspire One netbooks. It allows to access | 44 | This is a driver for Acer Aspire One netbooks. It allows to access |
45 | the temperature sensor and to control the fan. | 45 | the temperature sensor and to control the fan. |
@@ -760,4 +760,13 @@ config MXM_WMI | |||
760 | MXM is a standard for laptop graphics cards, the WMI interface | 760 | MXM is a standard for laptop graphics cards, the WMI interface |
761 | is required for switchable nvidia graphics machines | 761 | is required for switchable nvidia graphics machines |
762 | 762 | ||
763 | config INTEL_OAKTRAIL | ||
764 | tristate "Intel Oaktrail Platform Extras" | ||
765 | depends on ACPI | ||
766 | depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI | ||
767 | ---help--- | ||
768 | Intel Oaktrail platform need this driver to provide interfaces to | ||
769 | enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y | ||
770 | here; it will only load on supported platforms. | ||
771 | |||
763 | endif # X86_PLATFORM_DEVICES | 772 | endif # X86_PLATFORM_DEVICES |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index a7ab3bc7b3a1..afc1f832aa67 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -41,5 +41,6 @@ obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o | |||
41 | obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o | 41 | obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o |
42 | obj-$(CONFIG_IBM_RTL) += ibm_rtl.o | 42 | obj-$(CONFIG_IBM_RTL) += ibm_rtl.o |
43 | obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o | 43 | obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o |
44 | obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o | ||
45 | obj-$(CONFIG_MXM_WMI) += mxm-wmi.o | 44 | obj-$(CONFIG_MXM_WMI) += mxm-wmi.o |
45 | obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o | ||
46 | obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index ac4e7f83ce6c..005417bd429e 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -98,13 +98,26 @@ enum acer_wmi_event_ids { | |||
98 | 98 | ||
99 | static const struct key_entry acer_wmi_keymap[] = { | 99 | static const struct key_entry acer_wmi_keymap[] = { |
100 | {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ | 100 | {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ |
101 | {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ | ||
101 | {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ | 102 | {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ |
102 | {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ | 103 | {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ |
103 | {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ | 104 | {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ |
104 | {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ | 105 | {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ |
105 | {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ | 106 | {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ |
107 | {KE_IGNORE, 0x41, {KEY_MUTE} }, | ||
108 | {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, | ||
109 | {KE_IGNORE, 0x43, {KEY_NEXTSONG} }, | ||
110 | {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} }, | ||
111 | {KE_IGNORE, 0x45, {KEY_STOP} }, | ||
112 | {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, | ||
113 | {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, | ||
114 | {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} }, | ||
115 | {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, | ||
116 | {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, | ||
106 | {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ | 117 | {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ |
118 | {KE_IGNORE, 0x81, {KEY_SLEEP} }, | ||
107 | {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ | 119 | {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ |
120 | {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, | ||
108 | {KE_END, 0} | 121 | {KE_END, 0} |
109 | }; | 122 | }; |
110 | 123 | ||
@@ -122,6 +135,7 @@ struct event_return_value { | |||
122 | */ | 135 | */ |
123 | #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ | 136 | #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ |
124 | #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ | 137 | #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ |
138 | #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ | ||
125 | #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ | 139 | #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ |
126 | 140 | ||
127 | struct lm_input_params { | 141 | struct lm_input_params { |
@@ -737,8 +751,11 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) | |||
737 | 751 | ||
738 | obj = (union acpi_object *) result.pointer; | 752 | obj = (union acpi_object *) result.pointer; |
739 | if (obj && obj->type == ACPI_TYPE_BUFFER && | 753 | if (obj && obj->type == ACPI_TYPE_BUFFER && |
740 | obj->buffer.length == sizeof(u32)) { | 754 | (obj->buffer.length == sizeof(u32) || |
755 | obj->buffer.length == sizeof(u64))) { | ||
741 | tmp = *((u32 *) obj->buffer.pointer); | 756 | tmp = *((u32 *) obj->buffer.pointer); |
757 | } else if (obj->type == ACPI_TYPE_INTEGER) { | ||
758 | tmp = (u32) obj->integer.value; | ||
742 | } else { | 759 | } else { |
743 | tmp = 0; | 760 | tmp = 0; |
744 | } | 761 | } |
@@ -866,8 +883,11 @@ static acpi_status WMID_set_capabilities(void) | |||
866 | 883 | ||
867 | obj = (union acpi_object *) out.pointer; | 884 | obj = (union acpi_object *) out.pointer; |
868 | if (obj && obj->type == ACPI_TYPE_BUFFER && | 885 | if (obj && obj->type == ACPI_TYPE_BUFFER && |
869 | obj->buffer.length == sizeof(u32)) { | 886 | (obj->buffer.length == sizeof(u32) || |
887 | obj->buffer.length == sizeof(u64))) { | ||
870 | devices = *((u32 *) obj->buffer.pointer); | 888 | devices = *((u32 *) obj->buffer.pointer); |
889 | } else if (obj->type == ACPI_TYPE_INTEGER) { | ||
890 | devices = (u32) obj->integer.value; | ||
871 | } else { | 891 | } else { |
872 | kfree(out.pointer); | 892 | kfree(out.pointer); |
873 | return AE_ERROR; | 893 | return AE_ERROR; |
@@ -876,7 +896,8 @@ static acpi_status WMID_set_capabilities(void) | |||
876 | dmi_walk(type_aa_dmi_decode, NULL); | 896 | dmi_walk(type_aa_dmi_decode, NULL); |
877 | if (!has_type_aa) { | 897 | if (!has_type_aa) { |
878 | interface->capability |= ACER_CAP_WIRELESS; | 898 | interface->capability |= ACER_CAP_WIRELESS; |
879 | interface->capability |= ACER_CAP_THREEG; | 899 | if (devices & 0x40) |
900 | interface->capability |= ACER_CAP_THREEG; | ||
880 | if (devices & 0x10) | 901 | if (devices & 0x10) |
881 | interface->capability |= ACER_CAP_BLUETOOTH; | 902 | interface->capability |= ACER_CAP_BLUETOOTH; |
882 | } | 903 | } |
@@ -961,10 +982,12 @@ static void __init acer_commandline_init(void) | |||
961 | * These will all fail silently if the value given is invalid, or the | 982 | * These will all fail silently if the value given is invalid, or the |
962 | * capability isn't available on the given interface | 983 | * capability isn't available on the given interface |
963 | */ | 984 | */ |
964 | set_u32(mailled, ACER_CAP_MAILLED); | 985 | if (mailled >= 0) |
965 | if (!has_type_aa) | 986 | set_u32(mailled, ACER_CAP_MAILLED); |
987 | if (!has_type_aa && threeg >= 0) | ||
966 | set_u32(threeg, ACER_CAP_THREEG); | 988 | set_u32(threeg, ACER_CAP_THREEG); |
967 | set_u32(brightness, ACER_CAP_BRIGHTNESS); | 989 | if (brightness >= 0) |
990 | set_u32(brightness, ACER_CAP_BRIGHTNESS); | ||
968 | } | 991 | } |
969 | 992 | ||
970 | /* | 993 | /* |
@@ -1081,7 +1104,7 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device) | |||
1081 | return AE_ERROR; | 1104 | return AE_ERROR; |
1082 | } | 1105 | } |
1083 | if (obj->buffer.length != 8) { | 1106 | if (obj->buffer.length != 8) { |
1084 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | 1107 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); |
1085 | kfree(obj); | 1108 | kfree(obj); |
1086 | return AE_ERROR; | 1109 | return AE_ERROR; |
1087 | } | 1110 | } |
@@ -1090,8 +1113,8 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device) | |||
1090 | kfree(obj); | 1113 | kfree(obj); |
1091 | 1114 | ||
1092 | if (return_value.error_code || return_value.ec_return_value) | 1115 | if (return_value.error_code || return_value.ec_return_value) |
1093 | pr_warning("Get Device Status failed: " | 1116 | pr_warn("Get Device Status failed: 0x%x - 0x%x\n", |
1094 | "0x%x - 0x%x\n", return_value.error_code, | 1117 | return_value.error_code, |
1095 | return_value.ec_return_value); | 1118 | return_value.ec_return_value); |
1096 | else | 1119 | else |
1097 | *value = !!(return_value.devices & device); | 1120 | *value = !!(return_value.devices & device); |
@@ -1124,6 +1147,114 @@ static acpi_status get_device_status(u32 *value, u32 cap) | |||
1124 | } | 1147 | } |
1125 | } | 1148 | } |
1126 | 1149 | ||
1150 | static acpi_status wmid3_set_device_status(u32 value, u16 device) | ||
1151 | { | ||
1152 | struct wmid3_gds_return_value return_value; | ||
1153 | acpi_status status; | ||
1154 | union acpi_object *obj; | ||
1155 | u16 devices; | ||
1156 | struct wmid3_gds_input_param params = { | ||
1157 | .function_num = 0x1, | ||
1158 | .hotkey_number = 0x01, | ||
1159 | .devices = ACER_WMID3_GDS_WIRELESS & | ||
1160 | ACER_WMID3_GDS_THREEG & | ||
1161 | ACER_WMID3_GDS_WIMAX & | ||
1162 | ACER_WMID3_GDS_BLUETOOTH, | ||
1163 | }; | ||
1164 | struct acpi_buffer input = { | ||
1165 | sizeof(struct wmid3_gds_input_param), | ||
1166 | ¶ms | ||
1167 | }; | ||
1168 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1169 | struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1170 | |||
1171 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); | ||
1172 | if (ACPI_FAILURE(status)) | ||
1173 | return status; | ||
1174 | |||
1175 | obj = output.pointer; | ||
1176 | |||
1177 | if (!obj) | ||
1178 | return AE_ERROR; | ||
1179 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
1180 | kfree(obj); | ||
1181 | return AE_ERROR; | ||
1182 | } | ||
1183 | if (obj->buffer.length != 8) { | ||
1184 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
1185 | kfree(obj); | ||
1186 | return AE_ERROR; | ||
1187 | } | ||
1188 | |||
1189 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
1190 | kfree(obj); | ||
1191 | |||
1192 | if (return_value.error_code || return_value.ec_return_value) { | ||
1193 | pr_warning("Get Current Device Status failed: " | ||
1194 | "0x%x - 0x%x\n", return_value.error_code, | ||
1195 | return_value.ec_return_value); | ||
1196 | return status; | ||
1197 | } | ||
1198 | |||
1199 | devices = return_value.devices; | ||
1200 | params.function_num = 0x2; | ||
1201 | params.hotkey_number = 0x01; | ||
1202 | params.devices = (value) ? (devices | device) : (devices & ~device); | ||
1203 | |||
1204 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); | ||
1205 | if (ACPI_FAILURE(status)) | ||
1206 | return status; | ||
1207 | |||
1208 | obj = output2.pointer; | ||
1209 | |||
1210 | if (!obj) | ||
1211 | return AE_ERROR; | ||
1212 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
1213 | kfree(obj); | ||
1214 | return AE_ERROR; | ||
1215 | } | ||
1216 | if (obj->buffer.length != 4) { | ||
1217 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
1218 | kfree(obj); | ||
1219 | return AE_ERROR; | ||
1220 | } | ||
1221 | |||
1222 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
1223 | kfree(obj); | ||
1224 | |||
1225 | if (return_value.error_code || return_value.ec_return_value) | ||
1226 | pr_warning("Set Device Status failed: " | ||
1227 | "0x%x - 0x%x\n", return_value.error_code, | ||
1228 | return_value.ec_return_value); | ||
1229 | |||
1230 | return status; | ||
1231 | } | ||
1232 | |||
1233 | static acpi_status set_device_status(u32 value, u32 cap) | ||
1234 | { | ||
1235 | if (wmi_has_guid(WMID_GUID3)) { | ||
1236 | u16 device; | ||
1237 | |||
1238 | switch (cap) { | ||
1239 | case ACER_CAP_WIRELESS: | ||
1240 | device = ACER_WMID3_GDS_WIRELESS; | ||
1241 | break; | ||
1242 | case ACER_CAP_BLUETOOTH: | ||
1243 | device = ACER_WMID3_GDS_BLUETOOTH; | ||
1244 | break; | ||
1245 | case ACER_CAP_THREEG: | ||
1246 | device = ACER_WMID3_GDS_THREEG; | ||
1247 | break; | ||
1248 | default: | ||
1249 | return AE_ERROR; | ||
1250 | } | ||
1251 | return wmid3_set_device_status(value, device); | ||
1252 | |||
1253 | } else { | ||
1254 | return set_u32(value, cap); | ||
1255 | } | ||
1256 | } | ||
1257 | |||
1127 | /* | 1258 | /* |
1128 | * Rfkill devices | 1259 | * Rfkill devices |
1129 | */ | 1260 | */ |
@@ -1160,7 +1291,7 @@ static int acer_rfkill_set(void *data, bool blocked) | |||
1160 | u32 cap = (unsigned long)data; | 1291 | u32 cap = (unsigned long)data; |
1161 | 1292 | ||
1162 | if (rfkill_inited) { | 1293 | if (rfkill_inited) { |
1163 | status = set_u32(!blocked, cap); | 1294 | status = set_device_status(!blocked, cap); |
1164 | if (ACPI_FAILURE(status)) | 1295 | if (ACPI_FAILURE(status)) |
1165 | return -ENODEV; | 1296 | return -ENODEV; |
1166 | } | 1297 | } |
@@ -1317,7 +1448,7 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1317 | 1448 | ||
1318 | status = wmi_get_event_data(value, &response); | 1449 | status = wmi_get_event_data(value, &response); |
1319 | if (status != AE_OK) { | 1450 | if (status != AE_OK) { |
1320 | pr_warning("bad event status 0x%x\n", status); | 1451 | pr_warn("bad event status 0x%x\n", status); |
1321 | return; | 1452 | return; |
1322 | } | 1453 | } |
1323 | 1454 | ||
@@ -1326,12 +1457,12 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1326 | if (!obj) | 1457 | if (!obj) |
1327 | return; | 1458 | return; |
1328 | if (obj->type != ACPI_TYPE_BUFFER) { | 1459 | if (obj->type != ACPI_TYPE_BUFFER) { |
1329 | pr_warning("Unknown response received %d\n", obj->type); | 1460 | pr_warn("Unknown response received %d\n", obj->type); |
1330 | kfree(obj); | 1461 | kfree(obj); |
1331 | return; | 1462 | return; |
1332 | } | 1463 | } |
1333 | if (obj->buffer.length != 8) { | 1464 | if (obj->buffer.length != 8) { |
1334 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | 1465 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); |
1335 | kfree(obj); | 1466 | kfree(obj); |
1336 | return; | 1467 | return; |
1337 | } | 1468 | } |
@@ -1343,7 +1474,7 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1343 | case WMID_HOTKEY_EVENT: | 1474 | case WMID_HOTKEY_EVENT: |
1344 | if (return_value.device_state) { | 1475 | if (return_value.device_state) { |
1345 | u16 device_state = return_value.device_state; | 1476 | u16 device_state = return_value.device_state; |
1346 | pr_debug("deivces states: 0x%x\n", device_state); | 1477 | pr_debug("device state: 0x%x\n", device_state); |
1347 | if (has_cap(ACER_CAP_WIRELESS)) | 1478 | if (has_cap(ACER_CAP_WIRELESS)) |
1348 | rfkill_set_sw_state(wireless_rfkill, | 1479 | rfkill_set_sw_state(wireless_rfkill, |
1349 | !(device_state & ACER_WMID3_GDS_WIRELESS)); | 1480 | !(device_state & ACER_WMID3_GDS_WIRELESS)); |
@@ -1356,11 +1487,11 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1356 | } | 1487 | } |
1357 | if (!sparse_keymap_report_event(acer_wmi_input_dev, | 1488 | if (!sparse_keymap_report_event(acer_wmi_input_dev, |
1358 | return_value.key_num, 1, true)) | 1489 | return_value.key_num, 1, true)) |
1359 | pr_warning("Unknown key number - 0x%x\n", | 1490 | pr_warn("Unknown key number - 0x%x\n", |
1360 | return_value.key_num); | 1491 | return_value.key_num); |
1361 | break; | 1492 | break; |
1362 | default: | 1493 | default: |
1363 | pr_warning("Unknown function number - %d - %d\n", | 1494 | pr_warn("Unknown function number - %d - %d\n", |
1364 | return_value.function, return_value.key_num); | 1495 | return_value.function, return_value.key_num); |
1365 | break; | 1496 | break; |
1366 | } | 1497 | } |
@@ -1389,7 +1520,7 @@ wmid3_set_lm_mode(struct lm_input_params *params, | |||
1389 | return AE_ERROR; | 1520 | return AE_ERROR; |
1390 | } | 1521 | } |
1391 | if (obj->buffer.length != 4) { | 1522 | if (obj->buffer.length != 4) { |
1392 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | 1523 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); |
1393 | kfree(obj); | 1524 | kfree(obj); |
1394 | return AE_ERROR; | 1525 | return AE_ERROR; |
1395 | } | 1526 | } |
@@ -1414,11 +1545,11 @@ static int acer_wmi_enable_ec_raw(void) | |||
1414 | status = wmid3_set_lm_mode(¶ms, &return_value); | 1545 | status = wmid3_set_lm_mode(¶ms, &return_value); |
1415 | 1546 | ||
1416 | if (return_value.error_code || return_value.ec_return_value) | 1547 | if (return_value.error_code || return_value.ec_return_value) |
1417 | pr_warning("Enabling EC raw mode failed: " | 1548 | pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n", |
1418 | "0x%x - 0x%x\n", return_value.error_code, | 1549 | return_value.error_code, |
1419 | return_value.ec_return_value); | 1550 | return_value.ec_return_value); |
1420 | else | 1551 | else |
1421 | pr_info("Enabled EC raw mode"); | 1552 | pr_info("Enabled EC raw mode\n"); |
1422 | 1553 | ||
1423 | return status; | 1554 | return status; |
1424 | } | 1555 | } |
@@ -1437,9 +1568,9 @@ static int acer_wmi_enable_lm(void) | |||
1437 | status = wmid3_set_lm_mode(¶ms, &return_value); | 1568 | status = wmid3_set_lm_mode(¶ms, &return_value); |
1438 | 1569 | ||
1439 | if (return_value.error_code || return_value.ec_return_value) | 1570 | if (return_value.error_code || return_value.ec_return_value) |
1440 | pr_warning("Enabling Launch Manager failed: " | 1571 | pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n", |
1441 | "0x%x - 0x%x\n", return_value.error_code, | 1572 | return_value.error_code, |
1442 | return_value.ec_return_value); | 1573 | return_value.ec_return_value); |
1443 | 1574 | ||
1444 | return status; | 1575 | return status; |
1445 | } | 1576 | } |
@@ -1506,8 +1637,11 @@ static u32 get_wmid_devices(void) | |||
1506 | 1637 | ||
1507 | obj = (union acpi_object *) out.pointer; | 1638 | obj = (union acpi_object *) out.pointer; |
1508 | if (obj && obj->type == ACPI_TYPE_BUFFER && | 1639 | if (obj && obj->type == ACPI_TYPE_BUFFER && |
1509 | obj->buffer.length == sizeof(u32)) { | 1640 | (obj->buffer.length == sizeof(u32) || |
1641 | obj->buffer.length == sizeof(u64))) { | ||
1510 | devices = *((u32 *) obj->buffer.pointer); | 1642 | devices = *((u32 *) obj->buffer.pointer); |
1643 | } else if (obj->type == ACPI_TYPE_INTEGER) { | ||
1644 | devices = (u32) obj->integer.value; | ||
1511 | } | 1645 | } |
1512 | 1646 | ||
1513 | kfree(out.pointer); | 1647 | kfree(out.pointer); |
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 60f9cfcac93f..fca3489218b7 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -35,10 +35,8 @@ | |||
35 | 35 | ||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/fs.h> | ||
39 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
40 | #include <acpi/acpi_drivers.h> | 39 | #include <linux/acpi.h> |
41 | #include <linux/sched.h> | ||
42 | #include <linux/thermal.h> | 40 | #include <linux/thermal.h> |
43 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
44 | 42 | ||
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index c53b3ff7978a..d65df92e2acc 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -318,7 +318,7 @@ static int acpi_check_handle(acpi_handle handle, const char *method, | |||
318 | 318 | ||
319 | if (status != AE_OK) { | 319 | if (status != AE_OK) { |
320 | if (ret) | 320 | if (ret) |
321 | pr_warning("Error finding %s\n", method); | 321 | pr_warn("Error finding %s\n", method); |
322 | return -ENODEV; | 322 | return -ENODEV; |
323 | } | 323 | } |
324 | return 0; | 324 | return 0; |
@@ -383,7 +383,7 @@ static int asus_kled_lvl(struct asus_laptop *asus) | |||
383 | rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET, | 383 | rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET, |
384 | ¶ms, &kblv); | 384 | ¶ms, &kblv); |
385 | if (ACPI_FAILURE(rv)) { | 385 | if (ACPI_FAILURE(rv)) { |
386 | pr_warning("Error reading kled level\n"); | 386 | pr_warn("Error reading kled level\n"); |
387 | return -ENODEV; | 387 | return -ENODEV; |
388 | } | 388 | } |
389 | return kblv; | 389 | return kblv; |
@@ -397,7 +397,7 @@ static int asus_kled_set(struct asus_laptop *asus, int kblv) | |||
397 | kblv = 0; | 397 | kblv = 0; |
398 | 398 | ||
399 | if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) { | 399 | if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) { |
400 | pr_warning("Keyboard LED display write failed\n"); | 400 | pr_warn("Keyboard LED display write failed\n"); |
401 | return -EINVAL; | 401 | return -EINVAL; |
402 | } | 402 | } |
403 | return 0; | 403 | return 0; |
@@ -531,7 +531,7 @@ static int asus_read_brightness(struct backlight_device *bd) | |||
531 | rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET, | 531 | rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET, |
532 | NULL, &value); | 532 | NULL, &value); |
533 | if (ACPI_FAILURE(rv)) | 533 | if (ACPI_FAILURE(rv)) |
534 | pr_warning("Error reading brightness\n"); | 534 | pr_warn("Error reading brightness\n"); |
535 | 535 | ||
536 | return value; | 536 | return value; |
537 | } | 537 | } |
@@ -541,7 +541,7 @@ static int asus_set_brightness(struct backlight_device *bd, int value) | |||
541 | struct asus_laptop *asus = bl_get_data(bd); | 541 | struct asus_laptop *asus = bl_get_data(bd); |
542 | 542 | ||
543 | if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) { | 543 | if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) { |
544 | pr_warning("Error changing brightness\n"); | 544 | pr_warn("Error changing brightness\n"); |
545 | return -EIO; | 545 | return -EIO; |
546 | } | 546 | } |
547 | return 0; | 547 | return 0; |
@@ -730,7 +730,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, | |||
730 | rv = parse_arg(buf, count, &value); | 730 | rv = parse_arg(buf, count, &value); |
731 | if (rv > 0) { | 731 | if (rv > 0) { |
732 | if (write_acpi_int(asus->handle, METHOD_LEDD, value)) { | 732 | if (write_acpi_int(asus->handle, METHOD_LEDD, value)) { |
733 | pr_warning("LED display write failed\n"); | 733 | pr_warn("LED display write failed\n"); |
734 | return -ENODEV; | 734 | return -ENODEV; |
735 | } | 735 | } |
736 | asus->ledd_status = (u32) value; | 736 | asus->ledd_status = (u32) value; |
@@ -752,7 +752,7 @@ static int asus_wireless_status(struct asus_laptop *asus, int mask) | |||
752 | rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS, | 752 | rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS, |
753 | NULL, &status); | 753 | NULL, &status); |
754 | if (ACPI_FAILURE(rv)) { | 754 | if (ACPI_FAILURE(rv)) { |
755 | pr_warning("Error reading Wireless status\n"); | 755 | pr_warn("Error reading Wireless status\n"); |
756 | return -EINVAL; | 756 | return -EINVAL; |
757 | } | 757 | } |
758 | return !!(status & mask); | 758 | return !!(status & mask); |
@@ -764,7 +764,7 @@ static int asus_wireless_status(struct asus_laptop *asus, int mask) | |||
764 | static int asus_wlan_set(struct asus_laptop *asus, int status) | 764 | static int asus_wlan_set(struct asus_laptop *asus, int status) |
765 | { | 765 | { |
766 | if (write_acpi_int(asus->handle, METHOD_WLAN, !!status)) { | 766 | if (write_acpi_int(asus->handle, METHOD_WLAN, !!status)) { |
767 | pr_warning("Error setting wlan status to %d", status); | 767 | pr_warn("Error setting wlan status to %d\n", status); |
768 | return -EIO; | 768 | return -EIO; |
769 | } | 769 | } |
770 | return 0; | 770 | return 0; |
@@ -792,7 +792,7 @@ static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, | |||
792 | static int asus_bluetooth_set(struct asus_laptop *asus, int status) | 792 | static int asus_bluetooth_set(struct asus_laptop *asus, int status) |
793 | { | 793 | { |
794 | if (write_acpi_int(asus->handle, METHOD_BLUETOOTH, !!status)) { | 794 | if (write_acpi_int(asus->handle, METHOD_BLUETOOTH, !!status)) { |
795 | pr_warning("Error setting bluetooth status to %d", status); | 795 | pr_warn("Error setting bluetooth status to %d\n", status); |
796 | return -EIO; | 796 | return -EIO; |
797 | } | 797 | } |
798 | return 0; | 798 | return 0; |
@@ -821,7 +821,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
821 | static int asus_wimax_set(struct asus_laptop *asus, int status) | 821 | static int asus_wimax_set(struct asus_laptop *asus, int status) |
822 | { | 822 | { |
823 | if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) { | 823 | if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) { |
824 | pr_warning("Error setting wimax status to %d", status); | 824 | pr_warn("Error setting wimax status to %d\n", status); |
825 | return -EIO; | 825 | return -EIO; |
826 | } | 826 | } |
827 | return 0; | 827 | return 0; |
@@ -850,7 +850,7 @@ static ssize_t store_wimax(struct device *dev, | |||
850 | static int asus_wwan_set(struct asus_laptop *asus, int status) | 850 | static int asus_wwan_set(struct asus_laptop *asus, int status) |
851 | { | 851 | { |
852 | if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) { | 852 | if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) { |
853 | pr_warning("Error setting wwan status to %d", status); | 853 | pr_warn("Error setting wwan status to %d\n", status); |
854 | return -EIO; | 854 | return -EIO; |
855 | } | 855 | } |
856 | return 0; | 856 | return 0; |
@@ -880,7 +880,7 @@ static void asus_set_display(struct asus_laptop *asus, int value) | |||
880 | { | 880 | { |
881 | /* no sanity check needed for now */ | 881 | /* no sanity check needed for now */ |
882 | if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value)) | 882 | if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value)) |
883 | pr_warning("Error setting display\n"); | 883 | pr_warn("Error setting display\n"); |
884 | return; | 884 | return; |
885 | } | 885 | } |
886 | 886 | ||
@@ -909,7 +909,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | |||
909 | static void asus_als_switch(struct asus_laptop *asus, int value) | 909 | static void asus_als_switch(struct asus_laptop *asus, int value) |
910 | { | 910 | { |
911 | if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value)) | 911 | if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value)) |
912 | pr_warning("Error setting light sensor switch\n"); | 912 | pr_warn("Error setting light sensor switch\n"); |
913 | asus->light_switch = value; | 913 | asus->light_switch = value; |
914 | } | 914 | } |
915 | 915 | ||
@@ -937,7 +937,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, | |||
937 | static void asus_als_level(struct asus_laptop *asus, int value) | 937 | static void asus_als_level(struct asus_laptop *asus, int value) |
938 | { | 938 | { |
939 | if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value)) | 939 | if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value)) |
940 | pr_warning("Error setting light sensor level\n"); | 940 | pr_warn("Error setting light sensor level\n"); |
941 | asus->light_level = value; | 941 | asus->light_level = value; |
942 | } | 942 | } |
943 | 943 | ||
@@ -976,7 +976,7 @@ static int asus_gps_status(struct asus_laptop *asus) | |||
976 | rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS, | 976 | rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS, |
977 | NULL, &status); | 977 | NULL, &status); |
978 | if (ACPI_FAILURE(rv)) { | 978 | if (ACPI_FAILURE(rv)) { |
979 | pr_warning("Error reading GPS status\n"); | 979 | pr_warn("Error reading GPS status\n"); |
980 | return -ENODEV; | 980 | return -ENODEV; |
981 | } | 981 | } |
982 | return !!status; | 982 | return !!status; |
@@ -1284,7 +1284,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1284 | */ | 1284 | */ |
1285 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info); | 1285 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info); |
1286 | if (ACPI_FAILURE(status)) | 1286 | if (ACPI_FAILURE(status)) |
1287 | pr_warning("Couldn't get the DSDT table header\n"); | 1287 | pr_warn("Couldn't get the DSDT table header\n"); |
1288 | 1288 | ||
1289 | /* We have to write 0 on init this far for all ASUS models */ | 1289 | /* We have to write 0 on init this far for all ASUS models */ |
1290 | if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) { | 1290 | if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) { |
@@ -1296,7 +1296,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1296 | status = | 1296 | status = |
1297 | acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result); | 1297 | acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result); |
1298 | if (ACPI_FAILURE(status)) | 1298 | if (ACPI_FAILURE(status)) |
1299 | pr_warning("Error calling BSTS\n"); | 1299 | pr_warn("Error calling BSTS\n"); |
1300 | else if (bsts_result) | 1300 | else if (bsts_result) |
1301 | pr_notice("BSTS called, 0x%02x returned\n", | 1301 | pr_notice("BSTS called, 0x%02x returned\n", |
1302 | (uint) bsts_result); | 1302 | (uint) bsts_result); |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 832a3fd7c1c8..00460cb9587b 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -425,7 +425,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) | |||
425 | if (asus->hotplug_slot) { | 425 | if (asus->hotplug_slot) { |
426 | bus = pci_find_bus(0, 1); | 426 | bus = pci_find_bus(0, 1); |
427 | if (!bus) { | 427 | if (!bus) { |
428 | pr_warning("Unable to find PCI bus 1?\n"); | 428 | pr_warn("Unable to find PCI bus 1?\n"); |
429 | goto out_unlock; | 429 | goto out_unlock; |
430 | } | 430 | } |
431 | 431 | ||
@@ -436,12 +436,12 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) | |||
436 | absent = (l == 0xffffffff); | 436 | absent = (l == 0xffffffff); |
437 | 437 | ||
438 | if (blocked != absent) { | 438 | if (blocked != absent) { |
439 | pr_warning("BIOS says wireless lan is %s, " | 439 | pr_warn("BIOS says wireless lan is %s, " |
440 | "but the pci device is %s\n", | 440 | "but the pci device is %s\n", |
441 | blocked ? "blocked" : "unblocked", | 441 | blocked ? "blocked" : "unblocked", |
442 | absent ? "absent" : "present"); | 442 | absent ? "absent" : "present"); |
443 | pr_warning("skipped wireless hotplug as probably " | 443 | pr_warn("skipped wireless hotplug as probably " |
444 | "inappropriate for this model\n"); | 444 | "inappropriate for this model\n"); |
445 | goto out_unlock; | 445 | goto out_unlock; |
446 | } | 446 | } |
447 | 447 | ||
@@ -500,7 +500,7 @@ static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node) | |||
500 | ACPI_SYSTEM_NOTIFY, | 500 | ACPI_SYSTEM_NOTIFY, |
501 | asus_rfkill_notify, asus); | 501 | asus_rfkill_notify, asus); |
502 | if (ACPI_FAILURE(status)) | 502 | if (ACPI_FAILURE(status)) |
503 | pr_warning("Failed to register notify on %s\n", node); | 503 | pr_warn("Failed to register notify on %s\n", node); |
504 | } else | 504 | } else |
505 | return -ENODEV; | 505 | return -ENODEV; |
506 | 506 | ||
@@ -1223,7 +1223,7 @@ static int asus_wmi_sysfs_init(struct platform_device *device) | |||
1223 | /* | 1223 | /* |
1224 | * Platform device | 1224 | * Platform device |
1225 | */ | 1225 | */ |
1226 | static int __init asus_wmi_platform_init(struct asus_wmi *asus) | 1226 | static int asus_wmi_platform_init(struct asus_wmi *asus) |
1227 | { | 1227 | { |
1228 | int rv; | 1228 | int rv; |
1229 | 1229 | ||
@@ -1583,12 +1583,12 @@ static int asus_wmi_probe(struct platform_device *pdev) | |||
1583 | int ret; | 1583 | int ret; |
1584 | 1584 | ||
1585 | if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { | 1585 | if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { |
1586 | pr_warning("Management GUID not found\n"); | 1586 | pr_warn("Management GUID not found\n"); |
1587 | return -ENODEV; | 1587 | return -ENODEV; |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { | 1590 | if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { |
1591 | pr_warning("Event GUID not found\n"); | 1591 | pr_warn("Event GUID not found\n"); |
1592 | return -ENODEV; | 1592 | return -ENODEV; |
1593 | } | 1593 | } |
1594 | 1594 | ||
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index f503607c0645..d9312b3073e5 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -30,6 +30,8 @@ | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
34 | |||
33 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | 36 | #include <linux/module.h> |
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
@@ -581,8 +583,7 @@ static int read_led(const char *ledname, int ledmask) | |||
581 | if (read_acpi_int(NULL, ledname, &led_status)) | 583 | if (read_acpi_int(NULL, ledname, &led_status)) |
582 | return led_status; | 584 | return led_status; |
583 | else | 585 | else |
584 | printk(KERN_WARNING "Asus ACPI: Error reading LED " | 586 | pr_warn("Error reading LED status\n"); |
585 | "status\n"); | ||
586 | } | 587 | } |
587 | return (hotk->status & ledmask) ? 1 : 0; | 588 | return (hotk->status & ledmask) ? 1 : 0; |
588 | } | 589 | } |
@@ -621,8 +622,7 @@ write_led(const char __user *buffer, unsigned long count, | |||
621 | led_out = !led_out; | 622 | led_out = !led_out; |
622 | 623 | ||
623 | if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) | 624 | if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) |
624 | printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", | 625 | pr_warn("LED (%s) write failed\n", ledname); |
625 | ledname); | ||
626 | 626 | ||
627 | return rv; | 627 | return rv; |
628 | } | 628 | } |
@@ -679,8 +679,7 @@ static ssize_t ledd_proc_write(struct file *file, const char __user *buffer, | |||
679 | if (rv > 0) { | 679 | if (rv > 0) { |
680 | if (!write_acpi_int | 680 | if (!write_acpi_int |
681 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) | 681 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) |
682 | printk(KERN_WARNING | 682 | pr_warn("LED display write failed\n"); |
683 | "Asus ACPI: LED display write failed\n"); | ||
684 | else | 683 | else |
685 | hotk->ledd_status = (u32) value; | 684 | hotk->ledd_status = (u32) value; |
686 | } | 685 | } |
@@ -838,8 +837,7 @@ static int get_lcd_state(void) | |||
838 | } else { | 837 | } else { |
839 | /* We don't have to check anything if we are here */ | 838 | /* We don't have to check anything if we are here */ |
840 | if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) | 839 | if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) |
841 | printk(KERN_WARNING | 840 | pr_warn("Error reading LCD status\n"); |
842 | "Asus ACPI: Error reading LCD status\n"); | ||
843 | 841 | ||
844 | if (hotk->model == L2D) | 842 | if (hotk->model == L2D) |
845 | lcd = ~lcd; | 843 | lcd = ~lcd; |
@@ -871,7 +869,7 @@ static int set_lcd_state(int value) | |||
871 | the exact behaviour is simulated here */ | 869 | the exact behaviour is simulated here */ |
872 | } | 870 | } |
873 | if (ACPI_FAILURE(status)) | 871 | if (ACPI_FAILURE(status)) |
874 | printk(KERN_WARNING "Asus ACPI: Error switching LCD\n"); | 872 | pr_warn("Error switching LCD\n"); |
875 | } | 873 | } |
876 | return 0; | 874 | return 0; |
877 | 875 | ||
@@ -915,13 +913,11 @@ static int read_brightness(struct backlight_device *bd) | |||
915 | if (hotk->methods->brightness_get) { /* SPLV/GPLV laptop */ | 913 | if (hotk->methods->brightness_get) { /* SPLV/GPLV laptop */ |
916 | if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, | 914 | if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, |
917 | &value)) | 915 | &value)) |
918 | printk(KERN_WARNING | 916 | pr_warn("Error reading brightness\n"); |
919 | "Asus ACPI: Error reading brightness\n"); | ||
920 | } else if (hotk->methods->brightness_status) { /* For D1 for example */ | 917 | } else if (hotk->methods->brightness_status) { /* For D1 for example */ |
921 | if (!read_acpi_int(NULL, hotk->methods->brightness_status, | 918 | if (!read_acpi_int(NULL, hotk->methods->brightness_status, |
922 | &value)) | 919 | &value)) |
923 | printk(KERN_WARNING | 920 | pr_warn("Error reading brightness\n"); |
924 | "Asus ACPI: Error reading brightness\n"); | ||
925 | } else /* No GPLV method */ | 921 | } else /* No GPLV method */ |
926 | value = hotk->brightness; | 922 | value = hotk->brightness; |
927 | return value; | 923 | return value; |
@@ -939,8 +935,7 @@ static int set_brightness(int value) | |||
939 | if (hotk->methods->brightness_set) { | 935 | if (hotk->methods->brightness_set) { |
940 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, | 936 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, |
941 | value, NULL)) { | 937 | value, NULL)) { |
942 | printk(KERN_WARNING | 938 | pr_warn("Error changing brightness\n"); |
943 | "Asus ACPI: Error changing brightness\n"); | ||
944 | ret = -EIO; | 939 | ret = -EIO; |
945 | } | 940 | } |
946 | goto out; | 941 | goto out; |
@@ -955,8 +950,7 @@ static int set_brightness(int value) | |||
955 | NULL, NULL); | 950 | NULL, NULL); |
956 | (value > 0) ? value-- : value++; | 951 | (value > 0) ? value-- : value++; |
957 | if (ACPI_FAILURE(status)) { | 952 | if (ACPI_FAILURE(status)) { |
958 | printk(KERN_WARNING | 953 | pr_warn("Error changing brightness\n"); |
959 | "Asus ACPI: Error changing brightness\n"); | ||
960 | ret = -EIO; | 954 | ret = -EIO; |
961 | } | 955 | } |
962 | } | 956 | } |
@@ -1008,7 +1002,7 @@ static void set_display(int value) | |||
1008 | /* no sanity check needed for now */ | 1002 | /* no sanity check needed for now */ |
1009 | if (!write_acpi_int(hotk->handle, hotk->methods->display_set, | 1003 | if (!write_acpi_int(hotk->handle, hotk->methods->display_set, |
1010 | value, NULL)) | 1004 | value, NULL)) |
1011 | printk(KERN_WARNING "Asus ACPI: Error setting display\n"); | 1005 | pr_warn("Error setting display\n"); |
1012 | return; | 1006 | return; |
1013 | } | 1007 | } |
1014 | 1008 | ||
@@ -1021,8 +1015,7 @@ static int disp_proc_show(struct seq_file *m, void *v) | |||
1021 | int value = 0; | 1015 | int value = 0; |
1022 | 1016 | ||
1023 | if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) | 1017 | if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) |
1024 | printk(KERN_WARNING | 1018 | pr_warn("Error reading display status\n"); |
1025 | "Asus ACPI: Error reading display status\n"); | ||
1026 | value &= 0x07; /* needed for some models, shouldn't hurt others */ | 1019 | value &= 0x07; /* needed for some models, shouldn't hurt others */ |
1027 | seq_printf(m, "%d\n", value); | 1020 | seq_printf(m, "%d\n", value); |
1028 | return 0; | 1021 | return 0; |
@@ -1068,7 +1061,7 @@ asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode, | |||
1068 | proc = proc_create_data(name, mode, acpi_device_dir(device), | 1061 | proc = proc_create_data(name, mode, acpi_device_dir(device), |
1069 | proc_fops, acpi_driver_data(device)); | 1062 | proc_fops, acpi_driver_data(device)); |
1070 | if (!proc) { | 1063 | if (!proc) { |
1071 | printk(KERN_WARNING " Unable to create %s fs entry\n", name); | 1064 | pr_warn(" Unable to create %s fs entry\n", name); |
1072 | return -1; | 1065 | return -1; |
1073 | } | 1066 | } |
1074 | proc->uid = asus_uid; | 1067 | proc->uid = asus_uid; |
@@ -1085,8 +1078,8 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1085 | mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP; | 1078 | mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP; |
1086 | } else { | 1079 | } else { |
1087 | mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; | 1080 | mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; |
1088 | printk(KERN_WARNING " asus_uid and asus_gid parameters are " | 1081 | pr_warn(" asus_uid and asus_gid parameters are " |
1089 | "deprecated, use chown and chmod instead!\n"); | 1082 | "deprecated, use chown and chmod instead!\n"); |
1090 | } | 1083 | } |
1091 | 1084 | ||
1092 | acpi_device_dir(device) = asus_proc_dir; | 1085 | acpi_device_dir(device) = asus_proc_dir; |
@@ -1099,8 +1092,7 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1099 | proc->uid = asus_uid; | 1092 | proc->uid = asus_uid; |
1100 | proc->gid = asus_gid; | 1093 | proc->gid = asus_gid; |
1101 | } else { | 1094 | } else { |
1102 | printk(KERN_WARNING " Unable to create " PROC_INFO | 1095 | pr_warn(" Unable to create " PROC_INFO " fs entry\n"); |
1103 | " fs entry\n"); | ||
1104 | } | 1096 | } |
1105 | 1097 | ||
1106 | if (hotk->methods->mt_wled) { | 1098 | if (hotk->methods->mt_wled) { |
@@ -1283,20 +1275,19 @@ static int asus_hotk_get_info(void) | |||
1283 | */ | 1275 | */ |
1284 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); | 1276 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); |
1285 | if (ACPI_FAILURE(status)) | 1277 | if (ACPI_FAILURE(status)) |
1286 | printk(KERN_WARNING " Couldn't get the DSDT table header\n"); | 1278 | pr_warn(" Couldn't get the DSDT table header\n"); |
1287 | 1279 | ||
1288 | /* We have to write 0 on init this far for all ASUS models */ | 1280 | /* We have to write 0 on init this far for all ASUS models */ |
1289 | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { | 1281 | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { |
1290 | printk(KERN_ERR " Hotkey initialization failed\n"); | 1282 | pr_err(" Hotkey initialization failed\n"); |
1291 | return -ENODEV; | 1283 | return -ENODEV; |
1292 | } | 1284 | } |
1293 | 1285 | ||
1294 | /* This needs to be called for some laptops to init properly */ | 1286 | /* This needs to be called for some laptops to init properly */ |
1295 | if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result)) | 1287 | if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result)) |
1296 | printk(KERN_WARNING " Error calling BSTS\n"); | 1288 | pr_warn(" Error calling BSTS\n"); |
1297 | else if (bsts_result) | 1289 | else if (bsts_result) |
1298 | printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", | 1290 | pr_notice(" BSTS called, 0x%02x returned\n", bsts_result); |
1299 | bsts_result); | ||
1300 | 1291 | ||
1301 | /* | 1292 | /* |
1302 | * Try to match the object returned by INIT to the specific model. | 1293 | * Try to match the object returned by INIT to the specific model. |
@@ -1324,23 +1315,21 @@ static int asus_hotk_get_info(void) | |||
1324 | if (asus_info && | 1315 | if (asus_info && |
1325 | strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { | 1316 | strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { |
1326 | hotk->model = P30; | 1317 | hotk->model = P30; |
1327 | printk(KERN_NOTICE | 1318 | pr_notice(" Samsung P30 detected, supported\n"); |
1328 | " Samsung P30 detected, supported\n"); | ||
1329 | hotk->methods = &model_conf[hotk->model]; | 1319 | hotk->methods = &model_conf[hotk->model]; |
1330 | kfree(model); | 1320 | kfree(model); |
1331 | return 0; | 1321 | return 0; |
1332 | } else { | 1322 | } else { |
1333 | hotk->model = M2E; | 1323 | hotk->model = M2E; |
1334 | printk(KERN_NOTICE " unsupported model %s, trying " | 1324 | pr_notice(" unsupported model %s, trying default values\n", |
1335 | "default values\n", string); | 1325 | string); |
1336 | printk(KERN_NOTICE | 1326 | pr_notice(" send /proc/acpi/dsdt to the developers\n"); |
1337 | " send /proc/acpi/dsdt to the developers\n"); | ||
1338 | kfree(model); | 1327 | kfree(model); |
1339 | return -ENODEV; | 1328 | return -ENODEV; |
1340 | } | 1329 | } |
1341 | } | 1330 | } |
1342 | hotk->methods = &model_conf[hotk->model]; | 1331 | hotk->methods = &model_conf[hotk->model]; |
1343 | printk(KERN_NOTICE " %s model detected, supported\n", string); | 1332 | pr_notice(" %s model detected, supported\n", string); |
1344 | 1333 | ||
1345 | /* Sort of per-model blacklist */ | 1334 | /* Sort of per-model blacklist */ |
1346 | if (strncmp(string, "L2B", 3) == 0) | 1335 | if (strncmp(string, "L2B", 3) == 0) |
@@ -1385,7 +1374,7 @@ static int asus_hotk_check(void) | |||
1385 | if (hotk->device->status.present) { | 1374 | if (hotk->device->status.present) { |
1386 | result = asus_hotk_get_info(); | 1375 | result = asus_hotk_get_info(); |
1387 | } else { | 1376 | } else { |
1388 | printk(KERN_ERR " Hotkey device not present, aborting\n"); | 1377 | pr_err(" Hotkey device not present, aborting\n"); |
1389 | return -EINVAL; | 1378 | return -EINVAL; |
1390 | } | 1379 | } |
1391 | 1380 | ||
@@ -1399,8 +1388,7 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1399 | acpi_status status = AE_OK; | 1388 | acpi_status status = AE_OK; |
1400 | int result; | 1389 | int result; |
1401 | 1390 | ||
1402 | printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", | 1391 | pr_notice("Asus Laptop ACPI Extras version %s\n", ASUS_ACPI_VERSION); |
1403 | ASUS_ACPI_VERSION); | ||
1404 | 1392 | ||
1405 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); | 1393 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); |
1406 | if (!hotk) | 1394 | if (!hotk) |
@@ -1428,15 +1416,14 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1428 | acpi_evaluate_object(NULL, hotk->methods->brightness_down, | 1416 | acpi_evaluate_object(NULL, hotk->methods->brightness_down, |
1429 | NULL, NULL); | 1417 | NULL, NULL); |
1430 | if (ACPI_FAILURE(status)) | 1418 | if (ACPI_FAILURE(status)) |
1431 | printk(KERN_WARNING " Error changing brightness\n"); | 1419 | pr_warn(" Error changing brightness\n"); |
1432 | else { | 1420 | else { |
1433 | status = | 1421 | status = |
1434 | acpi_evaluate_object(NULL, | 1422 | acpi_evaluate_object(NULL, |
1435 | hotk->methods->brightness_up, | 1423 | hotk->methods->brightness_up, |
1436 | NULL, NULL); | 1424 | NULL, NULL); |
1437 | if (ACPI_FAILURE(status)) | 1425 | if (ACPI_FAILURE(status)) |
1438 | printk(KERN_WARNING " Strange, error changing" | 1426 | pr_warn(" Strange, error changing brightness\n"); |
1439 | " brightness\n"); | ||
1440 | } | 1427 | } |
1441 | } | 1428 | } |
1442 | 1429 | ||
@@ -1488,7 +1475,7 @@ static int __init asus_acpi_init(void) | |||
1488 | 1475 | ||
1489 | asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); | 1476 | asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); |
1490 | if (!asus_proc_dir) { | 1477 | if (!asus_proc_dir) { |
1491 | printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); | 1478 | pr_err("Unable to create /proc entry\n"); |
1492 | acpi_bus_unregister_driver(&asus_hotk_driver); | 1479 | acpi_bus_unregister_driver(&asus_hotk_driver); |
1493 | return -ENODEV; | 1480 | return -ENODEV; |
1494 | } | 1481 | } |
@@ -1513,7 +1500,7 @@ static int __init asus_acpi_init(void) | |||
1513 | &asus_backlight_data, | 1500 | &asus_backlight_data, |
1514 | &props); | 1501 | &props); |
1515 | if (IS_ERR(asus_backlight_device)) { | 1502 | if (IS_ERR(asus_backlight_device)) { |
1516 | printk(KERN_ERR "Could not register asus backlight device\n"); | 1503 | pr_err("Could not register asus backlight device\n"); |
1517 | asus_backlight_device = NULL; | 1504 | asus_backlight_device = NULL; |
1518 | asus_acpi_exit(); | 1505 | asus_acpi_exit(); |
1519 | return -ENODEV; | 1506 | return -ENODEV; |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index c16a27641ced..3f204fde1b02 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -68,6 +68,8 @@ | |||
68 | * only enabled on a JHL90 board until it is verified that they work on the | 68 | * only enabled on a JHL90 board until it is verified that they work on the |
69 | * other boards too. See the extra_features variable. */ | 69 | * other boards too. See the extra_features variable. */ |
70 | 70 | ||
71 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
72 | |||
71 | #include <linux/module.h> | 73 | #include <linux/module.h> |
72 | #include <linux/kernel.h> | 74 | #include <linux/kernel.h> |
73 | #include <linux/init.h> | 75 | #include <linux/init.h> |
@@ -200,8 +202,8 @@ static bool extra_features; | |||
200 | * watching the output of address 0x4F (do an ec_transaction writing 0x33 | 202 | * watching the output of address 0x4F (do an ec_transaction writing 0x33 |
201 | * into 0x4F and read a few bytes from the output, like so: | 203 | * into 0x4F and read a few bytes from the output, like so: |
202 | * u8 writeData = 0x33; | 204 | * u8 writeData = 0x33; |
203 | * ec_transaction(0x4F, &writeData, 1, buffer, 32, 0); | 205 | * ec_transaction(0x4F, &writeData, 1, buffer, 32); |
204 | * That address is labelled "fan1 table information" in the service manual. | 206 | * That address is labeled "fan1 table information" in the service manual. |
205 | * It should be clear which value in 'buffer' changes). This seems to be | 207 | * It should be clear which value in 'buffer' changes). This seems to be |
206 | * related to fan speed. It isn't a proper 'realtime' fan speed value | 208 | * related to fan speed. It isn't a proper 'realtime' fan speed value |
207 | * though, because physically stopping or speeding up the fan doesn't | 209 | * though, because physically stopping or speeding up the fan doesn't |
@@ -286,7 +288,7 @@ static int get_backlight_level(void) | |||
286 | static void set_backlight_state(bool on) | 288 | static void set_backlight_state(bool on) |
287 | { | 289 | { |
288 | u8 data = on ? BACKLIGHT_STATE_ON_DATA : BACKLIGHT_STATE_OFF_DATA; | 290 | u8 data = on ? BACKLIGHT_STATE_ON_DATA : BACKLIGHT_STATE_OFF_DATA; |
289 | ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0, 0); | 291 | ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0); |
290 | } | 292 | } |
291 | 293 | ||
292 | 294 | ||
@@ -294,24 +296,24 @@ static void set_backlight_state(bool on) | |||
294 | static void pwm_enable_control(void) | 296 | static void pwm_enable_control(void) |
295 | { | 297 | { |
296 | unsigned char writeData = PWM_ENABLE_DATA; | 298 | unsigned char writeData = PWM_ENABLE_DATA; |
297 | ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0, 0); | 299 | ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0); |
298 | } | 300 | } |
299 | 301 | ||
300 | static void pwm_disable_control(void) | 302 | static void pwm_disable_control(void) |
301 | { | 303 | { |
302 | unsigned char writeData = PWM_DISABLE_DATA; | 304 | unsigned char writeData = PWM_DISABLE_DATA; |
303 | ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0, 0); | 305 | ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0); |
304 | } | 306 | } |
305 | 307 | ||
306 | static void set_pwm(int pwm) | 308 | static void set_pwm(int pwm) |
307 | { | 309 | { |
308 | ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0, 0); | 310 | ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0); |
309 | } | 311 | } |
310 | 312 | ||
311 | static int get_fan_rpm(void) | 313 | static int get_fan_rpm(void) |
312 | { | 314 | { |
313 | u8 value, data = FAN_DATA; | 315 | u8 value, data = FAN_DATA; |
314 | ec_transaction(FAN_ADDRESS, &data, 1, &value, 1, 0); | 316 | ec_transaction(FAN_ADDRESS, &data, 1, &value, 1); |
315 | return 100 * (int)value; | 317 | return 100 * (int)value; |
316 | } | 318 | } |
317 | 319 | ||
@@ -760,16 +762,14 @@ static struct rfkill *bt_rfkill; | |||
760 | 762 | ||
761 | static int dmi_check_cb(const struct dmi_system_id *id) | 763 | static int dmi_check_cb(const struct dmi_system_id *id) |
762 | { | 764 | { |
763 | printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s'\n", | 765 | pr_info("Identified laptop model '%s'\n", id->ident); |
764 | id->ident); | ||
765 | extra_features = false; | 766 | extra_features = false; |
766 | return 1; | 767 | return 1; |
767 | } | 768 | } |
768 | 769 | ||
769 | static int dmi_check_cb_extra(const struct dmi_system_id *id) | 770 | static int dmi_check_cb_extra(const struct dmi_system_id *id) |
770 | { | 771 | { |
771 | printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s', " | 772 | pr_info("Identified laptop model '%s', enabling extra features\n", |
772 | "enabling extra features\n", | ||
773 | id->ident); | 773 | id->ident); |
774 | extra_features = true; | 774 | extra_features = true; |
775 | return 1; | 775 | return 1; |
@@ -956,14 +956,12 @@ static int __init compal_init(void) | |||
956 | int ret; | 956 | int ret; |
957 | 957 | ||
958 | if (acpi_disabled) { | 958 | if (acpi_disabled) { |
959 | printk(KERN_ERR DRIVER_NAME": ACPI needs to be enabled for " | 959 | pr_err("ACPI needs to be enabled for this driver to work!\n"); |
960 | "this driver to work!\n"); | ||
961 | return -ENODEV; | 960 | return -ENODEV; |
962 | } | 961 | } |
963 | 962 | ||
964 | if (!force && !dmi_check_system(compal_dmi_table)) { | 963 | if (!force && !dmi_check_system(compal_dmi_table)) { |
965 | printk(KERN_ERR DRIVER_NAME": Motherboard not recognized (You " | 964 | pr_err("Motherboard not recognized (You could try the module's force-parameter)\n"); |
966 | "could try the module's force-parameter)"); | ||
967 | return -ENODEV; | 965 | return -ENODEV; |
968 | } | 966 | } |
969 | 967 | ||
@@ -998,8 +996,7 @@ static int __init compal_init(void) | |||
998 | if (ret) | 996 | if (ret) |
999 | goto err_rfkill; | 997 | goto err_rfkill; |
1000 | 998 | ||
1001 | printk(KERN_INFO DRIVER_NAME": Driver "DRIVER_VERSION | 999 | pr_info("Driver " DRIVER_VERSION " successfully loaded\n"); |
1002 | " successfully loaded\n"); | ||
1003 | return 0; | 1000 | return 0; |
1004 | 1001 | ||
1005 | err_rfkill: | 1002 | err_rfkill: |
@@ -1064,7 +1061,7 @@ static void __exit compal_cleanup(void) | |||
1064 | rfkill_destroy(wifi_rfkill); | 1061 | rfkill_destroy(wifi_rfkill); |
1065 | rfkill_destroy(bt_rfkill); | 1062 | rfkill_destroy(bt_rfkill); |
1066 | 1063 | ||
1067 | printk(KERN_INFO DRIVER_NAME": Driver unloaded\n"); | 1064 | pr_info("Driver unloaded\n"); |
1068 | } | 1065 | } |
1069 | 1066 | ||
1070 | static int __devexit compal_remove(struct platform_device *pdev) | 1067 | static int __devexit compal_remove(struct platform_device *pdev) |
@@ -1074,8 +1071,7 @@ static int __devexit compal_remove(struct platform_device *pdev) | |||
1074 | if (!extra_features) | 1071 | if (!extra_features) |
1075 | return 0; | 1072 | return 0; |
1076 | 1073 | ||
1077 | printk(KERN_INFO DRIVER_NAME": Unloading: resetting fan control " | 1074 | pr_info("Unloading: resetting fan control to motherboard\n"); |
1078 | "to motherboard\n"); | ||
1079 | pwm_disable_control(); | 1075 | pwm_disable_control(); |
1080 | 1076 | ||
1081 | data = platform_get_drvdata(pdev); | 1077 | data = platform_get_drvdata(pdev); |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index de301aa8e5c3..d3841de6a8cf 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
@@ -434,8 +436,7 @@ static int __init dell_setup_rfkill(void) | |||
434 | int ret; | 436 | int ret; |
435 | 437 | ||
436 | if (dmi_check_system(dell_blacklist)) { | 438 | if (dmi_check_system(dell_blacklist)) { |
437 | printk(KERN_INFO "dell-laptop: Blacklisted hardware detected - " | 439 | pr_info("Blacklisted hardware detected - not enabling rfkill\n"); |
438 | "not enabling rfkill\n"); | ||
439 | return 0; | 440 | return 0; |
440 | } | 441 | } |
441 | 442 | ||
@@ -606,7 +607,7 @@ static int __init dell_init(void) | |||
606 | dmi_walk(find_tokens, NULL); | 607 | dmi_walk(find_tokens, NULL); |
607 | 608 | ||
608 | if (!da_tokens) { | 609 | if (!da_tokens) { |
609 | printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n"); | 610 | pr_info("Unable to find dmi tokens\n"); |
610 | return -ENODEV; | 611 | return -ENODEV; |
611 | } | 612 | } |
612 | 613 | ||
@@ -636,14 +637,13 @@ static int __init dell_init(void) | |||
636 | ret = dell_setup_rfkill(); | 637 | ret = dell_setup_rfkill(); |
637 | 638 | ||
638 | if (ret) { | 639 | if (ret) { |
639 | printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n"); | 640 | pr_warn("Unable to setup rfkill\n"); |
640 | goto fail_rfkill; | 641 | goto fail_rfkill; |
641 | } | 642 | } |
642 | 643 | ||
643 | ret = i8042_install_filter(dell_laptop_i8042_filter); | 644 | ret = i8042_install_filter(dell_laptop_i8042_filter); |
644 | if (ret) { | 645 | if (ret) { |
645 | printk(KERN_WARNING | 646 | pr_warn("Unable to install key filter\n"); |
646 | "dell-laptop: Unable to install key filter\n"); | ||
647 | goto fail_filter; | 647 | goto fail_filter; |
648 | } | 648 | } |
649 | 649 | ||
diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c index 0ed84573ae1f..3f945457f71c 100644 --- a/drivers/platform/x86/dell-wmi-aio.c +++ b/drivers/platform/x86/dell-wmi-aio.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | |||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
19 | 20 | ||
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -138,7 +139,7 @@ static int __init dell_wmi_aio_init(void) | |||
138 | 139 | ||
139 | guid = dell_wmi_aio_find(); | 140 | guid = dell_wmi_aio_find(); |
140 | if (!guid) { | 141 | if (!guid) { |
141 | pr_warning("No known WMI GUID found\n"); | 142 | pr_warn("No known WMI GUID found\n"); |
142 | return -ENXIO; | 143 | return -ENXIO; |
143 | } | 144 | } |
144 | 145 | ||
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 77f1d55414c6..ce790827e199 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c | |||
@@ -23,6 +23,8 @@ | |||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
27 | |||
26 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
28 | #include <linux/init.h> | 30 | #include <linux/init.h> |
@@ -141,7 +143,7 @@ static void dell_wmi_notify(u32 value, void *context) | |||
141 | 143 | ||
142 | status = wmi_get_event_data(value, &response); | 144 | status = wmi_get_event_data(value, &response); |
143 | if (status != AE_OK) { | 145 | if (status != AE_OK) { |
144 | printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status); | 146 | pr_info("bad event status 0x%x\n", status); |
145 | return; | 147 | return; |
146 | } | 148 | } |
147 | 149 | ||
@@ -153,8 +155,8 @@ static void dell_wmi_notify(u32 value, void *context) | |||
153 | u16 *buffer_entry = (u16 *)obj->buffer.pointer; | 155 | u16 *buffer_entry = (u16 *)obj->buffer.pointer; |
154 | 156 | ||
155 | if (dell_new_hk_type && (buffer_entry[1] != 0x10)) { | 157 | if (dell_new_hk_type && (buffer_entry[1] != 0x10)) { |
156 | printk(KERN_INFO "dell-wmi: Received unknown WMI event" | 158 | pr_info("Received unknown WMI event (0x%x)\n", |
157 | " (0x%x)\n", buffer_entry[1]); | 159 | buffer_entry[1]); |
158 | kfree(obj); | 160 | kfree(obj); |
159 | return; | 161 | return; |
160 | } | 162 | } |
@@ -167,8 +169,7 @@ static void dell_wmi_notify(u32 value, void *context) | |||
167 | key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, | 169 | key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, |
168 | reported_key); | 170 | reported_key); |
169 | if (!key) { | 171 | if (!key) { |
170 | printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n", | 172 | pr_info("Unknown key %x pressed\n", reported_key); |
171 | reported_key); | ||
172 | } else if ((key->keycode == KEY_BRIGHTNESSUP || | 173 | } else if ((key->keycode == KEY_BRIGHTNESSUP || |
173 | key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { | 174 | key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { |
174 | /* Don't report brightness notifications that will also | 175 | /* Don't report brightness notifications that will also |
@@ -275,7 +276,7 @@ static int __init dell_wmi_init(void) | |||
275 | acpi_status status; | 276 | acpi_status status; |
276 | 277 | ||
277 | if (!wmi_has_guid(DELL_EVENT_GUID)) { | 278 | if (!wmi_has_guid(DELL_EVENT_GUID)) { |
278 | printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); | 279 | pr_warn("No known WMI GUID found\n"); |
279 | return -ENODEV; | 280 | return -ENODEV; |
280 | } | 281 | } |
281 | 282 | ||
@@ -290,9 +291,7 @@ static int __init dell_wmi_init(void) | |||
290 | dell_wmi_notify, NULL); | 291 | dell_wmi_notify, NULL); |
291 | if (ACPI_FAILURE(status)) { | 292 | if (ACPI_FAILURE(status)) { |
292 | dell_wmi_input_destroy(); | 293 | dell_wmi_input_destroy(); |
293 | printk(KERN_ERR | 294 | pr_err("Unable to register notify handler - %d\n", status); |
294 | "dell-wmi: Unable to register notify handler - %d\n", | ||
295 | status); | ||
296 | return -ENODEV; | 295 | return -ENODEV; |
297 | } | 296 | } |
298 | 297 | ||
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 2c1abf63957f..1c45d92e2163 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -228,7 +228,7 @@ static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value) | |||
228 | return -ENODEV; | 228 | return -ENODEV; |
229 | 229 | ||
230 | if (write_acpi_int(eeepc->handle, method, value)) | 230 | if (write_acpi_int(eeepc->handle, method, value)) |
231 | pr_warning("Error writing %s\n", method); | 231 | pr_warn("Error writing %s\n", method); |
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
234 | 234 | ||
@@ -243,7 +243,7 @@ static int get_acpi(struct eeepc_laptop *eeepc, int cm) | |||
243 | return -ENODEV; | 243 | return -ENODEV; |
244 | 244 | ||
245 | if (read_acpi_int(eeepc->handle, method, &value)) | 245 | if (read_acpi_int(eeepc->handle, method, &value)) |
246 | pr_warning("Error reading %s\n", method); | 246 | pr_warn("Error reading %s\n", method); |
247 | return value; | 247 | return value; |
248 | } | 248 | } |
249 | 249 | ||
@@ -261,7 +261,7 @@ static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, | |||
261 | status = acpi_get_handle(eeepc->handle, (char *)method, | 261 | status = acpi_get_handle(eeepc->handle, (char *)method, |
262 | handle); | 262 | handle); |
263 | if (status != AE_OK) { | 263 | if (status != AE_OK) { |
264 | pr_warning("Error finding %s\n", method); | 264 | pr_warn("Error finding %s\n", method); |
265 | return -ENODEV; | 265 | return -ENODEV; |
266 | } | 266 | } |
267 | return 0; | 267 | return 0; |
@@ -417,7 +417,7 @@ static ssize_t store_cpufv_disabled(struct device *dev, | |||
417 | switch (value) { | 417 | switch (value) { |
418 | case 0: | 418 | case 0: |
419 | if (eeepc->cpufv_disabled) | 419 | if (eeepc->cpufv_disabled) |
420 | pr_warning("cpufv enabled (not officially supported " | 420 | pr_warn("cpufv enabled (not officially supported " |
421 | "on this model)\n"); | 421 | "on this model)\n"); |
422 | eeepc->cpufv_disabled = false; | 422 | eeepc->cpufv_disabled = false; |
423 | return rv; | 423 | return rv; |
@@ -609,7 +609,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
609 | bus = port->subordinate; | 609 | bus = port->subordinate; |
610 | 610 | ||
611 | if (!bus) { | 611 | if (!bus) { |
612 | pr_warning("Unable to find PCI bus?\n"); | 612 | pr_warn("Unable to find PCI bus 1?\n"); |
613 | goto out_unlock; | 613 | goto out_unlock; |
614 | } | 614 | } |
615 | 615 | ||
@@ -621,12 +621,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
621 | absent = (l == 0xffffffff); | 621 | absent = (l == 0xffffffff); |
622 | 622 | ||
623 | if (blocked != absent) { | 623 | if (blocked != absent) { |
624 | pr_warning("BIOS says wireless lan is %s, " | 624 | pr_warn("BIOS says wireless lan is %s, " |
625 | "but the pci device is %s\n", | 625 | "but the pci device is %s\n", |
626 | blocked ? "blocked" : "unblocked", | 626 | blocked ? "blocked" : "unblocked", |
627 | absent ? "absent" : "present"); | 627 | absent ? "absent" : "present"); |
628 | pr_warning("skipped wireless hotplug as probably " | 628 | pr_warn("skipped wireless hotplug as probably " |
629 | "inappropriate for this model\n"); | 629 | "inappropriate for this model\n"); |
630 | goto out_unlock; | 630 | goto out_unlock; |
631 | } | 631 | } |
632 | 632 | ||
@@ -691,7 +691,8 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, | |||
691 | eeepc_rfkill_notify, | 691 | eeepc_rfkill_notify, |
692 | eeepc); | 692 | eeepc); |
693 | if (ACPI_FAILURE(status)) | 693 | if (ACPI_FAILURE(status)) |
694 | pr_warning("Failed to register notify on %s\n", node); | 694 | pr_warn("Failed to register notify on %s\n", node); |
695 | |||
695 | /* | 696 | /* |
696 | * Refresh pci hotplug in case the rfkill state was | 697 | * Refresh pci hotplug in case the rfkill state was |
697 | * changed during setup. | 698 | * changed during setup. |
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 649dcadd8ea3..4aa867a9b88b 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -84,7 +84,7 @@ static const struct key_entry eeepc_wmi_keymap[] = { | |||
84 | static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, | 84 | static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, |
85 | void *context, void **retval) | 85 | void *context, void **retval) |
86 | { | 86 | { |
87 | pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID); | 87 | pr_warn("Found legacy ATKD device (%s)\n", EEEPC_ACPI_HID); |
88 | *(bool *)context = true; | 88 | *(bool *)context = true; |
89 | return AE_CTRL_TERMINATE; | 89 | return AE_CTRL_TERMINATE; |
90 | } | 90 | } |
@@ -105,12 +105,12 @@ static int eeepc_wmi_check_atkd(void) | |||
105 | static int eeepc_wmi_probe(struct platform_device *pdev) | 105 | static int eeepc_wmi_probe(struct platform_device *pdev) |
106 | { | 106 | { |
107 | if (eeepc_wmi_check_atkd()) { | 107 | if (eeepc_wmi_check_atkd()) { |
108 | pr_warning("WMI device present, but legacy ATKD device is also " | 108 | pr_warn("WMI device present, but legacy ATKD device is also " |
109 | "present and enabled."); | 109 | "present and enabled\n"); |
110 | pr_warning("You probably booted with acpi_osi=\"Linux\" or " | 110 | pr_warn("You probably booted with acpi_osi=\"Linux\" or " |
111 | "acpi_osi=\"!Windows 2009\""); | 111 | "acpi_osi=\"!Windows 2009\"\n"); |
112 | pr_warning("Can't load eeepc-wmi, use default acpi_osi " | 112 | pr_warn("Can't load eeepc-wmi, use default acpi_osi " |
113 | "(preferred) or eeepc-laptop"); | 113 | "(preferred) or eeepc-laptop\n"); |
114 | return -EBUSY; | 114 | return -EBUSY; |
115 | } | 115 | } |
116 | return 0; | 116 | return 0; |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 493054c2dbe1..6b26666b37f2 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -56,6 +56,8 @@ | |||
56 | * | 56 | * |
57 | */ | 57 | */ |
58 | 58 | ||
59 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
60 | |||
59 | #include <linux/module.h> | 61 | #include <linux/module.h> |
60 | #include <linux/kernel.h> | 62 | #include <linux/kernel.h> |
61 | #include <linux/init.h> | 63 | #include <linux/init.h> |
@@ -585,8 +587,7 @@ static struct platform_driver fujitsupf_driver = { | |||
585 | static void dmi_check_cb_common(const struct dmi_system_id *id) | 587 | static void dmi_check_cb_common(const struct dmi_system_id *id) |
586 | { | 588 | { |
587 | acpi_handle handle; | 589 | acpi_handle handle; |
588 | printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n", | 590 | pr_info("Identified laptop model '%s'\n", id->ident); |
589 | id->ident); | ||
590 | if (use_alt_lcd_levels == -1) { | 591 | if (use_alt_lcd_levels == -1) { |
591 | if (ACPI_SUCCESS(acpi_get_handle(NULL, | 592 | if (ACPI_SUCCESS(acpi_get_handle(NULL, |
592 | "\\_SB.PCI0.LPCB.FJEX.SBL2", &handle))) | 593 | "\\_SB.PCI0.LPCB.FJEX.SBL2", &handle))) |
@@ -691,11 +692,11 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
691 | 692 | ||
692 | result = acpi_bus_update_power(fujitsu->acpi_handle, &state); | 693 | result = acpi_bus_update_power(fujitsu->acpi_handle, &state); |
693 | if (result) { | 694 | if (result) { |
694 | printk(KERN_ERR "Error reading power state\n"); | 695 | pr_err("Error reading power state\n"); |
695 | goto err_unregister_input_dev; | 696 | goto err_unregister_input_dev; |
696 | } | 697 | } |
697 | 698 | ||
698 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", | 699 | pr_info("ACPI: %s [%s] (%s)\n", |
699 | acpi_device_name(device), acpi_device_bid(device), | 700 | acpi_device_name(device), acpi_device_bid(device), |
700 | !device->power.state ? "on" : "off"); | 701 | !device->power.state ? "on" : "off"); |
701 | 702 | ||
@@ -707,7 +708,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
707 | if (ACPI_FAILURE | 708 | if (ACPI_FAILURE |
708 | (acpi_evaluate_object | 709 | (acpi_evaluate_object |
709 | (device->handle, METHOD_NAME__INI, NULL, NULL))) | 710 | (device->handle, METHOD_NAME__INI, NULL, NULL))) |
710 | printk(KERN_ERR "_INI Method failed\n"); | 711 | pr_err("_INI Method failed\n"); |
711 | } | 712 | } |
712 | 713 | ||
713 | /* do config (detect defaults) */ | 714 | /* do config (detect defaults) */ |
@@ -827,7 +828,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
827 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), | 828 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), |
828 | GFP_KERNEL); | 829 | GFP_KERNEL); |
829 | if (error) { | 830 | if (error) { |
830 | printk(KERN_ERR "kfifo_alloc failed\n"); | 831 | pr_err("kfifo_alloc failed\n"); |
831 | goto err_stop; | 832 | goto err_stop; |
832 | } | 833 | } |
833 | 834 | ||
@@ -859,13 +860,13 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
859 | 860 | ||
860 | result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state); | 861 | result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state); |
861 | if (result) { | 862 | if (result) { |
862 | printk(KERN_ERR "Error reading power state\n"); | 863 | pr_err("Error reading power state\n"); |
863 | goto err_unregister_input_dev; | 864 | goto err_unregister_input_dev; |
864 | } | 865 | } |
865 | 866 | ||
866 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", | 867 | pr_info("ACPI: %s [%s] (%s)\n", |
867 | acpi_device_name(device), acpi_device_bid(device), | 868 | acpi_device_name(device), acpi_device_bid(device), |
868 | !device->power.state ? "on" : "off"); | 869 | !device->power.state ? "on" : "off"); |
869 | 870 | ||
870 | fujitsu_hotkey->dev = device; | 871 | fujitsu_hotkey->dev = device; |
871 | 872 | ||
@@ -875,7 +876,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
875 | if (ACPI_FAILURE | 876 | if (ACPI_FAILURE |
876 | (acpi_evaluate_object | 877 | (acpi_evaluate_object |
877 | (device->handle, METHOD_NAME__INI, NULL, NULL))) | 878 | (device->handle, METHOD_NAME__INI, NULL, NULL))) |
878 | printk(KERN_ERR "_INI Method failed\n"); | 879 | pr_err("_INI Method failed\n"); |
879 | } | 880 | } |
880 | 881 | ||
881 | i = 0; | 882 | i = 0; |
@@ -897,8 +898,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
897 | call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); | 898 | call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); |
898 | 899 | ||
899 | /* Suspect this is a keymap of the application panel, print it */ | 900 | /* Suspect this is a keymap of the application panel, print it */ |
900 | printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", | 901 | pr_info("BTNI: [0x%x]\n", call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); |
901 | call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); | ||
902 | 902 | ||
903 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | 903 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
904 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { | 904 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { |
@@ -907,8 +907,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
907 | if (result == 0) { | 907 | if (result == 0) { |
908 | fujitsu_hotkey->logolamp_registered = 1; | 908 | fujitsu_hotkey->logolamp_registered = 1; |
909 | } else { | 909 | } else { |
910 | printk(KERN_ERR "fujitsu-laptop: Could not register " | 910 | pr_err("Could not register LED handler for logo lamp, error %i\n", |
911 | "LED handler for logo lamp, error %i\n", result); | 911 | result); |
912 | } | 912 | } |
913 | } | 913 | } |
914 | 914 | ||
@@ -919,8 +919,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
919 | if (result == 0) { | 919 | if (result == 0) { |
920 | fujitsu_hotkey->kblamps_registered = 1; | 920 | fujitsu_hotkey->kblamps_registered = 1; |
921 | } else { | 921 | } else { |
922 | printk(KERN_ERR "fujitsu-laptop: Could not register " | 922 | pr_err("Could not register LED handler for keyboard lamps, error %i\n", |
923 | "LED handler for keyboard lamps, error %i\n", result); | 923 | result); |
924 | } | 924 | } |
925 | } | 925 | } |
926 | #endif | 926 | #endif |
@@ -1169,8 +1169,7 @@ static int __init fujitsu_init(void) | |||
1169 | fujitsu->bl_device->props.power = 0; | 1169 | fujitsu->bl_device->props.power = 0; |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION | 1172 | pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); |
1173 | " successfully loaded.\n"); | ||
1174 | 1173 | ||
1175 | return 0; | 1174 | return 0; |
1176 | 1175 | ||
@@ -1216,7 +1215,7 @@ static void __exit fujitsu_cleanup(void) | |||
1216 | 1215 | ||
1217 | kfree(fujitsu); | 1216 | kfree(fujitsu); |
1218 | 1217 | ||
1219 | printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); | 1218 | pr_info("driver unloaded\n"); |
1220 | } | 1219 | } |
1221 | 1220 | ||
1222 | module_init(fujitsu_init); | 1221 | module_init(fujitsu_init); |
diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c index 067bf36d32f3..5a34973dc164 100644 --- a/drivers/platform/x86/hdaps.c +++ b/drivers/platform/x86/hdaps.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | 26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
30 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
31 | #include <linux/input-polldev.h> | 33 | #include <linux/input-polldev.h> |
@@ -238,7 +240,7 @@ static int hdaps_device_init(void) | |||
238 | __check_latch(0x1611, 0x01)) | 240 | __check_latch(0x1611, 0x01)) |
239 | goto out; | 241 | goto out; |
240 | 242 | ||
241 | printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x).\n", | 243 | printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x)\n", |
242 | __get_latch(0x1611)); | 244 | __get_latch(0x1611)); |
243 | 245 | ||
244 | outb(0x17, 0x1610); | 246 | outb(0x17, 0x1610); |
@@ -299,7 +301,7 @@ static int hdaps_probe(struct platform_device *dev) | |||
299 | if (ret) | 301 | if (ret) |
300 | return ret; | 302 | return ret; |
301 | 303 | ||
302 | printk(KERN_INFO "hdaps: device successfully initialized.\n"); | 304 | pr_info("device successfully initialized\n"); |
303 | return 0; | 305 | return 0; |
304 | } | 306 | } |
305 | 307 | ||
@@ -480,7 +482,7 @@ static struct attribute_group hdaps_attribute_group = { | |||
480 | /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ | 482 | /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ |
481 | static int __init hdaps_dmi_match(const struct dmi_system_id *id) | 483 | static int __init hdaps_dmi_match(const struct dmi_system_id *id) |
482 | { | 484 | { |
483 | printk(KERN_INFO "hdaps: %s detected.\n", id->ident); | 485 | pr_info("%s detected\n", id->ident); |
484 | return 1; | 486 | return 1; |
485 | } | 487 | } |
486 | 488 | ||
@@ -488,8 +490,7 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id) | |||
488 | static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) | 490 | static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) |
489 | { | 491 | { |
490 | hdaps_invert = (unsigned long)id->driver_data; | 492 | hdaps_invert = (unsigned long)id->driver_data; |
491 | printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n", | 493 | pr_info("inverting axis (%u) readings\n", hdaps_invert); |
492 | hdaps_invert); | ||
493 | return hdaps_dmi_match(id); | 494 | return hdaps_dmi_match(id); |
494 | } | 495 | } |
495 | 496 | ||
@@ -543,7 +544,7 @@ static int __init hdaps_init(void) | |||
543 | int ret; | 544 | int ret; |
544 | 545 | ||
545 | if (!dmi_check_system(hdaps_whitelist)) { | 546 | if (!dmi_check_system(hdaps_whitelist)) { |
546 | printk(KERN_WARNING "hdaps: supported laptop not found!\n"); | 547 | pr_warn("supported laptop not found!\n"); |
547 | ret = -ENODEV; | 548 | ret = -ENODEV; |
548 | goto out; | 549 | goto out; |
549 | } | 550 | } |
@@ -595,7 +596,7 @@ static int __init hdaps_init(void) | |||
595 | if (ret) | 596 | if (ret) |
596 | goto out_idev; | 597 | goto out_idev; |
597 | 598 | ||
598 | printk(KERN_INFO "hdaps: driver successfully loaded.\n"); | 599 | pr_info("driver successfully loaded\n"); |
599 | return 0; | 600 | return 0; |
600 | 601 | ||
601 | out_idev: | 602 | out_idev: |
@@ -609,7 +610,7 @@ out_driver: | |||
609 | out_region: | 610 | out_region: |
610 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); | 611 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); |
611 | out: | 612 | out: |
612 | printk(KERN_WARNING "hdaps: driver init failed (ret=%d)!\n", ret); | 613 | pr_warn("driver init failed (ret=%d)!\n", ret); |
613 | return ret; | 614 | return ret; |
614 | } | 615 | } |
615 | 616 | ||
@@ -622,7 +623,7 @@ static void __exit hdaps_exit(void) | |||
622 | platform_driver_unregister(&hdaps_driver); | 623 | platform_driver_unregister(&hdaps_driver); |
623 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); | 624 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); |
624 | 625 | ||
625 | printk(KERN_INFO "hdaps: driver unloaded.\n"); | 626 | pr_info("driver unloaded\n"); |
626 | } | 627 | } |
627 | 628 | ||
628 | module_init(hdaps_init); | 629 | module_init(hdaps_init); |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 1bc4a7539ba9..f94017bcdd6e 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -24,6 +24,8 @@ | |||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
28 | |||
27 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 30 | #include <linux/module.h> |
29 | #include <linux/init.h> | 31 | #include <linux/init.h> |
@@ -54,9 +56,6 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); | |||
54 | #define HPWMI_HOTKEY_QUERY 0xc | 56 | #define HPWMI_HOTKEY_QUERY 0xc |
55 | #define HPWMI_WIRELESS2_QUERY 0x1b | 57 | #define HPWMI_WIRELESS2_QUERY 0x1b |
56 | 58 | ||
57 | #define PREFIX "HP WMI: " | ||
58 | #define UNIMP "Unimplemented " | ||
59 | |||
60 | enum hp_wmi_radio { | 59 | enum hp_wmi_radio { |
61 | HPWMI_WIFI = 0, | 60 | HPWMI_WIFI = 0, |
62 | HPWMI_BLUETOOTH = 1, | 61 | HPWMI_BLUETOOTH = 1, |
@@ -228,9 +227,8 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, | |||
228 | 227 | ||
229 | if (bios_return->return_code) { | 228 | if (bios_return->return_code) { |
230 | if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) | 229 | if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) |
231 | printk(KERN_WARNING PREFIX "query 0x%x returned " | 230 | pr_warn("query 0x%x returned error 0x%x\n", |
232 | "error 0x%x\n", | 231 | query, bios_return->return_code); |
233 | query, bios_return->return_code); | ||
234 | kfree(obj); | 232 | kfree(obj); |
235 | return bios_return->return_code; | 233 | return bios_return->return_code; |
236 | } | 234 | } |
@@ -384,8 +382,7 @@ static int hp_wmi_rfkill2_refresh(void) | |||
384 | 382 | ||
385 | if (num >= state.count || | 383 | if (num >= state.count || |
386 | devstate->rfkill_id != rfkill2[i].id) { | 384 | devstate->rfkill_id != rfkill2[i].id) { |
387 | printk(KERN_WARNING PREFIX "power configuration of " | 385 | pr_warn("power configuration of the wireless devices unexpectedly changed\n"); |
388 | "the wireless devices unexpectedly changed\n"); | ||
389 | continue; | 386 | continue; |
390 | } | 387 | } |
391 | 388 | ||
@@ -471,7 +468,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
471 | 468 | ||
472 | status = wmi_get_event_data(value, &response); | 469 | status = wmi_get_event_data(value, &response); |
473 | if (status != AE_OK) { | 470 | if (status != AE_OK) { |
474 | printk(KERN_INFO PREFIX "bad event status 0x%x\n", status); | 471 | pr_info("bad event status 0x%x\n", status); |
475 | return; | 472 | return; |
476 | } | 473 | } |
477 | 474 | ||
@@ -480,8 +477,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
480 | if (!obj) | 477 | if (!obj) |
481 | return; | 478 | return; |
482 | if (obj->type != ACPI_TYPE_BUFFER) { | 479 | if (obj->type != ACPI_TYPE_BUFFER) { |
483 | printk(KERN_INFO "hp-wmi: Unknown response received %d\n", | 480 | pr_info("Unknown response received %d\n", obj->type); |
484 | obj->type); | ||
485 | kfree(obj); | 481 | kfree(obj); |
486 | return; | 482 | return; |
487 | } | 483 | } |
@@ -498,8 +494,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
498 | event_id = *location; | 494 | event_id = *location; |
499 | event_data = *(location + 2); | 495 | event_data = *(location + 2); |
500 | } else { | 496 | } else { |
501 | printk(KERN_INFO "hp-wmi: Unknown buffer length %d\n", | 497 | pr_info("Unknown buffer length %d\n", obj->buffer.length); |
502 | obj->buffer.length); | ||
503 | kfree(obj); | 498 | kfree(obj); |
504 | return; | 499 | return; |
505 | } | 500 | } |
@@ -527,8 +522,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
527 | 522 | ||
528 | if (!sparse_keymap_report_event(hp_wmi_input_dev, | 523 | if (!sparse_keymap_report_event(hp_wmi_input_dev, |
529 | key_code, 1, true)) | 524 | key_code, 1, true)) |
530 | printk(KERN_INFO PREFIX "Unknown key code - 0x%x\n", | 525 | pr_info("Unknown key code - 0x%x\n", key_code); |
531 | key_code); | ||
532 | break; | 526 | break; |
533 | case HPWMI_WIRELESS: | 527 | case HPWMI_WIRELESS: |
534 | if (rfkill2_count) { | 528 | if (rfkill2_count) { |
@@ -550,14 +544,12 @@ static void hp_wmi_notify(u32 value, void *context) | |||
550 | hp_wmi_get_hw_state(HPWMI_WWAN)); | 544 | hp_wmi_get_hw_state(HPWMI_WWAN)); |
551 | break; | 545 | break; |
552 | case HPWMI_CPU_BATTERY_THROTTLE: | 546 | case HPWMI_CPU_BATTERY_THROTTLE: |
553 | printk(KERN_INFO PREFIX UNIMP "CPU throttle because of 3 Cell" | 547 | pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n"); |
554 | " battery event detected\n"); | ||
555 | break; | 548 | break; |
556 | case HPWMI_LOCK_SWITCH: | 549 | case HPWMI_LOCK_SWITCH: |
557 | break; | 550 | break; |
558 | default: | 551 | default: |
559 | printk(KERN_INFO PREFIX "Unknown event_id - %d - 0x%x\n", | 552 | pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); |
560 | event_id, event_data); | ||
561 | break; | 553 | break; |
562 | } | 554 | } |
563 | } | 555 | } |
@@ -705,7 +697,7 @@ static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) | |||
705 | return err; | 697 | return err; |
706 | 698 | ||
707 | if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { | 699 | if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { |
708 | printk(KERN_WARNING PREFIX "unable to parse 0x1b query output\n"); | 700 | pr_warn("unable to parse 0x1b query output\n"); |
709 | return -EINVAL; | 701 | return -EINVAL; |
710 | } | 702 | } |
711 | 703 | ||
@@ -727,14 +719,14 @@ static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) | |||
727 | name = "hp-wwan"; | 719 | name = "hp-wwan"; |
728 | break; | 720 | break; |
729 | default: | 721 | default: |
730 | printk(KERN_WARNING PREFIX "unknown device type 0x%x\n", | 722 | pr_warn("unknown device type 0x%x\n", |
731 | state.device[i].radio_type); | 723 | state.device[i].radio_type); |
732 | continue; | 724 | continue; |
733 | } | 725 | } |
734 | 726 | ||
735 | if (!state.device[i].vendor_id) { | 727 | if (!state.device[i].vendor_id) { |
736 | printk(KERN_WARNING PREFIX "zero device %d while %d " | 728 | pr_warn("zero device %d while %d reported\n", |
737 | "reported\n", i, state.count); | 729 | i, state.count); |
738 | continue; | 730 | continue; |
739 | } | 731 | } |
740 | 732 | ||
@@ -755,8 +747,7 @@ static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) | |||
755 | IS_HWBLOCKED(state.device[i].power)); | 747 | IS_HWBLOCKED(state.device[i].power)); |
756 | 748 | ||
757 | if (!(state.device[i].power & HPWMI_POWER_BIOS)) | 749 | if (!(state.device[i].power & HPWMI_POWER_BIOS)) |
758 | printk(KERN_INFO PREFIX "device %s blocked by BIOS\n", | 750 | pr_info("device %s blocked by BIOS\n", name); |
759 | name); | ||
760 | 751 | ||
761 | err = rfkill_register(rfkill); | 752 | err = rfkill_register(rfkill); |
762 | if (err) { | 753 | if (err) { |
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index b1396e5b2953..811d436cd677 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
26 | |||
25 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
26 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -69,9 +71,10 @@ struct ibm_rtl_table { | |||
69 | #define RTL_SIGNATURE 0x0000005f4c54525fULL | 71 | #define RTL_SIGNATURE 0x0000005f4c54525fULL |
70 | #define RTL_MASK 0x000000ffffffffffULL | 72 | #define RTL_MASK 0x000000ffffffffffULL |
71 | 73 | ||
72 | #define RTL_DEBUG(A, ...) do { \ | 74 | #define RTL_DEBUG(fmt, ...) \ |
73 | if (debug) \ | 75 | do { \ |
74 | pr_info("ibm-rtl: " A, ##__VA_ARGS__ ); \ | 76 | if (debug) \ |
77 | pr_info(fmt, ##__VA_ARGS__); \ | ||
75 | } while (0) | 78 | } while (0) |
76 | 79 | ||
77 | static DEFINE_MUTEX(rtl_lock); | 80 | static DEFINE_MUTEX(rtl_lock); |
@@ -114,7 +117,7 @@ static int ibm_rtl_write(u8 value) | |||
114 | int ret = 0, count = 0; | 117 | int ret = 0, count = 0; |
115 | static u32 cmd_port_val; | 118 | static u32 cmd_port_val; |
116 | 119 | ||
117 | RTL_DEBUG("%s(%d)\n", __FUNCTION__, value); | 120 | RTL_DEBUG("%s(%d)\n", __func__, value); |
118 | 121 | ||
119 | value = value == 1 ? RTL_CMD_ENTER_PRTM : RTL_CMD_EXIT_PRTM; | 122 | value = value == 1 ? RTL_CMD_ENTER_PRTM : RTL_CMD_EXIT_PRTM; |
120 | 123 | ||
@@ -144,8 +147,8 @@ static int ibm_rtl_write(u8 value) | |||
144 | while (ioread8(&rtl_table->command)) { | 147 | while (ioread8(&rtl_table->command)) { |
145 | msleep(10); | 148 | msleep(10); |
146 | if (count++ > 500) { | 149 | if (count++ > 500) { |
147 | pr_err("ibm-rtl: Hardware not responding to " | 150 | pr_err("Hardware not responding to " |
148 | "mode switch request\n"); | 151 | "mode switch request\n"); |
149 | ret = -EIO; | 152 | ret = -EIO; |
150 | break; | 153 | break; |
151 | } | 154 | } |
@@ -250,7 +253,7 @@ static int __init ibm_rtl_init(void) { | |||
250 | int ret = -ENODEV, i; | 253 | int ret = -ENODEV, i; |
251 | 254 | ||
252 | if (force) | 255 | if (force) |
253 | pr_warning("ibm-rtl: module loaded by force\n"); | 256 | pr_warn("module loaded by force\n"); |
254 | /* first ensure that we are running on IBM HW */ | 257 | /* first ensure that we are running on IBM HW */ |
255 | else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) | 258 | else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) |
256 | return -ENODEV; | 259 | return -ENODEV; |
@@ -288,19 +291,19 @@ static int __init ibm_rtl_init(void) { | |||
288 | if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) { | 291 | if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) { |
289 | phys_addr_t addr; | 292 | phys_addr_t addr; |
290 | unsigned int plen; | 293 | unsigned int plen; |
291 | RTL_DEBUG("found RTL_SIGNATURE at %#llx\n", (u64)tmp); | 294 | RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp); |
292 | rtl_table = tmp; | 295 | rtl_table = tmp; |
293 | /* The address, value, width and offset are platform | 296 | /* The address, value, width and offset are platform |
294 | * dependent and found in the ibm_rtl_table */ | 297 | * dependent and found in the ibm_rtl_table */ |
295 | rtl_cmd_width = ioread8(&rtl_table->cmd_granularity); | 298 | rtl_cmd_width = ioread8(&rtl_table->cmd_granularity); |
296 | rtl_cmd_type = ioread8(&rtl_table->cmd_address_type); | 299 | rtl_cmd_type = ioread8(&rtl_table->cmd_address_type); |
297 | RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", | 300 | RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", |
298 | rtl_cmd_width, rtl_cmd_type); | 301 | rtl_cmd_width, rtl_cmd_type); |
299 | addr = ioread32(&rtl_table->cmd_port_address); | 302 | addr = ioread32(&rtl_table->cmd_port_address); |
300 | RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr); | 303 | RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr); |
301 | plen = rtl_cmd_width/sizeof(char); | 304 | plen = rtl_cmd_width/sizeof(char); |
302 | rtl_cmd_addr = rtl_port_map(addr, plen); | 305 | rtl_cmd_addr = rtl_port_map(addr, plen); |
303 | RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr); | 306 | RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr); |
304 | if (!rtl_cmd_addr) { | 307 | if (!rtl_cmd_addr) { |
305 | ret = -ENOMEM; | 308 | ret = -ENOMEM; |
306 | break; | 309 | break; |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 21b101899bae..bfdda33feb26 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -20,6 +20,8 @@ | |||
20 | * 02110-1301, USA. | 20 | * 02110-1301, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
25 | #include <linux/init.h> | 27 | #include <linux/init.h> |
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index eacd5da7dd24..809adea4965f 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * to get/set bandwidth. | 27 | * to get/set bandwidth. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
31 | |||
30 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 33 | #include <linux/module.h> |
32 | #include <linux/init.h> | 34 | #include <linux/init.h> |
@@ -135,8 +137,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
135 | acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list, | 137 | acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list, |
136 | &temp); | 138 | &temp); |
137 | 139 | ||
138 | printk(KERN_INFO | 140 | pr_info("Bandwidth value was %ld: status is %d\n", state, status); |
139 | "Bandwidth value was %ld: status is %d\n", state, status); | ||
140 | if (ACPI_FAILURE(status)) | 141 | if (ACPI_FAILURE(status)) |
141 | return -EFAULT; | 142 | return -EFAULT; |
142 | 143 | ||
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 213e79ba68d5..f1ae5078b7ec 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c | |||
@@ -23,58 +23,48 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
26 | |||
26 | #include <asm/intel_scu_ipc.h> | 27 | #include <asm/intel_scu_ipc.h> |
27 | 28 | ||
28 | #define DRIVER_NAME "msic_power_btn" | 29 | #define DRIVER_NAME "msic_power_btn" |
29 | 30 | ||
30 | #define MSIC_IRQ_STAT 0x02 | ||
31 | #define MSIC_IRQ_PB (1 << 0) | ||
32 | #define MSIC_PB_CONFIG 0x3e | ||
33 | #define MSIC_PB_STATUS 0x3f | 31 | #define MSIC_PB_STATUS 0x3f |
34 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ | 32 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ |
35 | |||
36 | struct mfld_pb_priv { | ||
37 | struct input_dev *input; | ||
38 | unsigned int irq; | ||
39 | }; | ||
40 | 33 | ||
41 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) | 34 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) |
42 | { | 35 | { |
43 | struct mfld_pb_priv *priv = dev_id; | 36 | struct input_dev *input = dev_id; |
44 | int ret; | 37 | int ret; |
45 | u8 pbstat; | 38 | u8 pbstat; |
46 | 39 | ||
47 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); | 40 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); |
48 | if (ret < 0) | 41 | if (ret < 0) { |
49 | return IRQ_HANDLED; | 42 | dev_err(input->dev.parent, "Read error %d while reading" |
50 | 43 | " MSIC_PB_STATUS\n", ret); | |
51 | input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL)); | 44 | } else { |
52 | input_sync(priv->input); | 45 | input_event(input, EV_KEY, KEY_POWER, |
46 | !(pbstat & MSIC_PB_LEVEL)); | ||
47 | input_sync(input); | ||
48 | } | ||
53 | 49 | ||
54 | return IRQ_HANDLED; | 50 | return IRQ_HANDLED; |
55 | } | 51 | } |
56 | 52 | ||
57 | static int __devinit mfld_pb_probe(struct platform_device *pdev) | 53 | static int __devinit mfld_pb_probe(struct platform_device *pdev) |
58 | { | 54 | { |
59 | struct mfld_pb_priv *priv; | ||
60 | struct input_dev *input; | 55 | struct input_dev *input; |
61 | int irq; | 56 | int irq = platform_get_irq(pdev, 0); |
62 | int error; | 57 | int error; |
63 | 58 | ||
64 | irq = platform_get_irq(pdev, 0); | ||
65 | if (irq < 0) | 59 | if (irq < 0) |
66 | return -EINVAL; | 60 | return -EINVAL; |
67 | 61 | ||
68 | priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL); | ||
69 | input = input_allocate_device(); | 62 | input = input_allocate_device(); |
70 | if (!priv || !input) { | 63 | if (!input) { |
71 | error = -ENOMEM; | 64 | dev_err(&pdev->dev, "Input device allocation error\n"); |
72 | goto err_free_mem; | 65 | return -ENOMEM; |
73 | } | 66 | } |
74 | 67 | ||
75 | priv->input = input; | ||
76 | priv->irq = irq; | ||
77 | |||
78 | input->name = pdev->name; | 68 | input->name = pdev->name; |
79 | input->phys = "power-button/input0"; | 69 | input->phys = "power-button/input0"; |
80 | input->id.bustype = BUS_HOST; | 70 | input->id.bustype = BUS_HOST; |
@@ -82,42 +72,40 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) | |||
82 | 72 | ||
83 | input_set_capability(input, EV_KEY, KEY_POWER); | 73 | input_set_capability(input, EV_KEY, KEY_POWER); |
84 | 74 | ||
85 | error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr, | 75 | error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, |
86 | 0, DRIVER_NAME, priv); | 76 | DRIVER_NAME, input); |
87 | if (error) { | 77 | if (error) { |
88 | dev_err(&pdev->dev, | 78 | dev_err(&pdev->dev, "Unable to request irq %d for mfld power" |
89 | "unable to request irq %d for mfld power button\n", | 79 | "button\n", irq); |
90 | irq); | 80 | goto err_free_input; |
91 | goto err_free_mem; | ||
92 | } | 81 | } |
93 | 82 | ||
94 | error = input_register_device(input); | 83 | error = input_register_device(input); |
95 | if (error) { | 84 | if (error) { |
96 | dev_err(&pdev->dev, | 85 | dev_err(&pdev->dev, "Unable to register input dev, error " |
97 | "unable to register input dev, error %d\n", error); | 86 | "%d\n", error); |
98 | goto err_free_irq; | 87 | goto err_free_irq; |
99 | } | 88 | } |
100 | 89 | ||
101 | platform_set_drvdata(pdev, priv); | 90 | platform_set_drvdata(pdev, input); |
102 | return 0; | 91 | return 0; |
103 | 92 | ||
104 | err_free_irq: | 93 | err_free_irq: |
105 | free_irq(priv->irq, priv); | 94 | free_irq(irq, input); |
106 | err_free_mem: | 95 | err_free_input: |
107 | input_free_device(input); | 96 | input_free_device(input); |
108 | kfree(priv); | ||
109 | return error; | 97 | return error; |
110 | } | 98 | } |
111 | 99 | ||
112 | static int __devexit mfld_pb_remove(struct platform_device *pdev) | 100 | static int __devexit mfld_pb_remove(struct platform_device *pdev) |
113 | { | 101 | { |
114 | struct mfld_pb_priv *priv = platform_get_drvdata(pdev); | 102 | struct input_dev *input = platform_get_drvdata(pdev); |
115 | 103 | int irq = platform_get_irq(pdev, 0); | |
116 | free_irq(priv->irq, priv); | ||
117 | input_unregister_device(priv->input); | ||
118 | kfree(priv); | ||
119 | 104 | ||
105 | free_irq(irq, input); | ||
106 | input_unregister_device(input); | ||
120 | platform_set_drvdata(pdev, NULL); | 107 | platform_set_drvdata(pdev, NULL); |
108 | |||
121 | return 0; | 109 | return 0; |
122 | } | 110 | } |
123 | 111 | ||
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index c2f4bd8013b5..3a578323122b 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c | |||
@@ -37,49 +37,50 @@ | |||
37 | #include <asm/intel_scu_ipc.h> | 37 | #include <asm/intel_scu_ipc.h> |
38 | 38 | ||
39 | /* Number of thermal sensors */ | 39 | /* Number of thermal sensors */ |
40 | #define MSIC_THERMAL_SENSORS 4 | 40 | #define MSIC_THERMAL_SENSORS 4 |
41 | 41 | ||
42 | /* ADC1 - thermal registers */ | 42 | /* ADC1 - thermal registers */ |
43 | #define MSIC_THERM_ADC1CNTL1 0x1C0 | 43 | #define MSIC_THERM_ADC1CNTL1 0x1C0 |
44 | #define MSIC_ADC_ENBL 0x10 | 44 | #define MSIC_ADC_ENBL 0x10 |
45 | #define MSIC_ADC_START 0x08 | 45 | #define MSIC_ADC_START 0x08 |
46 | 46 | ||
47 | #define MSIC_THERM_ADC1CNTL3 0x1C2 | 47 | #define MSIC_THERM_ADC1CNTL3 0x1C2 |
48 | #define MSIC_ADCTHERM_ENBL 0x04 | 48 | #define MSIC_ADCTHERM_ENBL 0x04 |
49 | #define MSIC_ADCRRDATA_ENBL 0x05 | 49 | #define MSIC_ADCRRDATA_ENBL 0x05 |
50 | #define MSIC_CHANL_MASK_VAL 0x0F | 50 | #define MSIC_CHANL_MASK_VAL 0x0F |
51 | 51 | ||
52 | #define MSIC_STOPBIT_MASK 16 | 52 | #define MSIC_STOPBIT_MASK 16 |
53 | #define MSIC_ADCTHERM_MASK 4 | 53 | #define MSIC_ADCTHERM_MASK 4 |
54 | #define ADC_CHANLS_MAX 15 /* Number of ADC channels */ | 54 | /* Number of ADC channels */ |
55 | #define ADC_LOOP_MAX (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS) | 55 | #define ADC_CHANLS_MAX 15 |
56 | #define ADC_LOOP_MAX (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS) | ||
56 | 57 | ||
57 | /* ADC channel code values */ | 58 | /* ADC channel code values */ |
58 | #define SKIN_SENSOR0_CODE 0x08 | 59 | #define SKIN_SENSOR0_CODE 0x08 |
59 | #define SKIN_SENSOR1_CODE 0x09 | 60 | #define SKIN_SENSOR1_CODE 0x09 |
60 | #define SYS_SENSOR_CODE 0x0A | 61 | #define SYS_SENSOR_CODE 0x0A |
61 | #define MSIC_DIE_SENSOR_CODE 0x03 | 62 | #define MSIC_DIE_SENSOR_CODE 0x03 |
62 | 63 | ||
63 | #define SKIN_THERM_SENSOR0 0 | 64 | #define SKIN_THERM_SENSOR0 0 |
64 | #define SKIN_THERM_SENSOR1 1 | 65 | #define SKIN_THERM_SENSOR1 1 |
65 | #define SYS_THERM_SENSOR2 2 | 66 | #define SYS_THERM_SENSOR2 2 |
66 | #define MSIC_DIE_THERM_SENSOR3 3 | 67 | #define MSIC_DIE_THERM_SENSOR3 3 |
67 | 68 | ||
68 | /* ADC code range */ | 69 | /* ADC code range */ |
69 | #define ADC_MAX 977 | 70 | #define ADC_MAX 977 |
70 | #define ADC_MIN 162 | 71 | #define ADC_MIN 162 |
71 | #define ADC_VAL0C 887 | 72 | #define ADC_VAL0C 887 |
72 | #define ADC_VAL20C 720 | 73 | #define ADC_VAL20C 720 |
73 | #define ADC_VAL40C 508 | 74 | #define ADC_VAL40C 508 |
74 | #define ADC_VAL60C 315 | 75 | #define ADC_VAL60C 315 |
75 | 76 | ||
76 | /* ADC base addresses */ | 77 | /* ADC base addresses */ |
77 | #define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ | 78 | #define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ |
78 | #define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ | 79 | #define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ |
79 | 80 | ||
80 | /* MSIC die attributes */ | 81 | /* MSIC die attributes */ |
81 | #define MSIC_DIE_ADC_MIN 488 | 82 | #define MSIC_DIE_ADC_MIN 488 |
82 | #define MSIC_DIE_ADC_MAX 1004 | 83 | #define MSIC_DIE_ADC_MAX 1004 |
83 | 84 | ||
84 | /* This holds the address of the first free ADC channel, | 85 | /* This holds the address of the first free ADC channel, |
85 | * among the 15 channels | 86 | * among the 15 channels |
@@ -87,15 +88,15 @@ | |||
87 | static int channel_index; | 88 | static int channel_index; |
88 | 89 | ||
89 | struct platform_info { | 90 | struct platform_info { |
90 | struct platform_device *pdev; | 91 | struct platform_device *pdev; |
91 | struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS]; | 92 | struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS]; |
92 | }; | 93 | }; |
93 | 94 | ||
94 | struct thermal_device_info { | 95 | struct thermal_device_info { |
95 | unsigned int chnl_addr; | 96 | unsigned int chnl_addr; |
96 | int direct; | 97 | int direct; |
97 | /* This holds the current temperature in millidegree celsius */ | 98 | /* This holds the current temperature in millidegree celsius */ |
98 | long curr_temp; | 99 | long curr_temp; |
99 | }; | 100 | }; |
100 | 101 | ||
101 | /** | 102 | /** |
@@ -106,7 +107,7 @@ struct thermal_device_info { | |||
106 | */ | 107 | */ |
107 | static int to_msic_die_temp(uint16_t adc_val) | 108 | static int to_msic_die_temp(uint16_t adc_val) |
108 | { | 109 | { |
109 | return (368 * (adc_val) / 1000) - 220; | 110 | return (368 * (adc_val) / 1000) - 220; |
110 | } | 111 | } |
111 | 112 | ||
112 | /** | 113 | /** |
@@ -118,7 +119,7 @@ static int to_msic_die_temp(uint16_t adc_val) | |||
118 | */ | 119 | */ |
119 | static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) | 120 | static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) |
120 | { | 121 | { |
121 | return (adc_val >= min) && (adc_val <= max); | 122 | return (adc_val >= min) && (adc_val <= max); |
122 | } | 123 | } |
123 | 124 | ||
124 | /** | 125 | /** |
@@ -136,35 +137,35 @@ static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) | |||
136 | */ | 137 | */ |
137 | static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) | 138 | static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) |
138 | { | 139 | { |
139 | int temp; | 140 | int temp; |
140 | 141 | ||
141 | /* Direct conversion for die temperature */ | 142 | /* Direct conversion for die temperature */ |
142 | if (direct) { | 143 | if (direct) { |
143 | if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) { | 144 | if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) { |
144 | *tp = to_msic_die_temp(adc_val) * 1000; | 145 | *tp = to_msic_die_temp(adc_val) * 1000; |
145 | return 0; | 146 | return 0; |
146 | } | 147 | } |
147 | return -ERANGE; | 148 | return -ERANGE; |
148 | } | 149 | } |
149 | 150 | ||
150 | if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX)) | 151 | if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX)) |
151 | return -ERANGE; | 152 | return -ERANGE; |
152 | 153 | ||
153 | /* Linear approximation for skin temperature */ | 154 | /* Linear approximation for skin temperature */ |
154 | if (adc_val > ADC_VAL0C) | 155 | if (adc_val > ADC_VAL0C) |
155 | temp = 177 - (adc_val/5); | 156 | temp = 177 - (adc_val/5); |
156 | else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C)) | 157 | else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C)) |
157 | temp = 111 - (adc_val/8); | 158 | temp = 111 - (adc_val/8); |
158 | else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C)) | 159 | else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C)) |
159 | temp = 92 - (adc_val/10); | 160 | temp = 92 - (adc_val/10); |
160 | else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C)) | 161 | else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C)) |
161 | temp = 91 - (adc_val/10); | 162 | temp = 91 - (adc_val/10); |
162 | else | 163 | else |
163 | temp = 112 - (adc_val/6); | 164 | temp = 112 - (adc_val/6); |
164 | 165 | ||
165 | /* Convert temperature in celsius to milli degree celsius */ | 166 | /* Convert temperature in celsius to milli degree celsius */ |
166 | *tp = temp * 1000; | 167 | *tp = temp * 1000; |
167 | return 0; | 168 | return 0; |
168 | } | 169 | } |
169 | 170 | ||
170 | /** | 171 | /** |
@@ -178,47 +179,47 @@ static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) | |||
178 | */ | 179 | */ |
179 | static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) | 180 | static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) |
180 | { | 181 | { |
181 | struct thermal_device_info *td_info = tzd->devdata; | 182 | struct thermal_device_info *td_info = tzd->devdata; |
182 | uint16_t adc_val, addr; | 183 | uint16_t adc_val, addr; |
183 | uint8_t data = 0; | 184 | uint8_t data = 0; |
184 | int ret; | 185 | int ret; |
185 | unsigned long curr_temp; | 186 | unsigned long curr_temp; |
186 | 187 | ||
187 | 188 | ||
188 | addr = td_info->chnl_addr; | 189 | addr = td_info->chnl_addr; |
189 | 190 | ||
190 | /* Enable the msic for conversion before reading */ | 191 | /* Enable the msic for conversion before reading */ |
191 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL); | 192 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL); |
192 | if (ret) | 193 | if (ret) |
193 | return ret; | 194 | return ret; |
194 | 195 | ||
195 | /* Re-toggle the RRDATARD bit (temporary workaround) */ | 196 | /* Re-toggle the RRDATARD bit (temporary workaround) */ |
196 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL); | 197 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL); |
197 | if (ret) | 198 | if (ret) |
198 | return ret; | 199 | return ret; |
199 | 200 | ||
200 | /* Read the higher bits of data */ | 201 | /* Read the higher bits of data */ |
201 | ret = intel_scu_ipc_ioread8(addr, &data); | 202 | ret = intel_scu_ipc_ioread8(addr, &data); |
202 | if (ret) | 203 | if (ret) |
203 | return ret; | 204 | return ret; |
204 | 205 | ||
205 | /* Shift bits to accommodate the lower two data bits */ | 206 | /* Shift bits to accommodate the lower two data bits */ |
206 | adc_val = (data << 2); | 207 | adc_val = (data << 2); |
207 | addr++; | 208 | addr++; |
208 | 209 | ||
209 | ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */ | 210 | ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */ |
210 | if (ret) | 211 | if (ret) |
211 | return ret; | 212 | return ret; |
212 | 213 | ||
213 | /* Adding lower two bits to the higher bits */ | 214 | /* Adding lower two bits to the higher bits */ |
214 | data &= 03; | 215 | data &= 03; |
215 | adc_val += data; | 216 | adc_val += data; |
216 | 217 | ||
217 | /* Convert ADC value to temperature */ | 218 | /* Convert ADC value to temperature */ |
218 | ret = adc_to_temp(td_info->direct, adc_val, &curr_temp); | 219 | ret = adc_to_temp(td_info->direct, adc_val, &curr_temp); |
219 | if (ret == 0) | 220 | if (ret == 0) |
220 | *temp = td_info->curr_temp = curr_temp; | 221 | *temp = td_info->curr_temp = curr_temp; |
221 | return ret; | 222 | return ret; |
222 | } | 223 | } |
223 | 224 | ||
224 | /** | 225 | /** |
@@ -231,22 +232,21 @@ static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) | |||
231 | */ | 232 | */ |
232 | static int configure_adc(int val) | 233 | static int configure_adc(int val) |
233 | { | 234 | { |
234 | int ret; | 235 | int ret; |
235 | uint8_t data; | 236 | uint8_t data; |
236 | 237 | ||
237 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); | 238 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); |
238 | if (ret) | 239 | if (ret) |
239 | return ret; | 240 | return ret; |
240 | 241 | ||
241 | if (val) { | 242 | if (val) { |
242 | /* Enable and start the ADC */ | 243 | /* Enable and start the ADC */ |
243 | data |= (MSIC_ADC_ENBL | MSIC_ADC_START); | 244 | data |= (MSIC_ADC_ENBL | MSIC_ADC_START); |
244 | } else { | 245 | } else { |
245 | /* Just stop the ADC */ | 246 | /* Just stop the ADC */ |
246 | data &= (~MSIC_ADC_START); | 247 | data &= (~MSIC_ADC_START); |
247 | } | 248 | } |
248 | 249 | return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data); | |
249 | return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data); | ||
250 | } | 250 | } |
251 | 251 | ||
252 | /** | 252 | /** |
@@ -259,30 +259,30 @@ static int configure_adc(int val) | |||
259 | */ | 259 | */ |
260 | static int set_up_therm_channel(u16 base_addr) | 260 | static int set_up_therm_channel(u16 base_addr) |
261 | { | 261 | { |
262 | int ret; | 262 | int ret; |
263 | 263 | ||
264 | /* Enable all the sensor channels */ | 264 | /* Enable all the sensor channels */ |
265 | ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE); | 265 | ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE); |
266 | if (ret) | 266 | if (ret) |
267 | return ret; | 267 | return ret; |
268 | 268 | ||
269 | ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE); | 269 | ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE); |
270 | if (ret) | 270 | if (ret) |
271 | return ret; | 271 | return ret; |
272 | 272 | ||
273 | ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE); | 273 | ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE); |
274 | if (ret) | 274 | if (ret) |
275 | return ret; | 275 | return ret; |
276 | 276 | ||
277 | /* Since this is the last channel, set the stop bit | 277 | /* Since this is the last channel, set the stop bit |
278 | to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ | 278 | * to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ |
279 | ret = intel_scu_ipc_iowrite8(base_addr + 3, | 279 | ret = intel_scu_ipc_iowrite8(base_addr + 3, |
280 | (MSIC_DIE_SENSOR_CODE | 0x10)); | 280 | (MSIC_DIE_SENSOR_CODE | 0x10)); |
281 | if (ret) | 281 | if (ret) |
282 | return ret; | 282 | return ret; |
283 | 283 | ||
284 | /* Enable ADC and start it */ | 284 | /* Enable ADC and start it */ |
285 | return configure_adc(1); | 285 | return configure_adc(1); |
286 | } | 286 | } |
287 | 287 | ||
288 | /** | 288 | /** |
@@ -293,13 +293,13 @@ static int set_up_therm_channel(u16 base_addr) | |||
293 | */ | 293 | */ |
294 | static int reset_stopbit(uint16_t addr) | 294 | static int reset_stopbit(uint16_t addr) |
295 | { | 295 | { |
296 | int ret; | 296 | int ret; |
297 | uint8_t data; | 297 | uint8_t data; |
298 | ret = intel_scu_ipc_ioread8(addr, &data); | 298 | ret = intel_scu_ipc_ioread8(addr, &data); |
299 | if (ret) | 299 | if (ret) |
300 | return ret; | 300 | return ret; |
301 | /* Set the stop bit to zero */ | 301 | /* Set the stop bit to zero */ |
302 | return intel_scu_ipc_iowrite8(addr, (data & 0xEF)); | 302 | return intel_scu_ipc_iowrite8(addr, (data & 0xEF)); |
303 | } | 303 | } |
304 | 304 | ||
305 | /** | 305 | /** |
@@ -317,30 +317,30 @@ static int reset_stopbit(uint16_t addr) | |||
317 | */ | 317 | */ |
318 | static int find_free_channel(void) | 318 | static int find_free_channel(void) |
319 | { | 319 | { |
320 | int ret; | 320 | int ret; |
321 | int i; | 321 | int i; |
322 | uint8_t data; | 322 | uint8_t data; |
323 | 323 | ||
324 | /* check whether ADC is enabled */ | 324 | /* check whether ADC is enabled */ |
325 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); | 325 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); |
326 | if (ret) | 326 | if (ret) |
327 | return ret; | 327 | return ret; |
328 | 328 | ||
329 | if ((data & MSIC_ADC_ENBL) == 0) | 329 | if ((data & MSIC_ADC_ENBL) == 0) |
330 | return 0; | 330 | return 0; |
331 | 331 | ||
332 | /* ADC is already enabled; Looking for an empty channel */ | 332 | /* ADC is already enabled; Looking for an empty channel */ |
333 | for (i = 0; i < ADC_CHANLS_MAX; i++) { | 333 | for (i = 0; i < ADC_CHANLS_MAX; i++) { |
334 | ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data); | 334 | ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data); |
335 | if (ret) | 335 | if (ret) |
336 | return ret; | 336 | return ret; |
337 | 337 | ||
338 | if (data & MSIC_STOPBIT_MASK) { | 338 | if (data & MSIC_STOPBIT_MASK) { |
339 | ret = i; | 339 | ret = i; |
340 | break; | 340 | break; |
341 | } | 341 | } |
342 | } | 342 | } |
343 | return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret; | 343 | return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret; |
344 | } | 344 | } |
345 | 345 | ||
346 | /** | 346 | /** |
@@ -351,48 +351,48 @@ static int find_free_channel(void) | |||
351 | */ | 351 | */ |
352 | static int mid_initialize_adc(struct device *dev) | 352 | static int mid_initialize_adc(struct device *dev) |
353 | { | 353 | { |
354 | u8 data; | 354 | u8 data; |
355 | u16 base_addr; | 355 | u16 base_addr; |
356 | int ret; | 356 | int ret; |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * Ensure that adctherm is disabled before we | 359 | * Ensure that adctherm is disabled before we |
360 | * initialize the ADC | 360 | * initialize the ADC |
361 | */ | 361 | */ |
362 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data); | 362 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data); |
363 | if (ret) | 363 | if (ret) |
364 | return ret; | 364 | return ret; |
365 | 365 | ||
366 | if (data & MSIC_ADCTHERM_MASK) | 366 | if (data & MSIC_ADCTHERM_MASK) |
367 | dev_warn(dev, "ADCTHERM already set"); | 367 | dev_warn(dev, "ADCTHERM already set"); |
368 | 368 | ||
369 | /* Index of the first channel in which the stop bit is set */ | 369 | /* Index of the first channel in which the stop bit is set */ |
370 | channel_index = find_free_channel(); | 370 | channel_index = find_free_channel(); |
371 | if (channel_index < 0) { | 371 | if (channel_index < 0) { |
372 | dev_err(dev, "No free ADC channels"); | 372 | dev_err(dev, "No free ADC channels"); |
373 | return channel_index; | 373 | return channel_index; |
374 | } | 374 | } |
375 | 375 | ||
376 | base_addr = ADC_CHNL_START_ADDR + channel_index; | 376 | base_addr = ADC_CHNL_START_ADDR + channel_index; |
377 | 377 | ||
378 | if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) { | 378 | if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) { |
379 | /* Reset stop bit for channels other than 0 and 12 */ | 379 | /* Reset stop bit for channels other than 0 and 12 */ |
380 | ret = reset_stopbit(base_addr); | 380 | ret = reset_stopbit(base_addr); |
381 | if (ret) | 381 | if (ret) |
382 | return ret; | 382 | return ret; |
383 | 383 | ||
384 | /* Index of the first free channel */ | 384 | /* Index of the first free channel */ |
385 | base_addr++; | 385 | base_addr++; |
386 | channel_index++; | 386 | channel_index++; |
387 | } | 387 | } |
388 | 388 | ||
389 | ret = set_up_therm_channel(base_addr); | 389 | ret = set_up_therm_channel(base_addr); |
390 | if (ret) { | 390 | if (ret) { |
391 | dev_err(dev, "unable to enable ADC"); | 391 | dev_err(dev, "unable to enable ADC"); |
392 | return ret; | 392 | return ret; |
393 | } | 393 | } |
394 | dev_dbg(dev, "ADC initialization successful"); | 394 | dev_dbg(dev, "ADC initialization successful"); |
395 | return ret; | 395 | return ret; |
396 | } | 396 | } |
397 | 397 | ||
398 | /** | 398 | /** |
@@ -403,18 +403,18 @@ static int mid_initialize_adc(struct device *dev) | |||
403 | */ | 403 | */ |
404 | static struct thermal_device_info *initialize_sensor(int index) | 404 | static struct thermal_device_info *initialize_sensor(int index) |
405 | { | 405 | { |
406 | struct thermal_device_info *td_info = | 406 | struct thermal_device_info *td_info = |
407 | kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL); | 407 | kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL); |
408 | 408 | ||
409 | if (!td_info) | 409 | if (!td_info) |
410 | return NULL; | 410 | return NULL; |
411 | 411 | ||
412 | /* Set the base addr of the channel for this sensor */ | 412 | /* Set the base addr of the channel for this sensor */ |
413 | td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index); | 413 | td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index); |
414 | /* Sensor 3 is direct conversion */ | 414 | /* Sensor 3 is direct conversion */ |
415 | if (index == 3) | 415 | if (index == 3) |
416 | td_info->direct = 1; | 416 | td_info->direct = 1; |
417 | return td_info; | 417 | return td_info; |
418 | } | 418 | } |
419 | 419 | ||
420 | /** | 420 | /** |
@@ -425,7 +425,7 @@ static struct thermal_device_info *initialize_sensor(int index) | |||
425 | */ | 425 | */ |
426 | static int mid_thermal_resume(struct platform_device *pdev) | 426 | static int mid_thermal_resume(struct platform_device *pdev) |
427 | { | 427 | { |
428 | return mid_initialize_adc(&pdev->dev); | 428 | return mid_initialize_adc(&pdev->dev); |
429 | } | 429 | } |
430 | 430 | ||
431 | /** | 431 | /** |
@@ -437,12 +437,12 @@ static int mid_thermal_resume(struct platform_device *pdev) | |||
437 | */ | 437 | */ |
438 | static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) | 438 | static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) |
439 | { | 439 | { |
440 | /* | 440 | /* |
441 | * This just stops the ADC and does not disable it. | 441 | * This just stops the ADC and does not disable it. |
442 | * temporary workaround until we have a generic ADC driver. | 442 | * temporary workaround until we have a generic ADC driver. |
443 | * If 0 is passed, it disables the ADC. | 443 | * If 0 is passed, it disables the ADC. |
444 | */ | 444 | */ |
445 | return configure_adc(0); | 445 | return configure_adc(0); |
446 | } | 446 | } |
447 | 447 | ||
448 | /** | 448 | /** |
@@ -453,16 +453,15 @@ static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
453 | */ | 453 | */ |
454 | static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) | 454 | static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) |
455 | { | 455 | { |
456 | WARN_ON(tzd == NULL); | 456 | WARN_ON(tzd == NULL); |
457 | return mid_read_temp(tzd, temp); | 457 | return mid_read_temp(tzd, temp); |
458 | } | 458 | } |
459 | 459 | ||
460 | /* Can't be const */ | 460 | /* Can't be const */ |
461 | static struct thermal_zone_device_ops tzd_ops = { | 461 | static struct thermal_zone_device_ops tzd_ops = { |
462 | .get_temp = read_curr_temp, | 462 | .get_temp = read_curr_temp, |
463 | }; | 463 | }; |
464 | 464 | ||
465 | |||
466 | /** | 465 | /** |
467 | * mid_thermal_probe - mfld thermal initialize | 466 | * mid_thermal_probe - mfld thermal initialize |
468 | * @pdev: platform device structure | 467 | * @pdev: platform device structure |
@@ -472,46 +471,45 @@ static struct thermal_zone_device_ops tzd_ops = { | |||
472 | */ | 471 | */ |
473 | static int mid_thermal_probe(struct platform_device *pdev) | 472 | static int mid_thermal_probe(struct platform_device *pdev) |
474 | { | 473 | { |
475 | static char *name[MSIC_THERMAL_SENSORS] = { | 474 | static char *name[MSIC_THERMAL_SENSORS] = { |
476 | "skin0", "skin1", "sys", "msicdie" | 475 | "skin0", "skin1", "sys", "msicdie" |
477 | }; | 476 | }; |
478 | 477 | ||
479 | int ret; | 478 | int ret; |
480 | int i; | 479 | int i; |
481 | struct platform_info *pinfo; | 480 | struct platform_info *pinfo; |
482 | 481 | ||
483 | pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL); | 482 | pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL); |
484 | if (!pinfo) | 483 | if (!pinfo) |
485 | return -ENOMEM; | 484 | return -ENOMEM; |
486 | 485 | ||
487 | /* Initializing the hardware */ | 486 | /* Initializing the hardware */ |
488 | ret = mid_initialize_adc(&pdev->dev); | 487 | ret = mid_initialize_adc(&pdev->dev); |
489 | if (ret) { | 488 | if (ret) { |
490 | dev_err(&pdev->dev, "ADC init failed"); | 489 | dev_err(&pdev->dev, "ADC init failed"); |
491 | kfree(pinfo); | 490 | kfree(pinfo); |
492 | return ret; | 491 | return ret; |
493 | } | 492 | } |
494 | 493 | ||
495 | /* Register each sensor with the generic thermal framework*/ | 494 | /* Register each sensor with the generic thermal framework*/ |
496 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { | 495 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { |
497 | pinfo->tzd[i] = thermal_zone_device_register(name[i], | 496 | pinfo->tzd[i] = thermal_zone_device_register(name[i], |
498 | 0, initialize_sensor(i), | 497 | 0, initialize_sensor(i), &tzd_ops, 0, 0, 0, 0); |
499 | &tzd_ops, 0, 0, 0, 0); | 498 | if (IS_ERR(pinfo->tzd[i])) |
500 | if (IS_ERR(pinfo->tzd[i])) | 499 | goto reg_fail; |
501 | goto reg_fail; | 500 | } |
502 | } | 501 | |
503 | 502 | pinfo->pdev = pdev; | |
504 | pinfo->pdev = pdev; | 503 | platform_set_drvdata(pdev, pinfo); |
505 | platform_set_drvdata(pdev, pinfo); | 504 | return 0; |
506 | return 0; | ||
507 | 505 | ||
508 | reg_fail: | 506 | reg_fail: |
509 | ret = PTR_ERR(pinfo->tzd[i]); | 507 | ret = PTR_ERR(pinfo->tzd[i]); |
510 | while (--i >= 0) | 508 | while (--i >= 0) |
511 | thermal_zone_device_unregister(pinfo->tzd[i]); | 509 | thermal_zone_device_unregister(pinfo->tzd[i]); |
512 | configure_adc(0); | 510 | configure_adc(0); |
513 | kfree(pinfo); | 511 | kfree(pinfo); |
514 | return ret; | 512 | return ret; |
515 | } | 513 | } |
516 | 514 | ||
517 | /** | 515 | /** |
@@ -523,49 +521,46 @@ reg_fail: | |||
523 | */ | 521 | */ |
524 | static int mid_thermal_remove(struct platform_device *pdev) | 522 | static int mid_thermal_remove(struct platform_device *pdev) |
525 | { | 523 | { |
526 | int i; | 524 | int i; |
527 | struct platform_info *pinfo = platform_get_drvdata(pdev); | 525 | struct platform_info *pinfo = platform_get_drvdata(pdev); |
528 | 526 | ||
529 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) | 527 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) |
530 | thermal_zone_device_unregister(pinfo->tzd[i]); | 528 | thermal_zone_device_unregister(pinfo->tzd[i]); |
531 | 529 | ||
532 | platform_set_drvdata(pdev, NULL); | 530 | kfree(pinfo); |
531 | platform_set_drvdata(pdev, NULL); | ||
533 | 532 | ||
534 | /* Stop the ADC */ | 533 | /* Stop the ADC */ |
535 | return configure_adc(0); | 534 | return configure_adc(0); |
536 | } | 535 | } |
537 | 536 | ||
538 | /********************************************************************* | ||
539 | * Driver initialisation and finalization | ||
540 | *********************************************************************/ | ||
541 | |||
542 | #define DRIVER_NAME "msic_sensor" | 537 | #define DRIVER_NAME "msic_sensor" |
543 | 538 | ||
544 | static const struct platform_device_id therm_id_table[] = { | 539 | static const struct platform_device_id therm_id_table[] = { |
545 | { DRIVER_NAME, 1 }, | 540 | { DRIVER_NAME, 1 }, |
546 | { } | 541 | { } |
547 | }; | 542 | }; |
548 | 543 | ||
549 | static struct platform_driver mid_thermal_driver = { | 544 | static struct platform_driver mid_thermal_driver = { |
550 | .driver = { | 545 | .driver = { |
551 | .name = DRIVER_NAME, | 546 | .name = DRIVER_NAME, |
552 | .owner = THIS_MODULE, | 547 | .owner = THIS_MODULE, |
553 | }, | 548 | }, |
554 | .probe = mid_thermal_probe, | 549 | .probe = mid_thermal_probe, |
555 | .suspend = mid_thermal_suspend, | 550 | .suspend = mid_thermal_suspend, |
556 | .resume = mid_thermal_resume, | 551 | .resume = mid_thermal_resume, |
557 | .remove = __devexit_p(mid_thermal_remove), | 552 | .remove = __devexit_p(mid_thermal_remove), |
558 | .id_table = therm_id_table, | 553 | .id_table = therm_id_table, |
559 | }; | 554 | }; |
560 | 555 | ||
561 | static int __init mid_thermal_module_init(void) | 556 | static int __init mid_thermal_module_init(void) |
562 | { | 557 | { |
563 | return platform_driver_register(&mid_thermal_driver); | 558 | return platform_driver_register(&mid_thermal_driver); |
564 | } | 559 | } |
565 | 560 | ||
566 | static void __exit mid_thermal_module_exit(void) | 561 | static void __exit mid_thermal_module_exit(void) |
567 | { | 562 | { |
568 | platform_driver_unregister(&mid_thermal_driver); | 563 | platform_driver_unregister(&mid_thermal_driver); |
569 | } | 564 | } |
570 | 565 | ||
571 | module_init(mid_thermal_module_init); | 566 | module_init(mid_thermal_module_init); |
diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c new file mode 100644 index 000000000000..e936364a609d --- /dev/null +++ b/drivers/platform/x86/intel_oaktrail.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | * intel_oaktrail.c - Intel OakTrail Platform support. | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Intel Corporation | ||
5 | * Author: Yin Kangkai (kangkai.yin@intel.com) | ||
6 | * | ||
7 | * based on Compal driver, Copyright (C) 2008 Cezary Jackiewicz | ||
8 | * <cezary.jackiewicz (at) gmail.com>, based on MSI driver | ||
9 | * Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but | ||
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
24 | * 02110-1301, USA. | ||
25 | * | ||
26 | * This driver does below things: | ||
27 | * 1. registers itself in the Linux backlight control in | ||
28 | * /sys/class/backlight/intel_oaktrail/ | ||
29 | * | ||
30 | * 2. registers in the rfkill subsystem here: /sys/class/rfkill/rfkillX/ | ||
31 | * for these components: wifi, bluetooth, wwan (3g), gps | ||
32 | * | ||
33 | * This driver might work on other products based on Oaktrail. If you | ||
34 | * want to try it you can pass force=1 as argument to the module which | ||
35 | * will force it to load even when the DMI data doesn't identify the | ||
36 | * product as compatible. | ||
37 | */ | ||
38 | |||
39 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
40 | |||
41 | #include <linux/module.h> | ||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/acpi.h> | ||
45 | #include <linux/fb.h> | ||
46 | #include <linux/mutex.h> | ||
47 | #include <linux/err.h> | ||
48 | #include <linux/i2c.h> | ||
49 | #include <linux/backlight.h> | ||
50 | #include <linux/platform_device.h> | ||
51 | #include <linux/dmi.h> | ||
52 | #include <linux/rfkill.h> | ||
53 | #include <acpi/acpi_bus.h> | ||
54 | #include <acpi/acpi_drivers.h> | ||
55 | |||
56 | |||
57 | #define DRIVER_NAME "intel_oaktrail" | ||
58 | #define DRIVER_VERSION "0.4ac1" | ||
59 | |||
60 | /* | ||
61 | * This is the devices status address in EC space, and the control bits | ||
62 | * definition: | ||
63 | * | ||
64 | * (1 << 0): Camera enable/disable, RW. | ||
65 | * (1 << 1): Bluetooth enable/disable, RW. | ||
66 | * (1 << 2): GPS enable/disable, RW. | ||
67 | * (1 << 3): WiFi enable/disable, RW. | ||
68 | * (1 << 4): WWAN (3G) enable/disalbe, RW. | ||
69 | * (1 << 5): Touchscreen enable/disable, Read Only. | ||
70 | */ | ||
71 | #define OT_EC_DEVICE_STATE_ADDRESS 0xD6 | ||
72 | |||
73 | #define OT_EC_CAMERA_MASK (1 << 0) | ||
74 | #define OT_EC_BT_MASK (1 << 1) | ||
75 | #define OT_EC_GPS_MASK (1 << 2) | ||
76 | #define OT_EC_WIFI_MASK (1 << 3) | ||
77 | #define OT_EC_WWAN_MASK (1 << 4) | ||
78 | #define OT_EC_TS_MASK (1 << 5) | ||
79 | |||
80 | /* | ||
81 | * This is the address in EC space and commands used to control LCD backlight: | ||
82 | * | ||
83 | * Two steps needed to change the LCD backlight: | ||
84 | * 1. write the backlight percentage into OT_EC_BL_BRIGHTNESS_ADDRESS; | ||
85 | * 2. write OT_EC_BL_CONTROL_ON_DATA into OT_EC_BL_CONTROL_ADDRESS. | ||
86 | * | ||
87 | * To read the LCD back light, just read out the value from | ||
88 | * OT_EC_BL_BRIGHTNESS_ADDRESS. | ||
89 | * | ||
90 | * LCD backlight brightness range: 0 - 100 (OT_EC_BL_BRIGHTNESS_MAX) | ||
91 | */ | ||
92 | #define OT_EC_BL_BRIGHTNESS_ADDRESS 0x44 | ||
93 | #define OT_EC_BL_BRIGHTNESS_MAX 100 | ||
94 | #define OT_EC_BL_CONTROL_ADDRESS 0x3A | ||
95 | #define OT_EC_BL_CONTROL_ON_DATA 0x1A | ||
96 | |||
97 | |||
98 | static int force; | ||
99 | module_param(force, bool, 0); | ||
100 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | ||
101 | |||
102 | static struct platform_device *oaktrail_device; | ||
103 | static struct backlight_device *oaktrail_bl_device; | ||
104 | static struct rfkill *bt_rfkill; | ||
105 | static struct rfkill *gps_rfkill; | ||
106 | static struct rfkill *wifi_rfkill; | ||
107 | static struct rfkill *wwan_rfkill; | ||
108 | |||
109 | |||
110 | /* rfkill */ | ||
111 | static int oaktrail_rfkill_set(void *data, bool blocked) | ||
112 | { | ||
113 | u8 value; | ||
114 | u8 result; | ||
115 | unsigned long radio = (unsigned long) data; | ||
116 | |||
117 | ec_read(OT_EC_DEVICE_STATE_ADDRESS, &result); | ||
118 | |||
119 | if (!blocked) | ||
120 | value = (u8) (result | radio); | ||
121 | else | ||
122 | value = (u8) (result & ~radio); | ||
123 | |||
124 | ec_write(OT_EC_DEVICE_STATE_ADDRESS, value); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static const struct rfkill_ops oaktrail_rfkill_ops = { | ||
130 | .set_block = oaktrail_rfkill_set, | ||
131 | }; | ||
132 | |||
133 | static struct rfkill *oaktrail_rfkill_new(char *name, enum rfkill_type type, | ||
134 | unsigned long mask) | ||
135 | { | ||
136 | struct rfkill *rfkill_dev; | ||
137 | u8 value; | ||
138 | int err; | ||
139 | |||
140 | rfkill_dev = rfkill_alloc(name, &oaktrail_device->dev, type, | ||
141 | &oaktrail_rfkill_ops, (void *)mask); | ||
142 | if (!rfkill_dev) | ||
143 | return ERR_PTR(-ENOMEM); | ||
144 | |||
145 | ec_read(OT_EC_DEVICE_STATE_ADDRESS, &value); | ||
146 | rfkill_init_sw_state(rfkill_dev, (value & mask) != 1); | ||
147 | |||
148 | err = rfkill_register(rfkill_dev); | ||
149 | if (err) { | ||
150 | rfkill_destroy(rfkill_dev); | ||
151 | return ERR_PTR(err); | ||
152 | } | ||
153 | |||
154 | return rfkill_dev; | ||
155 | } | ||
156 | |||
157 | static inline void __oaktrail_rfkill_cleanup(struct rfkill *rf) | ||
158 | { | ||
159 | if (rf) { | ||
160 | rfkill_unregister(rf); | ||
161 | rfkill_destroy(rf); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static void oaktrail_rfkill_cleanup(void) | ||
166 | { | ||
167 | __oaktrail_rfkill_cleanup(wifi_rfkill); | ||
168 | __oaktrail_rfkill_cleanup(bt_rfkill); | ||
169 | __oaktrail_rfkill_cleanup(gps_rfkill); | ||
170 | __oaktrail_rfkill_cleanup(wwan_rfkill); | ||
171 | } | ||
172 | |||
173 | static int oaktrail_rfkill_init(void) | ||
174 | { | ||
175 | int ret; | ||
176 | |||
177 | wifi_rfkill = oaktrail_rfkill_new("oaktrail-wifi", | ||
178 | RFKILL_TYPE_WLAN, | ||
179 | OT_EC_WIFI_MASK); | ||
180 | if (IS_ERR(wifi_rfkill)) { | ||
181 | ret = PTR_ERR(wifi_rfkill); | ||
182 | wifi_rfkill = NULL; | ||
183 | goto cleanup; | ||
184 | } | ||
185 | |||
186 | bt_rfkill = oaktrail_rfkill_new("oaktrail-bluetooth", | ||
187 | RFKILL_TYPE_BLUETOOTH, | ||
188 | OT_EC_BT_MASK); | ||
189 | if (IS_ERR(bt_rfkill)) { | ||
190 | ret = PTR_ERR(bt_rfkill); | ||
191 | bt_rfkill = NULL; | ||
192 | goto cleanup; | ||
193 | } | ||
194 | |||
195 | gps_rfkill = oaktrail_rfkill_new("oaktrail-gps", | ||
196 | RFKILL_TYPE_GPS, | ||
197 | OT_EC_GPS_MASK); | ||
198 | if (IS_ERR(gps_rfkill)) { | ||
199 | ret = PTR_ERR(gps_rfkill); | ||
200 | gps_rfkill = NULL; | ||
201 | goto cleanup; | ||
202 | } | ||
203 | |||
204 | wwan_rfkill = oaktrail_rfkill_new("oaktrail-wwan", | ||
205 | RFKILL_TYPE_WWAN, | ||
206 | OT_EC_WWAN_MASK); | ||
207 | if (IS_ERR(wwan_rfkill)) { | ||
208 | ret = PTR_ERR(wwan_rfkill); | ||
209 | wwan_rfkill = NULL; | ||
210 | goto cleanup; | ||
211 | } | ||
212 | |||
213 | return 0; | ||
214 | |||
215 | cleanup: | ||
216 | oaktrail_rfkill_cleanup(); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | |||
221 | /* backlight */ | ||
222 | static int get_backlight_brightness(struct backlight_device *b) | ||
223 | { | ||
224 | u8 value; | ||
225 | ec_read(OT_EC_BL_BRIGHTNESS_ADDRESS, &value); | ||
226 | |||
227 | return value; | ||
228 | } | ||
229 | |||
230 | static int set_backlight_brightness(struct backlight_device *b) | ||
231 | { | ||
232 | u8 percent = (u8) b->props.brightness; | ||
233 | if (percent < 0 || percent > OT_EC_BL_BRIGHTNESS_MAX) | ||
234 | return -EINVAL; | ||
235 | |||
236 | ec_write(OT_EC_BL_BRIGHTNESS_ADDRESS, percent); | ||
237 | ec_write(OT_EC_BL_CONTROL_ADDRESS, OT_EC_BL_CONTROL_ON_DATA); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static const struct backlight_ops oaktrail_bl_ops = { | ||
243 | .get_brightness = get_backlight_brightness, | ||
244 | .update_status = set_backlight_brightness, | ||
245 | }; | ||
246 | |||
247 | static int oaktrail_backlight_init(void) | ||
248 | { | ||
249 | struct backlight_device *bd; | ||
250 | struct backlight_properties props; | ||
251 | |||
252 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
253 | props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX; | ||
254 | bd = backlight_device_register(DRIVER_NAME, | ||
255 | &oaktrail_device->dev, NULL, | ||
256 | &oaktrail_bl_ops, | ||
257 | &props); | ||
258 | |||
259 | if (IS_ERR(bd)) { | ||
260 | oaktrail_bl_device = NULL; | ||
261 | pr_warning("Unable to register backlight device\n"); | ||
262 | return PTR_ERR(bd); | ||
263 | } | ||
264 | |||
265 | oaktrail_bl_device = bd; | ||
266 | |||
267 | bd->props.brightness = get_backlight_brightness(bd); | ||
268 | bd->props.power = FB_BLANK_UNBLANK; | ||
269 | backlight_update_status(bd); | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static void oaktrail_backlight_exit(void) | ||
275 | { | ||
276 | if (oaktrail_bl_device) | ||
277 | backlight_device_unregister(oaktrail_bl_device); | ||
278 | } | ||
279 | |||
280 | static int __devinit oaktrail_probe(struct platform_device *pdev) | ||
281 | { | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int __devexit oaktrail_remove(struct platform_device *pdev) | ||
286 | { | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static struct platform_driver oaktrail_driver = { | ||
291 | .driver = { | ||
292 | .name = DRIVER_NAME, | ||
293 | .owner = THIS_MODULE, | ||
294 | }, | ||
295 | .probe = oaktrail_probe, | ||
296 | .remove = __devexit_p(oaktrail_remove) | ||
297 | }; | ||
298 | |||
299 | static int dmi_check_cb(const struct dmi_system_id *id) | ||
300 | { | ||
301 | pr_info("Identified model '%s'\n", id->ident); | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static struct dmi_system_id __initdata oaktrail_dmi_table[] = { | ||
306 | { | ||
307 | .ident = "OakTrail platform", | ||
308 | .matches = { | ||
309 | DMI_MATCH(DMI_PRODUCT_NAME, "OakTrail platform"), | ||
310 | }, | ||
311 | .callback = dmi_check_cb | ||
312 | }, | ||
313 | { } | ||
314 | }; | ||
315 | |||
316 | static int __init oaktrail_init(void) | ||
317 | { | ||
318 | int ret; | ||
319 | |||
320 | if (acpi_disabled) { | ||
321 | pr_err("ACPI needs to be enabled for this driver to work!\n"); | ||
322 | return -ENODEV; | ||
323 | } | ||
324 | |||
325 | if (!force && !dmi_check_system(oaktrail_dmi_table)) { | ||
326 | pr_err("Platform not recognized (You could try the module's force-parameter)"); | ||
327 | return -ENODEV; | ||
328 | } | ||
329 | |||
330 | ret = platform_driver_register(&oaktrail_driver); | ||
331 | if (ret) { | ||
332 | pr_warning("Unable to register platform driver\n"); | ||
333 | goto err_driver_reg; | ||
334 | } | ||
335 | |||
336 | oaktrail_device = platform_device_alloc(DRIVER_NAME, -1); | ||
337 | if (!oaktrail_device) { | ||
338 | pr_warning("Unable to allocate platform device\n"); | ||
339 | ret = -ENOMEM; | ||
340 | goto err_device_alloc; | ||
341 | } | ||
342 | |||
343 | ret = platform_device_add(oaktrail_device); | ||
344 | if (ret) { | ||
345 | pr_warning("Unable to add platform device\n"); | ||
346 | goto err_device_add; | ||
347 | } | ||
348 | |||
349 | if (!acpi_video_backlight_support()) { | ||
350 | ret = oaktrail_backlight_init(); | ||
351 | if (ret) | ||
352 | goto err_backlight; | ||
353 | |||
354 | } else | ||
355 | pr_info("Backlight controlled by ACPI video driver\n"); | ||
356 | |||
357 | ret = oaktrail_rfkill_init(); | ||
358 | if (ret) { | ||
359 | pr_warning("Setup rfkill failed\n"); | ||
360 | goto err_rfkill; | ||
361 | } | ||
362 | |||
363 | pr_info("Driver "DRIVER_VERSION" successfully loaded\n"); | ||
364 | return 0; | ||
365 | |||
366 | err_rfkill: | ||
367 | oaktrail_backlight_exit(); | ||
368 | err_backlight: | ||
369 | platform_device_del(oaktrail_device); | ||
370 | err_device_add: | ||
371 | platform_device_put(oaktrail_device); | ||
372 | err_device_alloc: | ||
373 | platform_driver_unregister(&oaktrail_driver); | ||
374 | err_driver_reg: | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static void __exit oaktrail_cleanup(void) | ||
380 | { | ||
381 | oaktrail_backlight_exit(); | ||
382 | oaktrail_rfkill_cleanup(); | ||
383 | platform_device_unregister(oaktrail_device); | ||
384 | platform_driver_unregister(&oaktrail_driver); | ||
385 | |||
386 | pr_info("Driver unloaded\n"); | ||
387 | } | ||
388 | |||
389 | module_init(oaktrail_init); | ||
390 | module_exit(oaktrail_cleanup); | ||
391 | |||
392 | MODULE_AUTHOR("Yin Kangkai (kangkai.yin@intel.com)"); | ||
393 | MODULE_DESCRIPTION("Intel Oaktrail Platform ACPI Extras"); | ||
394 | MODULE_VERSION(DRIVER_VERSION); | ||
395 | MODULE_LICENSE("GPL"); | ||
396 | MODULE_ALIAS("dmi:*:svnIntelCorporation:pnOakTrailplatform:*"); | ||
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 464bb3fc4d88..1686c1e07d5d 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Moorestown platform PMIC chip | 19 | * Moorestown platform PMIC chip |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
23 | |||
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
24 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
@@ -90,8 +92,7 @@ static void pmic_program_irqtype(int gpio, int type) | |||
90 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 92 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
91 | { | 93 | { |
92 | if (offset > 8) { | 94 | if (offset > 8) { |
93 | printk(KERN_ERR | 95 | pr_err("only pin 0-7 support input\n"); |
94 | "%s: only pin 0-7 support input\n", __func__); | ||
95 | return -1;/* we only have 8 GPIO can use as input */ | 96 | return -1;/* we only have 8 GPIO can use as input */ |
96 | } | 97 | } |
97 | return intel_scu_ipc_update_register(GPIO0 + offset, | 98 | return intel_scu_ipc_update_register(GPIO0 + offset, |
@@ -116,8 +117,7 @@ static int pmic_gpio_direction_output(struct gpio_chip *chip, | |||
116 | value ? 1 << (offset - 16) : 0, | 117 | value ? 1 << (offset - 16) : 0, |
117 | 1 << (offset - 16)); | 118 | 1 << (offset - 16)); |
118 | else { | 119 | else { |
119 | printk(KERN_ERR | 120 | pr_err("invalid PMIC GPIO pin %d!\n", offset); |
120 | "%s: invalid PMIC GPIO pin %d!\n", __func__, offset); | ||
121 | WARN_ON(1); | 121 | WARN_ON(1); |
122 | } | 122 | } |
123 | 123 | ||
@@ -260,7 +260,7 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) | |||
260 | /* setting up SRAM mapping for GPIOINT register */ | 260 | /* setting up SRAM mapping for GPIOINT register */ |
261 | pg->gpiointr = ioremap_nocache(pdata->gpiointr, 8); | 261 | pg->gpiointr = ioremap_nocache(pdata->gpiointr, 8); |
262 | if (!pg->gpiointr) { | 262 | if (!pg->gpiointr) { |
263 | printk(KERN_ERR "%s: Can not map GPIOINT.\n", __func__); | 263 | pr_err("Can not map GPIOINT\n"); |
264 | retval = -EINVAL; | 264 | retval = -EINVAL; |
265 | goto err2; | 265 | goto err2; |
266 | } | 266 | } |
@@ -281,13 +281,13 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) | |||
281 | pg->chip.dev = dev; | 281 | pg->chip.dev = dev; |
282 | retval = gpiochip_add(&pg->chip); | 282 | retval = gpiochip_add(&pg->chip); |
283 | if (retval) { | 283 | if (retval) { |
284 | printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); | 284 | pr_err("Can not add pmic gpio chip\n"); |
285 | goto err; | 285 | goto err; |
286 | } | 286 | } |
287 | 287 | ||
288 | retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); | 288 | retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); |
289 | if (retval) { | 289 | if (retval) { |
290 | printk(KERN_WARNING "pmic: Interrupt request failed\n"); | 290 | pr_warn("Interrupt request failed\n"); |
291 | goto err; | 291 | goto err; |
292 | } | 292 | } |
293 | 293 | ||
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 23fb2afda00b..3ff629df9f01 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c | |||
@@ -135,7 +135,7 @@ static int set_lcd_level(int level) | |||
135 | buf[1] = (u8) (level*31); | 135 | buf[1] = (u8) (level*31); |
136 | 136 | ||
137 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), | 137 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), |
138 | NULL, 0, 1); | 138 | NULL, 0); |
139 | } | 139 | } |
140 | 140 | ||
141 | static int get_lcd_level(void) | 141 | static int get_lcd_level(void) |
@@ -144,7 +144,7 @@ static int get_lcd_level(void) | |||
144 | int result; | 144 | int result; |
145 | 145 | ||
146 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, | 146 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, |
147 | &rdata, 1, 1); | 147 | &rdata, 1); |
148 | if (result < 0) | 148 | if (result < 0) |
149 | return result; | 149 | return result; |
150 | 150 | ||
@@ -157,7 +157,7 @@ static int get_auto_brightness(void) | |||
157 | int result; | 157 | int result; |
158 | 158 | ||
159 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, | 159 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, |
160 | &rdata, 1, 1); | 160 | &rdata, 1); |
161 | if (result < 0) | 161 | if (result < 0) |
162 | return result; | 162 | return result; |
163 | 163 | ||
@@ -172,7 +172,7 @@ static int set_auto_brightness(int enable) | |||
172 | wdata[0] = 4; | 172 | wdata[0] = 4; |
173 | 173 | ||
174 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, | 174 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, |
175 | &rdata, 1, 1); | 175 | &rdata, 1); |
176 | if (result < 0) | 176 | if (result < 0) |
177 | return result; | 177 | return result; |
178 | 178 | ||
@@ -180,7 +180,7 @@ static int set_auto_brightness(int enable) | |||
180 | wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); | 180 | wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); |
181 | 181 | ||
182 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, | 182 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, |
183 | NULL, 0, 1); | 183 | NULL, 0); |
184 | } | 184 | } |
185 | 185 | ||
186 | static ssize_t set_device_state(const char *buf, size_t count, u8 mask) | 186 | static ssize_t set_device_state(const char *buf, size_t count, u8 mask) |
@@ -217,7 +217,7 @@ static int get_wireless_state(int *wlan, int *bluetooth) | |||
217 | u8 wdata = 0, rdata; | 217 | u8 wdata = 0, rdata; |
218 | int result; | 218 | int result; |
219 | 219 | ||
220 | result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1, 1); | 220 | result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); |
221 | if (result < 0) | 221 | if (result < 0) |
222 | return -1; | 222 | return -1; |
223 | 223 | ||
@@ -447,7 +447,7 @@ static struct platform_device *msipf_device; | |||
447 | 447 | ||
448 | static int dmi_check_cb(const struct dmi_system_id *id) | 448 | static int dmi_check_cb(const struct dmi_system_id *id) |
449 | { | 449 | { |
450 | pr_info("Identified laptop model '%s'.\n", id->ident); | 450 | pr_info("Identified laptop model '%s'\n", id->ident); |
451 | return 1; | 451 | return 1; |
452 | } | 452 | } |
453 | 453 | ||
@@ -800,7 +800,7 @@ static void msi_laptop_input_destroy(void) | |||
800 | input_unregister_device(msi_laptop_input_dev); | 800 | input_unregister_device(msi_laptop_input_dev); |
801 | } | 801 | } |
802 | 802 | ||
803 | static int load_scm_model_init(struct platform_device *sdev) | 803 | static int __init load_scm_model_init(struct platform_device *sdev) |
804 | { | 804 | { |
805 | u8 data; | 805 | u8 data; |
806 | int result; | 806 | int result; |
@@ -875,8 +875,7 @@ static int __init msi_init(void) | |||
875 | /* Register backlight stuff */ | 875 | /* Register backlight stuff */ |
876 | 876 | ||
877 | if (acpi_video_backlight_support()) { | 877 | if (acpi_video_backlight_support()) { |
878 | pr_info("Brightness ignored, must be controlled " | 878 | pr_info("Brightness ignored, must be controlled by ACPI video driver\n"); |
879 | "by ACPI video driver\n"); | ||
880 | } else { | 879 | } else { |
881 | struct backlight_properties props; | 880 | struct backlight_properties props; |
882 | memset(&props, 0, sizeof(struct backlight_properties)); | 881 | memset(&props, 0, sizeof(struct backlight_properties)); |
@@ -930,7 +929,7 @@ static int __init msi_init(void) | |||
930 | if (auto_brightness != 2) | 929 | if (auto_brightness != 2) |
931 | set_auto_brightness(auto_brightness); | 930 | set_auto_brightness(auto_brightness); |
932 | 931 | ||
933 | pr_info("driver "MSI_DRIVER_VERSION" successfully loaded.\n"); | 932 | pr_info("driver " MSI_DRIVER_VERSION " successfully loaded\n"); |
934 | 933 | ||
935 | return 0; | 934 | return 0; |
936 | 935 | ||
@@ -978,7 +977,7 @@ static void __exit msi_cleanup(void) | |||
978 | if (auto_brightness != 2) | 977 | if (auto_brightness != 2) |
979 | set_auto_brightness(1); | 978 | set_auto_brightness(1); |
980 | 979 | ||
981 | pr_info("driver unloaded.\n"); | 980 | pr_info("driver unloaded\n"); |
982 | } | 981 | } |
983 | 982 | ||
984 | module_init(msi_init); | 983 | module_init(msi_init); |
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index d5419c9ec07a..c832e3356cd6 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | 24 | ||
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/input.h> | 26 | #include <linux/input.h> |
@@ -36,13 +37,10 @@ MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45"); | |||
36 | MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); | 37 | MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); |
37 | 38 | ||
38 | #define DRV_NAME "msi-wmi" | 39 | #define DRV_NAME "msi-wmi" |
39 | #define DRV_PFX DRV_NAME ": " | ||
40 | 40 | ||
41 | #define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45" | 41 | #define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45" |
42 | #define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2" | 42 | #define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2" |
43 | 43 | ||
44 | #define dprintk(msg...) pr_debug(DRV_PFX msg) | ||
45 | |||
46 | #define SCANCODE_BASE 0xD0 | 44 | #define SCANCODE_BASE 0xD0 |
47 | #define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE | 45 | #define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE |
48 | #define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1) | 46 | #define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1) |
@@ -78,7 +76,7 @@ static int msi_wmi_query_block(int instance, int *ret) | |||
78 | 76 | ||
79 | if (!obj || obj->type != ACPI_TYPE_INTEGER) { | 77 | if (!obj || obj->type != ACPI_TYPE_INTEGER) { |
80 | if (obj) { | 78 | if (obj) { |
81 | printk(KERN_ERR DRV_PFX "query block returned object " | 79 | pr_err("query block returned object " |
82 | "type: %d - buffer length:%d\n", obj->type, | 80 | "type: %d - buffer length:%d\n", obj->type, |
83 | obj->type == ACPI_TYPE_BUFFER ? | 81 | obj->type == ACPI_TYPE_BUFFER ? |
84 | obj->buffer.length : 0); | 82 | obj->buffer.length : 0); |
@@ -97,8 +95,8 @@ static int msi_wmi_set_block(int instance, int value) | |||
97 | 95 | ||
98 | struct acpi_buffer input = { sizeof(int), &value }; | 96 | struct acpi_buffer input = { sizeof(int), &value }; |
99 | 97 | ||
100 | dprintk("Going to set block of instance: %d - value: %d\n", | 98 | pr_debug("Going to set block of instance: %d - value: %d\n", |
101 | instance, value); | 99 | instance, value); |
102 | 100 | ||
103 | status = wmi_set_block(MSIWMI_BIOS_GUID, instance, &input); | 101 | status = wmi_set_block(MSIWMI_BIOS_GUID, instance, &input); |
104 | 102 | ||
@@ -112,20 +110,19 @@ static int bl_get(struct backlight_device *bd) | |||
112 | /* Instance 1 is "get backlight", cmp with DSDT */ | 110 | /* Instance 1 is "get backlight", cmp with DSDT */ |
113 | err = msi_wmi_query_block(1, &ret); | 111 | err = msi_wmi_query_block(1, &ret); |
114 | if (err) { | 112 | if (err) { |
115 | printk(KERN_ERR DRV_PFX "Could not query backlight: %d\n", err); | 113 | pr_err("Could not query backlight: %d\n", err); |
116 | return -EINVAL; | 114 | return -EINVAL; |
117 | } | 115 | } |
118 | dprintk("Get: Query block returned: %d\n", ret); | 116 | pr_debug("Get: Query block returned: %d\n", ret); |
119 | for (level = 0; level < ARRAY_SIZE(backlight_map); level++) { | 117 | for (level = 0; level < ARRAY_SIZE(backlight_map); level++) { |
120 | if (backlight_map[level] == ret) { | 118 | if (backlight_map[level] == ret) { |
121 | dprintk("Current backlight level: 0x%X - index: %d\n", | 119 | pr_debug("Current backlight level: 0x%X - index: %d\n", |
122 | backlight_map[level], level); | 120 | backlight_map[level], level); |
123 | break; | 121 | break; |
124 | } | 122 | } |
125 | } | 123 | } |
126 | if (level == ARRAY_SIZE(backlight_map)) { | 124 | if (level == ARRAY_SIZE(backlight_map)) { |
127 | printk(KERN_ERR DRV_PFX "get: Invalid brightness value: 0x%X\n", | 125 | pr_err("get: Invalid brightness value: 0x%X\n", ret); |
128 | ret); | ||
129 | return -EINVAL; | 126 | return -EINVAL; |
130 | } | 127 | } |
131 | return level; | 128 | return level; |
@@ -156,7 +153,7 @@ static void msi_wmi_notify(u32 value, void *context) | |||
156 | 153 | ||
157 | status = wmi_get_event_data(value, &response); | 154 | status = wmi_get_event_data(value, &response); |
158 | if (status != AE_OK) { | 155 | if (status != AE_OK) { |
159 | printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status); | 156 | pr_info("bad event status 0x%x\n", status); |
160 | return; | 157 | return; |
161 | } | 158 | } |
162 | 159 | ||
@@ -164,7 +161,7 @@ static void msi_wmi_notify(u32 value, void *context) | |||
164 | 161 | ||
165 | if (obj && obj->type == ACPI_TYPE_INTEGER) { | 162 | if (obj && obj->type == ACPI_TYPE_INTEGER) { |
166 | int eventcode = obj->integer.value; | 163 | int eventcode = obj->integer.value; |
167 | dprintk("Eventcode: 0x%x\n", eventcode); | 164 | pr_debug("Eventcode: 0x%x\n", eventcode); |
168 | key = sparse_keymap_entry_from_scancode(msi_wmi_input_dev, | 165 | key = sparse_keymap_entry_from_scancode(msi_wmi_input_dev, |
169 | eventcode); | 166 | eventcode); |
170 | if (key) { | 167 | if (key) { |
@@ -175,8 +172,8 @@ static void msi_wmi_notify(u32 value, void *context) | |||
175 | /* Ignore event if the same event happened in a 50 ms | 172 | /* Ignore event if the same event happened in a 50 ms |
176 | timeframe -> Key press may result in 10-20 GPEs */ | 173 | timeframe -> Key press may result in 10-20 GPEs */ |
177 | if (ktime_to_us(diff) < 1000 * 50) { | 174 | if (ktime_to_us(diff) < 1000 * 50) { |
178 | dprintk("Suppressed key event 0x%X - " | 175 | pr_debug("Suppressed key event 0x%X - " |
179 | "Last press was %lld us ago\n", | 176 | "Last press was %lld us ago\n", |
180 | key->code, ktime_to_us(diff)); | 177 | key->code, ktime_to_us(diff)); |
181 | return; | 178 | return; |
182 | } | 179 | } |
@@ -187,17 +184,16 @@ static void msi_wmi_notify(u32 value, void *context) | |||
187 | (!acpi_video_backlight_support() || | 184 | (!acpi_video_backlight_support() || |
188 | (key->code != MSI_WMI_BRIGHTNESSUP && | 185 | (key->code != MSI_WMI_BRIGHTNESSUP && |
189 | key->code != MSI_WMI_BRIGHTNESSDOWN))) { | 186 | key->code != MSI_WMI_BRIGHTNESSDOWN))) { |
190 | dprintk("Send key: 0x%X - " | 187 | pr_debug("Send key: 0x%X - " |
191 | "Input layer keycode: %d\n", key->code, | 188 | "Input layer keycode: %d\n", |
192 | key->keycode); | 189 | key->code, key->keycode); |
193 | sparse_keymap_report_entry(msi_wmi_input_dev, | 190 | sparse_keymap_report_entry(msi_wmi_input_dev, |
194 | key, 1, true); | 191 | key, 1, true); |
195 | } | 192 | } |
196 | } else | 193 | } else |
197 | printk(KERN_INFO "Unknown key pressed - %x\n", | 194 | pr_info("Unknown key pressed - %x\n", eventcode); |
198 | eventcode); | ||
199 | } else | 195 | } else |
200 | printk(KERN_INFO DRV_PFX "Unknown event received\n"); | 196 | pr_info("Unknown event received\n"); |
201 | kfree(response.pointer); | 197 | kfree(response.pointer); |
202 | } | 198 | } |
203 | 199 | ||
@@ -238,8 +234,7 @@ static int __init msi_wmi_init(void) | |||
238 | int err; | 234 | int err; |
239 | 235 | ||
240 | if (!wmi_has_guid(MSIWMI_EVENT_GUID)) { | 236 | if (!wmi_has_guid(MSIWMI_EVENT_GUID)) { |
241 | printk(KERN_ERR | 237 | pr_err("This machine doesn't have MSI-hotkeys through WMI\n"); |
242 | "This machine doesn't have MSI-hotkeys through WMI\n"); | ||
243 | return -ENODEV; | 238 | return -ENODEV; |
244 | } | 239 | } |
245 | err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, | 240 | err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, |
@@ -270,7 +265,7 @@ static int __init msi_wmi_init(void) | |||
270 | 265 | ||
271 | backlight->props.brightness = err; | 266 | backlight->props.brightness = err; |
272 | } | 267 | } |
273 | dprintk("Event handler installed\n"); | 268 | pr_debug("Event handler installed\n"); |
274 | 269 | ||
275 | return 0; | 270 | return 0; |
276 | 271 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 6fe8cd6e23b5..bbd182e178cb 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -42,6 +42,8 @@ | |||
42 | * | 42 | * |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
46 | |||
45 | #include <linux/kernel.h> | 47 | #include <linux/kernel.h> |
46 | #include <linux/module.h> | 48 | #include <linux/module.h> |
47 | #include <linux/moduleparam.h> | 49 | #include <linux/moduleparam.h> |
@@ -70,10 +72,10 @@ | |||
70 | #include <linux/miscdevice.h> | 72 | #include <linux/miscdevice.h> |
71 | #endif | 73 | #endif |
72 | 74 | ||
73 | #define DRV_PFX "sony-laptop: " | 75 | #define dprintk(fmt, ...) \ |
74 | #define dprintk(msg...) do { \ | 76 | do { \ |
75 | if (debug) \ | 77 | if (debug) \ |
76 | pr_warn(DRV_PFX msg); \ | 78 | pr_warn(fmt, ##__VA_ARGS__); \ |
77 | } while (0) | 79 | } while (0) |
78 | 80 | ||
79 | #define SONY_LAPTOP_DRIVER_VERSION "0.6" | 81 | #define SONY_LAPTOP_DRIVER_VERSION "0.6" |
@@ -418,7 +420,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
418 | error = kfifo_alloc(&sony_laptop_input.fifo, | 420 | error = kfifo_alloc(&sony_laptop_input.fifo, |
419 | SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); | 421 | SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
420 | if (error) { | 422 | if (error) { |
421 | pr_err(DRV_PFX "kfifo_alloc failed\n"); | 423 | pr_err("kfifo_alloc failed\n"); |
422 | goto err_dec_users; | 424 | goto err_dec_users; |
423 | } | 425 | } |
424 | 426 | ||
@@ -702,7 +704,7 @@ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) | |||
702 | return 0; | 704 | return 0; |
703 | } | 705 | } |
704 | 706 | ||
705 | pr_warn(DRV_PFX "acpi_callreadfunc failed\n"); | 707 | pr_warn("acpi_callreadfunc failed\n"); |
706 | 708 | ||
707 | return -1; | 709 | return -1; |
708 | } | 710 | } |
@@ -728,8 +730,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, | |||
728 | if (status == AE_OK) { | 730 | if (status == AE_OK) { |
729 | if (result != NULL) { | 731 | if (result != NULL) { |
730 | if (out_obj.type != ACPI_TYPE_INTEGER) { | 732 | if (out_obj.type != ACPI_TYPE_INTEGER) { |
731 | pr_warn(DRV_PFX "acpi_evaluate_object bad " | 733 | pr_warn("acpi_evaluate_object bad return type\n"); |
732 | "return type\n"); | ||
733 | return -1; | 734 | return -1; |
734 | } | 735 | } |
735 | *result = out_obj.integer.value; | 736 | *result = out_obj.integer.value; |
@@ -737,7 +738,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, | |||
737 | return 0; | 738 | return 0; |
738 | } | 739 | } |
739 | 740 | ||
740 | pr_warn(DRV_PFX "acpi_evaluate_object failed\n"); | 741 | pr_warn("acpi_evaluate_object failed\n"); |
741 | 742 | ||
742 | return -1; | 743 | return -1; |
743 | } | 744 | } |
@@ -961,7 +962,6 @@ static int sony_backlight_get_brightness(struct backlight_device *bd) | |||
961 | static int sony_nc_get_brightness_ng(struct backlight_device *bd) | 962 | static int sony_nc_get_brightness_ng(struct backlight_device *bd) |
962 | { | 963 | { |
963 | int result; | 964 | int result; |
964 | int *handle = (int *)bl_get_data(bd); | ||
965 | struct sony_backlight_props *sdev = | 965 | struct sony_backlight_props *sdev = |
966 | (struct sony_backlight_props *)bl_get_data(bd); | 966 | (struct sony_backlight_props *)bl_get_data(bd); |
967 | 967 | ||
@@ -973,7 +973,6 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) | |||
973 | static int sony_nc_update_status_ng(struct backlight_device *bd) | 973 | static int sony_nc_update_status_ng(struct backlight_device *bd) |
974 | { | 974 | { |
975 | int value, result; | 975 | int value, result; |
976 | int *handle = (int *)bl_get_data(bd); | ||
977 | struct sony_backlight_props *sdev = | 976 | struct sony_backlight_props *sdev = |
978 | (struct sony_backlight_props *)bl_get_data(bd); | 977 | (struct sony_backlight_props *)bl_get_data(bd); |
979 | 978 | ||
@@ -1104,10 +1103,8 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1104 | } | 1103 | } |
1105 | 1104 | ||
1106 | if (!key_event->data) | 1105 | if (!key_event->data) |
1107 | pr_info(DRV_PFX | 1106 | pr_info("Unknown event: 0x%x 0x%x\n", |
1108 | "Unknown event: 0x%x 0x%x\n", | 1107 | key_handle, ev); |
1109 | key_handle, | ||
1110 | ev); | ||
1111 | else | 1108 | else |
1112 | sony_laptop_report_input_event(ev); | 1109 | sony_laptop_report_input_event(ev); |
1113 | } | 1110 | } |
@@ -1128,7 +1125,7 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, | |||
1128 | struct acpi_device_info *info; | 1125 | struct acpi_device_info *info; |
1129 | 1126 | ||
1130 | if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { | 1127 | if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { |
1131 | pr_warn(DRV_PFX "method: name: %4.4s, args %X\n", | 1128 | pr_warn("method: name: %4.4s, args %X\n", |
1132 | (char *)&info->name, info->param_count); | 1129 | (char *)&info->name, info->param_count); |
1133 | 1130 | ||
1134 | kfree(info); | 1131 | kfree(info); |
@@ -1169,7 +1166,7 @@ static int sony_nc_resume(struct acpi_device *device) | |||
1169 | ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, | 1166 | ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, |
1170 | item->value, NULL); | 1167 | item->value, NULL); |
1171 | if (ret < 0) { | 1168 | if (ret < 0) { |
1172 | pr_err(DRV_PFX "%s: %d\n", __func__, ret); | 1169 | pr_err("%s: %d\n", __func__, ret); |
1173 | break; | 1170 | break; |
1174 | } | 1171 | } |
1175 | } | 1172 | } |
@@ -1336,12 +1333,12 @@ static void sony_nc_rfkill_setup(struct acpi_device *device) | |||
1336 | 1333 | ||
1337 | device_enum = (union acpi_object *) buffer.pointer; | 1334 | device_enum = (union acpi_object *) buffer.pointer; |
1338 | if (!device_enum) { | 1335 | if (!device_enum) { |
1339 | pr_err(DRV_PFX "No SN06 return object."); | 1336 | pr_err("No SN06 return object\n"); |
1340 | goto out_no_enum; | 1337 | goto out_no_enum; |
1341 | } | 1338 | } |
1342 | if (device_enum->type != ACPI_TYPE_BUFFER) { | 1339 | if (device_enum->type != ACPI_TYPE_BUFFER) { |
1343 | pr_err(DRV_PFX "Invalid SN06 return object 0x%.2x\n", | 1340 | pr_err("Invalid SN06 return object 0x%.2x\n", |
1344 | device_enum->type); | 1341 | device_enum->type); |
1345 | goto out_no_enum; | 1342 | goto out_no_enum; |
1346 | } | 1343 | } |
1347 | 1344 | ||
@@ -1662,7 +1659,7 @@ static void sony_nc_backlight_setup(void) | |||
1662 | ops, &props); | 1659 | ops, &props); |
1663 | 1660 | ||
1664 | if (IS_ERR(sony_bl_props.dev)) { | 1661 | if (IS_ERR(sony_bl_props.dev)) { |
1665 | pr_warn(DRV_PFX "unable to register backlight device\n"); | 1662 | pr_warn("unable to register backlight device\n"); |
1666 | sony_bl_props.dev = NULL; | 1663 | sony_bl_props.dev = NULL; |
1667 | } else | 1664 | } else |
1668 | sony_bl_props.dev->props.brightness = | 1665 | sony_bl_props.dev->props.brightness = |
@@ -1682,8 +1679,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
1682 | acpi_handle handle; | 1679 | acpi_handle handle; |
1683 | struct sony_nc_value *item; | 1680 | struct sony_nc_value *item; |
1684 | 1681 | ||
1685 | pr_info(DRV_PFX "%s v%s.\n", SONY_NC_DRIVER_NAME, | 1682 | pr_info("%s v%s\n", SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); |
1686 | SONY_LAPTOP_DRIVER_VERSION); | ||
1687 | 1683 | ||
1688 | sony_nc_acpi_device = device; | 1684 | sony_nc_acpi_device = device; |
1689 | strcpy(acpi_device_class(device), "sony/hotkey"); | 1685 | strcpy(acpi_device_class(device), "sony/hotkey"); |
@@ -1708,7 +1704,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
1708 | sony_nc_acpi_handle, 1, sony_walk_callback, | 1704 | sony_nc_acpi_handle, 1, sony_walk_callback, |
1709 | NULL, NULL, NULL); | 1705 | NULL, NULL, NULL); |
1710 | if (ACPI_FAILURE(status)) { | 1706 | if (ACPI_FAILURE(status)) { |
1711 | pr_warn(DRV_PFX "unable to walk acpi resources\n"); | 1707 | pr_warn("unable to walk acpi resources\n"); |
1712 | result = -ENODEV; | 1708 | result = -ENODEV; |
1713 | goto outpresent; | 1709 | goto outpresent; |
1714 | } | 1710 | } |
@@ -1736,13 +1732,12 @@ static int sony_nc_add(struct acpi_device *device) | |||
1736 | /* setup input devices and helper fifo */ | 1732 | /* setup input devices and helper fifo */ |
1737 | result = sony_laptop_setup_input(device); | 1733 | result = sony_laptop_setup_input(device); |
1738 | if (result) { | 1734 | if (result) { |
1739 | pr_err(DRV_PFX "Unable to create input devices.\n"); | 1735 | pr_err("Unable to create input devices\n"); |
1740 | goto outkbdbacklight; | 1736 | goto outkbdbacklight; |
1741 | } | 1737 | } |
1742 | 1738 | ||
1743 | if (acpi_video_backlight_support()) { | 1739 | if (acpi_video_backlight_support()) { |
1744 | pr_info(DRV_PFX "brightness ignored, must be " | 1740 | pr_info("brightness ignored, must be controlled by ACPI video driver\n"); |
1745 | "controlled by ACPI video driver\n"); | ||
1746 | } else { | 1741 | } else { |
1747 | sony_nc_backlight_setup(); | 1742 | sony_nc_backlight_setup(); |
1748 | } | 1743 | } |
@@ -2265,9 +2260,9 @@ out: | |||
2265 | if (pcidev) | 2260 | if (pcidev) |
2266 | pci_dev_put(pcidev); | 2261 | pci_dev_put(pcidev); |
2267 | 2262 | ||
2268 | pr_info(DRV_PFX "detected Type%d model\n", | 2263 | pr_info("detected Type%d model\n", |
2269 | dev->model == SONYPI_DEVICE_TYPE1 ? 1 : | 2264 | dev->model == SONYPI_DEVICE_TYPE1 ? 1 : |
2270 | dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); | 2265 | dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); |
2271 | } | 2266 | } |
2272 | 2267 | ||
2273 | /* camera tests and poweron/poweroff */ | 2268 | /* camera tests and poweron/poweroff */ |
@@ -2313,7 +2308,7 @@ static int __sony_pic_camera_ready(void) | |||
2313 | static int __sony_pic_camera_off(void) | 2308 | static int __sony_pic_camera_off(void) |
2314 | { | 2309 | { |
2315 | if (!camera) { | 2310 | if (!camera) { |
2316 | pr_warn(DRV_PFX "camera control not enabled\n"); | 2311 | pr_warn("camera control not enabled\n"); |
2317 | return -ENODEV; | 2312 | return -ENODEV; |
2318 | } | 2313 | } |
2319 | 2314 | ||
@@ -2333,7 +2328,7 @@ static int __sony_pic_camera_on(void) | |||
2333 | int i, j, x; | 2328 | int i, j, x; |
2334 | 2329 | ||
2335 | if (!camera) { | 2330 | if (!camera) { |
2336 | pr_warn(DRV_PFX "camera control not enabled\n"); | 2331 | pr_warn("camera control not enabled\n"); |
2337 | return -ENODEV; | 2332 | return -ENODEV; |
2338 | } | 2333 | } |
2339 | 2334 | ||
@@ -2356,7 +2351,7 @@ static int __sony_pic_camera_on(void) | |||
2356 | } | 2351 | } |
2357 | 2352 | ||
2358 | if (j == 0) { | 2353 | if (j == 0) { |
2359 | pr_warn(DRV_PFX "failed to power on camera\n"); | 2354 | pr_warn("failed to power on camera\n"); |
2360 | return -ENODEV; | 2355 | return -ENODEV; |
2361 | } | 2356 | } |
2362 | 2357 | ||
@@ -2412,8 +2407,7 @@ int sony_pic_camera_command(int command, u8 value) | |||
2412 | ITERATIONS_SHORT); | 2407 | ITERATIONS_SHORT); |
2413 | break; | 2408 | break; |
2414 | default: | 2409 | default: |
2415 | pr_err(DRV_PFX "sony_pic_camera_command invalid: %d\n", | 2410 | pr_err("sony_pic_camera_command invalid: %d\n", command); |
2416 | command); | ||
2417 | break; | 2411 | break; |
2418 | } | 2412 | } |
2419 | mutex_unlock(&spic_dev.lock); | 2413 | mutex_unlock(&spic_dev.lock); |
@@ -2819,7 +2813,7 @@ static int sonypi_compat_init(void) | |||
2819 | error = | 2813 | error = |
2820 | kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); | 2814 | kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
2821 | if (error) { | 2815 | if (error) { |
2822 | pr_err(DRV_PFX "kfifo_alloc failed\n"); | 2816 | pr_err("kfifo_alloc failed\n"); |
2823 | return error; | 2817 | return error; |
2824 | } | 2818 | } |
2825 | 2819 | ||
@@ -2829,12 +2823,12 @@ static int sonypi_compat_init(void) | |||
2829 | sonypi_misc_device.minor = minor; | 2823 | sonypi_misc_device.minor = minor; |
2830 | error = misc_register(&sonypi_misc_device); | 2824 | error = misc_register(&sonypi_misc_device); |
2831 | if (error) { | 2825 | if (error) { |
2832 | pr_err(DRV_PFX "misc_register failed\n"); | 2826 | pr_err("misc_register failed\n"); |
2833 | goto err_free_kfifo; | 2827 | goto err_free_kfifo; |
2834 | } | 2828 | } |
2835 | if (minor == -1) | 2829 | if (minor == -1) |
2836 | pr_info(DRV_PFX "device allocated minor is %d\n", | 2830 | pr_info("device allocated minor is %d\n", |
2837 | sonypi_misc_device.minor); | 2831 | sonypi_misc_device.minor); |
2838 | 2832 | ||
2839 | return 0; | 2833 | return 0; |
2840 | 2834 | ||
@@ -2893,8 +2887,8 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) | |||
2893 | } | 2887 | } |
2894 | for (i = 0; i < p->interrupt_count; i++) { | 2888 | for (i = 0; i < p->interrupt_count; i++) { |
2895 | if (!p->interrupts[i]) { | 2889 | if (!p->interrupts[i]) { |
2896 | pr_warn(DRV_PFX "Invalid IRQ %d\n", | 2890 | pr_warn("Invalid IRQ %d\n", |
2897 | p->interrupts[i]); | 2891 | p->interrupts[i]); |
2898 | continue; | 2892 | continue; |
2899 | } | 2893 | } |
2900 | interrupt = kzalloc(sizeof(*interrupt), | 2894 | interrupt = kzalloc(sizeof(*interrupt), |
@@ -2932,14 +2926,14 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) | |||
2932 | ioport->io2.address_length); | 2926 | ioport->io2.address_length); |
2933 | } | 2927 | } |
2934 | else { | 2928 | else { |
2935 | pr_err(DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); | 2929 | pr_err("Unknown SPIC Type, more than 2 IO Ports\n"); |
2936 | return AE_ERROR; | 2930 | return AE_ERROR; |
2937 | } | 2931 | } |
2938 | return AE_OK; | 2932 | return AE_OK; |
2939 | } | 2933 | } |
2940 | default: | 2934 | default: |
2941 | dprintk("Resource %d isn't an IRQ nor an IO port\n", | 2935 | dprintk("Resource %d isn't an IRQ nor an IO port\n", |
2942 | resource->type); | 2936 | resource->type); |
2943 | 2937 | ||
2944 | case ACPI_RESOURCE_TYPE_END_TAG: | 2938 | case ACPI_RESOURCE_TYPE_END_TAG: |
2945 | return AE_OK; | 2939 | return AE_OK; |
@@ -2960,7 +2954,7 @@ static int sony_pic_possible_resources(struct acpi_device *device) | |||
2960 | dprintk("Evaluating _STA\n"); | 2954 | dprintk("Evaluating _STA\n"); |
2961 | result = acpi_bus_get_status(device); | 2955 | result = acpi_bus_get_status(device); |
2962 | if (result) { | 2956 | if (result) { |
2963 | pr_warn(DRV_PFX "Unable to read status\n"); | 2957 | pr_warn("Unable to read status\n"); |
2964 | goto end; | 2958 | goto end; |
2965 | } | 2959 | } |
2966 | 2960 | ||
@@ -2976,8 +2970,7 @@ static int sony_pic_possible_resources(struct acpi_device *device) | |||
2976 | status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, | 2970 | status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, |
2977 | sony_pic_read_possible_resource, &spic_dev); | 2971 | sony_pic_read_possible_resource, &spic_dev); |
2978 | if (ACPI_FAILURE(status)) { | 2972 | if (ACPI_FAILURE(status)) { |
2979 | pr_warn(DRV_PFX "Failure evaluating %s\n", | 2973 | pr_warn("Failure evaluating %s\n", METHOD_NAME__PRS); |
2980 | METHOD_NAME__PRS); | ||
2981 | result = -ENODEV; | 2974 | result = -ENODEV; |
2982 | } | 2975 | } |
2983 | end: | 2976 | end: |
@@ -3090,7 +3083,7 @@ static int sony_pic_enable(struct acpi_device *device, | |||
3090 | 3083 | ||
3091 | /* check for total failure */ | 3084 | /* check for total failure */ |
3092 | if (ACPI_FAILURE(status)) { | 3085 | if (ACPI_FAILURE(status)) { |
3093 | pr_err(DRV_PFX "Error evaluating _SRS\n"); | 3086 | pr_err("Error evaluating _SRS\n"); |
3094 | result = -ENODEV; | 3087 | result = -ENODEV; |
3095 | goto end; | 3088 | goto end; |
3096 | } | 3089 | } |
@@ -3182,7 +3175,7 @@ static int sony_pic_remove(struct acpi_device *device, int type) | |||
3182 | struct sony_pic_irq *irq, *tmp_irq; | 3175 | struct sony_pic_irq *irq, *tmp_irq; |
3183 | 3176 | ||
3184 | if (sony_pic_disable(device)) { | 3177 | if (sony_pic_disable(device)) { |
3185 | pr_err(DRV_PFX "Couldn't disable device.\n"); | 3178 | pr_err("Couldn't disable device\n"); |
3186 | return -ENXIO; | 3179 | return -ENXIO; |
3187 | } | 3180 | } |
3188 | 3181 | ||
@@ -3222,8 +3215,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3222 | struct sony_pic_ioport *io, *tmp_io; | 3215 | struct sony_pic_ioport *io, *tmp_io; |
3223 | struct sony_pic_irq *irq, *tmp_irq; | 3216 | struct sony_pic_irq *irq, *tmp_irq; |
3224 | 3217 | ||
3225 | pr_info(DRV_PFX "%s v%s.\n", SONY_PIC_DRIVER_NAME, | 3218 | pr_info("%s v%s\n", SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); |
3226 | SONY_LAPTOP_DRIVER_VERSION); | ||
3227 | 3219 | ||
3228 | spic_dev.acpi_dev = device; | 3220 | spic_dev.acpi_dev = device; |
3229 | strcpy(acpi_device_class(device), "sony/hotkey"); | 3221 | strcpy(acpi_device_class(device), "sony/hotkey"); |
@@ -3233,14 +3225,14 @@ static int sony_pic_add(struct acpi_device *device) | |||
3233 | /* read _PRS resources */ | 3225 | /* read _PRS resources */ |
3234 | result = sony_pic_possible_resources(device); | 3226 | result = sony_pic_possible_resources(device); |
3235 | if (result) { | 3227 | if (result) { |
3236 | pr_err(DRV_PFX "Unable to read possible resources.\n"); | 3228 | pr_err("Unable to read possible resources\n"); |
3237 | goto err_free_resources; | 3229 | goto err_free_resources; |
3238 | } | 3230 | } |
3239 | 3231 | ||
3240 | /* setup input devices and helper fifo */ | 3232 | /* setup input devices and helper fifo */ |
3241 | result = sony_laptop_setup_input(device); | 3233 | result = sony_laptop_setup_input(device); |
3242 | if (result) { | 3234 | if (result) { |
3243 | pr_err(DRV_PFX "Unable to create input devices.\n"); | 3235 | pr_err("Unable to create input devices\n"); |
3244 | goto err_free_resources; | 3236 | goto err_free_resources; |
3245 | } | 3237 | } |
3246 | 3238 | ||
@@ -3281,7 +3273,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3281 | } | 3273 | } |
3282 | } | 3274 | } |
3283 | if (!spic_dev.cur_ioport) { | 3275 | if (!spic_dev.cur_ioport) { |
3284 | pr_err(DRV_PFX "Failed to request_region.\n"); | 3276 | pr_err("Failed to request_region\n"); |
3285 | result = -ENODEV; | 3277 | result = -ENODEV; |
3286 | goto err_remove_compat; | 3278 | goto err_remove_compat; |
3287 | } | 3279 | } |
@@ -3301,7 +3293,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3301 | } | 3293 | } |
3302 | } | 3294 | } |
3303 | if (!spic_dev.cur_irq) { | 3295 | if (!spic_dev.cur_irq) { |
3304 | pr_err(DRV_PFX "Failed to request_irq.\n"); | 3296 | pr_err("Failed to request_irq\n"); |
3305 | result = -ENODEV; | 3297 | result = -ENODEV; |
3306 | goto err_release_region; | 3298 | goto err_release_region; |
3307 | } | 3299 | } |
@@ -3309,7 +3301,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3309 | /* set resource status _SRS */ | 3301 | /* set resource status _SRS */ |
3310 | result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); | 3302 | result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); |
3311 | if (result) { | 3303 | if (result) { |
3312 | pr_err(DRV_PFX "Couldn't enable device.\n"); | 3304 | pr_err("Couldn't enable device\n"); |
3313 | goto err_free_irq; | 3305 | goto err_free_irq; |
3314 | } | 3306 | } |
3315 | 3307 | ||
@@ -3418,7 +3410,7 @@ static int __init sony_laptop_init(void) | |||
3418 | if (!no_spic && dmi_check_system(sonypi_dmi_table)) { | 3410 | if (!no_spic && dmi_check_system(sonypi_dmi_table)) { |
3419 | result = acpi_bus_register_driver(&sony_pic_driver); | 3411 | result = acpi_bus_register_driver(&sony_pic_driver); |
3420 | if (result) { | 3412 | if (result) { |
3421 | pr_err(DRV_PFX "Unable to register SPIC driver."); | 3413 | pr_err("Unable to register SPIC driver\n"); |
3422 | goto out; | 3414 | goto out; |
3423 | } | 3415 | } |
3424 | spic_drv_registered = 1; | 3416 | spic_drv_registered = 1; |
@@ -3426,7 +3418,7 @@ static int __init sony_laptop_init(void) | |||
3426 | 3418 | ||
3427 | result = acpi_bus_register_driver(&sony_nc_driver); | 3419 | result = acpi_bus_register_driver(&sony_nc_driver); |
3428 | if (result) { | 3420 | if (result) { |
3429 | pr_err(DRV_PFX "Unable to register SNC driver."); | 3421 | pr_err("Unable to register SNC driver\n"); |
3430 | goto out_unregister_pic; | 3422 | goto out_unregister_pic; |
3431 | } | 3423 | } |
3432 | 3424 | ||
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 865ef78d6f1a..e24f5ae475af 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 25 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
28 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 31 | #include <linux/module.h> |
30 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
@@ -40,9 +42,6 @@ | |||
40 | #define TC1100_INSTANCE_WIRELESS 1 | 42 | #define TC1100_INSTANCE_WIRELESS 1 |
41 | #define TC1100_INSTANCE_JOGDIAL 2 | 43 | #define TC1100_INSTANCE_JOGDIAL 2 |
42 | 44 | ||
43 | #define TC1100_LOGPREFIX "tc1100-wmi: " | ||
44 | #define TC1100_INFO KERN_INFO TC1100_LOGPREFIX | ||
45 | |||
46 | MODULE_AUTHOR("Jamey Hicks, Carlos Corbacho"); | 45 | MODULE_AUTHOR("Jamey Hicks, Carlos Corbacho"); |
47 | MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); | 46 | MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); |
48 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
@@ -264,7 +263,7 @@ static int __init tc1100_init(void) | |||
264 | if (error) | 263 | if (error) |
265 | goto err_device_del; | 264 | goto err_device_del; |
266 | 265 | ||
267 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); | 266 | pr_info("HP Compaq TC1100 Tablet WMI Extras loaded\n"); |
268 | return 0; | 267 | return 0; |
269 | 268 | ||
270 | err_device_del: | 269 | err_device_del: |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 562fcf0dd2b5..77f6e707a2a9 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * 02110-1301, USA. | 21 | * 02110-1301, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
24 | #define TPACPI_VERSION "0.24" | 26 | #define TPACPI_VERSION "0.24" |
25 | #define TPACPI_SYSFS_VERSION 0x020700 | 27 | #define TPACPI_SYSFS_VERSION 0x020700 |
26 | 28 | ||
@@ -224,17 +226,6 @@ enum tpacpi_hkey_event_t { | |||
224 | 226 | ||
225 | #define TPACPI_MAX_ACPI_ARGS 3 | 227 | #define TPACPI_MAX_ACPI_ARGS 3 |
226 | 228 | ||
227 | /* printk headers */ | ||
228 | #define TPACPI_LOG TPACPI_FILE ": " | ||
229 | #define TPACPI_EMERG KERN_EMERG TPACPI_LOG | ||
230 | #define TPACPI_ALERT KERN_ALERT TPACPI_LOG | ||
231 | #define TPACPI_CRIT KERN_CRIT TPACPI_LOG | ||
232 | #define TPACPI_ERR KERN_ERR TPACPI_LOG | ||
233 | #define TPACPI_WARN KERN_WARNING TPACPI_LOG | ||
234 | #define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG | ||
235 | #define TPACPI_INFO KERN_INFO TPACPI_LOG | ||
236 | #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG | ||
237 | |||
238 | /* Debugging printk groups */ | 229 | /* Debugging printk groups */ |
239 | #define TPACPI_DBG_ALL 0xffff | 230 | #define TPACPI_DBG_ALL 0xffff |
240 | #define TPACPI_DBG_DISCLOSETASK 0x8000 | 231 | #define TPACPI_DBG_DISCLOSETASK 0x8000 |
@@ -389,34 +380,36 @@ static int tpacpi_uwb_emulstate; | |||
389 | * Debugging helpers | 380 | * Debugging helpers |
390 | */ | 381 | */ |
391 | 382 | ||
392 | #define dbg_printk(a_dbg_level, format, arg...) \ | 383 | #define dbg_printk(a_dbg_level, format, arg...) \ |
393 | do { if (dbg_level & (a_dbg_level)) \ | 384 | do { \ |
394 | printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ | 385 | if (dbg_level & (a_dbg_level)) \ |
395 | } while (0) | 386 | printk(KERN_DEBUG pr_fmt("%s: " format), \ |
387 | __func__, ##arg); \ | ||
388 | } while (0) | ||
396 | 389 | ||
397 | #ifdef CONFIG_THINKPAD_ACPI_DEBUG | 390 | #ifdef CONFIG_THINKPAD_ACPI_DEBUG |
398 | #define vdbg_printk dbg_printk | 391 | #define vdbg_printk dbg_printk |
399 | static const char *str_supported(int is_supported); | 392 | static const char *str_supported(int is_supported); |
400 | #else | 393 | #else |
401 | #define vdbg_printk(a_dbg_level, format, arg...) \ | 394 | static inline const char *str_supported(int is_supported) { return ""; } |
402 | do { } while (0) | 395 | #define vdbg_printk(a_dbg_level, format, arg...) \ |
396 | no_printk(format, ##arg) | ||
403 | #endif | 397 | #endif |
404 | 398 | ||
405 | static void tpacpi_log_usertask(const char * const what) | 399 | static void tpacpi_log_usertask(const char * const what) |
406 | { | 400 | { |
407 | printk(TPACPI_DEBUG "%s: access by process with PID %d\n", | 401 | printk(KERN_DEBUG pr_fmt("%s: access by process with PID %d\n"), |
408 | what, task_tgid_vnr(current)); | 402 | what, task_tgid_vnr(current)); |
409 | } | 403 | } |
410 | 404 | ||
411 | #define tpacpi_disclose_usertask(what, format, arg...) \ | 405 | #define tpacpi_disclose_usertask(what, format, arg...) \ |
412 | do { \ | 406 | do { \ |
413 | if (unlikely( \ | 407 | if (unlikely((dbg_level & TPACPI_DBG_DISCLOSETASK) && \ |
414 | (dbg_level & TPACPI_DBG_DISCLOSETASK) && \ | 408 | (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ |
415 | (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ | 409 | printk(KERN_DEBUG pr_fmt("%s: PID %d: " format), \ |
416 | printk(TPACPI_DEBUG "%s: PID %d: " format, \ | 410 | what, task_tgid_vnr(current), ## arg); \ |
417 | what, task_tgid_vnr(current), ## arg); \ | 411 | } \ |
418 | } \ | 412 | } while (0) |
419 | } while (0) | ||
420 | 413 | ||
421 | /* | 414 | /* |
422 | * Quirk handling helpers | 415 | * Quirk handling helpers |
@@ -535,15 +528,6 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ | |||
535 | "HKEY", /* all others */ | 528 | "HKEY", /* all others */ |
536 | ); /* 570 */ | 529 | ); /* 570 */ |
537 | 530 | ||
538 | TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ | ||
539 | "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ | ||
540 | "\\_SB.PCI0.VID0", /* 770e */ | ||
541 | "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ | ||
542 | "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */ | ||
543 | "\\_SB.PCI0.AGP.VID", /* all others */ | ||
544 | ); /* R30, R31 */ | ||
545 | |||
546 | |||
547 | /************************************************************************* | 531 | /************************************************************************* |
548 | * ACPI helpers | 532 | * ACPI helpers |
549 | */ | 533 | */ |
@@ -563,7 +547,7 @@ static int acpi_evalf(acpi_handle handle, | |||
563 | int quiet; | 547 | int quiet; |
564 | 548 | ||
565 | if (!*fmt) { | 549 | if (!*fmt) { |
566 | printk(TPACPI_ERR "acpi_evalf() called with empty format\n"); | 550 | pr_err("acpi_evalf() called with empty format\n"); |
567 | return 0; | 551 | return 0; |
568 | } | 552 | } |
569 | 553 | ||
@@ -588,7 +572,7 @@ static int acpi_evalf(acpi_handle handle, | |||
588 | break; | 572 | break; |
589 | /* add more types as needed */ | 573 | /* add more types as needed */ |
590 | default: | 574 | default: |
591 | printk(TPACPI_ERR "acpi_evalf() called " | 575 | pr_err("acpi_evalf() called " |
592 | "with invalid format character '%c'\n", c); | 576 | "with invalid format character '%c'\n", c); |
593 | va_end(ap); | 577 | va_end(ap); |
594 | return 0; | 578 | return 0; |
@@ -617,13 +601,13 @@ static int acpi_evalf(acpi_handle handle, | |||
617 | break; | 601 | break; |
618 | /* add more types as needed */ | 602 | /* add more types as needed */ |
619 | default: | 603 | default: |
620 | printk(TPACPI_ERR "acpi_evalf() called " | 604 | pr_err("acpi_evalf() called " |
621 | "with invalid format character '%c'\n", res_type); | 605 | "with invalid format character '%c'\n", res_type); |
622 | return 0; | 606 | return 0; |
623 | } | 607 | } |
624 | 608 | ||
625 | if (!success && !quiet) | 609 | if (!success && !quiet) |
626 | printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %s\n", | 610 | pr_err("acpi_evalf(%s, %s, ...) failed: %s\n", |
627 | method, fmt0, acpi_format_exception(status)); | 611 | method, fmt0, acpi_format_exception(status)); |
628 | 612 | ||
629 | return success; | 613 | return success; |
@@ -767,8 +751,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm) | |||
767 | 751 | ||
768 | rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); | 752 | rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); |
769 | if (rc < 0) { | 753 | if (rc < 0) { |
770 | printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n", | 754 | pr_err("acpi_bus_get_device(%s) failed: %d\n", ibm->name, rc); |
771 | ibm->name, rc); | ||
772 | return -ENODEV; | 755 | return -ENODEV; |
773 | } | 756 | } |
774 | 757 | ||
@@ -781,12 +764,10 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm) | |||
781 | ibm->acpi->type, dispatch_acpi_notify, ibm); | 764 | ibm->acpi->type, dispatch_acpi_notify, ibm); |
782 | if (ACPI_FAILURE(status)) { | 765 | if (ACPI_FAILURE(status)) { |
783 | if (status == AE_ALREADY_EXISTS) { | 766 | if (status == AE_ALREADY_EXISTS) { |
784 | printk(TPACPI_NOTICE | 767 | pr_notice("another device driver is already " |
785 | "another device driver is already " | 768 | "handling %s events\n", ibm->name); |
786 | "handling %s events\n", ibm->name); | ||
787 | } else { | 769 | } else { |
788 | printk(TPACPI_ERR | 770 | pr_err("acpi_install_notify_handler(%s) failed: %s\n", |
789 | "acpi_install_notify_handler(%s) failed: %s\n", | ||
790 | ibm->name, acpi_format_exception(status)); | 771 | ibm->name, acpi_format_exception(status)); |
791 | } | 772 | } |
792 | return -ENODEV; | 773 | return -ENODEV; |
@@ -811,8 +792,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
811 | 792 | ||
812 | ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); | 793 | ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); |
813 | if (!ibm->acpi->driver) { | 794 | if (!ibm->acpi->driver) { |
814 | printk(TPACPI_ERR | 795 | pr_err("failed to allocate memory for ibm->acpi->driver\n"); |
815 | "failed to allocate memory for ibm->acpi->driver\n"); | ||
816 | return -ENOMEM; | 796 | return -ENOMEM; |
817 | } | 797 | } |
818 | 798 | ||
@@ -823,7 +803,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
823 | 803 | ||
824 | rc = acpi_bus_register_driver(ibm->acpi->driver); | 804 | rc = acpi_bus_register_driver(ibm->acpi->driver); |
825 | if (rc < 0) { | 805 | if (rc < 0) { |
826 | printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n", | 806 | pr_err("acpi_bus_register_driver(%s) failed: %d\n", |
827 | ibm->name, rc); | 807 | ibm->name, rc); |
828 | kfree(ibm->acpi->driver); | 808 | kfree(ibm->acpi->driver); |
829 | ibm->acpi->driver = NULL; | 809 | ibm->acpi->driver = NULL; |
@@ -1081,15 +1061,14 @@ static int parse_strtoul(const char *buf, | |||
1081 | static void tpacpi_disable_brightness_delay(void) | 1061 | static void tpacpi_disable_brightness_delay(void) |
1082 | { | 1062 | { |
1083 | if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) | 1063 | if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) |
1084 | printk(TPACPI_NOTICE | 1064 | pr_notice("ACPI backlight control delay disabled\n"); |
1085 | "ACPI backlight control delay disabled\n"); | ||
1086 | } | 1065 | } |
1087 | 1066 | ||
1088 | static void printk_deprecated_attribute(const char * const what, | 1067 | static void printk_deprecated_attribute(const char * const what, |
1089 | const char * const details) | 1068 | const char * const details) |
1090 | { | 1069 | { |
1091 | tpacpi_log_usertask("deprecated sysfs attribute"); | 1070 | tpacpi_log_usertask("deprecated sysfs attribute"); |
1092 | printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " | 1071 | pr_warn("WARNING: sysfs attribute %s is deprecated and " |
1093 | "will be removed. %s\n", | 1072 | "will be removed. %s\n", |
1094 | what, details); | 1073 | what, details); |
1095 | } | 1074 | } |
@@ -1264,8 +1243,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1264 | &tpacpi_rfk_rfkill_ops, | 1243 | &tpacpi_rfk_rfkill_ops, |
1265 | atp_rfk); | 1244 | atp_rfk); |
1266 | if (!atp_rfk || !atp_rfk->rfkill) { | 1245 | if (!atp_rfk || !atp_rfk->rfkill) { |
1267 | printk(TPACPI_ERR | 1246 | pr_err("failed to allocate memory for rfkill class\n"); |
1268 | "failed to allocate memory for rfkill class\n"); | ||
1269 | kfree(atp_rfk); | 1247 | kfree(atp_rfk); |
1270 | return -ENOMEM; | 1248 | return -ENOMEM; |
1271 | } | 1249 | } |
@@ -1275,9 +1253,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1275 | 1253 | ||
1276 | sw_status = (tp_rfkops->get_status)(); | 1254 | sw_status = (tp_rfkops->get_status)(); |
1277 | if (sw_status < 0) { | 1255 | if (sw_status < 0) { |
1278 | printk(TPACPI_ERR | 1256 | pr_err("failed to read initial state for %s, error %d\n", |
1279 | "failed to read initial state for %s, error %d\n", | 1257 | name, sw_status); |
1280 | name, sw_status); | ||
1281 | } else { | 1258 | } else { |
1282 | sw_state = (sw_status == TPACPI_RFK_RADIO_OFF); | 1259 | sw_state = (sw_status == TPACPI_RFK_RADIO_OFF); |
1283 | if (set_default) { | 1260 | if (set_default) { |
@@ -1291,9 +1268,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1291 | 1268 | ||
1292 | res = rfkill_register(atp_rfk->rfkill); | 1269 | res = rfkill_register(atp_rfk->rfkill); |
1293 | if (res < 0) { | 1270 | if (res < 0) { |
1294 | printk(TPACPI_ERR | 1271 | pr_err("failed to register %s rfkill switch: %d\n", name, res); |
1295 | "failed to register %s rfkill switch: %d\n", | ||
1296 | name, res); | ||
1297 | rfkill_destroy(atp_rfk->rfkill); | 1272 | rfkill_destroy(atp_rfk->rfkill); |
1298 | kfree(atp_rfk); | 1273 | kfree(atp_rfk); |
1299 | return res; | 1274 | return res; |
@@ -1301,7 +1276,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1301 | 1276 | ||
1302 | tpacpi_rfkill_switches[id] = atp_rfk; | 1277 | tpacpi_rfkill_switches[id] = atp_rfk; |
1303 | 1278 | ||
1304 | printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n", | 1279 | pr_info("rfkill switch %s: radio is %sblocked\n", |
1305 | name, (sw_state || hw_state) ? "" : "un"); | 1280 | name, (sw_state || hw_state) ? "" : "un"); |
1306 | return 0; | 1281 | return 0; |
1307 | } | 1282 | } |
@@ -1825,10 +1800,8 @@ static void __init tpacpi_check_outdated_fw(void) | |||
1825 | * broken, or really stable to begin with, so it is | 1800 | * broken, or really stable to begin with, so it is |
1826 | * best if the user upgrades the firmware anyway. | 1801 | * best if the user upgrades the firmware anyway. |
1827 | */ | 1802 | */ |
1828 | printk(TPACPI_WARN | 1803 | pr_warn("WARNING: Outdated ThinkPad BIOS/EC firmware\n"); |
1829 | "WARNING: Outdated ThinkPad BIOS/EC firmware\n"); | 1804 | pr_warn("WARNING: This firmware may be missing critical bug " |
1830 | printk(TPACPI_WARN | ||
1831 | "WARNING: This firmware may be missing critical bug " | ||
1832 | "fixes and/or important features\n"); | 1805 | "fixes and/or important features\n"); |
1833 | } | 1806 | } |
1834 | } | 1807 | } |
@@ -2117,9 +2090,7 @@ void static hotkey_mask_warn_incomplete_mask(void) | |||
2117 | (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK); | 2090 | (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK); |
2118 | 2091 | ||
2119 | if (wantedmask) | 2092 | if (wantedmask) |
2120 | printk(TPACPI_NOTICE | 2093 | pr_notice("required events 0x%08x not enabled!\n", wantedmask); |
2121 | "required events 0x%08x not enabled!\n", | ||
2122 | wantedmask); | ||
2123 | } | 2094 | } |
2124 | 2095 | ||
2125 | /* | 2096 | /* |
@@ -2157,10 +2128,9 @@ static int hotkey_mask_set(u32 mask) | |||
2157 | * a given event. | 2128 | * a given event. |
2158 | */ | 2129 | */ |
2159 | if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) { | 2130 | if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) { |
2160 | printk(TPACPI_NOTICE | 2131 | pr_notice("asked for hotkey mask 0x%08x, but " |
2161 | "asked for hotkey mask 0x%08x, but " | 2132 | "firmware forced it to 0x%08x\n", |
2162 | "firmware forced it to 0x%08x\n", | 2133 | fwmask, hotkey_acpi_mask); |
2163 | fwmask, hotkey_acpi_mask); | ||
2164 | } | 2134 | } |
2165 | 2135 | ||
2166 | if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) | 2136 | if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) |
@@ -2184,13 +2154,11 @@ static int hotkey_user_mask_set(const u32 mask) | |||
2184 | (mask == 0xffff || mask == 0xffffff || | 2154 | (mask == 0xffff || mask == 0xffffff || |
2185 | mask == 0xffffffff)) { | 2155 | mask == 0xffffffff)) { |
2186 | tp_warned.hotkey_mask_ff = 1; | 2156 | tp_warned.hotkey_mask_ff = 1; |
2187 | printk(TPACPI_NOTICE | 2157 | pr_notice("setting the hotkey mask to 0x%08x is likely " |
2188 | "setting the hotkey mask to 0x%08x is likely " | 2158 | "not the best way to go about it\n", mask); |
2189 | "not the best way to go about it\n", mask); | 2159 | pr_notice("please consider using the driver defaults, " |
2190 | printk(TPACPI_NOTICE | 2160 | "and refer to up-to-date thinkpad-acpi " |
2191 | "please consider using the driver defaults, " | 2161 | "documentation\n"); |
2192 | "and refer to up-to-date thinkpad-acpi " | ||
2193 | "documentation\n"); | ||
2194 | } | 2162 | } |
2195 | 2163 | ||
2196 | /* Try to enable what the user asked for, plus whatever we need. | 2164 | /* Try to enable what the user asked for, plus whatever we need. |
@@ -2574,8 +2542,7 @@ static void hotkey_poll_setup(const bool may_warn) | |||
2574 | NULL, TPACPI_NVRAM_KTHREAD_NAME); | 2542 | NULL, TPACPI_NVRAM_KTHREAD_NAME); |
2575 | if (IS_ERR(tpacpi_hotkey_task)) { | 2543 | if (IS_ERR(tpacpi_hotkey_task)) { |
2576 | tpacpi_hotkey_task = NULL; | 2544 | tpacpi_hotkey_task = NULL; |
2577 | printk(TPACPI_ERR | 2545 | pr_err("could not create kernel thread " |
2578 | "could not create kernel thread " | ||
2579 | "for hotkey polling\n"); | 2546 | "for hotkey polling\n"); |
2580 | } | 2547 | } |
2581 | } | 2548 | } |
@@ -2583,11 +2550,10 @@ static void hotkey_poll_setup(const bool may_warn) | |||
2583 | hotkey_poll_stop_sync(); | 2550 | hotkey_poll_stop_sync(); |
2584 | if (may_warn && (poll_driver_mask || poll_user_mask) && | 2551 | if (may_warn && (poll_driver_mask || poll_user_mask) && |
2585 | hotkey_poll_freq == 0) { | 2552 | hotkey_poll_freq == 0) { |
2586 | printk(TPACPI_NOTICE | 2553 | pr_notice("hot keys 0x%08x and/or events 0x%08x " |
2587 | "hot keys 0x%08x and/or events 0x%08x " | 2554 | "require polling, which is currently " |
2588 | "require polling, which is currently " | 2555 | "disabled\n", |
2589 | "disabled\n", | 2556 | poll_user_mask, poll_driver_mask); |
2590 | poll_user_mask, poll_driver_mask); | ||
2591 | } | 2557 | } |
2592 | } | 2558 | } |
2593 | } | 2559 | } |
@@ -2811,13 +2777,13 @@ static ssize_t hotkey_source_mask_store(struct device *dev, | |||
2811 | mutex_unlock(&hotkey_mutex); | 2777 | mutex_unlock(&hotkey_mutex); |
2812 | 2778 | ||
2813 | if (rc < 0) | 2779 | if (rc < 0) |
2814 | printk(TPACPI_ERR "hotkey_source_mask: failed to update the" | 2780 | pr_err("hotkey_source_mask: " |
2815 | "firmware event mask!\n"); | 2781 | "failed to update the firmware event mask!\n"); |
2816 | 2782 | ||
2817 | if (r_ev) | 2783 | if (r_ev) |
2818 | printk(TPACPI_NOTICE "hotkey_source_mask: " | 2784 | pr_notice("hotkey_source_mask: " |
2819 | "some important events were disabled: " | 2785 | "some important events were disabled: 0x%04x\n", |
2820 | "0x%04x\n", r_ev); | 2786 | r_ev); |
2821 | 2787 | ||
2822 | tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); | 2788 | tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); |
2823 | 2789 | ||
@@ -3048,8 +3014,7 @@ static void hotkey_exit(void) | |||
3048 | if (((tp_features.hotkey_mask && | 3014 | if (((tp_features.hotkey_mask && |
3049 | hotkey_mask_set(hotkey_orig_mask)) | | 3015 | hotkey_mask_set(hotkey_orig_mask)) | |
3050 | hotkey_status_set(false)) != 0) | 3016 | hotkey_status_set(false)) != 0) |
3051 | printk(TPACPI_ERR | 3017 | pr_err("failed to restore hot key mask " |
3052 | "failed to restore hot key mask " | ||
3053 | "to BIOS defaults\n"); | 3018 | "to BIOS defaults\n"); |
3054 | } | 3019 | } |
3055 | 3020 | ||
@@ -3288,10 +3253,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3288 | for HKEY interface version 0x100 */ | 3253 | for HKEY interface version 0x100 */ |
3289 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 3254 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { |
3290 | if ((hkeyv >> 8) != 1) { | 3255 | if ((hkeyv >> 8) != 1) { |
3291 | printk(TPACPI_ERR "unknown version of the " | 3256 | pr_err("unknown version of the HKEY interface: 0x%x\n", |
3292 | "HKEY interface: 0x%x\n", hkeyv); | 3257 | hkeyv); |
3293 | printk(TPACPI_ERR "please report this to %s\n", | 3258 | pr_err("please report this to %s\n", TPACPI_MAIL); |
3294 | TPACPI_MAIL); | ||
3295 | } else { | 3259 | } else { |
3296 | /* | 3260 | /* |
3297 | * MHKV 0x100 in A31, R40, R40e, | 3261 | * MHKV 0x100 in A31, R40, R40e, |
@@ -3304,8 +3268,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3304 | /* Paranoia check AND init hotkey_all_mask */ | 3268 | /* Paranoia check AND init hotkey_all_mask */ |
3305 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | 3269 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, |
3306 | "MHKA", "qd")) { | 3270 | "MHKA", "qd")) { |
3307 | printk(TPACPI_ERR | 3271 | pr_err("missing MHKA handler, " |
3308 | "missing MHKA handler, " | ||
3309 | "please report this to %s\n", | 3272 | "please report this to %s\n", |
3310 | TPACPI_MAIL); | 3273 | TPACPI_MAIL); |
3311 | /* Fallback: pre-init for FN+F3,F4,F12 */ | 3274 | /* Fallback: pre-init for FN+F3,F4,F12 */ |
@@ -3343,16 +3306,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3343 | if (dbg_wlswemul) { | 3306 | if (dbg_wlswemul) { |
3344 | tp_features.hotkey_wlsw = 1; | 3307 | tp_features.hotkey_wlsw = 1; |
3345 | radiosw_state = !!tpacpi_wlsw_emulstate; | 3308 | radiosw_state = !!tpacpi_wlsw_emulstate; |
3346 | printk(TPACPI_INFO | 3309 | pr_info("radio switch emulation enabled\n"); |
3347 | "radio switch emulation enabled\n"); | ||
3348 | } else | 3310 | } else |
3349 | #endif | 3311 | #endif |
3350 | /* Not all thinkpads have a hardware radio switch */ | 3312 | /* Not all thinkpads have a hardware radio switch */ |
3351 | if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { | 3313 | if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { |
3352 | tp_features.hotkey_wlsw = 1; | 3314 | tp_features.hotkey_wlsw = 1; |
3353 | radiosw_state = !!status; | 3315 | radiosw_state = !!status; |
3354 | printk(TPACPI_INFO | 3316 | pr_info("radio switch found; radios are %s\n", |
3355 | "radio switch found; radios are %s\n", | ||
3356 | enabled(status, 0)); | 3317 | enabled(status, 0)); |
3357 | } | 3318 | } |
3358 | if (tp_features.hotkey_wlsw) | 3319 | if (tp_features.hotkey_wlsw) |
@@ -3363,8 +3324,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3363 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { | 3324 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { |
3364 | tp_features.hotkey_tablet = 1; | 3325 | tp_features.hotkey_tablet = 1; |
3365 | tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK); | 3326 | tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK); |
3366 | printk(TPACPI_INFO | 3327 | pr_info("possible tablet mode switch found; " |
3367 | "possible tablet mode switch found; " | ||
3368 | "ThinkPad in %s mode\n", | 3328 | "ThinkPad in %s mode\n", |
3369 | (tabletsw_state) ? "tablet" : "laptop"); | 3329 | (tabletsw_state) ? "tablet" : "laptop"); |
3370 | res = add_to_attr_set(hotkey_dev_attributes, | 3330 | res = add_to_attr_set(hotkey_dev_attributes, |
@@ -3382,8 +3342,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3382 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | 3342 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, |
3383 | GFP_KERNEL); | 3343 | GFP_KERNEL); |
3384 | if (!hotkey_keycode_map) { | 3344 | if (!hotkey_keycode_map) { |
3385 | printk(TPACPI_ERR | 3345 | pr_err("failed to allocate memory for key map\n"); |
3386 | "failed to allocate memory for key map\n"); | ||
3387 | res = -ENOMEM; | 3346 | res = -ENOMEM; |
3388 | goto err_exit; | 3347 | goto err_exit; |
3389 | } | 3348 | } |
@@ -3426,13 +3385,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3426 | * userspace. tpacpi_detect_brightness_capabilities() must have | 3385 | * userspace. tpacpi_detect_brightness_capabilities() must have |
3427 | * been called before this point */ | 3386 | * been called before this point */ |
3428 | if (tp_features.bright_acpimode && acpi_video_backlight_support()) { | 3387 | if (tp_features.bright_acpimode && acpi_video_backlight_support()) { |
3429 | printk(TPACPI_INFO | 3388 | pr_info("This ThinkPad has standard ACPI backlight " |
3430 | "This ThinkPad has standard ACPI backlight " | 3389 | "brightness control, supported by the ACPI " |
3431 | "brightness control, supported by the ACPI " | 3390 | "video driver\n"); |
3432 | "video driver\n"); | 3391 | pr_notice("Disabling thinkpad-acpi brightness events " |
3433 | printk(TPACPI_NOTICE | 3392 | "by default...\n"); |
3434 | "Disabling thinkpad-acpi brightness events " | ||
3435 | "by default...\n"); | ||
3436 | 3393 | ||
3437 | /* Disable brightness up/down on Lenovo thinkpads when | 3394 | /* Disable brightness up/down on Lenovo thinkpads when |
3438 | * ACPI is handling them, otherwise it is plain impossible | 3395 | * ACPI is handling them, otherwise it is plain impossible |
@@ -3539,8 +3496,7 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
3539 | 3496 | ||
3540 | case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */ | 3497 | case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */ |
3541 | case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */ | 3498 | case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */ |
3542 | printk(TPACPI_ALERT | 3499 | pr_alert("EMERGENCY WAKEUP: battery almost empty\n"); |
3543 | "EMERGENCY WAKEUP: battery almost empty\n"); | ||
3544 | /* how to auto-heal: */ | 3500 | /* how to auto-heal: */ |
3545 | /* 2313: woke up from S3, go to S4/S5 */ | 3501 | /* 2313: woke up from S3, go to S4/S5 */ |
3546 | /* 2413: woke up from S4, go to S5 */ | 3502 | /* 2413: woke up from S4, go to S5 */ |
@@ -3551,9 +3507,7 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
3551 | } | 3507 | } |
3552 | 3508 | ||
3553 | if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { | 3509 | if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { |
3554 | printk(TPACPI_INFO | 3510 | pr_info("woke up due to a hot-unplug request...\n"); |
3555 | "woke up due to a hot-unplug " | ||
3556 | "request...\n"); | ||
3557 | hotkey_wakeup_reason_notify_change(); | 3511 | hotkey_wakeup_reason_notify_change(); |
3558 | } | 3512 | } |
3559 | return true; | 3513 | return true; |
@@ -3605,37 +3559,31 @@ static bool hotkey_notify_thermal(const u32 hkey, | |||
3605 | 3559 | ||
3606 | switch (hkey) { | 3560 | switch (hkey) { |
3607 | case TP_HKEY_EV_THM_TABLE_CHANGED: | 3561 | case TP_HKEY_EV_THM_TABLE_CHANGED: |
3608 | printk(TPACPI_INFO | 3562 | pr_info("EC reports that Thermal Table has changed\n"); |
3609 | "EC reports that Thermal Table has changed\n"); | ||
3610 | /* recommended action: do nothing, we don't have | 3563 | /* recommended action: do nothing, we don't have |
3611 | * Lenovo ATM information */ | 3564 | * Lenovo ATM information */ |
3612 | return true; | 3565 | return true; |
3613 | case TP_HKEY_EV_ALARM_BAT_HOT: | 3566 | case TP_HKEY_EV_ALARM_BAT_HOT: |
3614 | printk(TPACPI_CRIT | 3567 | pr_crit("THERMAL ALARM: battery is too hot!\n"); |
3615 | "THERMAL ALARM: battery is too hot!\n"); | ||
3616 | /* recommended action: warn user through gui */ | 3568 | /* recommended action: warn user through gui */ |
3617 | break; | 3569 | break; |
3618 | case TP_HKEY_EV_ALARM_BAT_XHOT: | 3570 | case TP_HKEY_EV_ALARM_BAT_XHOT: |
3619 | printk(TPACPI_ALERT | 3571 | pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n"); |
3620 | "THERMAL EMERGENCY: battery is extremely hot!\n"); | ||
3621 | /* recommended action: immediate sleep/hibernate */ | 3572 | /* recommended action: immediate sleep/hibernate */ |
3622 | break; | 3573 | break; |
3623 | case TP_HKEY_EV_ALARM_SENSOR_HOT: | 3574 | case TP_HKEY_EV_ALARM_SENSOR_HOT: |
3624 | printk(TPACPI_CRIT | 3575 | pr_crit("THERMAL ALARM: " |
3625 | "THERMAL ALARM: " | ||
3626 | "a sensor reports something is too hot!\n"); | 3576 | "a sensor reports something is too hot!\n"); |
3627 | /* recommended action: warn user through gui, that */ | 3577 | /* recommended action: warn user through gui, that */ |
3628 | /* some internal component is too hot */ | 3578 | /* some internal component is too hot */ |
3629 | break; | 3579 | break; |
3630 | case TP_HKEY_EV_ALARM_SENSOR_XHOT: | 3580 | case TP_HKEY_EV_ALARM_SENSOR_XHOT: |
3631 | printk(TPACPI_ALERT | 3581 | pr_alert("THERMAL EMERGENCY: " |
3632 | "THERMAL EMERGENCY: " | 3582 | "a sensor reports something is extremely hot!\n"); |
3633 | "a sensor reports something is extremely hot!\n"); | ||
3634 | /* recommended action: immediate sleep/hibernate */ | 3583 | /* recommended action: immediate sleep/hibernate */ |
3635 | break; | 3584 | break; |
3636 | default: | 3585 | default: |
3637 | printk(TPACPI_ALERT | 3586 | pr_alert("THERMAL ALERT: unknown thermal alarm received\n"); |
3638 | "THERMAL ALERT: unknown thermal alarm received\n"); | ||
3639 | known = false; | 3587 | known = false; |
3640 | } | 3588 | } |
3641 | 3589 | ||
@@ -3652,8 +3600,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3652 | bool known_ev; | 3600 | bool known_ev; |
3653 | 3601 | ||
3654 | if (event != 0x80) { | 3602 | if (event != 0x80) { |
3655 | printk(TPACPI_ERR | 3603 | pr_err("unknown HKEY notification event %d\n", event); |
3656 | "unknown HKEY notification event %d\n", event); | ||
3657 | /* forward it to userspace, maybe it knows how to handle it */ | 3604 | /* forward it to userspace, maybe it knows how to handle it */ |
3658 | acpi_bus_generate_netlink_event( | 3605 | acpi_bus_generate_netlink_event( |
3659 | ibm->acpi->device->pnp.device_class, | 3606 | ibm->acpi->device->pnp.device_class, |
@@ -3664,7 +3611,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3664 | 3611 | ||
3665 | while (1) { | 3612 | while (1) { |
3666 | if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { | 3613 | if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { |
3667 | printk(TPACPI_ERR "failed to retrieve HKEY event\n"); | 3614 | pr_err("failed to retrieve HKEY event\n"); |
3668 | return; | 3615 | return; |
3669 | } | 3616 | } |
3670 | 3617 | ||
@@ -3692,8 +3639,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3692 | switch (hkey) { | 3639 | switch (hkey) { |
3693 | case TP_HKEY_EV_BAYEJ_ACK: | 3640 | case TP_HKEY_EV_BAYEJ_ACK: |
3694 | hotkey_autosleep_ack = 1; | 3641 | hotkey_autosleep_ack = 1; |
3695 | printk(TPACPI_INFO | 3642 | pr_info("bay ejected\n"); |
3696 | "bay ejected\n"); | ||
3697 | hotkey_wakeup_hotunplug_complete_notify_change(); | 3643 | hotkey_wakeup_hotunplug_complete_notify_change(); |
3698 | known_ev = true; | 3644 | known_ev = true; |
3699 | break; | 3645 | break; |
@@ -3709,8 +3655,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3709 | /* 0x4000-0x4FFF: dock-related wakeups */ | 3655 | /* 0x4000-0x4FFF: dock-related wakeups */ |
3710 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { | 3656 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { |
3711 | hotkey_autosleep_ack = 1; | 3657 | hotkey_autosleep_ack = 1; |
3712 | printk(TPACPI_INFO | 3658 | pr_info("undocked\n"); |
3713 | "undocked\n"); | ||
3714 | hotkey_wakeup_hotunplug_complete_notify_change(); | 3659 | hotkey_wakeup_hotunplug_complete_notify_change(); |
3715 | known_ev = true; | 3660 | known_ev = true; |
3716 | } else { | 3661 | } else { |
@@ -3741,11 +3686,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3741 | known_ev = false; | 3686 | known_ev = false; |
3742 | } | 3687 | } |
3743 | if (!known_ev) { | 3688 | if (!known_ev) { |
3744 | printk(TPACPI_NOTICE | 3689 | pr_notice("unhandled HKEY event 0x%04x\n", hkey); |
3745 | "unhandled HKEY event 0x%04x\n", hkey); | 3690 | pr_notice("please report the conditions when this " |
3746 | printk(TPACPI_NOTICE | 3691 | "event happened to %s\n", TPACPI_MAIL); |
3747 | "please report the conditions when this " | ||
3748 | "event happened to %s\n", TPACPI_MAIL); | ||
3749 | } | 3692 | } |
3750 | 3693 | ||
3751 | /* Legacy events */ | 3694 | /* Legacy events */ |
@@ -3778,8 +3721,7 @@ static void hotkey_resume(void) | |||
3778 | 3721 | ||
3779 | if (hotkey_status_set(true) < 0 || | 3722 | if (hotkey_status_set(true) < 0 || |
3780 | hotkey_mask_set(hotkey_acpi_mask) < 0) | 3723 | hotkey_mask_set(hotkey_acpi_mask) < 0) |
3781 | printk(TPACPI_ERR | 3724 | pr_err("error while attempting to reset the event " |
3782 | "error while attempting to reset the event " | ||
3783 | "firmware interface\n"); | 3725 | "firmware interface\n"); |
3784 | 3726 | ||
3785 | tpacpi_send_radiosw_update(); | 3727 | tpacpi_send_radiosw_update(); |
@@ -3824,14 +3766,12 @@ static void hotkey_enabledisable_warn(bool enable) | |||
3824 | { | 3766 | { |
3825 | tpacpi_log_usertask("procfs hotkey enable/disable"); | 3767 | tpacpi_log_usertask("procfs hotkey enable/disable"); |
3826 | if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable), | 3768 | if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable), |
3827 | TPACPI_WARN | 3769 | pr_fmt("hotkey enable/disable functionality has been " |
3828 | "hotkey enable/disable functionality has been " | 3770 | "removed from the driver. " |
3829 | "removed from the driver. Hotkeys are always " | 3771 | "Hotkeys are always enabled.\n"))) |
3830 | "enabled\n")) | 3772 | pr_err("Please remove the hotkey=enable module " |
3831 | printk(TPACPI_ERR | 3773 | "parameter, it is deprecated. " |
3832 | "Please remove the hotkey=enable module " | 3774 | "Hotkeys are always enabled.\n"); |
3833 | "parameter, it is deprecated. Hotkeys are always " | ||
3834 | "enabled\n"); | ||
3835 | } | 3775 | } |
3836 | 3776 | ||
3837 | static int hotkey_write(char *buf) | 3777 | static int hotkey_write(char *buf) |
@@ -4011,8 +3951,7 @@ static void bluetooth_shutdown(void) | |||
4011 | /* Order firmware to save current state to NVRAM */ | 3951 | /* Order firmware to save current state to NVRAM */ |
4012 | if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", | 3952 | if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", |
4013 | TP_ACPI_BLTH_SAVE_STATE)) | 3953 | TP_ACPI_BLTH_SAVE_STATE)) |
4014 | printk(TPACPI_NOTICE | 3954 | pr_notice("failed to save bluetooth state to NVRAM\n"); |
4015 | "failed to save bluetooth state to NVRAM\n"); | ||
4016 | else | 3955 | else |
4017 | vdbg_printk(TPACPI_DBG_RFKILL, | 3956 | vdbg_printk(TPACPI_DBG_RFKILL, |
4018 | "bluestooth state saved to NVRAM\n"); | 3957 | "bluestooth state saved to NVRAM\n"); |
@@ -4051,8 +3990,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
4051 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 3990 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
4052 | if (dbg_bluetoothemul) { | 3991 | if (dbg_bluetoothemul) { |
4053 | tp_features.bluetooth = 1; | 3992 | tp_features.bluetooth = 1; |
4054 | printk(TPACPI_INFO | 3993 | pr_info("bluetooth switch emulation enabled\n"); |
4055 | "bluetooth switch emulation enabled\n"); | ||
4056 | } else | 3994 | } else |
4057 | #endif | 3995 | #endif |
4058 | if (tp_features.bluetooth && | 3996 | if (tp_features.bluetooth && |
@@ -4203,8 +4141,7 @@ static void wan_shutdown(void) | |||
4203 | /* Order firmware to save current state to NVRAM */ | 4141 | /* Order firmware to save current state to NVRAM */ |
4204 | if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd", | 4142 | if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd", |
4205 | TP_ACPI_WGSV_SAVE_STATE)) | 4143 | TP_ACPI_WGSV_SAVE_STATE)) |
4206 | printk(TPACPI_NOTICE | 4144 | pr_notice("failed to save WWAN state to NVRAM\n"); |
4207 | "failed to save WWAN state to NVRAM\n"); | ||
4208 | else | 4145 | else |
4209 | vdbg_printk(TPACPI_DBG_RFKILL, | 4146 | vdbg_printk(TPACPI_DBG_RFKILL, |
4210 | "WWAN state saved to NVRAM\n"); | 4147 | "WWAN state saved to NVRAM\n"); |
@@ -4241,8 +4178,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) | |||
4241 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 4178 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
4242 | if (dbg_wwanemul) { | 4179 | if (dbg_wwanemul) { |
4243 | tp_features.wan = 1; | 4180 | tp_features.wan = 1; |
4244 | printk(TPACPI_INFO | 4181 | pr_info("wwan switch emulation enabled\n"); |
4245 | "wwan switch emulation enabled\n"); | ||
4246 | } else | 4182 | } else |
4247 | #endif | 4183 | #endif |
4248 | if (tp_features.wan && | 4184 | if (tp_features.wan && |
@@ -4382,8 +4318,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm) | |||
4382 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 4318 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
4383 | if (dbg_uwbemul) { | 4319 | if (dbg_uwbemul) { |
4384 | tp_features.uwb = 1; | 4320 | tp_features.uwb = 1; |
4385 | printk(TPACPI_INFO | 4321 | pr_info("uwb switch emulation enabled\n"); |
4386 | "uwb switch emulation enabled\n"); | ||
4387 | } else | 4322 | } else |
4388 | #endif | 4323 | #endif |
4389 | if (tp_features.uwb && | 4324 | if (tp_features.uwb && |
@@ -4444,6 +4379,15 @@ static int video_orig_autosw; | |||
4444 | static int video_autosw_get(void); | 4379 | static int video_autosw_get(void); |
4445 | static int video_autosw_set(int enable); | 4380 | static int video_autosw_set(int enable); |
4446 | 4381 | ||
4382 | TPACPI_HANDLE(vid, root, | ||
4383 | "\\_SB.PCI.AGP.VGA", /* 570 */ | ||
4384 | "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ | ||
4385 | "\\_SB.PCI0.VID0", /* 770e */ | ||
4386 | "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ | ||
4387 | "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */ | ||
4388 | "\\_SB.PCI0.AGP.VID", /* all others */ | ||
4389 | ); /* R30, R31 */ | ||
4390 | |||
4447 | TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ | 4391 | TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ |
4448 | 4392 | ||
4449 | static int __init video_init(struct ibm_init_struct *iibm) | 4393 | static int __init video_init(struct ibm_init_struct *iibm) |
@@ -4487,7 +4431,7 @@ static void video_exit(void) | |||
4487 | dbg_printk(TPACPI_DBG_EXIT, | 4431 | dbg_printk(TPACPI_DBG_EXIT, |
4488 | "restoring original video autoswitch mode\n"); | 4432 | "restoring original video autoswitch mode\n"); |
4489 | if (video_autosw_set(video_orig_autosw)) | 4433 | if (video_autosw_set(video_orig_autosw)) |
4490 | printk(TPACPI_ERR "error while trying to restore original " | 4434 | pr_err("error while trying to restore original " |
4491 | "video autoswitch mode\n"); | 4435 | "video autoswitch mode\n"); |
4492 | } | 4436 | } |
4493 | 4437 | ||
@@ -4560,8 +4504,7 @@ static int video_outputsw_set(int status) | |||
4560 | res = acpi_evalf(vid_handle, NULL, | 4504 | res = acpi_evalf(vid_handle, NULL, |
4561 | "ASWT", "vdd", status * 0x100, 0); | 4505 | "ASWT", "vdd", status * 0x100, 0); |
4562 | if (!autosw && video_autosw_set(autosw)) { | 4506 | if (!autosw && video_autosw_set(autosw)) { |
4563 | printk(TPACPI_ERR | 4507 | pr_err("video auto-switch left enabled due to error\n"); |
4564 | "video auto-switch left enabled due to error\n"); | ||
4565 | return -EIO; | 4508 | return -EIO; |
4566 | } | 4509 | } |
4567 | break; | 4510 | break; |
@@ -4630,8 +4573,7 @@ static int video_outputsw_cycle(void) | |||
4630 | return -ENOSYS; | 4573 | return -ENOSYS; |
4631 | } | 4574 | } |
4632 | if (!autosw && video_autosw_set(autosw)) { | 4575 | if (!autosw && video_autosw_set(autosw)) { |
4633 | printk(TPACPI_ERR | 4576 | pr_err("video auto-switch left enabled due to error\n"); |
4634 | "video auto-switch left enabled due to error\n"); | ||
4635 | return -EIO; | 4577 | return -EIO; |
4636 | } | 4578 | } |
4637 | 4579 | ||
@@ -5348,7 +5290,7 @@ static int __init led_init(struct ibm_init_struct *iibm) | |||
5348 | tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, | 5290 | tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, |
5349 | GFP_KERNEL); | 5291 | GFP_KERNEL); |
5350 | if (!tpacpi_leds) { | 5292 | if (!tpacpi_leds) { |
5351 | printk(TPACPI_ERR "Out of memory for LED data\n"); | 5293 | pr_err("Out of memory for LED data\n"); |
5352 | return -ENOMEM; | 5294 | return -ENOMEM; |
5353 | } | 5295 | } |
5354 | 5296 | ||
@@ -5367,9 +5309,8 @@ static int __init led_init(struct ibm_init_struct *iibm) | |||
5367 | } | 5309 | } |
5368 | 5310 | ||
5369 | #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS | 5311 | #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS |
5370 | printk(TPACPI_NOTICE | 5312 | pr_notice("warning: userspace override of important " |
5371 | "warning: userspace override of important " | 5313 | "firmware LEDs is enabled\n"); |
5372 | "firmware LEDs is enabled\n"); | ||
5373 | #endif | 5314 | #endif |
5374 | return 0; | 5315 | return 0; |
5375 | } | 5316 | } |
@@ -5639,17 +5580,16 @@ static void thermal_dump_all_sensors(void) | |||
5639 | if (n <= 0) | 5580 | if (n <= 0) |
5640 | return; | 5581 | return; |
5641 | 5582 | ||
5642 | printk(TPACPI_NOTICE | 5583 | pr_notice("temperatures (Celsius):"); |
5643 | "temperatures (Celsius):"); | ||
5644 | 5584 | ||
5645 | for (i = 0; i < n; i++) { | 5585 | for (i = 0; i < n; i++) { |
5646 | if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) | 5586 | if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) |
5647 | printk(KERN_CONT " %d", (int)(t.temp[i] / 1000)); | 5587 | pr_cont(" %d", (int)(t.temp[i] / 1000)); |
5648 | else | 5588 | else |
5649 | printk(KERN_CONT " N/A"); | 5589 | pr_cont(" N/A"); |
5650 | } | 5590 | } |
5651 | 5591 | ||
5652 | printk(KERN_CONT "\n"); | 5592 | pr_cont("\n"); |
5653 | } | 5593 | } |
5654 | 5594 | ||
5655 | /* sysfs temp##_input -------------------------------------------------- */ | 5595 | /* sysfs temp##_input -------------------------------------------------- */ |
@@ -5769,14 +5709,12 @@ static int __init thermal_init(struct ibm_init_struct *iibm) | |||
5769 | if (ta1 == 0) { | 5709 | if (ta1 == 0) { |
5770 | /* This is sheer paranoia, but we handle it anyway */ | 5710 | /* This is sheer paranoia, but we handle it anyway */ |
5771 | if (acpi_tmp7) { | 5711 | if (acpi_tmp7) { |
5772 | printk(TPACPI_ERR | 5712 | pr_err("ThinkPad ACPI EC access misbehaving, " |
5773 | "ThinkPad ACPI EC access misbehaving, " | ||
5774 | "falling back to ACPI TMPx access " | 5713 | "falling back to ACPI TMPx access " |
5775 | "mode\n"); | 5714 | "mode\n"); |
5776 | thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; | 5715 | thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; |
5777 | } else { | 5716 | } else { |
5778 | printk(TPACPI_ERR | 5717 | pr_err("ThinkPad ACPI EC access misbehaving, " |
5779 | "ThinkPad ACPI EC access misbehaving, " | ||
5780 | "disabling thermal sensors access\n"); | 5718 | "disabling thermal sensors access\n"); |
5781 | thermal_read_mode = TPACPI_THERMAL_NONE; | 5719 | thermal_read_mode = TPACPI_THERMAL_NONE; |
5782 | } | 5720 | } |
@@ -6129,8 +6067,8 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle) | |||
6129 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { | 6067 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { |
6130 | obj = (union acpi_object *)buffer.pointer; | 6068 | obj = (union acpi_object *)buffer.pointer; |
6131 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { | 6069 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { |
6132 | printk(TPACPI_ERR "Unknown _BCL data, " | 6070 | pr_err("Unknown _BCL data, please report this to %s\n", |
6133 | "please report this to %s\n", TPACPI_MAIL); | 6071 | TPACPI_MAIL); |
6134 | rc = 0; | 6072 | rc = 0; |
6135 | } else { | 6073 | } else { |
6136 | rc = obj->package.count; | 6074 | rc = obj->package.count; |
@@ -6214,18 +6152,15 @@ static void __init tpacpi_detect_brightness_capabilities(void) | |||
6214 | switch (b) { | 6152 | switch (b) { |
6215 | case 16: | 6153 | case 16: |
6216 | bright_maxlvl = 15; | 6154 | bright_maxlvl = 15; |
6217 | printk(TPACPI_INFO | 6155 | pr_info("detected a 16-level brightness capable ThinkPad\n"); |
6218 | "detected a 16-level brightness capable ThinkPad\n"); | ||
6219 | break; | 6156 | break; |
6220 | case 8: | 6157 | case 8: |
6221 | case 0: | 6158 | case 0: |
6222 | bright_maxlvl = 7; | 6159 | bright_maxlvl = 7; |
6223 | printk(TPACPI_INFO | 6160 | pr_info("detected a 8-level brightness capable ThinkPad\n"); |
6224 | "detected a 8-level brightness capable ThinkPad\n"); | ||
6225 | break; | 6161 | break; |
6226 | default: | 6162 | default: |
6227 | printk(TPACPI_ERR | 6163 | pr_err("Unsupported brightness interface, " |
6228 | "Unsupported brightness interface, " | ||
6229 | "please contact %s\n", TPACPI_MAIL); | 6164 | "please contact %s\n", TPACPI_MAIL); |
6230 | tp_features.bright_unkfw = 1; | 6165 | tp_features.bright_unkfw = 1; |
6231 | bright_maxlvl = b - 1; | 6166 | bright_maxlvl = b - 1; |
@@ -6260,22 +6195,19 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6260 | 6195 | ||
6261 | if (acpi_video_backlight_support()) { | 6196 | if (acpi_video_backlight_support()) { |
6262 | if (brightness_enable > 1) { | 6197 | if (brightness_enable > 1) { |
6263 | printk(TPACPI_INFO | 6198 | pr_info("Standard ACPI backlight interface " |
6264 | "Standard ACPI backlight interface " | 6199 | "available, not loading native one\n"); |
6265 | "available, not loading native one.\n"); | ||
6266 | return 1; | 6200 | return 1; |
6267 | } else if (brightness_enable == 1) { | 6201 | } else if (brightness_enable == 1) { |
6268 | printk(TPACPI_WARN | 6202 | pr_warn("Cannot enable backlight brightness support, " |
6269 | "Cannot enable backlight brightness support, " | ||
6270 | "ACPI is already handling it. Refer to the " | 6203 | "ACPI is already handling it. Refer to the " |
6271 | "acpi_backlight kernel parameter\n"); | 6204 | "acpi_backlight kernel parameter.\n"); |
6272 | return 1; | 6205 | return 1; |
6273 | } | 6206 | } |
6274 | } else if (tp_features.bright_acpimode && brightness_enable > 1) { | 6207 | } else if (tp_features.bright_acpimode && brightness_enable > 1) { |
6275 | printk(TPACPI_NOTICE | 6208 | pr_notice("Standard ACPI backlight interface not " |
6276 | "Standard ACPI backlight interface not " | 6209 | "available, thinkpad_acpi native " |
6277 | "available, thinkpad_acpi native " | 6210 | "brightness control enabled\n"); |
6278 | "brightness control enabled\n"); | ||
6279 | } | 6211 | } |
6280 | 6212 | ||
6281 | /* | 6213 | /* |
@@ -6319,19 +6251,17 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6319 | if (IS_ERR(ibm_backlight_device)) { | 6251 | if (IS_ERR(ibm_backlight_device)) { |
6320 | int rc = PTR_ERR(ibm_backlight_device); | 6252 | int rc = PTR_ERR(ibm_backlight_device); |
6321 | ibm_backlight_device = NULL; | 6253 | ibm_backlight_device = NULL; |
6322 | printk(TPACPI_ERR "Could not register backlight device\n"); | 6254 | pr_err("Could not register backlight device\n"); |
6323 | return rc; | 6255 | return rc; |
6324 | } | 6256 | } |
6325 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, | 6257 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, |
6326 | "brightness is supported\n"); | 6258 | "brightness is supported\n"); |
6327 | 6259 | ||
6328 | if (quirks & TPACPI_BRGHT_Q_ASK) { | 6260 | if (quirks & TPACPI_BRGHT_Q_ASK) { |
6329 | printk(TPACPI_NOTICE | 6261 | pr_notice("brightness: will use unverified default: " |
6330 | "brightness: will use unverified default: " | 6262 | "brightness_mode=%d\n", brightness_mode); |
6331 | "brightness_mode=%d\n", brightness_mode); | 6263 | pr_notice("brightness: please report to %s whether it works well " |
6332 | printk(TPACPI_NOTICE | 6264 | "or not on your ThinkPad\n", TPACPI_MAIL); |
6333 | "brightness: please report to %s whether it works well " | ||
6334 | "or not on your ThinkPad\n", TPACPI_MAIL); | ||
6335 | } | 6265 | } |
6336 | 6266 | ||
6337 | /* Added by mistake in early 2007. Probably useless, but it could | 6267 | /* Added by mistake in early 2007. Probably useless, but it could |
@@ -6804,8 +6734,7 @@ static int __init volume_create_alsa_mixer(void) | |||
6804 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, | 6734 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, |
6805 | sizeof(struct tpacpi_alsa_data), &card); | 6735 | sizeof(struct tpacpi_alsa_data), &card); |
6806 | if (rc < 0 || !card) { | 6736 | if (rc < 0 || !card) { |
6807 | printk(TPACPI_ERR | 6737 | pr_err("Failed to create ALSA card structures: %d\n", rc); |
6808 | "Failed to create ALSA card structures: %d\n", rc); | ||
6809 | return 1; | 6738 | return 1; |
6810 | } | 6739 | } |
6811 | 6740 | ||
@@ -6839,9 +6768,8 @@ static int __init volume_create_alsa_mixer(void) | |||
6839 | ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL); | 6768 | ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL); |
6840 | rc = snd_ctl_add(card, ctl_vol); | 6769 | rc = snd_ctl_add(card, ctl_vol); |
6841 | if (rc < 0) { | 6770 | if (rc < 0) { |
6842 | printk(TPACPI_ERR | 6771 | pr_err("Failed to create ALSA volume control: %d\n", |
6843 | "Failed to create ALSA volume control: %d\n", | 6772 | rc); |
6844 | rc); | ||
6845 | goto err_exit; | 6773 | goto err_exit; |
6846 | } | 6774 | } |
6847 | data->ctl_vol_id = &ctl_vol->id; | 6775 | data->ctl_vol_id = &ctl_vol->id; |
@@ -6850,8 +6778,7 @@ static int __init volume_create_alsa_mixer(void) | |||
6850 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); | 6778 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); |
6851 | rc = snd_ctl_add(card, ctl_mute); | 6779 | rc = snd_ctl_add(card, ctl_mute); |
6852 | if (rc < 0) { | 6780 | if (rc < 0) { |
6853 | printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n", | 6781 | pr_err("Failed to create ALSA mute control: %d\n", rc); |
6854 | rc); | ||
6855 | goto err_exit; | 6782 | goto err_exit; |
6856 | } | 6783 | } |
6857 | data->ctl_mute_id = &ctl_mute->id; | 6784 | data->ctl_mute_id = &ctl_mute->id; |
@@ -6859,7 +6786,7 @@ static int __init volume_create_alsa_mixer(void) | |||
6859 | snd_card_set_dev(card, &tpacpi_pdev->dev); | 6786 | snd_card_set_dev(card, &tpacpi_pdev->dev); |
6860 | rc = snd_card_register(card); | 6787 | rc = snd_card_register(card); |
6861 | if (rc < 0) { | 6788 | if (rc < 0) { |
6862 | printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc); | 6789 | pr_err("Failed to register ALSA card: %d\n", rc); |
6863 | goto err_exit; | 6790 | goto err_exit; |
6864 | } | 6791 | } |
6865 | 6792 | ||
@@ -6915,9 +6842,8 @@ static int __init volume_init(struct ibm_init_struct *iibm) | |||
6915 | return -EINVAL; | 6842 | return -EINVAL; |
6916 | 6843 | ||
6917 | if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) { | 6844 | if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) { |
6918 | printk(TPACPI_ERR | 6845 | pr_err("UCMS step volume mode not implemented, " |
6919 | "UCMS step volume mode not implemented, " | 6846 | "please contact %s\n", TPACPI_MAIL); |
6920 | "please contact %s\n", TPACPI_MAIL); | ||
6921 | return 1; | 6847 | return 1; |
6922 | } | 6848 | } |
6923 | 6849 | ||
@@ -6981,13 +6907,11 @@ static int __init volume_init(struct ibm_init_struct *iibm) | |||
6981 | 6907 | ||
6982 | rc = volume_create_alsa_mixer(); | 6908 | rc = volume_create_alsa_mixer(); |
6983 | if (rc) { | 6909 | if (rc) { |
6984 | printk(TPACPI_ERR | 6910 | pr_err("Could not create the ALSA mixer interface\n"); |
6985 | "Could not create the ALSA mixer interface\n"); | ||
6986 | return rc; | 6911 | return rc; |
6987 | } | 6912 | } |
6988 | 6913 | ||
6989 | printk(TPACPI_INFO | 6914 | pr_info("Console audio control enabled, mode: %s\n", |
6990 | "Console audio control enabled, mode: %s\n", | ||
6991 | (volume_control_allowed) ? | 6915 | (volume_control_allowed) ? |
6992 | "override (read/write)" : | 6916 | "override (read/write)" : |
6993 | "monitor (read only)"); | 6917 | "monitor (read only)"); |
@@ -7049,12 +6973,10 @@ static int volume_write(char *buf) | |||
7049 | if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) { | 6973 | if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) { |
7050 | if (unlikely(!tp_warned.volume_ctrl_forbidden)) { | 6974 | if (unlikely(!tp_warned.volume_ctrl_forbidden)) { |
7051 | tp_warned.volume_ctrl_forbidden = 1; | 6975 | tp_warned.volume_ctrl_forbidden = 1; |
7052 | printk(TPACPI_NOTICE | 6976 | pr_notice("Console audio control in monitor mode, " |
7053 | "Console audio control in monitor mode, " | 6977 | "changes are not allowed\n"); |
7054 | "changes are not allowed.\n"); | 6978 | pr_notice("Use the volume_control=1 module parameter " |
7055 | printk(TPACPI_NOTICE | 6979 | "to enable volume control\n"); |
7056 | "Use the volume_control=1 module parameter " | ||
7057 | "to enable volume control\n"); | ||
7058 | } | 6980 | } |
7059 | return -EPERM; | 6981 | return -EPERM; |
7060 | } | 6982 | } |
@@ -7129,8 +7051,7 @@ static void inline volume_alsa_notify_change(void) | |||
7129 | 7051 | ||
7130 | static int __init volume_init(struct ibm_init_struct *iibm) | 7052 | static int __init volume_init(struct ibm_init_struct *iibm) |
7131 | { | 7053 | { |
7132 | printk(TPACPI_INFO | 7054 | pr_info("volume: disabled as there is no ALSA support in this kernel\n"); |
7133 | "volume: disabled as there is no ALSA support in this kernel\n"); | ||
7134 | 7055 | ||
7135 | return 1; | 7056 | return 1; |
7136 | } | 7057 | } |
@@ -7337,9 +7258,8 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */ | |||
7337 | static void fan_quirk1_setup(void) | 7258 | static void fan_quirk1_setup(void) |
7338 | { | 7259 | { |
7339 | if (fan_control_initial_status == 0x07) { | 7260 | if (fan_control_initial_status == 0x07) { |
7340 | printk(TPACPI_NOTICE | 7261 | pr_notice("fan_init: initial fan status is unknown, " |
7341 | "fan_init: initial fan status is unknown, " | 7262 | "assuming it is in auto mode\n"); |
7342 | "assuming it is in auto mode\n"); | ||
7343 | tp_features.fan_ctrl_status_undef = 1; | 7263 | tp_features.fan_ctrl_status_undef = 1; |
7344 | } | 7264 | } |
7345 | } | 7265 | } |
@@ -7726,8 +7646,7 @@ static void fan_watchdog_reset(void) | |||
7726 | if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, | 7646 | if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, |
7727 | msecs_to_jiffies(fan_watchdog_maxinterval | 7647 | msecs_to_jiffies(fan_watchdog_maxinterval |
7728 | * 1000))) { | 7648 | * 1000))) { |
7729 | printk(TPACPI_ERR | 7649 | pr_err("failed to queue the fan watchdog, " |
7730 | "failed to queue the fan watchdog, " | ||
7731 | "watchdog will not trigger\n"); | 7650 | "watchdog will not trigger\n"); |
7732 | } | 7651 | } |
7733 | } else | 7652 | } else |
@@ -7741,11 +7660,11 @@ static void fan_watchdog_fire(struct work_struct *ignored) | |||
7741 | if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) | 7660 | if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) |
7742 | return; | 7661 | return; |
7743 | 7662 | ||
7744 | printk(TPACPI_NOTICE "fan watchdog: enabling fan\n"); | 7663 | pr_notice("fan watchdog: enabling fan\n"); |
7745 | rc = fan_set_enable(); | 7664 | rc = fan_set_enable(); |
7746 | if (rc < 0) { | 7665 | if (rc < 0) { |
7747 | printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, " | 7666 | pr_err("fan watchdog: error %d while enabling fan, " |
7748 | "will try again later...\n", -rc); | 7667 | "will try again later...\n", -rc); |
7749 | /* reschedule for later */ | 7668 | /* reschedule for later */ |
7750 | fan_watchdog_reset(); | 7669 | fan_watchdog_reset(); |
7751 | } | 7670 | } |
@@ -8049,8 +7968,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
8049 | "secondary fan support enabled\n"); | 7968 | "secondary fan support enabled\n"); |
8050 | } | 7969 | } |
8051 | } else { | 7970 | } else { |
8052 | printk(TPACPI_ERR | 7971 | pr_err("ThinkPad ACPI EC access misbehaving, " |
8053 | "ThinkPad ACPI EC access misbehaving, " | ||
8054 | "fan status and control unavailable\n"); | 7972 | "fan status and control unavailable\n"); |
8055 | return 1; | 7973 | return 1; |
8056 | } | 7974 | } |
@@ -8150,9 +8068,8 @@ static void fan_suspend(pm_message_t state) | |||
8150 | fan_control_resume_level = 0; | 8068 | fan_control_resume_level = 0; |
8151 | rc = fan_get_status_safe(&fan_control_resume_level); | 8069 | rc = fan_get_status_safe(&fan_control_resume_level); |
8152 | if (rc < 0) | 8070 | if (rc < 0) |
8153 | printk(TPACPI_NOTICE | 8071 | pr_notice("failed to read fan level for later " |
8154 | "failed to read fan level for later " | 8072 | "restore during resume: %d\n", rc); |
8155 | "restore during resume: %d\n", rc); | ||
8156 | 8073 | ||
8157 | /* if it is undefined, don't attempt to restore it. | 8074 | /* if it is undefined, don't attempt to restore it. |
8158 | * KEEP THIS LAST */ | 8075 | * KEEP THIS LAST */ |
@@ -8207,13 +8124,11 @@ static void fan_resume(void) | |||
8207 | return; | 8124 | return; |
8208 | } | 8125 | } |
8209 | if (do_set) { | 8126 | if (do_set) { |
8210 | printk(TPACPI_NOTICE | 8127 | pr_notice("restoring fan level to 0x%02x\n", |
8211 | "restoring fan level to 0x%02x\n", | 8128 | fan_control_resume_level); |
8212 | fan_control_resume_level); | ||
8213 | rc = fan_set_level_safe(fan_control_resume_level); | 8129 | rc = fan_set_level_safe(fan_control_resume_level); |
8214 | if (rc < 0) | 8130 | if (rc < 0) |
8215 | printk(TPACPI_NOTICE | 8131 | pr_notice("failed to restore fan level: %d\n", rc); |
8216 | "failed to restore fan level: %d\n", rc); | ||
8217 | } | 8132 | } |
8218 | } | 8133 | } |
8219 | 8134 | ||
@@ -8305,8 +8220,8 @@ static int fan_write_cmd_level(const char *cmd, int *rc) | |||
8305 | 8220 | ||
8306 | *rc = fan_set_level_safe(level); | 8221 | *rc = fan_set_level_safe(level); |
8307 | if (*rc == -ENXIO) | 8222 | if (*rc == -ENXIO) |
8308 | printk(TPACPI_ERR "level command accepted for unsupported " | 8223 | pr_err("level command accepted for unsupported access mode %d\n", |
8309 | "access mode %d", fan_control_access_mode); | 8224 | fan_control_access_mode); |
8310 | else if (!*rc) | 8225 | else if (!*rc) |
8311 | tpacpi_disclose_usertask("procfs fan", | 8226 | tpacpi_disclose_usertask("procfs fan", |
8312 | "set level to %d\n", level); | 8227 | "set level to %d\n", level); |
@@ -8321,8 +8236,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc) | |||
8321 | 8236 | ||
8322 | *rc = fan_set_enable(); | 8237 | *rc = fan_set_enable(); |
8323 | if (*rc == -ENXIO) | 8238 | if (*rc == -ENXIO) |
8324 | printk(TPACPI_ERR "enable command accepted for unsupported " | 8239 | pr_err("enable command accepted for unsupported access mode %d\n", |
8325 | "access mode %d", fan_control_access_mode); | 8240 | fan_control_access_mode); |
8326 | else if (!*rc) | 8241 | else if (!*rc) |
8327 | tpacpi_disclose_usertask("procfs fan", "enable\n"); | 8242 | tpacpi_disclose_usertask("procfs fan", "enable\n"); |
8328 | 8243 | ||
@@ -8336,8 +8251,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc) | |||
8336 | 8251 | ||
8337 | *rc = fan_set_disable(); | 8252 | *rc = fan_set_disable(); |
8338 | if (*rc == -ENXIO) | 8253 | if (*rc == -ENXIO) |
8339 | printk(TPACPI_ERR "disable command accepted for unsupported " | 8254 | pr_err("disable command accepted for unsupported access mode %d\n", |
8340 | "access mode %d", fan_control_access_mode); | 8255 | fan_control_access_mode); |
8341 | else if (!*rc) | 8256 | else if (!*rc) |
8342 | tpacpi_disclose_usertask("procfs fan", "disable\n"); | 8257 | tpacpi_disclose_usertask("procfs fan", "disable\n"); |
8343 | 8258 | ||
@@ -8356,8 +8271,8 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) | |||
8356 | 8271 | ||
8357 | *rc = fan_set_speed(speed); | 8272 | *rc = fan_set_speed(speed); |
8358 | if (*rc == -ENXIO) | 8273 | if (*rc == -ENXIO) |
8359 | printk(TPACPI_ERR "speed command accepted for unsupported " | 8274 | pr_err("speed command accepted for unsupported access mode %d\n", |
8360 | "access mode %d", fan_control_access_mode); | 8275 | fan_control_access_mode); |
8361 | else if (!*rc) | 8276 | else if (!*rc) |
8362 | tpacpi_disclose_usertask("procfs fan", | 8277 | tpacpi_disclose_usertask("procfs fan", |
8363 | "set speed to %d\n", speed); | 8278 | "set speed to %d\n", speed); |
@@ -8560,8 +8475,8 @@ static int __init ibm_init(struct ibm_init_struct *iibm) | |||
8560 | if (ibm->acpi->notify) { | 8475 | if (ibm->acpi->notify) { |
8561 | ret = setup_acpi_notify(ibm); | 8476 | ret = setup_acpi_notify(ibm); |
8562 | if (ret == -ENODEV) { | 8477 | if (ret == -ENODEV) { |
8563 | printk(TPACPI_NOTICE "disabling subdriver %s\n", | 8478 | pr_notice("disabling subdriver %s\n", |
8564 | ibm->name); | 8479 | ibm->name); |
8565 | ret = 0; | 8480 | ret = 0; |
8566 | goto err_out; | 8481 | goto err_out; |
8567 | } | 8482 | } |
@@ -8583,8 +8498,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm) | |||
8583 | entry = proc_create_data(ibm->name, mode, proc_dir, | 8498 | entry = proc_create_data(ibm->name, mode, proc_dir, |
8584 | &dispatch_proc_fops, ibm); | 8499 | &dispatch_proc_fops, ibm); |
8585 | if (!entry) { | 8500 | if (!entry) { |
8586 | printk(TPACPI_ERR "unable to create proc entry %s\n", | 8501 | pr_err("unable to create proc entry %s\n", ibm->name); |
8587 | ibm->name); | ||
8588 | ret = -ENODEV; | 8502 | ret = -ENODEV; |
8589 | goto err_out; | 8503 | goto err_out; |
8590 | } | 8504 | } |
@@ -8683,13 +8597,11 @@ static int __must_check __init get_thinkpad_model_data( | |||
8683 | tp->ec_release = (ec_fw_string[4] << 8) | 8597 | tp->ec_release = (ec_fw_string[4] << 8) |
8684 | | ec_fw_string[5]; | 8598 | | ec_fw_string[5]; |
8685 | } else { | 8599 | } else { |
8686 | printk(TPACPI_NOTICE | 8600 | pr_notice("ThinkPad firmware release %s " |
8687 | "ThinkPad firmware release %s " | 8601 | "doesn't match the known patterns\n", |
8688 | "doesn't match the known patterns\n", | 8602 | ec_fw_string); |
8689 | ec_fw_string); | 8603 | pr_notice("please report this to %s\n", |
8690 | printk(TPACPI_NOTICE | 8604 | TPACPI_MAIL); |
8691 | "please report this to %s\n", | ||
8692 | TPACPI_MAIL); | ||
8693 | } | 8605 | } |
8694 | break; | 8606 | break; |
8695 | } | 8607 | } |
@@ -8733,8 +8645,7 @@ static int __init probe_for_thinkpad(void) | |||
8733 | tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle); | 8645 | tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle); |
8734 | if (!ec_handle) { | 8646 | if (!ec_handle) { |
8735 | if (is_thinkpad) | 8647 | if (is_thinkpad) |
8736 | printk(TPACPI_ERR | 8648 | pr_err("Not yet supported ThinkPad detected!\n"); |
8737 | "Not yet supported ThinkPad detected!\n"); | ||
8738 | return -ENODEV; | 8649 | return -ENODEV; |
8739 | } | 8650 | } |
8740 | 8651 | ||
@@ -8746,10 +8657,10 @@ static int __init probe_for_thinkpad(void) | |||
8746 | 8657 | ||
8747 | static void __init thinkpad_acpi_init_banner(void) | 8658 | static void __init thinkpad_acpi_init_banner(void) |
8748 | { | 8659 | { |
8749 | printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); | 8660 | pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION); |
8750 | printk(TPACPI_INFO "%s\n", TPACPI_URL); | 8661 | pr_info("%s\n", TPACPI_URL); |
8751 | 8662 | ||
8752 | printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", | 8663 | pr_info("ThinkPad BIOS %s, EC %s\n", |
8753 | (thinkpad_id.bios_version_str) ? | 8664 | (thinkpad_id.bios_version_str) ? |
8754 | thinkpad_id.bios_version_str : "unknown", | 8665 | thinkpad_id.bios_version_str : "unknown", |
8755 | (thinkpad_id.ec_version_str) ? | 8666 | (thinkpad_id.ec_version_str) ? |
@@ -8758,7 +8669,7 @@ static void __init thinkpad_acpi_init_banner(void) | |||
8758 | BUG_ON(!thinkpad_id.vendor); | 8669 | BUG_ON(!thinkpad_id.vendor); |
8759 | 8670 | ||
8760 | if (thinkpad_id.model_str) | 8671 | if (thinkpad_id.model_str) |
8761 | printk(TPACPI_INFO "%s %s, model %s\n", | 8672 | pr_info("%s %s, model %s\n", |
8762 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? | 8673 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? |
8763 | "IBM" : ((thinkpad_id.vendor == | 8674 | "IBM" : ((thinkpad_id.vendor == |
8764 | PCI_VENDOR_ID_LENOVO) ? | 8675 | PCI_VENDOR_ID_LENOVO) ? |
@@ -9024,8 +8935,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9024 | 8935 | ||
9025 | ret = get_thinkpad_model_data(&thinkpad_id); | 8936 | ret = get_thinkpad_model_data(&thinkpad_id); |
9026 | if (ret) { | 8937 | if (ret) { |
9027 | printk(TPACPI_ERR | 8938 | pr_err("unable to get DMI data: %d\n", ret); |
9028 | "unable to get DMI data: %d\n", ret); | ||
9029 | thinkpad_acpi_module_exit(); | 8939 | thinkpad_acpi_module_exit(); |
9030 | return ret; | 8940 | return ret; |
9031 | } | 8941 | } |
@@ -9051,16 +8961,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
9051 | 8961 | ||
9052 | proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); | 8962 | proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); |
9053 | if (!proc_dir) { | 8963 | if (!proc_dir) { |
9054 | printk(TPACPI_ERR | 8964 | pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n"); |
9055 | "unable to create proc dir " TPACPI_PROC_DIR); | ||
9056 | thinkpad_acpi_module_exit(); | 8965 | thinkpad_acpi_module_exit(); |
9057 | return -ENODEV; | 8966 | return -ENODEV; |
9058 | } | 8967 | } |
9059 | 8968 | ||
9060 | ret = platform_driver_register(&tpacpi_pdriver); | 8969 | ret = platform_driver_register(&tpacpi_pdriver); |
9061 | if (ret) { | 8970 | if (ret) { |
9062 | printk(TPACPI_ERR | 8971 | pr_err("unable to register main platform driver\n"); |
9063 | "unable to register main platform driver\n"); | ||
9064 | thinkpad_acpi_module_exit(); | 8972 | thinkpad_acpi_module_exit(); |
9065 | return ret; | 8973 | return ret; |
9066 | } | 8974 | } |
@@ -9068,8 +8976,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9068 | 8976 | ||
9069 | ret = platform_driver_register(&tpacpi_hwmon_pdriver); | 8977 | ret = platform_driver_register(&tpacpi_hwmon_pdriver); |
9070 | if (ret) { | 8978 | if (ret) { |
9071 | printk(TPACPI_ERR | 8979 | pr_err("unable to register hwmon platform driver\n"); |
9072 | "unable to register hwmon platform driver\n"); | ||
9073 | thinkpad_acpi_module_exit(); | 8980 | thinkpad_acpi_module_exit(); |
9074 | return ret; | 8981 | return ret; |
9075 | } | 8982 | } |
@@ -9082,8 +8989,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9082 | &tpacpi_hwmon_pdriver.driver); | 8989 | &tpacpi_hwmon_pdriver.driver); |
9083 | } | 8990 | } |
9084 | if (ret) { | 8991 | if (ret) { |
9085 | printk(TPACPI_ERR | 8992 | pr_err("unable to create sysfs driver attributes\n"); |
9086 | "unable to create sysfs driver attributes\n"); | ||
9087 | thinkpad_acpi_module_exit(); | 8993 | thinkpad_acpi_module_exit(); |
9088 | return ret; | 8994 | return ret; |
9089 | } | 8995 | } |
@@ -9096,7 +9002,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9096 | if (IS_ERR(tpacpi_pdev)) { | 9002 | if (IS_ERR(tpacpi_pdev)) { |
9097 | ret = PTR_ERR(tpacpi_pdev); | 9003 | ret = PTR_ERR(tpacpi_pdev); |
9098 | tpacpi_pdev = NULL; | 9004 | tpacpi_pdev = NULL; |
9099 | printk(TPACPI_ERR "unable to register platform device\n"); | 9005 | pr_err("unable to register platform device\n"); |
9100 | thinkpad_acpi_module_exit(); | 9006 | thinkpad_acpi_module_exit(); |
9101 | return ret; | 9007 | return ret; |
9102 | } | 9008 | } |
@@ -9106,16 +9012,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
9106 | if (IS_ERR(tpacpi_sensors_pdev)) { | 9012 | if (IS_ERR(tpacpi_sensors_pdev)) { |
9107 | ret = PTR_ERR(tpacpi_sensors_pdev); | 9013 | ret = PTR_ERR(tpacpi_sensors_pdev); |
9108 | tpacpi_sensors_pdev = NULL; | 9014 | tpacpi_sensors_pdev = NULL; |
9109 | printk(TPACPI_ERR | 9015 | pr_err("unable to register hwmon platform device\n"); |
9110 | "unable to register hwmon platform device\n"); | ||
9111 | thinkpad_acpi_module_exit(); | 9016 | thinkpad_acpi_module_exit(); |
9112 | return ret; | 9017 | return ret; |
9113 | } | 9018 | } |
9114 | ret = device_create_file(&tpacpi_sensors_pdev->dev, | 9019 | ret = device_create_file(&tpacpi_sensors_pdev->dev, |
9115 | &dev_attr_thinkpad_acpi_pdev_name); | 9020 | &dev_attr_thinkpad_acpi_pdev_name); |
9116 | if (ret) { | 9021 | if (ret) { |
9117 | printk(TPACPI_ERR | 9022 | pr_err("unable to create sysfs hwmon device attributes\n"); |
9118 | "unable to create sysfs hwmon device attributes\n"); | ||
9119 | thinkpad_acpi_module_exit(); | 9023 | thinkpad_acpi_module_exit(); |
9120 | return ret; | 9024 | return ret; |
9121 | } | 9025 | } |
@@ -9124,14 +9028,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
9124 | if (IS_ERR(tpacpi_hwmon)) { | 9028 | if (IS_ERR(tpacpi_hwmon)) { |
9125 | ret = PTR_ERR(tpacpi_hwmon); | 9029 | ret = PTR_ERR(tpacpi_hwmon); |
9126 | tpacpi_hwmon = NULL; | 9030 | tpacpi_hwmon = NULL; |
9127 | printk(TPACPI_ERR "unable to register hwmon device\n"); | 9031 | pr_err("unable to register hwmon device\n"); |
9128 | thinkpad_acpi_module_exit(); | 9032 | thinkpad_acpi_module_exit(); |
9129 | return ret; | 9033 | return ret; |
9130 | } | 9034 | } |
9131 | mutex_init(&tpacpi_inputdev_send_mutex); | 9035 | mutex_init(&tpacpi_inputdev_send_mutex); |
9132 | tpacpi_inputdev = input_allocate_device(); | 9036 | tpacpi_inputdev = input_allocate_device(); |
9133 | if (!tpacpi_inputdev) { | 9037 | if (!tpacpi_inputdev) { |
9134 | printk(TPACPI_ERR "unable to allocate input device\n"); | 9038 | pr_err("unable to allocate input device\n"); |
9135 | thinkpad_acpi_module_exit(); | 9039 | thinkpad_acpi_module_exit(); |
9136 | return -ENOMEM; | 9040 | return -ENOMEM; |
9137 | } else { | 9041 | } else { |
@@ -9163,7 +9067,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9163 | 9067 | ||
9164 | ret = input_register_device(tpacpi_inputdev); | 9068 | ret = input_register_device(tpacpi_inputdev); |
9165 | if (ret < 0) { | 9069 | if (ret < 0) { |
9166 | printk(TPACPI_ERR "unable to register input device\n"); | 9070 | pr_err("unable to register input device\n"); |
9167 | thinkpad_acpi_module_exit(); | 9071 | thinkpad_acpi_module_exit(); |
9168 | return ret; | 9072 | return ret; |
9169 | } else { | 9073 | } else { |
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 1d07d6d09f27..4c20447ddbb7 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c | |||
@@ -194,7 +194,7 @@ static int __init topstar_laptop_init(void) | |||
194 | if (ret < 0) | 194 | if (ret < 0) |
195 | return ret; | 195 | return ret; |
196 | 196 | ||
197 | printk(KERN_INFO "Topstar Laptop ACPI extras driver loaded\n"); | 197 | pr_info("ACPI extras driver loaded\n"); |
198 | 198 | ||
199 | return 0; | 199 | return 0; |
200 | } | 200 | } |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 63f42a22e102..cb009b2629ee 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -35,6 +35,8 @@ | |||
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
39 | |||
38 | #define TOSHIBA_ACPI_VERSION "0.19" | 40 | #define TOSHIBA_ACPI_VERSION "0.19" |
39 | #define PROC_INTERFACE_VERSION 1 | 41 | #define PROC_INTERFACE_VERSION 1 |
40 | 42 | ||
@@ -60,11 +62,6 @@ MODULE_AUTHOR("John Belmonte"); | |||
60 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); | 62 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); |
61 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
62 | 64 | ||
63 | #define MY_LOGPREFIX "toshiba_acpi: " | ||
64 | #define MY_ERR KERN_ERR MY_LOGPREFIX | ||
65 | #define MY_NOTICE KERN_NOTICE MY_LOGPREFIX | ||
66 | #define MY_INFO KERN_INFO MY_LOGPREFIX | ||
67 | |||
68 | /* Toshiba ACPI method paths */ | 65 | /* Toshiba ACPI method paths */ |
69 | #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" | 66 | #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" |
70 | #define TOSH_INTERFACE_1 "\\_SB_.VALD" | 67 | #define TOSH_INTERFACE_1 "\\_SB_.VALD" |
@@ -301,7 +298,7 @@ static int toshiba_illumination_available(void) | |||
301 | in[0] = 0xf100; | 298 | in[0] = 0xf100; |
302 | status = hci_raw(in, out); | 299 | status = hci_raw(in, out); |
303 | if (ACPI_FAILURE(status)) { | 300 | if (ACPI_FAILURE(status)) { |
304 | printk(MY_INFO "Illumination device not available\n"); | 301 | pr_info("Illumination device not available\n"); |
305 | return 0; | 302 | return 0; |
306 | } | 303 | } |
307 | in[0] = 0xf400; | 304 | in[0] = 0xf400; |
@@ -320,7 +317,7 @@ static void toshiba_illumination_set(struct led_classdev *cdev, | |||
320 | in[0] = 0xf100; | 317 | in[0] = 0xf100; |
321 | status = hci_raw(in, out); | 318 | status = hci_raw(in, out); |
322 | if (ACPI_FAILURE(status)) { | 319 | if (ACPI_FAILURE(status)) { |
323 | printk(MY_INFO "Illumination device not available\n"); | 320 | pr_info("Illumination device not available\n"); |
324 | return; | 321 | return; |
325 | } | 322 | } |
326 | 323 | ||
@@ -331,7 +328,7 @@ static void toshiba_illumination_set(struct led_classdev *cdev, | |||
331 | in[2] = 1; | 328 | in[2] = 1; |
332 | status = hci_raw(in, out); | 329 | status = hci_raw(in, out); |
333 | if (ACPI_FAILURE(status)) { | 330 | if (ACPI_FAILURE(status)) { |
334 | printk(MY_INFO "ACPI call for illumination failed.\n"); | 331 | pr_info("ACPI call for illumination failed\n"); |
335 | return; | 332 | return; |
336 | } | 333 | } |
337 | } else { | 334 | } else { |
@@ -341,7 +338,7 @@ static void toshiba_illumination_set(struct led_classdev *cdev, | |||
341 | in[2] = 0; | 338 | in[2] = 0; |
342 | status = hci_raw(in, out); | 339 | status = hci_raw(in, out); |
343 | if (ACPI_FAILURE(status)) { | 340 | if (ACPI_FAILURE(status)) { |
344 | printk(MY_INFO "ACPI call for illumination failed.\n"); | 341 | pr_info("ACPI call for illumination failed.\n"); |
345 | return; | 342 | return; |
346 | } | 343 | } |
347 | } | 344 | } |
@@ -364,7 +361,7 @@ static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) | |||
364 | in[0] = 0xf100; | 361 | in[0] = 0xf100; |
365 | status = hci_raw(in, out); | 362 | status = hci_raw(in, out); |
366 | if (ACPI_FAILURE(status)) { | 363 | if (ACPI_FAILURE(status)) { |
367 | printk(MY_INFO "Illumination device not available\n"); | 364 | pr_info("Illumination device not available\n"); |
368 | return LED_OFF; | 365 | return LED_OFF; |
369 | } | 366 | } |
370 | 367 | ||
@@ -373,7 +370,7 @@ static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) | |||
373 | in[1] = 0x14e; | 370 | in[1] = 0x14e; |
374 | status = hci_raw(in, out); | 371 | status = hci_raw(in, out); |
375 | if (ACPI_FAILURE(status)) { | 372 | if (ACPI_FAILURE(status)) { |
376 | printk(MY_INFO "ACPI call for illumination failed.\n"); | 373 | pr_info("ACPI call for illumination failed.\n"); |
377 | return LED_OFF; | 374 | return LED_OFF; |
378 | } | 375 | } |
379 | 376 | ||
@@ -517,7 +514,7 @@ static int lcd_proc_show(struct seq_file *m, void *v) | |||
517 | seq_printf(m, "brightness_levels: %d\n", | 514 | seq_printf(m, "brightness_levels: %d\n", |
518 | HCI_LCD_BRIGHTNESS_LEVELS); | 515 | HCI_LCD_BRIGHTNESS_LEVELS); |
519 | } else { | 516 | } else { |
520 | printk(MY_ERR "Error reading LCD brightness\n"); | 517 | pr_err("Error reading LCD brightness\n"); |
521 | } | 518 | } |
522 | 519 | ||
523 | return 0; | 520 | return 0; |
@@ -592,7 +589,7 @@ static int video_proc_show(struct seq_file *m, void *v) | |||
592 | seq_printf(m, "crt_out: %d\n", is_crt); | 589 | seq_printf(m, "crt_out: %d\n", is_crt); |
593 | seq_printf(m, "tv_out: %d\n", is_tv); | 590 | seq_printf(m, "tv_out: %d\n", is_tv); |
594 | } else { | 591 | } else { |
595 | printk(MY_ERR "Error reading video out status\n"); | 592 | pr_err("Error reading video out status\n"); |
596 | } | 593 | } |
597 | 594 | ||
598 | return 0; | 595 | return 0; |
@@ -686,7 +683,7 @@ static int fan_proc_show(struct seq_file *m, void *v) | |||
686 | seq_printf(m, "running: %d\n", (value > 0)); | 683 | seq_printf(m, "running: %d\n", (value > 0)); |
687 | seq_printf(m, "force_on: %d\n", force_fan); | 684 | seq_printf(m, "force_on: %d\n", force_fan); |
688 | } else { | 685 | } else { |
689 | printk(MY_ERR "Error reading fan status\n"); | 686 | pr_err("Error reading fan status\n"); |
690 | } | 687 | } |
691 | 688 | ||
692 | return 0; | 689 | return 0; |
@@ -750,9 +747,9 @@ static int keys_proc_show(struct seq_file *m, void *v) | |||
750 | * some machines where system events sporadically | 747 | * some machines where system events sporadically |
751 | * become disabled. */ | 748 | * become disabled. */ |
752 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); | 749 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); |
753 | printk(MY_NOTICE "Re-enabled hotkeys\n"); | 750 | pr_notice("Re-enabled hotkeys\n"); |
754 | } else { | 751 | } else { |
755 | printk(MY_ERR "Error reading hotkey status\n"); | 752 | pr_err("Error reading hotkey status\n"); |
756 | goto end; | 753 | goto end; |
757 | } | 754 | } |
758 | } | 755 | } |
@@ -863,7 +860,7 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) | |||
863 | 860 | ||
864 | if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev, | 861 | if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev, |
865 | value, 1, true)) { | 862 | value, 1, true)) { |
866 | printk(MY_INFO "Unknown key %x\n", | 863 | pr_info("Unknown key %x\n", |
867 | value); | 864 | value); |
868 | } | 865 | } |
869 | } else if (hci_result == HCI_NOT_SUPPORTED) { | 866 | } else if (hci_result == HCI_NOT_SUPPORTED) { |
@@ -871,7 +868,7 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) | |||
871 | * some machines where system events sporadically | 868 | * some machines where system events sporadically |
872 | * become disabled. */ | 869 | * become disabled. */ |
873 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); | 870 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); |
874 | printk(MY_NOTICE "Re-enabled hotkeys\n"); | 871 | pr_notice("Re-enabled hotkeys\n"); |
875 | } | 872 | } |
876 | } while (hci_result != HCI_EMPTY); | 873 | } while (hci_result != HCI_EMPTY); |
877 | } | 874 | } |
@@ -883,13 +880,13 @@ static int __init toshiba_acpi_setup_keyboard(char *device) | |||
883 | 880 | ||
884 | status = acpi_get_handle(NULL, device, &toshiba_acpi.handle); | 881 | status = acpi_get_handle(NULL, device, &toshiba_acpi.handle); |
885 | if (ACPI_FAILURE(status)) { | 882 | if (ACPI_FAILURE(status)) { |
886 | printk(MY_INFO "Unable to get notification device\n"); | 883 | pr_info("Unable to get notification device\n"); |
887 | return -ENODEV; | 884 | return -ENODEV; |
888 | } | 885 | } |
889 | 886 | ||
890 | toshiba_acpi.hotkey_dev = input_allocate_device(); | 887 | toshiba_acpi.hotkey_dev = input_allocate_device(); |
891 | if (!toshiba_acpi.hotkey_dev) { | 888 | if (!toshiba_acpi.hotkey_dev) { |
892 | printk(MY_INFO "Unable to register input device\n"); | 889 | pr_info("Unable to register input device\n"); |
893 | return -ENOMEM; | 890 | return -ENOMEM; |
894 | } | 891 | } |
895 | 892 | ||
@@ -905,21 +902,21 @@ static int __init toshiba_acpi_setup_keyboard(char *device) | |||
905 | status = acpi_install_notify_handler(toshiba_acpi.handle, | 902 | status = acpi_install_notify_handler(toshiba_acpi.handle, |
906 | ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL); | 903 | ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL); |
907 | if (ACPI_FAILURE(status)) { | 904 | if (ACPI_FAILURE(status)) { |
908 | printk(MY_INFO "Unable to install hotkey notification\n"); | 905 | pr_info("Unable to install hotkey notification\n"); |
909 | error = -ENODEV; | 906 | error = -ENODEV; |
910 | goto err_free_keymap; | 907 | goto err_free_keymap; |
911 | } | 908 | } |
912 | 909 | ||
913 | status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL); | 910 | status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL); |
914 | if (ACPI_FAILURE(status)) { | 911 | if (ACPI_FAILURE(status)) { |
915 | printk(MY_INFO "Unable to enable hotkeys\n"); | 912 | pr_info("Unable to enable hotkeys\n"); |
916 | error = -ENODEV; | 913 | error = -ENODEV; |
917 | goto err_remove_notify; | 914 | goto err_remove_notify; |
918 | } | 915 | } |
919 | 916 | ||
920 | error = input_register_device(toshiba_acpi.hotkey_dev); | 917 | error = input_register_device(toshiba_acpi.hotkey_dev); |
921 | if (error) { | 918 | if (error) { |
922 | printk(MY_INFO "Unable to register input device\n"); | 919 | pr_info("Unable to register input device\n"); |
923 | goto err_remove_notify; | 920 | goto err_remove_notify; |
924 | } | 921 | } |
925 | 922 | ||
@@ -980,17 +977,17 @@ static int __init toshiba_acpi_init(void) | |||
980 | if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) { | 977 | if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) { |
981 | method_hci = TOSH_INTERFACE_1 GHCI_METHOD; | 978 | method_hci = TOSH_INTERFACE_1 GHCI_METHOD; |
982 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1)) | 979 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1)) |
983 | printk(MY_INFO "Unable to activate hotkeys\n"); | 980 | pr_info("Unable to activate hotkeys\n"); |
984 | } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) { | 981 | } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) { |
985 | method_hci = TOSH_INTERFACE_2 GHCI_METHOD; | 982 | method_hci = TOSH_INTERFACE_2 GHCI_METHOD; |
986 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2)) | 983 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2)) |
987 | printk(MY_INFO "Unable to activate hotkeys\n"); | 984 | pr_info("Unable to activate hotkeys\n"); |
988 | } else | 985 | } else |
989 | return -ENODEV; | 986 | return -ENODEV; |
990 | 987 | ||
991 | printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", | 988 | pr_info("Toshiba Laptop ACPI Extras version %s\n", |
992 | TOSHIBA_ACPI_VERSION); | 989 | TOSHIBA_ACPI_VERSION); |
993 | printk(MY_INFO " HCI method: %s\n", method_hci); | 990 | pr_info(" HCI method: %s\n", method_hci); |
994 | 991 | ||
995 | mutex_init(&toshiba_acpi.mutex); | 992 | mutex_init(&toshiba_acpi.mutex); |
996 | 993 | ||
@@ -998,7 +995,7 @@ static int __init toshiba_acpi_init(void) | |||
998 | -1, NULL, 0); | 995 | -1, NULL, 0); |
999 | if (IS_ERR(toshiba_acpi.p_dev)) { | 996 | if (IS_ERR(toshiba_acpi.p_dev)) { |
1000 | ret = PTR_ERR(toshiba_acpi.p_dev); | 997 | ret = PTR_ERR(toshiba_acpi.p_dev); |
1001 | printk(MY_ERR "unable to register platform device\n"); | 998 | pr_err("unable to register platform device\n"); |
1002 | toshiba_acpi.p_dev = NULL; | 999 | toshiba_acpi.p_dev = NULL; |
1003 | toshiba_acpi_exit(); | 1000 | toshiba_acpi_exit(); |
1004 | return ret; | 1001 | return ret; |
@@ -1028,7 +1025,7 @@ static int __init toshiba_acpi_init(void) | |||
1028 | if (IS_ERR(toshiba_backlight_device)) { | 1025 | if (IS_ERR(toshiba_backlight_device)) { |
1029 | ret = PTR_ERR(toshiba_backlight_device); | 1026 | ret = PTR_ERR(toshiba_backlight_device); |
1030 | 1027 | ||
1031 | printk(KERN_ERR "Could not register toshiba backlight device\n"); | 1028 | pr_err("Could not register toshiba backlight device\n"); |
1032 | toshiba_backlight_device = NULL; | 1029 | toshiba_backlight_device = NULL; |
1033 | toshiba_acpi_exit(); | 1030 | toshiba_acpi_exit(); |
1034 | return ret; | 1031 | return ret; |
@@ -1042,14 +1039,14 @@ static int __init toshiba_acpi_init(void) | |||
1042 | &toshiba_rfk_ops, | 1039 | &toshiba_rfk_ops, |
1043 | &toshiba_acpi); | 1040 | &toshiba_acpi); |
1044 | if (!toshiba_acpi.bt_rfk) { | 1041 | if (!toshiba_acpi.bt_rfk) { |
1045 | printk(MY_ERR "unable to allocate rfkill device\n"); | 1042 | pr_err("unable to allocate rfkill device\n"); |
1046 | toshiba_acpi_exit(); | 1043 | toshiba_acpi_exit(); |
1047 | return -ENOMEM; | 1044 | return -ENOMEM; |
1048 | } | 1045 | } |
1049 | 1046 | ||
1050 | ret = rfkill_register(toshiba_acpi.bt_rfk); | 1047 | ret = rfkill_register(toshiba_acpi.bt_rfk); |
1051 | if (ret) { | 1048 | if (ret) { |
1052 | printk(MY_ERR "unable to register rfkill device\n"); | 1049 | pr_err("unable to register rfkill device\n"); |
1053 | rfkill_destroy(toshiba_acpi.bt_rfk); | 1050 | rfkill_destroy(toshiba_acpi.bt_rfk); |
1054 | toshiba_acpi_exit(); | 1051 | toshiba_acpi_exit(); |
1055 | return ret; | 1052 | return ret; |
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 944068611919..5fb7186694df 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -17,6 +17,8 @@ | |||
17 | * delivered. | 17 | * delivered. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 23 | #include <linux/module.h> |
22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -70,14 +72,13 @@ static int toshiba_bluetooth_enable(acpi_handle handle) | |||
70 | if (!(result & 0x01)) | 72 | if (!(result & 0x01)) |
71 | return 0; | 73 | return 0; |
72 | 74 | ||
73 | printk(KERN_INFO "toshiba_bluetooth: Re-enabling Toshiba Bluetooth\n"); | 75 | pr_info("Re-enabling Toshiba Bluetooth\n"); |
74 | res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL); | 76 | res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL); |
75 | res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL); | 77 | res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL); |
76 | if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2)) | 78 | if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2)) |
77 | return 0; | 79 | return 0; |
78 | 80 | ||
79 | printk(KERN_WARNING "toshiba_bluetooth: Failed to re-enable " | 81 | pr_warn("Failed to re-enable Toshiba Bluetooth\n"); |
80 | "Toshiba Bluetooth\n"); | ||
81 | 82 | ||
82 | return -ENODEV; | 83 | return -ENODEV; |
83 | } | 84 | } |
@@ -107,8 +108,8 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) | |||
107 | &bt_present); | 108 | &bt_present); |
108 | 109 | ||
109 | if (!ACPI_FAILURE(status) && bt_present) { | 110 | if (!ACPI_FAILURE(status) && bt_present) { |
110 | printk(KERN_INFO "Detected Toshiba ACPI Bluetooth device - " | 111 | pr_info("Detected Toshiba ACPI Bluetooth device - " |
111 | "installing RFKill handler\n"); | 112 | "installing RFKill handler\n"); |
112 | result = toshiba_bluetooth_enable(device->handle); | 113 | result = toshiba_bluetooth_enable(device->handle); |
113 | } | 114 | } |
114 | 115 | ||
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 05cc79672a8b..f23d5a84e7b1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -486,16 +486,16 @@ static void wmi_dump_wdg(const struct guid_block *g) | |||
486 | pr_info("\tnotify_id: %02X\n", g->notify_id); | 486 | pr_info("\tnotify_id: %02X\n", g->notify_id); |
487 | pr_info("\treserved: %02X\n", g->reserved); | 487 | pr_info("\treserved: %02X\n", g->reserved); |
488 | pr_info("\tinstance_count: %d\n", g->instance_count); | 488 | pr_info("\tinstance_count: %d\n", g->instance_count); |
489 | pr_info("\tflags: %#x ", g->flags); | 489 | pr_info("\tflags: %#x", g->flags); |
490 | if (g->flags) { | 490 | if (g->flags) { |
491 | if (g->flags & ACPI_WMI_EXPENSIVE) | 491 | if (g->flags & ACPI_WMI_EXPENSIVE) |
492 | pr_cont("ACPI_WMI_EXPENSIVE "); | 492 | pr_cont(" ACPI_WMI_EXPENSIVE"); |
493 | if (g->flags & ACPI_WMI_METHOD) | 493 | if (g->flags & ACPI_WMI_METHOD) |
494 | pr_cont("ACPI_WMI_METHOD "); | 494 | pr_cont(" ACPI_WMI_METHOD"); |
495 | if (g->flags & ACPI_WMI_STRING) | 495 | if (g->flags & ACPI_WMI_STRING) |
496 | pr_cont("ACPI_WMI_STRING "); | 496 | pr_cont(" ACPI_WMI_STRING"); |
497 | if (g->flags & ACPI_WMI_EVENT) | 497 | if (g->flags & ACPI_WMI_EVENT) |
498 | pr_cont("ACPI_WMI_EVENT "); | 498 | pr_cont(" ACPI_WMI_EVENT"); |
499 | } | 499 | } |
500 | pr_cont("\n"); | 500 | pr_cont("\n"); |
501 | 501 | ||
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index c1372ed9d2e9..fad153dc0355 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * your option) any later version. | 11 | * your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
@@ -20,7 +22,6 @@ | |||
20 | #include <acpi/acpi_drivers.h> | 22 | #include <acpi/acpi_drivers.h> |
21 | 23 | ||
22 | #define MODULE_NAME "xo15-ebook" | 24 | #define MODULE_NAME "xo15-ebook" |
23 | #define PREFIX MODULE_NAME ": " | ||
24 | 25 | ||
25 | #define XO15_EBOOK_CLASS MODULE_NAME | 26 | #define XO15_EBOOK_CLASS MODULE_NAME |
26 | #define XO15_EBOOK_TYPE_UNKNOWN 0x00 | 27 | #define XO15_EBOOK_TYPE_UNKNOWN 0x00 |
@@ -105,7 +106,7 @@ static int ebook_switch_add(struct acpi_device *device) | |||
105 | class = acpi_device_class(device); | 106 | class = acpi_device_class(device); |
106 | 107 | ||
107 | if (strcmp(hid, XO15_EBOOK_HID)) { | 108 | if (strcmp(hid, XO15_EBOOK_HID)) { |
108 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); | 109 | pr_err("Unsupported hid [%s]\n", hid); |
109 | error = -ENODEV; | 110 | error = -ENODEV; |
110 | goto err_free_input; | 111 | goto err_free_input; |
111 | } | 112 | } |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 3b7e83d2dab4..d5ff142c93a2 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -486,7 +486,7 @@ static ssize_t asd_show_update_bios(struct device *dev, | |||
486 | flash_error_table[i].reason); | 486 | flash_error_table[i].reason); |
487 | } | 487 | } |
488 | 488 | ||
489 | static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUGO, | 489 | static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUSR, |
490 | asd_show_update_bios, asd_store_update_bios); | 490 | asd_show_update_bios, asd_store_update_bios); |
491 | 491 | ||
492 | static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha) | 492 | static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha) |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index c1f72c49196f..6c7e0339dda4 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -56,6 +56,8 @@ BFA_TRC_FILE(CNA, IOC); | |||
56 | #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) | 56 | #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) |
57 | #define bfa_ioc_notify_fail(__ioc) \ | 57 | #define bfa_ioc_notify_fail(__ioc) \ |
58 | ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) | 58 | ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) |
59 | #define bfa_ioc_sync_start(__ioc) \ | ||
60 | ((__ioc)->ioc_hwif->ioc_sync_start(__ioc)) | ||
59 | #define bfa_ioc_sync_join(__ioc) \ | 61 | #define bfa_ioc_sync_join(__ioc) \ |
60 | ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) | 62 | ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) |
61 | #define bfa_ioc_sync_leave(__ioc) \ | 63 | #define bfa_ioc_sync_leave(__ioc) \ |
@@ -647,7 +649,7 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
647 | switch (event) { | 649 | switch (event) { |
648 | case IOCPF_E_SEMLOCKED: | 650 | case IOCPF_E_SEMLOCKED: |
649 | if (bfa_ioc_firmware_lock(ioc)) { | 651 | if (bfa_ioc_firmware_lock(ioc)) { |
650 | if (bfa_ioc_sync_complete(ioc)) { | 652 | if (bfa_ioc_sync_start(ioc)) { |
651 | iocpf->retry_count = 0; | 653 | iocpf->retry_count = 0; |
652 | bfa_ioc_sync_join(ioc); | 654 | bfa_ioc_sync_join(ioc); |
653 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); | 655 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); |
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index ec9cf08b0e7f..c85182a704fb 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h | |||
@@ -263,6 +263,7 @@ struct bfa_ioc_hwif_s { | |||
263 | bfa_boolean_t msix); | 263 | bfa_boolean_t msix); |
264 | void (*ioc_notify_fail) (struct bfa_ioc_s *ioc); | 264 | void (*ioc_notify_fail) (struct bfa_ioc_s *ioc); |
265 | void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc); | 265 | void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc); |
266 | bfa_boolean_t (*ioc_sync_start) (struct bfa_ioc_s *ioc); | ||
266 | void (*ioc_sync_join) (struct bfa_ioc_s *ioc); | 267 | void (*ioc_sync_join) (struct bfa_ioc_s *ioc); |
267 | void (*ioc_sync_leave) (struct bfa_ioc_s *ioc); | 268 | void (*ioc_sync_leave) (struct bfa_ioc_s *ioc); |
268 | void (*ioc_sync_ack) (struct bfa_ioc_s *ioc); | 269 | void (*ioc_sync_ack) (struct bfa_ioc_s *ioc); |
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index e4a0713185b6..89ae4c8f95a2 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c | |||
@@ -32,6 +32,7 @@ static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc); | |||
32 | static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); | 32 | static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); |
33 | static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc); | 33 | static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc); |
34 | static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); | 34 | static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); |
35 | static bfa_boolean_t bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc); | ||
35 | static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc); | 36 | static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc); |
36 | static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc); | 37 | static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc); |
37 | static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc); | 38 | static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc); |
@@ -53,6 +54,7 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) | |||
53 | hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set; | 54 | hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set; |
54 | hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail; | 55 | hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail; |
55 | hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset; | 56 | hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset; |
57 | hwif_cb.ioc_sync_start = bfa_ioc_cb_sync_start; | ||
56 | hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join; | 58 | hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join; |
57 | hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave; | 59 | hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave; |
58 | hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack; | 60 | hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack; |
@@ -195,6 +197,15 @@ bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) | |||
195 | } | 197 | } |
196 | 198 | ||
197 | /* | 199 | /* |
200 | * Synchronized IOC failure processing routines | ||
201 | */ | ||
202 | static bfa_boolean_t | ||
203 | bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc) | ||
204 | { | ||
205 | return bfa_ioc_cb_sync_complete(ioc); | ||
206 | } | ||
207 | |||
208 | /* | ||
198 | * Cleanup hw semaphore and usecnt registers | 209 | * Cleanup hw semaphore and usecnt registers |
199 | */ | 210 | */ |
200 | static void | 211 | static void |
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 008d129ddfcd..93612520f0d2 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
@@ -41,6 +41,7 @@ static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc); | |||
41 | static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); | 41 | static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); |
42 | static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc); | 42 | static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc); |
43 | static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); | 43 | static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); |
44 | static bfa_boolean_t bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc); | ||
44 | static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc); | 45 | static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc); |
45 | static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); | 46 | static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); |
46 | static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); | 47 | static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); |
@@ -62,6 +63,7 @@ bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) | |||
62 | hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; | 63 | hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; |
63 | hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail; | 64 | hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail; |
64 | hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; | 65 | hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; |
66 | hwif_ct.ioc_sync_start = bfa_ioc_ct_sync_start; | ||
65 | hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join; | 67 | hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join; |
66 | hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave; | 68 | hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave; |
67 | hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack; | 69 | hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack; |
@@ -351,6 +353,30 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) | |||
351 | writel(1, ioc->ioc_regs.ioc_sem_reg); | 353 | writel(1, ioc->ioc_regs.ioc_sem_reg); |
352 | } | 354 | } |
353 | 355 | ||
356 | static bfa_boolean_t | ||
357 | bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc) | ||
358 | { | ||
359 | uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); | ||
360 | uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); | ||
361 | |||
362 | /* | ||
363 | * Driver load time. If the sync required bit for this PCI fn | ||
364 | * is set, it is due to an unclean exit by the driver for this | ||
365 | * PCI fn in the previous incarnation. Whoever comes here first | ||
366 | * should clean it up, no matter which PCI fn. | ||
367 | */ | ||
368 | |||
369 | if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) { | ||
370 | writel(0, ioc->ioc_regs.ioc_fail_sync); | ||
371 | writel(1, ioc->ioc_regs.ioc_usage_reg); | ||
372 | writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); | ||
373 | writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); | ||
374 | return BFA_TRUE; | ||
375 | } | ||
376 | |||
377 | return bfa_ioc_ct_sync_complete(ioc); | ||
378 | } | ||
379 | |||
354 | /* | 380 | /* |
355 | * Synchronized IOC failure processing routines | 381 | * Synchronized IOC failure processing routines |
356 | */ | 382 | */ |
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index cfd59023227b..6bdd25a93db9 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h | |||
@@ -66,11 +66,11 @@ | |||
66 | #define BD_SPLIT_SIZE 32768 | 66 | #define BD_SPLIT_SIZE 32768 |
67 | 67 | ||
68 | /* min, max & default values for SQ/RQ/CQ size, configurable via' modparam */ | 68 | /* min, max & default values for SQ/RQ/CQ size, configurable via' modparam */ |
69 | #define BNX2I_SQ_WQES_MIN 16 | 69 | #define BNX2I_SQ_WQES_MIN 16 |
70 | #define BNX2I_570X_SQ_WQES_MAX 128 | 70 | #define BNX2I_570X_SQ_WQES_MAX 128 |
71 | #define BNX2I_5770X_SQ_WQES_MAX 512 | 71 | #define BNX2I_5770X_SQ_WQES_MAX 512 |
72 | #define BNX2I_570X_SQ_WQES_DEFAULT 128 | 72 | #define BNX2I_570X_SQ_WQES_DEFAULT 128 |
73 | #define BNX2I_5770X_SQ_WQES_DEFAULT 256 | 73 | #define BNX2I_5770X_SQ_WQES_DEFAULT 128 |
74 | 74 | ||
75 | #define BNX2I_570X_CQ_WQES_MAX 128 | 75 | #define BNX2I_570X_CQ_WQES_MAX 128 |
76 | #define BNX2I_5770X_CQ_WQES_MAX 512 | 76 | #define BNX2I_5770X_CQ_WQES_MAX 512 |
@@ -115,6 +115,7 @@ | |||
115 | #define BNX2X_MAX_CQS 8 | 115 | #define BNX2X_MAX_CQS 8 |
116 | 116 | ||
117 | #define CNIC_ARM_CQE 1 | 117 | #define CNIC_ARM_CQE 1 |
118 | #define CNIC_ARM_CQE_FP 2 | ||
118 | #define CNIC_DISARM_CQE 0 | 119 | #define CNIC_DISARM_CQE 0 |
119 | 120 | ||
120 | #define REG_RD(__hba, offset) \ | 121 | #define REG_RD(__hba, offset) \ |
@@ -666,7 +667,9 @@ enum { | |||
666 | * after HBA reset is completed by bnx2i/cnic/bnx2 | 667 | * after HBA reset is completed by bnx2i/cnic/bnx2 |
667 | * modules | 668 | * modules |
668 | * @state: tracks offload connection state machine | 669 | * @state: tracks offload connection state machine |
669 | * @teardown_mode: indicates if conn teardown is abortive or orderly | 670 | * @timestamp: tracks the start time when the ep begins to connect |
671 | * @num_active_cmds: tracks the number of outstanding commands for this ep | ||
672 | * @ec_shift: the amount of shift as part of the event coal calc | ||
670 | * @qp: QP information | 673 | * @qp: QP information |
671 | * @ids: contains chip allocated *context id* & driver assigned | 674 | * @ids: contains chip allocated *context id* & driver assigned |
672 | * *iscsi cid* | 675 | * *iscsi cid* |
@@ -685,6 +688,7 @@ struct bnx2i_endpoint { | |||
685 | u32 state; | 688 | u32 state; |
686 | unsigned long timestamp; | 689 | unsigned long timestamp; |
687 | int num_active_cmds; | 690 | int num_active_cmds; |
691 | u32 ec_shift; | ||
688 | 692 | ||
689 | struct qp_info qp; | 693 | struct qp_info qp; |
690 | struct ep_handles ids; | 694 | struct ep_handles ids; |
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index f0b89513faed..5c54a2d9b834 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c | |||
@@ -138,7 +138,6 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action) | |||
138 | u16 next_index; | 138 | u16 next_index; |
139 | u32 num_active_cmds; | 139 | u32 num_active_cmds; |
140 | 140 | ||
141 | |||
142 | /* Coalesce CQ entries only on 10G devices */ | 141 | /* Coalesce CQ entries only on 10G devices */ |
143 | if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) | 142 | if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) |
144 | return; | 143 | return; |
@@ -148,16 +147,19 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action) | |||
148 | * interrupts and other unwanted results | 147 | * interrupts and other unwanted results |
149 | */ | 148 | */ |
150 | cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt; | 149 | cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt; |
151 | if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF) | ||
152 | return; | ||
153 | 150 | ||
154 | if (action == CNIC_ARM_CQE) { | 151 | if (action != CNIC_ARM_CQE_FP) |
152 | if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF) | ||
153 | return; | ||
154 | |||
155 | if (action == CNIC_ARM_CQE || action == CNIC_ARM_CQE_FP) { | ||
155 | num_active_cmds = ep->num_active_cmds; | 156 | num_active_cmds = ep->num_active_cmds; |
156 | if (num_active_cmds <= event_coal_min) | 157 | if (num_active_cmds <= event_coal_min) |
157 | next_index = 1; | 158 | next_index = 1; |
158 | else | 159 | else |
159 | next_index = event_coal_min + | 160 | next_index = event_coal_min + |
160 | (num_active_cmds - event_coal_min) / event_coal_div; | 161 | ((num_active_cmds - event_coal_min) >> |
162 | ep->ec_shift); | ||
161 | if (!next_index) | 163 | if (!next_index) |
162 | next_index = 1; | 164 | next_index = 1; |
163 | cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1; | 165 | cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1; |
@@ -1274,6 +1276,7 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba) | |||
1274 | iscsi_init.dummy_buffer_addr_hi = | 1276 | iscsi_init.dummy_buffer_addr_hi = |
1275 | (u32) ((u64) hba->dummy_buf_dma >> 32); | 1277 | (u32) ((u64) hba->dummy_buf_dma >> 32); |
1276 | 1278 | ||
1279 | hba->num_ccell = hba->max_sqes >> 1; | ||
1277 | hba->ctx_ccell_tasks = | 1280 | hba->ctx_ccell_tasks = |
1278 | ((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16)); | 1281 | ((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16)); |
1279 | iscsi_init.num_ccells_per_conn = hba->num_ccell; | 1282 | iscsi_init.num_ccells_per_conn = hba->num_ccell; |
@@ -1934,7 +1937,6 @@ cqe_out: | |||
1934 | qp->cq_cons_idx++; | 1937 | qp->cq_cons_idx++; |
1935 | } | 1938 | } |
1936 | } | 1939 | } |
1937 | bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE); | ||
1938 | } | 1940 | } |
1939 | 1941 | ||
1940 | /** | 1942 | /** |
@@ -1948,22 +1950,23 @@ cqe_out: | |||
1948 | static void bnx2i_fastpath_notification(struct bnx2i_hba *hba, | 1950 | static void bnx2i_fastpath_notification(struct bnx2i_hba *hba, |
1949 | struct iscsi_kcqe *new_cqe_kcqe) | 1951 | struct iscsi_kcqe *new_cqe_kcqe) |
1950 | { | 1952 | { |
1951 | struct bnx2i_conn *conn; | 1953 | struct bnx2i_conn *bnx2i_conn; |
1952 | u32 iscsi_cid; | 1954 | u32 iscsi_cid; |
1953 | 1955 | ||
1954 | iscsi_cid = new_cqe_kcqe->iscsi_conn_id; | 1956 | iscsi_cid = new_cqe_kcqe->iscsi_conn_id; |
1955 | conn = bnx2i_get_conn_from_id(hba, iscsi_cid); | 1957 | bnx2i_conn = bnx2i_get_conn_from_id(hba, iscsi_cid); |
1956 | 1958 | ||
1957 | if (!conn) { | 1959 | if (!bnx2i_conn) { |
1958 | printk(KERN_ALERT "cid #%x not valid\n", iscsi_cid); | 1960 | printk(KERN_ALERT "cid #%x not valid\n", iscsi_cid); |
1959 | return; | 1961 | return; |
1960 | } | 1962 | } |
1961 | if (!conn->ep) { | 1963 | if (!bnx2i_conn->ep) { |
1962 | printk(KERN_ALERT "cid #%x - ep not bound\n", iscsi_cid); | 1964 | printk(KERN_ALERT "cid #%x - ep not bound\n", iscsi_cid); |
1963 | return; | 1965 | return; |
1964 | } | 1966 | } |
1965 | 1967 | bnx2i_process_new_cqes(bnx2i_conn); | |
1966 | bnx2i_process_new_cqes(conn); | 1968 | bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE_FP); |
1969 | bnx2i_process_new_cqes(bnx2i_conn); | ||
1967 | } | 1970 | } |
1968 | 1971 | ||
1969 | 1972 | ||
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 1d24a2819736..6adbdc34a9a5 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c | |||
@@ -244,7 +244,7 @@ void bnx2i_stop(void *handle) | |||
244 | wait_event_interruptible_timeout(hba->eh_wait, | 244 | wait_event_interruptible_timeout(hba->eh_wait, |
245 | (list_empty(&hba->ep_ofld_list) && | 245 | (list_empty(&hba->ep_ofld_list) && |
246 | list_empty(&hba->ep_destroy_list)), | 246 | list_empty(&hba->ep_destroy_list)), |
247 | 10 * HZ); | 247 | 2 * HZ); |
248 | /* Wait for all endpoints to be torn down, Chip will be reset once | 248 | /* Wait for all endpoints to be torn down, Chip will be reset once |
249 | * control returns to network driver. So it is required to cleanup and | 249 | * control returns to network driver. So it is required to cleanup and |
250 | * release all connection resources before returning from this routine. | 250 | * release all connection resources before returning from this routine. |
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 1809f9ccc4ce..041928b23cb0 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c | |||
@@ -379,6 +379,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba) | |||
379 | { | 379 | { |
380 | struct iscsi_endpoint *ep; | 380 | struct iscsi_endpoint *ep; |
381 | struct bnx2i_endpoint *bnx2i_ep; | 381 | struct bnx2i_endpoint *bnx2i_ep; |
382 | u32 ec_div; | ||
382 | 383 | ||
383 | ep = iscsi_create_endpoint(sizeof(*bnx2i_ep)); | 384 | ep = iscsi_create_endpoint(sizeof(*bnx2i_ep)); |
384 | if (!ep) { | 385 | if (!ep) { |
@@ -393,6 +394,11 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba) | |||
393 | bnx2i_ep->ep_iscsi_cid = (u16) -1; | 394 | bnx2i_ep->ep_iscsi_cid = (u16) -1; |
394 | bnx2i_ep->hba = hba; | 395 | bnx2i_ep->hba = hba; |
395 | bnx2i_ep->hba_age = hba->age; | 396 | bnx2i_ep->hba_age = hba->age; |
397 | |||
398 | ec_div = event_coal_div; | ||
399 | while (ec_div >>= 1) | ||
400 | bnx2i_ep->ec_shift += 1; | ||
401 | |||
396 | hba->ofld_conns_active++; | 402 | hba->ofld_conns_active++; |
397 | init_waitqueue_head(&bnx2i_ep->ofld_wait); | 403 | init_waitqueue_head(&bnx2i_ep->ofld_wait); |
398 | return ep; | 404 | return ep; |
@@ -858,7 +864,7 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) | |||
858 | mutex_init(&hba->net_dev_lock); | 864 | mutex_init(&hba->net_dev_lock); |
859 | init_waitqueue_head(&hba->eh_wait); | 865 | init_waitqueue_head(&hba->eh_wait); |
860 | if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { | 866 | if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { |
861 | hba->hba_shutdown_tmo = 20 * HZ; | 867 | hba->hba_shutdown_tmo = 30 * HZ; |
862 | hba->conn_teardown_tmo = 20 * HZ; | 868 | hba->conn_teardown_tmo = 20 * HZ; |
863 | hba->conn_ctx_destroy_tmo = 6 * HZ; | 869 | hba->conn_ctx_destroy_tmo = 6 * HZ; |
864 | } else { /* 5706/5708/5709 */ | 870 | } else { /* 5706/5708/5709 */ |
@@ -1208,6 +1214,9 @@ static int bnx2i_task_xmit(struct iscsi_task *task) | |||
1208 | struct bnx2i_cmd *cmd = task->dd_data; | 1214 | struct bnx2i_cmd *cmd = task->dd_data; |
1209 | struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; | 1215 | struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; |
1210 | 1216 | ||
1217 | if (bnx2i_conn->ep->num_active_cmds + 1 > hba->max_sqes) | ||
1218 | return -ENOMEM; | ||
1219 | |||
1211 | /* | 1220 | /* |
1212 | * If there is no scsi_cmnd this must be a mgmt task | 1221 | * If there is no scsi_cmnd this must be a mgmt task |
1213 | */ | 1222 | */ |
@@ -2156,7 +2165,7 @@ static struct scsi_host_template bnx2i_host_template = { | |||
2156 | .change_queue_depth = iscsi_change_queue_depth, | 2165 | .change_queue_depth = iscsi_change_queue_depth, |
2157 | .can_queue = 1024, | 2166 | .can_queue = 1024, |
2158 | .max_sectors = 127, | 2167 | .max_sectors = 127, |
2159 | .cmd_per_lun = 32, | 2168 | .cmd_per_lun = 24, |
2160 | .this_id = -1, | 2169 | .this_id = -1, |
2161 | .use_clustering = ENABLE_CLUSTERING, | 2170 | .use_clustering = ENABLE_CLUSTERING, |
2162 | .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, | 2171 | .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index cc23bd9480b2..155d7b9bdeae 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -137,6 +137,7 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled); | |||
137 | static int fcoe_vport_disable(struct fc_vport *, bool disable); | 137 | static int fcoe_vport_disable(struct fc_vport *, bool disable); |
138 | static void fcoe_set_vport_symbolic_name(struct fc_vport *); | 138 | static void fcoe_set_vport_symbolic_name(struct fc_vport *); |
139 | static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); | 139 | static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); |
140 | static int fcoe_validate_vport_create(struct fc_vport *); | ||
140 | 141 | ||
141 | static struct libfc_function_template fcoe_libfc_fcn_templ = { | 142 | static struct libfc_function_template fcoe_libfc_fcn_templ = { |
142 | .frame_send = fcoe_xmit, | 143 | .frame_send = fcoe_xmit, |
@@ -2351,6 +2352,17 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled) | |||
2351 | struct fcoe_interface *fcoe = port->priv; | 2352 | struct fcoe_interface *fcoe = port->priv; |
2352 | struct net_device *netdev = fcoe->netdev; | 2353 | struct net_device *netdev = fcoe->netdev; |
2353 | struct fc_lport *vn_port; | 2354 | struct fc_lport *vn_port; |
2355 | int rc; | ||
2356 | char buf[32]; | ||
2357 | |||
2358 | rc = fcoe_validate_vport_create(vport); | ||
2359 | if (rc) { | ||
2360 | wwn_to_str(vport->port_name, buf, sizeof(buf)); | ||
2361 | printk(KERN_ERR "fcoe: Failed to create vport, " | ||
2362 | "WWPN (0x%s) already exists\n", | ||
2363 | buf); | ||
2364 | return rc; | ||
2365 | } | ||
2354 | 2366 | ||
2355 | mutex_lock(&fcoe_config_mutex); | 2367 | mutex_lock(&fcoe_config_mutex); |
2356 | vn_port = fcoe_if_create(fcoe, &vport->dev, 1); | 2368 | vn_port = fcoe_if_create(fcoe, &vport->dev, 1); |
@@ -2497,3 +2509,49 @@ static void fcoe_set_port_id(struct fc_lport *lport, | |||
2497 | if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) | 2509 | if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) |
2498 | fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); | 2510 | fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); |
2499 | } | 2511 | } |
2512 | |||
2513 | /** | ||
2514 | * fcoe_validate_vport_create() - Validate a vport before creating it | ||
2515 | * @vport: NPIV port to be created | ||
2516 | * | ||
2517 | * This routine is meant to add validation for a vport before creating it | ||
2518 | * via fcoe_vport_create(). | ||
2519 | * Current validations are: | ||
2520 | * - WWPN supplied is unique for given lport | ||
2521 | * | ||
2522 | * | ||
2523 | */ | ||
2524 | static int fcoe_validate_vport_create(struct fc_vport *vport) | ||
2525 | { | ||
2526 | struct Scsi_Host *shost = vport_to_shost(vport); | ||
2527 | struct fc_lport *n_port = shost_priv(shost); | ||
2528 | struct fc_lport *vn_port; | ||
2529 | int rc = 0; | ||
2530 | char buf[32]; | ||
2531 | |||
2532 | mutex_lock(&n_port->lp_mutex); | ||
2533 | |||
2534 | wwn_to_str(vport->port_name, buf, sizeof(buf)); | ||
2535 | /* Check if the wwpn is not same as that of the lport */ | ||
2536 | if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) { | ||
2537 | FCOE_DBG("vport WWPN 0x%s is same as that of the " | ||
2538 | "base port WWPN\n", buf); | ||
2539 | rc = -EINVAL; | ||
2540 | goto out; | ||
2541 | } | ||
2542 | |||
2543 | /* Check if there is any existing vport with same wwpn */ | ||
2544 | list_for_each_entry(vn_port, &n_port->vports, list) { | ||
2545 | if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) { | ||
2546 | FCOE_DBG("vport with given WWPN 0x%s already " | ||
2547 | "exists\n", buf); | ||
2548 | rc = -EINVAL; | ||
2549 | break; | ||
2550 | } | ||
2551 | } | ||
2552 | |||
2553 | out: | ||
2554 | mutex_unlock(&n_port->lp_mutex); | ||
2555 | |||
2556 | return rc; | ||
2557 | } | ||
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index 408a6fd78fb4..c4a93993c0cf 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h | |||
@@ -99,4 +99,14 @@ static inline struct net_device *fcoe_netdev(const struct fc_lport *lport) | |||
99 | ((struct fcoe_port *)lport_priv(lport))->priv)->netdev; | 99 | ((struct fcoe_port *)lport_priv(lport))->priv)->netdev; |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void wwn_to_str(u64 wwn, char *buf, int len) | ||
103 | { | ||
104 | u8 wwpn[8]; | ||
105 | |||
106 | u64_to_wwn(wwn, wwpn); | ||
107 | snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x", | ||
108 | wwpn[0], wwpn[1], wwpn[2], wwpn[3], | ||
109 | wwpn[4], wwpn[5], wwpn[6], wwpn[7]); | ||
110 | } | ||
111 | |||
102 | #endif /* _FCOE_H_ */ | 112 | #endif /* _FCOE_H_ */ |
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 229e4af5508a..c74c4b8e71ef 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c | |||
@@ -1173,7 +1173,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
1173 | struct fc_lport *lport = fip->lp; | 1173 | struct fc_lport *lport = fip->lp; |
1174 | struct fc_lport *vn_port = NULL; | 1174 | struct fc_lport *vn_port = NULL; |
1175 | u32 desc_mask; | 1175 | u32 desc_mask; |
1176 | int is_vn_port = 0; | 1176 | int num_vlink_desc; |
1177 | int reset_phys_port = 0; | ||
1178 | struct fip_vn_desc **vlink_desc_arr = NULL; | ||
1177 | 1179 | ||
1178 | LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); | 1180 | LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); |
1179 | 1181 | ||
@@ -1183,70 +1185,73 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
1183 | /* | 1185 | /* |
1184 | * mask of required descriptors. Validating each one clears its bit. | 1186 | * mask of required descriptors. Validating each one clears its bit. |
1185 | */ | 1187 | */ |
1186 | desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) | BIT(FIP_DT_VN_ID); | 1188 | desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME); |
1187 | 1189 | ||
1188 | rlen = ntohs(fh->fip_dl_len) * FIP_BPW; | 1190 | rlen = ntohs(fh->fip_dl_len) * FIP_BPW; |
1189 | desc = (struct fip_desc *)(fh + 1); | 1191 | desc = (struct fip_desc *)(fh + 1); |
1192 | |||
1193 | /* | ||
1194 | * Actually need to subtract 'sizeof(*mp) - sizeof(*wp)' from 'rlen' | ||
1195 | * before determining max Vx_Port descriptor but a buggy FCF could have | ||
1196 | * omited either or both MAC Address and Name Identifier descriptors | ||
1197 | */ | ||
1198 | num_vlink_desc = rlen / sizeof(*vp); | ||
1199 | if (num_vlink_desc) | ||
1200 | vlink_desc_arr = kmalloc(sizeof(vp) * num_vlink_desc, | ||
1201 | GFP_ATOMIC); | ||
1202 | if (!vlink_desc_arr) | ||
1203 | return; | ||
1204 | num_vlink_desc = 0; | ||
1205 | |||
1190 | while (rlen >= sizeof(*desc)) { | 1206 | while (rlen >= sizeof(*desc)) { |
1191 | dlen = desc->fip_dlen * FIP_BPW; | 1207 | dlen = desc->fip_dlen * FIP_BPW; |
1192 | if (dlen > rlen) | 1208 | if (dlen > rlen) |
1193 | return; | 1209 | goto err; |
1194 | /* Drop CVL if there are duplicate critical descriptors */ | 1210 | /* Drop CVL if there are duplicate critical descriptors */ |
1195 | if ((desc->fip_dtype < 32) && | 1211 | if ((desc->fip_dtype < 32) && |
1212 | (desc->fip_dtype != FIP_DT_VN_ID) && | ||
1196 | !(desc_mask & 1U << desc->fip_dtype)) { | 1213 | !(desc_mask & 1U << desc->fip_dtype)) { |
1197 | LIBFCOE_FIP_DBG(fip, "Duplicate Critical " | 1214 | LIBFCOE_FIP_DBG(fip, "Duplicate Critical " |
1198 | "Descriptors in FIP CVL\n"); | 1215 | "Descriptors in FIP CVL\n"); |
1199 | return; | 1216 | goto err; |
1200 | } | 1217 | } |
1201 | switch (desc->fip_dtype) { | 1218 | switch (desc->fip_dtype) { |
1202 | case FIP_DT_MAC: | 1219 | case FIP_DT_MAC: |
1203 | mp = (struct fip_mac_desc *)desc; | 1220 | mp = (struct fip_mac_desc *)desc; |
1204 | if (dlen < sizeof(*mp)) | 1221 | if (dlen < sizeof(*mp)) |
1205 | return; | 1222 | goto err; |
1206 | if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac)) | 1223 | if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac)) |
1207 | return; | 1224 | goto err; |
1208 | desc_mask &= ~BIT(FIP_DT_MAC); | 1225 | desc_mask &= ~BIT(FIP_DT_MAC); |
1209 | break; | 1226 | break; |
1210 | case FIP_DT_NAME: | 1227 | case FIP_DT_NAME: |
1211 | wp = (struct fip_wwn_desc *)desc; | 1228 | wp = (struct fip_wwn_desc *)desc; |
1212 | if (dlen < sizeof(*wp)) | 1229 | if (dlen < sizeof(*wp)) |
1213 | return; | 1230 | goto err; |
1214 | if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name) | 1231 | if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name) |
1215 | return; | 1232 | goto err; |
1216 | desc_mask &= ~BIT(FIP_DT_NAME); | 1233 | desc_mask &= ~BIT(FIP_DT_NAME); |
1217 | break; | 1234 | break; |
1218 | case FIP_DT_VN_ID: | 1235 | case FIP_DT_VN_ID: |
1219 | vp = (struct fip_vn_desc *)desc; | 1236 | vp = (struct fip_vn_desc *)desc; |
1220 | if (dlen < sizeof(*vp)) | 1237 | if (dlen < sizeof(*vp)) |
1221 | return; | 1238 | goto err; |
1222 | if (compare_ether_addr(vp->fd_mac, | 1239 | vlink_desc_arr[num_vlink_desc++] = vp; |
1223 | fip->get_src_addr(lport)) == 0 && | 1240 | vn_port = fc_vport_id_lookup(lport, |
1224 | get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn && | 1241 | ntoh24(vp->fd_fc_id)); |
1225 | ntoh24(vp->fd_fc_id) == lport->port_id) { | 1242 | if (vn_port && (vn_port == lport)) { |
1226 | desc_mask &= ~BIT(FIP_DT_VN_ID); | 1243 | mutex_lock(&fip->ctlr_mutex); |
1227 | break; | 1244 | per_cpu_ptr(lport->dev_stats, |
1245 | get_cpu())->VLinkFailureCount++; | ||
1246 | put_cpu(); | ||
1247 | fcoe_ctlr_reset(fip); | ||
1248 | mutex_unlock(&fip->ctlr_mutex); | ||
1228 | } | 1249 | } |
1229 | /* check if clr_vlink is for NPIV port */ | ||
1230 | mutex_lock(&lport->lp_mutex); | ||
1231 | list_for_each_entry(vn_port, &lport->vports, list) { | ||
1232 | if (compare_ether_addr(vp->fd_mac, | ||
1233 | fip->get_src_addr(vn_port)) == 0 && | ||
1234 | (get_unaligned_be64(&vp->fd_wwpn) | ||
1235 | == vn_port->wwpn) && | ||
1236 | (ntoh24(vp->fd_fc_id) == | ||
1237 | fc_host_port_id(vn_port->host))) { | ||
1238 | desc_mask &= ~BIT(FIP_DT_VN_ID); | ||
1239 | is_vn_port = 1; | ||
1240 | break; | ||
1241 | } | ||
1242 | } | ||
1243 | mutex_unlock(&lport->lp_mutex); | ||
1244 | |||
1245 | break; | 1250 | break; |
1246 | default: | 1251 | default: |
1247 | /* standard says ignore unknown descriptors >= 128 */ | 1252 | /* standard says ignore unknown descriptors >= 128 */ |
1248 | if (desc->fip_dtype < FIP_DT_VENDOR_BASE) | 1253 | if (desc->fip_dtype < FIP_DT_VENDOR_BASE) |
1249 | return; | 1254 | goto err; |
1250 | break; | 1255 | break; |
1251 | } | 1256 | } |
1252 | desc = (struct fip_desc *)((char *)desc + dlen); | 1257 | desc = (struct fip_desc *)((char *)desc + dlen); |
@@ -1256,26 +1261,68 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
1256 | /* | 1261 | /* |
1257 | * reset only if all required descriptors were present and valid. | 1262 | * reset only if all required descriptors were present and valid. |
1258 | */ | 1263 | */ |
1259 | if (desc_mask) { | 1264 | if (desc_mask) |
1260 | LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n", | 1265 | LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n", |
1261 | desc_mask); | 1266 | desc_mask); |
1267 | else if (!num_vlink_desc) { | ||
1268 | LIBFCOE_FIP_DBG(fip, "CVL: no Vx_Port descriptor found\n"); | ||
1269 | /* | ||
1270 | * No Vx_Port description. Clear all NPIV ports, | ||
1271 | * followed by physical port | ||
1272 | */ | ||
1273 | mutex_lock(&lport->lp_mutex); | ||
1274 | list_for_each_entry(vn_port, &lport->vports, list) | ||
1275 | fc_lport_reset(vn_port); | ||
1276 | mutex_unlock(&lport->lp_mutex); | ||
1277 | |||
1278 | mutex_lock(&fip->ctlr_mutex); | ||
1279 | per_cpu_ptr(lport->dev_stats, | ||
1280 | get_cpu())->VLinkFailureCount++; | ||
1281 | put_cpu(); | ||
1282 | fcoe_ctlr_reset(fip); | ||
1283 | mutex_unlock(&fip->ctlr_mutex); | ||
1284 | |||
1285 | fc_lport_reset(fip->lp); | ||
1286 | fcoe_ctlr_solicit(fip, NULL); | ||
1262 | } else { | 1287 | } else { |
1263 | LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); | 1288 | int i; |
1264 | 1289 | ||
1265 | if (is_vn_port) | 1290 | LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); |
1266 | fc_lport_reset(vn_port); | 1291 | for (i = 0; i < num_vlink_desc; i++) { |
1267 | else { | 1292 | vp = vlink_desc_arr[i]; |
1268 | mutex_lock(&fip->ctlr_mutex); | 1293 | vn_port = fc_vport_id_lookup(lport, |
1269 | per_cpu_ptr(lport->dev_stats, | 1294 | ntoh24(vp->fd_fc_id)); |
1270 | get_cpu())->VLinkFailureCount++; | 1295 | if (!vn_port) |
1271 | put_cpu(); | 1296 | continue; |
1272 | fcoe_ctlr_reset(fip); | 1297 | |
1273 | mutex_unlock(&fip->ctlr_mutex); | 1298 | /* |
1299 | * 'port_id' is already validated, check MAC address and | ||
1300 | * wwpn | ||
1301 | */ | ||
1302 | if (compare_ether_addr(fip->get_src_addr(vn_port), | ||
1303 | vp->fd_mac) != 0 || | ||
1304 | get_unaligned_be64(&vp->fd_wwpn) != | ||
1305 | vn_port->wwpn) | ||
1306 | continue; | ||
1307 | |||
1308 | if (vn_port == lport) | ||
1309 | /* | ||
1310 | * Physical port, defer processing till all | ||
1311 | * listed NPIV ports are cleared | ||
1312 | */ | ||
1313 | reset_phys_port = 1; | ||
1314 | else /* NPIV port */ | ||
1315 | fc_lport_reset(vn_port); | ||
1316 | } | ||
1274 | 1317 | ||
1318 | if (reset_phys_port) { | ||
1275 | fc_lport_reset(fip->lp); | 1319 | fc_lport_reset(fip->lp); |
1276 | fcoe_ctlr_solicit(fip, NULL); | 1320 | fcoe_ctlr_solicit(fip, NULL); |
1277 | } | 1321 | } |
1278 | } | 1322 | } |
1323 | |||
1324 | err: | ||
1325 | kfree(vlink_desc_arr); | ||
1279 | } | 1326 | } |
1280 | 1327 | ||
1281 | /** | 1328 | /** |
diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index f81f77c8569e..41068e8748e7 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c | |||
@@ -544,16 +544,6 @@ static int fcoe_transport_create(const char *buffer, struct kernel_param *kp) | |||
544 | struct fcoe_transport *ft = NULL; | 544 | struct fcoe_transport *ft = NULL; |
545 | enum fip_state fip_mode = (enum fip_state)(long)kp->arg; | 545 | enum fip_state fip_mode = (enum fip_state)(long)kp->arg; |
546 | 546 | ||
547 | #ifdef CONFIG_LIBFCOE_MODULE | ||
548 | /* | ||
549 | * Make sure the module has been initialized, and is not about to be | ||
550 | * removed. Module parameter sysfs files are writable before the | ||
551 | * module_init function is called and after module_exit. | ||
552 | */ | ||
553 | if (THIS_MODULE->state != MODULE_STATE_LIVE) | ||
554 | goto out_nodev; | ||
555 | #endif | ||
556 | |||
557 | mutex_lock(&ft_mutex); | 547 | mutex_lock(&ft_mutex); |
558 | 548 | ||
559 | netdev = fcoe_if_to_netdev(buffer); | 549 | netdev = fcoe_if_to_netdev(buffer); |
@@ -618,16 +608,6 @@ static int fcoe_transport_destroy(const char *buffer, struct kernel_param *kp) | |||
618 | struct net_device *netdev = NULL; | 608 | struct net_device *netdev = NULL; |
619 | struct fcoe_transport *ft = NULL; | 609 | struct fcoe_transport *ft = NULL; |
620 | 610 | ||
621 | #ifdef CONFIG_LIBFCOE_MODULE | ||
622 | /* | ||
623 | * Make sure the module has been initialized, and is not about to be | ||
624 | * removed. Module parameter sysfs files are writable before the | ||
625 | * module_init function is called and after module_exit. | ||
626 | */ | ||
627 | if (THIS_MODULE->state != MODULE_STATE_LIVE) | ||
628 | goto out_nodev; | ||
629 | #endif | ||
630 | |||
631 | mutex_lock(&ft_mutex); | 611 | mutex_lock(&ft_mutex); |
632 | 612 | ||
633 | netdev = fcoe_if_to_netdev(buffer); | 613 | netdev = fcoe_if_to_netdev(buffer); |
@@ -672,16 +652,6 @@ static int fcoe_transport_disable(const char *buffer, struct kernel_param *kp) | |||
672 | struct net_device *netdev = NULL; | 652 | struct net_device *netdev = NULL; |
673 | struct fcoe_transport *ft = NULL; | 653 | struct fcoe_transport *ft = NULL; |
674 | 654 | ||
675 | #ifdef CONFIG_LIBFCOE_MODULE | ||
676 | /* | ||
677 | * Make sure the module has been initialized, and is not about to be | ||
678 | * removed. Module parameter sysfs files are writable before the | ||
679 | * module_init function is called and after module_exit. | ||
680 | */ | ||
681 | if (THIS_MODULE->state != MODULE_STATE_LIVE) | ||
682 | goto out_nodev; | ||
683 | #endif | ||
684 | |||
685 | mutex_lock(&ft_mutex); | 655 | mutex_lock(&ft_mutex); |
686 | 656 | ||
687 | netdev = fcoe_if_to_netdev(buffer); | 657 | netdev = fcoe_if_to_netdev(buffer); |
@@ -720,16 +690,6 @@ static int fcoe_transport_enable(const char *buffer, struct kernel_param *kp) | |||
720 | struct net_device *netdev = NULL; | 690 | struct net_device *netdev = NULL; |
721 | struct fcoe_transport *ft = NULL; | 691 | struct fcoe_transport *ft = NULL; |
722 | 692 | ||
723 | #ifdef CONFIG_LIBFCOE_MODULE | ||
724 | /* | ||
725 | * Make sure the module has been initialized, and is not about to be | ||
726 | * removed. Module parameter sysfs files are writable before the | ||
727 | * module_init function is called and after module_exit. | ||
728 | */ | ||
729 | if (THIS_MODULE->state != MODULE_STATE_LIVE) | ||
730 | goto out_nodev; | ||
731 | #endif | ||
732 | |||
733 | mutex_lock(&ft_mutex); | 693 | mutex_lock(&ft_mutex); |
734 | 694 | ||
735 | netdev = fcoe_if_to_netdev(buffer); | 695 | netdev = fcoe_if_to_netdev(buffer); |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 12868ca46110..888086c4e709 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -5149,21 +5149,21 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
5149 | 5149 | ||
5150 | if (ipr_cmd != NULL) { | 5150 | if (ipr_cmd != NULL) { |
5151 | /* Clear the PCI interrupt */ | 5151 | /* Clear the PCI interrupt */ |
5152 | num_hrrq = 0; | ||
5152 | do { | 5153 | do { |
5153 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); | 5154 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); |
5154 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); | 5155 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); |
5155 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && | 5156 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && |
5156 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); | 5157 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); |
5157 | 5158 | ||
5158 | if (int_reg & IPR_PCII_HRRQ_UPDATED) { | ||
5159 | ipr_isr_eh(ioa_cfg, "Error clearing HRRQ"); | ||
5160 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
5161 | return IRQ_HANDLED; | ||
5162 | } | ||
5163 | |||
5164 | } else if (rc == IRQ_NONE && irq_none == 0) { | 5159 | } else if (rc == IRQ_NONE && irq_none == 0) { |
5165 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); | 5160 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); |
5166 | irq_none++; | 5161 | irq_none++; |
5162 | } else if (num_hrrq == IPR_MAX_HRRQ_RETRIES && | ||
5163 | int_reg & IPR_PCII_HRRQ_UPDATED) { | ||
5164 | ipr_isr_eh(ioa_cfg, "Error clearing HRRQ"); | ||
5165 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
5166 | return IRQ_HANDLED; | ||
5167 | } else | 5167 | } else |
5168 | break; | 5168 | break; |
5169 | } | 5169 | } |
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 911b2736cafa..b9cb8140b398 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
@@ -205,6 +205,7 @@ static void fc_disc_recv_req(struct fc_lport *lport, struct fc_frame *fp) | |||
205 | default: | 205 | default: |
206 | FC_DISC_DBG(disc, "Received an unsupported request, " | 206 | FC_DISC_DBG(disc, "Received an unsupported request, " |
207 | "the opcode is (%x)\n", op); | 207 | "the opcode is (%x)\n", op); |
208 | fc_frame_free(fp); | ||
208 | break; | 209 | break; |
209 | } | 210 | } |
210 | } | 211 | } |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 77035a746f60..3b8a6451ea28 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -1434,6 +1434,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
1434 | (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) == | 1434 | (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) == |
1435 | (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) { | 1435 | (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) { |
1436 | spin_lock_bh(&ep->ex_lock); | 1436 | spin_lock_bh(&ep->ex_lock); |
1437 | resp = ep->resp; | ||
1437 | rc = fc_exch_done_locked(ep); | 1438 | rc = fc_exch_done_locked(ep); |
1438 | WARN_ON(fc_seq_exch(sp) != ep); | 1439 | WARN_ON(fc_seq_exch(sp) != ep); |
1439 | spin_unlock_bh(&ep->ex_lock); | 1440 | spin_unlock_bh(&ep->ex_lock); |
@@ -1978,6 +1979,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, | |||
1978 | spin_unlock_bh(&ep->ex_lock); | 1979 | spin_unlock_bh(&ep->ex_lock); |
1979 | return sp; | 1980 | return sp; |
1980 | err: | 1981 | err: |
1982 | fc_fcp_ddp_done(fr_fsp(fp)); | ||
1981 | rc = fc_exch_done_locked(ep); | 1983 | rc = fc_exch_done_locked(ep); |
1982 | spin_unlock_bh(&ep->ex_lock); | 1984 | spin_unlock_bh(&ep->ex_lock); |
1983 | if (!rc) | 1985 | if (!rc) |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 2a3a4720a771..9cd2149519ac 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -312,7 +312,7 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid) | |||
312 | * DDP related resources for a fcp_pkt | 312 | * DDP related resources for a fcp_pkt |
313 | * @fsp: The FCP packet that DDP had been used on | 313 | * @fsp: The FCP packet that DDP had been used on |
314 | */ | 314 | */ |
315 | static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp) | 315 | void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp) |
316 | { | 316 | { |
317 | struct fc_lport *lport; | 317 | struct fc_lport *lport; |
318 | 318 | ||
@@ -681,8 +681,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, | |||
681 | error = lport->tt.seq_send(lport, seq, fp); | 681 | error = lport->tt.seq_send(lport, seq, fp); |
682 | if (error) { | 682 | if (error) { |
683 | WARN_ON(1); /* send error should be rare */ | 683 | WARN_ON(1); /* send error should be rare */ |
684 | fc_fcp_retry_cmd(fsp); | 684 | return error; |
685 | return 0; | ||
686 | } | 685 | } |
687 | fp = NULL; | 686 | fp = NULL; |
688 | } | 687 | } |
@@ -1673,7 +1672,8 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset) | |||
1673 | FC_FCTL_REQ, 0); | 1672 | FC_FCTL_REQ, 0); |
1674 | 1673 | ||
1675 | rec_tov = get_fsp_rec_tov(fsp); | 1674 | rec_tov = get_fsp_rec_tov(fsp); |
1676 | seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL, | 1675 | seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, |
1676 | fc_fcp_pkt_destroy, | ||
1677 | fsp, jiffies_to_msecs(rec_tov)); | 1677 | fsp, jiffies_to_msecs(rec_tov)); |
1678 | if (!seq) | 1678 | if (!seq) |
1679 | goto retry; | 1679 | goto retry; |
@@ -1720,7 +1720,6 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) | |||
1720 | return; | 1720 | return; |
1721 | } | 1721 | } |
1722 | 1722 | ||
1723 | fsp->recov_seq = NULL; | ||
1724 | switch (fc_frame_payload_op(fp)) { | 1723 | switch (fc_frame_payload_op(fp)) { |
1725 | case ELS_LS_ACC: | 1724 | case ELS_LS_ACC: |
1726 | fsp->recov_retry = 0; | 1725 | fsp->recov_retry = 0; |
@@ -1732,10 +1731,9 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) | |||
1732 | break; | 1731 | break; |
1733 | } | 1732 | } |
1734 | fc_fcp_unlock_pkt(fsp); | 1733 | fc_fcp_unlock_pkt(fsp); |
1735 | fsp->lp->tt.exch_done(seq); | ||
1736 | out: | 1734 | out: |
1735 | fsp->lp->tt.exch_done(seq); | ||
1737 | fc_frame_free(fp); | 1736 | fc_frame_free(fp); |
1738 | fc_fcp_pkt_release(fsp); /* drop hold for outstanding SRR */ | ||
1739 | } | 1737 | } |
1740 | 1738 | ||
1741 | /** | 1739 | /** |
@@ -1747,8 +1745,6 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
1747 | { | 1745 | { |
1748 | if (fc_fcp_lock_pkt(fsp)) | 1746 | if (fc_fcp_lock_pkt(fsp)) |
1749 | goto out; | 1747 | goto out; |
1750 | fsp->lp->tt.exch_done(fsp->recov_seq); | ||
1751 | fsp->recov_seq = NULL; | ||
1752 | switch (PTR_ERR(fp)) { | 1748 | switch (PTR_ERR(fp)) { |
1753 | case -FC_EX_TIMEOUT: | 1749 | case -FC_EX_TIMEOUT: |
1754 | if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) | 1750 | if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) |
@@ -1764,7 +1760,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
1764 | } | 1760 | } |
1765 | fc_fcp_unlock_pkt(fsp); | 1761 | fc_fcp_unlock_pkt(fsp); |
1766 | out: | 1762 | out: |
1767 | fc_fcp_pkt_release(fsp); /* drop hold for outstanding SRR */ | 1763 | fsp->lp->tt.exch_done(fsp->recov_seq); |
1768 | } | 1764 | } |
1769 | 1765 | ||
1770 | /** | 1766 | /** |
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h index fedc819d70c0..c7d071289af5 100644 --- a/drivers/scsi/libfc/fc_libfc.h +++ b/drivers/scsi/libfc/fc_libfc.h | |||
@@ -108,6 +108,7 @@ extern struct fc4_prov fc_rport_fcp_init; /* FCP initiator provider */ | |||
108 | * Set up direct-data placement for this I/O request | 108 | * Set up direct-data placement for this I/O request |
109 | */ | 109 | */ |
110 | void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid); | 110 | void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid); |
111 | void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp); | ||
111 | 112 | ||
112 | /* | 113 | /* |
113 | * Module setup functions | 114 | * Module setup functions |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 31fc21f4d831..db9238f2ecb8 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -99,19 +99,29 @@ static void sas_ata_task_done(struct sas_task *task) | |||
99 | struct sas_ha_struct *sas_ha; | 99 | struct sas_ha_struct *sas_ha; |
100 | enum ata_completion_errors ac; | 100 | enum ata_completion_errors ac; |
101 | unsigned long flags; | 101 | unsigned long flags; |
102 | struct ata_link *link; | ||
102 | 103 | ||
103 | if (!qc) | 104 | if (!qc) |
104 | goto qc_already_gone; | 105 | goto qc_already_gone; |
105 | 106 | ||
106 | dev = qc->ap->private_data; | 107 | dev = qc->ap->private_data; |
107 | sas_ha = dev->port->ha; | 108 | sas_ha = dev->port->ha; |
109 | link = &dev->sata_dev.ap->link; | ||
108 | 110 | ||
109 | spin_lock_irqsave(dev->sata_dev.ap->lock, flags); | 111 | spin_lock_irqsave(dev->sata_dev.ap->lock, flags); |
110 | if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || | 112 | if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || |
111 | ((stat->stat == SAM_STAT_CHECK_CONDITION && | 113 | ((stat->stat == SAM_STAT_CHECK_CONDITION && |
112 | dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { | 114 | dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { |
113 | ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); | 115 | ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); |
114 | qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); | 116 | |
117 | if (!link->sactive) { | ||
118 | qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); | ||
119 | } else { | ||
120 | link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command); | ||
121 | if (unlikely(link->eh_info.err_mask)) | ||
122 | qc->flags |= ATA_QCFLAG_FAILED; | ||
123 | } | ||
124 | |||
115 | dev->sata_dev.sstatus = resp->sstatus; | 125 | dev->sata_dev.sstatus = resp->sstatus; |
116 | dev->sata_dev.serror = resp->serror; | 126 | dev->sata_dev.serror = resp->serror; |
117 | dev->sata_dev.scontrol = resp->scontrol; | 127 | dev->sata_dev.scontrol = resp->scontrol; |
@@ -121,7 +131,13 @@ static void sas_ata_task_done(struct sas_task *task) | |||
121 | SAS_DPRINTK("%s: SAS error %x\n", __func__, | 131 | SAS_DPRINTK("%s: SAS error %x\n", __func__, |
122 | stat->stat); | 132 | stat->stat); |
123 | /* We saw a SAS error. Send a vague error. */ | 133 | /* We saw a SAS error. Send a vague error. */ |
124 | qc->err_mask = ac; | 134 | if (!link->sactive) { |
135 | qc->err_mask = ac; | ||
136 | } else { | ||
137 | link->eh_info.err_mask |= AC_ERR_DEV; | ||
138 | qc->flags |= ATA_QCFLAG_FAILED; | ||
139 | } | ||
140 | |||
125 | dev->sata_dev.tf.feature = 0x04; /* status err */ | 141 | dev->sata_dev.tf.feature = 0x04; /* status err */ |
126 | dev->sata_dev.tf.command = ATA_ERR; | 142 | dev->sata_dev.tf.command = ATA_ERR; |
127 | } | 143 | } |
@@ -279,6 +295,44 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, | |||
279 | return ret; | 295 | return ret; |
280 | } | 296 | } |
281 | 297 | ||
298 | static int sas_ata_soft_reset(struct ata_link *link, unsigned int *class, | ||
299 | unsigned long deadline) | ||
300 | { | ||
301 | struct ata_port *ap = link->ap; | ||
302 | struct domain_device *dev = ap->private_data; | ||
303 | struct sas_internal *i = | ||
304 | to_sas_internal(dev->port->ha->core.shost->transportt); | ||
305 | int res = TMF_RESP_FUNC_FAILED; | ||
306 | int ret = 0; | ||
307 | |||
308 | if (i->dft->lldd_ata_soft_reset) | ||
309 | res = i->dft->lldd_ata_soft_reset(dev); | ||
310 | |||
311 | if (res != TMF_RESP_FUNC_COMPLETE) { | ||
312 | SAS_DPRINTK("%s: Unable to soft reset\n", __func__); | ||
313 | ret = -EAGAIN; | ||
314 | } | ||
315 | |||
316 | switch (dev->sata_dev.command_set) { | ||
317 | case ATA_COMMAND_SET: | ||
318 | SAS_DPRINTK("%s: Found ATA device.\n", __func__); | ||
319 | *class = ATA_DEV_ATA; | ||
320 | break; | ||
321 | case ATAPI_COMMAND_SET: | ||
322 | SAS_DPRINTK("%s: Found ATAPI device.\n", __func__); | ||
323 | *class = ATA_DEV_ATAPI; | ||
324 | break; | ||
325 | default: | ||
326 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", | ||
327 | __func__, dev->sata_dev.command_set); | ||
328 | *class = ATA_DEV_UNKNOWN; | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | ap->cbl = ATA_CBL_SATA; | ||
333 | return ret; | ||
334 | } | ||
335 | |||
282 | static void sas_ata_post_internal(struct ata_queued_cmd *qc) | 336 | static void sas_ata_post_internal(struct ata_queued_cmd *qc) |
283 | { | 337 | { |
284 | if (qc->flags & ATA_QCFLAG_FAILED) | 338 | if (qc->flags & ATA_QCFLAG_FAILED) |
@@ -309,7 +363,7 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc) | |||
309 | 363 | ||
310 | static struct ata_port_operations sas_sata_ops = { | 364 | static struct ata_port_operations sas_sata_ops = { |
311 | .prereset = ata_std_prereset, | 365 | .prereset = ata_std_prereset, |
312 | .softreset = NULL, | 366 | .softreset = sas_ata_soft_reset, |
313 | .hardreset = sas_ata_hard_reset, | 367 | .hardreset = sas_ata_hard_reset, |
314 | .postreset = ata_std_postreset, | 368 | .postreset = ata_std_postreset, |
315 | .error_handler = ata_std_error_handler, | 369 | .error_handler = ata_std_error_handler, |
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 8b538bd1ff2b..14e21b5fb8ba 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h | |||
@@ -57,7 +57,7 @@ int sas_init_queue(struct sas_ha_struct *sas_ha); | |||
57 | int sas_init_events(struct sas_ha_struct *sas_ha); | 57 | int sas_init_events(struct sas_ha_struct *sas_ha); |
58 | void sas_shutdown_queue(struct sas_ha_struct *sas_ha); | 58 | void sas_shutdown_queue(struct sas_ha_struct *sas_ha); |
59 | 59 | ||
60 | void sas_deform_port(struct asd_sas_phy *phy); | 60 | void sas_deform_port(struct asd_sas_phy *phy, int gone); |
61 | 61 | ||
62 | void sas_porte_bytes_dmaed(struct work_struct *work); | 62 | void sas_porte_bytes_dmaed(struct work_struct *work); |
63 | void sas_porte_broadcast_rcvd(struct work_struct *work); | 63 | void sas_porte_broadcast_rcvd(struct work_struct *work); |
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index b459c4b635b1..e0f5018e9071 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c | |||
@@ -39,7 +39,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work) | |||
39 | sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock, | 39 | sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock, |
40 | &phy->phy_events_pending); | 40 | &phy->phy_events_pending); |
41 | phy->error = 0; | 41 | phy->error = 0; |
42 | sas_deform_port(phy); | 42 | sas_deform_port(phy, 1); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void sas_phye_oob_done(struct work_struct *work) | 45 | static void sas_phye_oob_done(struct work_struct *work) |
@@ -66,7 +66,7 @@ static void sas_phye_oob_error(struct work_struct *work) | |||
66 | sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock, | 66 | sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock, |
67 | &phy->phy_events_pending); | 67 | &phy->phy_events_pending); |
68 | 68 | ||
69 | sas_deform_port(phy); | 69 | sas_deform_port(phy, 1); |
70 | 70 | ||
71 | if (!port && phy->enabled && i->dft->lldd_control_phy) { | 71 | if (!port && phy->enabled && i->dft->lldd_control_phy) { |
72 | phy->error++; | 72 | phy->error++; |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index 5257fdfe699a..42fd1f25b664 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
@@ -57,7 +57,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
57 | 57 | ||
58 | if (port) { | 58 | if (port) { |
59 | if (!phy_is_wideport_member(port, phy)) | 59 | if (!phy_is_wideport_member(port, phy)) |
60 | sas_deform_port(phy); | 60 | sas_deform_port(phy, 0); |
61 | else { | 61 | else { |
62 | SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", | 62 | SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", |
63 | __func__, phy->id, phy->port->id, | 63 | __func__, phy->id, phy->port->id, |
@@ -153,28 +153,31 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
153 | * This is called when the physical link to the other phy has been | 153 | * This is called when the physical link to the other phy has been |
154 | * lost (on this phy), in Event thread context. We cannot delay here. | 154 | * lost (on this phy), in Event thread context. We cannot delay here. |
155 | */ | 155 | */ |
156 | void sas_deform_port(struct asd_sas_phy *phy) | 156 | void sas_deform_port(struct asd_sas_phy *phy, int gone) |
157 | { | 157 | { |
158 | struct sas_ha_struct *sas_ha = phy->ha; | 158 | struct sas_ha_struct *sas_ha = phy->ha; |
159 | struct asd_sas_port *port = phy->port; | 159 | struct asd_sas_port *port = phy->port; |
160 | struct sas_internal *si = | 160 | struct sas_internal *si = |
161 | to_sas_internal(sas_ha->core.shost->transportt); | 161 | to_sas_internal(sas_ha->core.shost->transportt); |
162 | struct domain_device *dev; | ||
162 | unsigned long flags; | 163 | unsigned long flags; |
163 | 164 | ||
164 | if (!port) | 165 | if (!port) |
165 | return; /* done by a phy event */ | 166 | return; /* done by a phy event */ |
166 | 167 | ||
167 | if (port->port_dev) | 168 | dev = port->port_dev; |
168 | port->port_dev->pathways--; | 169 | if (dev) |
170 | dev->pathways--; | ||
169 | 171 | ||
170 | if (port->num_phys == 1) { | 172 | if (port->num_phys == 1) { |
173 | if (dev && gone) | ||
174 | dev->gone = 1; | ||
171 | sas_unregister_domain_devices(port); | 175 | sas_unregister_domain_devices(port); |
172 | sas_port_delete(port->port); | 176 | sas_port_delete(port->port); |
173 | port->port = NULL; | 177 | port->port = NULL; |
174 | } else | 178 | } else |
175 | sas_port_delete_phy(port->port, phy->phy); | 179 | sas_port_delete_phy(port->port, phy->phy); |
176 | 180 | ||
177 | |||
178 | if (si->dft->lldd_port_deformed) | 181 | if (si->dft->lldd_port_deformed) |
179 | si->dft->lldd_port_deformed(phy); | 182 | si->dft->lldd_port_deformed(phy); |
180 | 183 | ||
@@ -244,7 +247,7 @@ void sas_porte_link_reset_err(struct work_struct *work) | |||
244 | sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock, | 247 | sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock, |
245 | &phy->port_events_pending); | 248 | &phy->port_events_pending); |
246 | 249 | ||
247 | sas_deform_port(phy); | 250 | sas_deform_port(phy, 1); |
248 | } | 251 | } |
249 | 252 | ||
250 | void sas_porte_timer_event(struct work_struct *work) | 253 | void sas_porte_timer_event(struct work_struct *work) |
@@ -256,7 +259,7 @@ void sas_porte_timer_event(struct work_struct *work) | |||
256 | sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock, | 259 | sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock, |
257 | &phy->port_events_pending); | 260 | &phy->port_events_pending); |
258 | 261 | ||
259 | sas_deform_port(phy); | 262 | sas_deform_port(phy, 1); |
260 | } | 263 | } |
261 | 264 | ||
262 | void sas_porte_hard_reset(struct work_struct *work) | 265 | void sas_porte_hard_reset(struct work_struct *work) |
@@ -268,7 +271,7 @@ void sas_porte_hard_reset(struct work_struct *work) | |||
268 | sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock, | 271 | sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock, |
269 | &phy->port_events_pending); | 272 | &phy->port_events_pending); |
270 | 273 | ||
271 | sas_deform_port(phy); | 274 | sas_deform_port(phy, 1); |
272 | } | 275 | } |
273 | 276 | ||
274 | /* ---------- SAS port registration ---------- */ | 277 | /* ---------- SAS port registration ---------- */ |
@@ -306,6 +309,6 @@ void sas_unregister_ports(struct sas_ha_struct *sas_ha) | |||
306 | 309 | ||
307 | for (i = 0; i < sas_ha->num_phys; i++) | 310 | for (i = 0; i < sas_ha->num_phys; i++) |
308 | if (sas_ha->sas_phy[i]->port) | 311 | if (sas_ha->sas_phy[i]->port) |
309 | sas_deform_port(sas_ha->sas_phy[i]); | 312 | sas_deform_port(sas_ha->sas_phy[i], 0); |
310 | 313 | ||
311 | } | 314 | } |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index f6e189f40917..eeba76cdf774 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -207,6 +207,13 @@ static int sas_queuecommand_lck(struct scsi_cmnd *cmd, | |||
207 | struct sas_ha_struct *sas_ha = dev->port->ha; | 207 | struct sas_ha_struct *sas_ha = dev->port->ha; |
208 | struct sas_task *task; | 208 | struct sas_task *task; |
209 | 209 | ||
210 | /* If the device fell off, no sense in issuing commands */ | ||
211 | if (dev->gone) { | ||
212 | cmd->result = DID_BAD_TARGET << 16; | ||
213 | scsi_done(cmd); | ||
214 | goto out; | ||
215 | } | ||
216 | |||
210 | if (dev_is_sata(dev)) { | 217 | if (dev_is_sata(dev)) { |
211 | unsigned long flags; | 218 | unsigned long flags; |
212 | 219 | ||
@@ -216,13 +223,6 @@ static int sas_queuecommand_lck(struct scsi_cmnd *cmd, | |||
216 | goto out; | 223 | goto out; |
217 | } | 224 | } |
218 | 225 | ||
219 | /* If the device fell off, no sense in issuing commands */ | ||
220 | if (dev->gone) { | ||
221 | cmd->result = DID_BAD_TARGET << 16; | ||
222 | scsi_done(cmd); | ||
223 | goto out; | ||
224 | } | ||
225 | |||
226 | res = -ENOMEM; | 226 | res = -ENOMEM; |
227 | task = sas_create_task(cmd, dev, GFP_ATOMIC); | 227 | task = sas_create_task(cmd, dev, GFP_ATOMIC); |
228 | if (!task) | 228 | if (!task) |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 02d53d89534f..8ec2c86a49d4 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -41,6 +41,7 @@ struct lpfc_sli2_slim; | |||
41 | downloads using bsg */ | 41 | downloads using bsg */ |
42 | #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ | 42 | #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ |
43 | #define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ | 43 | #define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ |
44 | #define LPFC_MAX_SGE_SIZE 0x80000000 /* Maximum data allowed in a SGE */ | ||
44 | #define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ | 45 | #define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ |
45 | #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ | 46 | #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ |
46 | #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ | 47 | #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ |
@@ -486,6 +487,42 @@ struct unsol_rcv_ct_ctx { | |||
486 | (1 << LPFC_USER_LINK_SPEED_AUTO)) | 487 | (1 << LPFC_USER_LINK_SPEED_AUTO)) |
487 | #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16" | 488 | #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16" |
488 | 489 | ||
490 | enum nemb_type { | ||
491 | nemb_mse = 1, | ||
492 | nemb_hbd | ||
493 | }; | ||
494 | |||
495 | enum mbox_type { | ||
496 | mbox_rd = 1, | ||
497 | mbox_wr | ||
498 | }; | ||
499 | |||
500 | enum dma_type { | ||
501 | dma_mbox = 1, | ||
502 | dma_ebuf | ||
503 | }; | ||
504 | |||
505 | enum sta_type { | ||
506 | sta_pre_addr = 1, | ||
507 | sta_pos_addr | ||
508 | }; | ||
509 | |||
510 | struct lpfc_mbox_ext_buf_ctx { | ||
511 | uint32_t state; | ||
512 | #define LPFC_BSG_MBOX_IDLE 0 | ||
513 | #define LPFC_BSG_MBOX_HOST 1 | ||
514 | #define LPFC_BSG_MBOX_PORT 2 | ||
515 | #define LPFC_BSG_MBOX_DONE 3 | ||
516 | #define LPFC_BSG_MBOX_ABTS 4 | ||
517 | enum nemb_type nembType; | ||
518 | enum mbox_type mboxType; | ||
519 | uint32_t numBuf; | ||
520 | uint32_t mbxTag; | ||
521 | uint32_t seqNum; | ||
522 | struct lpfc_dmabuf *mbx_dmabuf; | ||
523 | struct list_head ext_dmabuf_list; | ||
524 | }; | ||
525 | |||
489 | struct lpfc_hba { | 526 | struct lpfc_hba { |
490 | /* SCSI interface function jump table entries */ | 527 | /* SCSI interface function jump table entries */ |
491 | int (*lpfc_new_scsi_buf) | 528 | int (*lpfc_new_scsi_buf) |
@@ -589,6 +626,7 @@ struct lpfc_hba { | |||
589 | 626 | ||
590 | MAILBOX_t *mbox; | 627 | MAILBOX_t *mbox; |
591 | uint32_t *mbox_ext; | 628 | uint32_t *mbox_ext; |
629 | struct lpfc_mbox_ext_buf_ctx mbox_ext_buf_ctx; | ||
592 | uint32_t ha_copy; | 630 | uint32_t ha_copy; |
593 | struct _PCB *pcb; | 631 | struct _PCB *pcb; |
594 | struct _IOCB *IOCBs; | 632 | struct _IOCB *IOCBs; |
@@ -659,6 +697,7 @@ struct lpfc_hba { | |||
659 | uint32_t cfg_hostmem_hgp; | 697 | uint32_t cfg_hostmem_hgp; |
660 | uint32_t cfg_log_verbose; | 698 | uint32_t cfg_log_verbose; |
661 | uint32_t cfg_aer_support; | 699 | uint32_t cfg_aer_support; |
700 | uint32_t cfg_sriov_nr_virtfn; | ||
662 | uint32_t cfg_iocb_cnt; | 701 | uint32_t cfg_iocb_cnt; |
663 | uint32_t cfg_suppress_link_up; | 702 | uint32_t cfg_suppress_link_up; |
664 | #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ | 703 | #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ |
@@ -706,7 +745,6 @@ struct lpfc_hba { | |||
706 | uint32_t *hbq_get; /* Host mem address of HBQ get ptrs */ | 745 | uint32_t *hbq_get; /* Host mem address of HBQ get ptrs */ |
707 | 746 | ||
708 | int brd_no; /* FC board number */ | 747 | int brd_no; /* FC board number */ |
709 | |||
710 | char SerialNumber[32]; /* adapter Serial Number */ | 748 | char SerialNumber[32]; /* adapter Serial Number */ |
711 | char OptionROMVersion[32]; /* adapter BIOS / Fcode version */ | 749 | char OptionROMVersion[32]; /* adapter BIOS / Fcode version */ |
712 | char ModelDesc[256]; /* Model Description */ | 750 | char ModelDesc[256]; /* Model Description */ |
@@ -778,6 +816,9 @@ struct lpfc_hba { | |||
778 | uint16_t vpi_base; | 816 | uint16_t vpi_base; |
779 | uint16_t vfi_base; | 817 | uint16_t vfi_base; |
780 | unsigned long *vpi_bmask; /* vpi allocation table */ | 818 | unsigned long *vpi_bmask; /* vpi allocation table */ |
819 | uint16_t *vpi_ids; | ||
820 | uint16_t vpi_count; | ||
821 | struct list_head lpfc_vpi_blk_list; | ||
781 | 822 | ||
782 | /* Data structure used by fabric iocb scheduler */ | 823 | /* Data structure used by fabric iocb scheduler */ |
783 | struct list_head fabric_iocb_list; | 824 | struct list_head fabric_iocb_list; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 8dcbf8fff673..135a53baa735 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -755,6 +755,73 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr, | |||
755 | } | 755 | } |
756 | 756 | ||
757 | /** | 757 | /** |
758 | * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc | ||
759 | * @phba: lpfc_hba pointer. | ||
760 | * | ||
761 | * Description: | ||
762 | * Request SLI4 interface type-2 device to perform a physical register set | ||
763 | * access. | ||
764 | * | ||
765 | * Returns: | ||
766 | * zero for success | ||
767 | **/ | ||
768 | static ssize_t | ||
769 | lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) | ||
770 | { | ||
771 | struct completion online_compl; | ||
772 | uint32_t reg_val; | ||
773 | int status = 0; | ||
774 | int rc; | ||
775 | |||
776 | if (!phba->cfg_enable_hba_reset) | ||
777 | return -EIO; | ||
778 | |||
779 | if ((phba->sli_rev < LPFC_SLI_REV4) || | ||
780 | (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
781 | LPFC_SLI_INTF_IF_TYPE_2)) | ||
782 | return -EPERM; | ||
783 | |||
784 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); | ||
785 | |||
786 | if (status != 0) | ||
787 | return status; | ||
788 | |||
789 | /* wait for the device to be quiesced before firmware reset */ | ||
790 | msleep(100); | ||
791 | |||
792 | reg_val = readl(phba->sli4_hba.conf_regs_memmap_p + | ||
793 | LPFC_CTL_PDEV_CTL_OFFSET); | ||
794 | |||
795 | if (opcode == LPFC_FW_DUMP) | ||
796 | reg_val |= LPFC_FW_DUMP_REQUEST; | ||
797 | else if (opcode == LPFC_FW_RESET) | ||
798 | reg_val |= LPFC_CTL_PDEV_CTL_FRST; | ||
799 | else if (opcode == LPFC_DV_RESET) | ||
800 | reg_val |= LPFC_CTL_PDEV_CTL_DRST; | ||
801 | |||
802 | writel(reg_val, phba->sli4_hba.conf_regs_memmap_p + | ||
803 | LPFC_CTL_PDEV_CTL_OFFSET); | ||
804 | /* flush */ | ||
805 | readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET); | ||
806 | |||
807 | /* delay driver action following IF_TYPE_2 reset */ | ||
808 | msleep(100); | ||
809 | |||
810 | init_completion(&online_compl); | ||
811 | rc = lpfc_workq_post_event(phba, &status, &online_compl, | ||
812 | LPFC_EVT_ONLINE); | ||
813 | if (rc == 0) | ||
814 | return -ENOMEM; | ||
815 | |||
816 | wait_for_completion(&online_compl); | ||
817 | |||
818 | if (status != 0) | ||
819 | return -EIO; | ||
820 | |||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | /** | ||
758 | * lpfc_nport_evt_cnt_show - Return the number of nport events | 825 | * lpfc_nport_evt_cnt_show - Return the number of nport events |
759 | * @dev: class device that is converted into a Scsi_host. | 826 | * @dev: class device that is converted into a Scsi_host. |
760 | * @attr: device attribute, not used. | 827 | * @attr: device attribute, not used. |
@@ -848,6 +915,12 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, | |||
848 | return -EINVAL; | 915 | return -EINVAL; |
849 | else | 916 | else |
850 | status = lpfc_do_offline(phba, LPFC_EVT_KILL); | 917 | status = lpfc_do_offline(phba, LPFC_EVT_KILL); |
918 | else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0) | ||
919 | status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP); | ||
920 | else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0) | ||
921 | status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET); | ||
922 | else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0) | ||
923 | status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET); | ||
851 | else | 924 | else |
852 | return -EINVAL; | 925 | return -EINVAL; |
853 | 926 | ||
@@ -1322,6 +1395,102 @@ lpfc_dss_show(struct device *dev, struct device_attribute *attr, | |||
1322 | } | 1395 | } |
1323 | 1396 | ||
1324 | /** | 1397 | /** |
1398 | * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions | ||
1399 | * @dev: class converted to a Scsi_host structure. | ||
1400 | * @attr: device attribute, not used. | ||
1401 | * @buf: on return contains the formatted support level. | ||
1402 | * | ||
1403 | * Description: | ||
1404 | * Returns the maximum number of virtual functions a physical function can | ||
1405 | * support, 0 will be returned if called on virtual function. | ||
1406 | * | ||
1407 | * Returns: size of formatted string. | ||
1408 | **/ | ||
1409 | static ssize_t | ||
1410 | lpfc_sriov_hw_max_virtfn_show(struct device *dev, | ||
1411 | struct device_attribute *attr, | ||
1412 | char *buf) | ||
1413 | { | ||
1414 | struct Scsi_Host *shost = class_to_shost(dev); | ||
1415 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
1416 | struct lpfc_hba *phba = vport->phba; | ||
1417 | struct pci_dev *pdev = phba->pcidev; | ||
1418 | union lpfc_sli4_cfg_shdr *shdr; | ||
1419 | uint32_t shdr_status, shdr_add_status; | ||
1420 | LPFC_MBOXQ_t *mboxq; | ||
1421 | struct lpfc_mbx_get_prof_cfg *get_prof_cfg; | ||
1422 | struct lpfc_rsrc_desc_pcie *desc; | ||
1423 | uint32_t max_nr_virtfn; | ||
1424 | uint32_t desc_count; | ||
1425 | int length, rc, i; | ||
1426 | |||
1427 | if ((phba->sli_rev < LPFC_SLI_REV4) || | ||
1428 | (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
1429 | LPFC_SLI_INTF_IF_TYPE_2)) | ||
1430 | return -EPERM; | ||
1431 | |||
1432 | if (!pdev->is_physfn) | ||
1433 | return snprintf(buf, PAGE_SIZE, "%d\n", 0); | ||
1434 | |||
1435 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1436 | if (!mboxq) | ||
1437 | return -ENOMEM; | ||
1438 | |||
1439 | /* get the maximum number of virtfn support by physfn */ | ||
1440 | length = (sizeof(struct lpfc_mbx_get_prof_cfg) - | ||
1441 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
1442 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
1443 | LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG, | ||
1444 | length, LPFC_SLI4_MBX_EMBED); | ||
1445 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
1446 | &mboxq->u.mqe.un.sli4_config.header.cfg_shdr; | ||
1447 | bf_set(lpfc_mbox_hdr_pf_num, &shdr->request, | ||
1448 | phba->sli4_hba.iov.pf_number + 1); | ||
1449 | |||
1450 | get_prof_cfg = &mboxq->u.mqe.un.get_prof_cfg; | ||
1451 | bf_set(lpfc_mbx_get_prof_cfg_prof_tp, &get_prof_cfg->u.request, | ||
1452 | LPFC_CFG_TYPE_CURRENT_ACTIVE); | ||
1453 | |||
1454 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, | ||
1455 | lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG)); | ||
1456 | |||
1457 | if (rc != MBX_TIMEOUT) { | ||
1458 | /* check return status */ | ||
1459 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
1460 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
1461 | &shdr->response); | ||
1462 | if (shdr_status || shdr_add_status || rc) | ||
1463 | goto error_out; | ||
1464 | |||
1465 | } else | ||
1466 | goto error_out; | ||
1467 | |||
1468 | desc_count = get_prof_cfg->u.response.prof_cfg.rsrc_desc_count; | ||
1469 | |||
1470 | for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) { | ||
1471 | desc = (struct lpfc_rsrc_desc_pcie *) | ||
1472 | &get_prof_cfg->u.response.prof_cfg.desc[i]; | ||
1473 | if (LPFC_RSRC_DESC_TYPE_PCIE == | ||
1474 | bf_get(lpfc_rsrc_desc_pcie_type, desc)) { | ||
1475 | max_nr_virtfn = bf_get(lpfc_rsrc_desc_pcie_nr_virtfn, | ||
1476 | desc); | ||
1477 | break; | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | if (i < LPFC_RSRC_DESC_MAX_NUM) { | ||
1482 | if (rc != MBX_TIMEOUT) | ||
1483 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1484 | return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn); | ||
1485 | } | ||
1486 | |||
1487 | error_out: | ||
1488 | if (rc != MBX_TIMEOUT) | ||
1489 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1490 | return -EIO; | ||
1491 | } | ||
1492 | |||
1493 | /** | ||
1325 | * lpfc_param_show - Return a cfg attribute value in decimal | 1494 | * lpfc_param_show - Return a cfg attribute value in decimal |
1326 | * | 1495 | * |
1327 | * Description: | 1496 | * Description: |
@@ -1762,6 +1931,8 @@ static DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, NULL); | |||
1762 | static DEVICE_ATTR(lpfc_fips_level, S_IRUGO, lpfc_fips_level_show, NULL); | 1931 | static DEVICE_ATTR(lpfc_fips_level, S_IRUGO, lpfc_fips_level_show, NULL); |
1763 | static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL); | 1932 | static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL); |
1764 | static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); | 1933 | static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); |
1934 | static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO, | ||
1935 | lpfc_sriov_hw_max_virtfn_show, NULL); | ||
1765 | 1936 | ||
1766 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; | 1937 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
1767 | 1938 | ||
@@ -3014,7 +3185,7 @@ static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR, | |||
3014 | * | 3185 | * |
3015 | * @dev: class device that is converted into a Scsi_host. | 3186 | * @dev: class device that is converted into a Scsi_host. |
3016 | * @attr: device attribute, not used. | 3187 | * @attr: device attribute, not used. |
3017 | * @buf: containing the string "selective". | 3188 | * @buf: containing enable or disable aer flag. |
3018 | * @count: unused variable. | 3189 | * @count: unused variable. |
3019 | * | 3190 | * |
3020 | * Description: | 3191 | * Description: |
@@ -3098,7 +3269,7 @@ lpfc_param_show(aer_support) | |||
3098 | /** | 3269 | /** |
3099 | * lpfc_aer_support_init - Set the initial adapters aer support flag | 3270 | * lpfc_aer_support_init - Set the initial adapters aer support flag |
3100 | * @phba: lpfc_hba pointer. | 3271 | * @phba: lpfc_hba pointer. |
3101 | * @val: link speed value. | 3272 | * @val: enable aer or disable aer flag. |
3102 | * | 3273 | * |
3103 | * Description: | 3274 | * Description: |
3104 | * If val is in a valid range [0,1], then set the adapter's initial | 3275 | * If val is in a valid range [0,1], then set the adapter's initial |
@@ -3137,7 +3308,7 @@ static DEVICE_ATTR(lpfc_aer_support, S_IRUGO | S_IWUSR, | |||
3137 | * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device | 3308 | * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device |
3138 | * @dev: class device that is converted into a Scsi_host. | 3309 | * @dev: class device that is converted into a Scsi_host. |
3139 | * @attr: device attribute, not used. | 3310 | * @attr: device attribute, not used. |
3140 | * @buf: containing the string "selective". | 3311 | * @buf: containing flag 1 for aer cleanup state. |
3141 | * @count: unused variable. | 3312 | * @count: unused variable. |
3142 | * | 3313 | * |
3143 | * Description: | 3314 | * Description: |
@@ -3180,6 +3351,136 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, | |||
3180 | static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, | 3351 | static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, |
3181 | lpfc_aer_cleanup_state); | 3352 | lpfc_aer_cleanup_state); |
3182 | 3353 | ||
3354 | /** | ||
3355 | * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions | ||
3356 | * | ||
3357 | * @dev: class device that is converted into a Scsi_host. | ||
3358 | * @attr: device attribute, not used. | ||
3359 | * @buf: containing the string the number of vfs to be enabled. | ||
3360 | * @count: unused variable. | ||
3361 | * | ||
3362 | * Description: | ||
3363 | * When this api is called either through user sysfs, the driver shall | ||
3364 | * try to enable or disable SR-IOV virtual functions according to the | ||
3365 | * following: | ||
3366 | * | ||
3367 | * If zero virtual function has been enabled to the physical function, | ||
3368 | * the driver shall invoke the pci enable virtual function api trying | ||
3369 | * to enable the virtual functions. If the nr_vfn provided is greater | ||
3370 | * than the maximum supported, the maximum virtual function number will | ||
3371 | * be used for invoking the api; otherwise, the nr_vfn provided shall | ||
3372 | * be used for invoking the api. If the api call returned success, the | ||
3373 | * actual number of virtual functions enabled will be set to the driver | ||
3374 | * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver | ||
3375 | * cfg_sriov_nr_virtfn remains zero. | ||
3376 | * | ||
3377 | * If none-zero virtual functions have already been enabled to the | ||
3378 | * physical function, as reflected by the driver's cfg_sriov_nr_virtfn, | ||
3379 | * -EINVAL will be returned and the driver does nothing; | ||
3380 | * | ||
3381 | * If the nr_vfn provided is zero and none-zero virtual functions have | ||
3382 | * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the | ||
3383 | * disabling virtual function api shall be invoded to disable all the | ||
3384 | * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to | ||
3385 | * zero. Otherwise, if zero virtual function has been enabled, do | ||
3386 | * nothing. | ||
3387 | * | ||
3388 | * Returns: | ||
3389 | * length of the buf on success if val is in range the intended mode | ||
3390 | * is supported. | ||
3391 | * -EINVAL if val out of range or intended mode is not supported. | ||
3392 | **/ | ||
3393 | static ssize_t | ||
3394 | lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr, | ||
3395 | const char *buf, size_t count) | ||
3396 | { | ||
3397 | struct Scsi_Host *shost = class_to_shost(dev); | ||
3398 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; | ||
3399 | struct lpfc_hba *phba = vport->phba; | ||
3400 | struct pci_dev *pdev = phba->pcidev; | ||
3401 | int val = 0, rc = -EINVAL; | ||
3402 | |||
3403 | /* Sanity check on user data */ | ||
3404 | if (!isdigit(buf[0])) | ||
3405 | return -EINVAL; | ||
3406 | if (sscanf(buf, "%i", &val) != 1) | ||
3407 | return -EINVAL; | ||
3408 | if (val < 0) | ||
3409 | return -EINVAL; | ||
3410 | |||
3411 | /* Request disabling virtual functions */ | ||
3412 | if (val == 0) { | ||
3413 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
3414 | pci_disable_sriov(pdev); | ||
3415 | phba->cfg_sriov_nr_virtfn = 0; | ||
3416 | } | ||
3417 | return strlen(buf); | ||
3418 | } | ||
3419 | |||
3420 | /* Request enabling virtual functions */ | ||
3421 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
3422 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3423 | "3018 There are %d virtual functions " | ||
3424 | "enabled on physical function.\n", | ||
3425 | phba->cfg_sriov_nr_virtfn); | ||
3426 | return -EEXIST; | ||
3427 | } | ||
3428 | |||
3429 | if (val <= LPFC_MAX_VFN_PER_PFN) | ||
3430 | phba->cfg_sriov_nr_virtfn = val; | ||
3431 | else { | ||
3432 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3433 | "3019 Enabling %d virtual functions is not " | ||
3434 | "allowed.\n", val); | ||
3435 | return -EINVAL; | ||
3436 | } | ||
3437 | |||
3438 | rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn); | ||
3439 | if (rc) { | ||
3440 | phba->cfg_sriov_nr_virtfn = 0; | ||
3441 | rc = -EPERM; | ||
3442 | } else | ||
3443 | rc = strlen(buf); | ||
3444 | |||
3445 | return rc; | ||
3446 | } | ||
3447 | |||
3448 | static int lpfc_sriov_nr_virtfn = LPFC_DEF_VFN_PER_PFN; | ||
3449 | module_param(lpfc_sriov_nr_virtfn, int, S_IRUGO|S_IWUSR); | ||
3450 | MODULE_PARM_DESC(lpfc_sriov_nr_virtfn, "Enable PCIe device SR-IOV virtual fn"); | ||
3451 | lpfc_param_show(sriov_nr_virtfn) | ||
3452 | |||
3453 | /** | ||
3454 | * lpfc_sriov_nr_virtfn_init - Set the initial sr-iov virtual function enable | ||
3455 | * @phba: lpfc_hba pointer. | ||
3456 | * @val: link speed value. | ||
3457 | * | ||
3458 | * Description: | ||
3459 | * If val is in a valid range [0,255], then set the adapter's initial | ||
3460 | * cfg_sriov_nr_virtfn field. If it's greater than the maximum, the maximum | ||
3461 | * number shall be used instead. It will be up to the driver's probe_one | ||
3462 | * routine to determine whether the device's SR-IOV is supported or not. | ||
3463 | * | ||
3464 | * Returns: | ||
3465 | * zero if val saved. | ||
3466 | * -EINVAL val out of range | ||
3467 | **/ | ||
3468 | static int | ||
3469 | lpfc_sriov_nr_virtfn_init(struct lpfc_hba *phba, int val) | ||
3470 | { | ||
3471 | if (val >= 0 && val <= LPFC_MAX_VFN_PER_PFN) { | ||
3472 | phba->cfg_sriov_nr_virtfn = val; | ||
3473 | return 0; | ||
3474 | } | ||
3475 | |||
3476 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3477 | "3017 Enabling %d virtual functions is not " | ||
3478 | "allowed.\n", val); | ||
3479 | return -EINVAL; | ||
3480 | } | ||
3481 | static DEVICE_ATTR(lpfc_sriov_nr_virtfn, S_IRUGO | S_IWUSR, | ||
3482 | lpfc_sriov_nr_virtfn_show, lpfc_sriov_nr_virtfn_store); | ||
3483 | |||
3183 | /* | 3484 | /* |
3184 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. | 3485 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. |
3185 | # Value range is [2,3]. Default value is 3. | 3486 | # Value range is [2,3]. Default value is 3. |
@@ -3497,6 +3798,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
3497 | &dev_attr_lpfc_prot_sg_seg_cnt, | 3798 | &dev_attr_lpfc_prot_sg_seg_cnt, |
3498 | &dev_attr_lpfc_aer_support, | 3799 | &dev_attr_lpfc_aer_support, |
3499 | &dev_attr_lpfc_aer_state_cleanup, | 3800 | &dev_attr_lpfc_aer_state_cleanup, |
3801 | &dev_attr_lpfc_sriov_nr_virtfn, | ||
3500 | &dev_attr_lpfc_suppress_link_up, | 3802 | &dev_attr_lpfc_suppress_link_up, |
3501 | &dev_attr_lpfc_iocb_cnt, | 3803 | &dev_attr_lpfc_iocb_cnt, |
3502 | &dev_attr_iocb_hw, | 3804 | &dev_attr_iocb_hw, |
@@ -3505,6 +3807,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
3505 | &dev_attr_lpfc_fips_level, | 3807 | &dev_attr_lpfc_fips_level, |
3506 | &dev_attr_lpfc_fips_rev, | 3808 | &dev_attr_lpfc_fips_rev, |
3507 | &dev_attr_lpfc_dss, | 3809 | &dev_attr_lpfc_dss, |
3810 | &dev_attr_lpfc_sriov_hw_max_virtfn, | ||
3508 | NULL, | 3811 | NULL, |
3509 | }; | 3812 | }; |
3510 | 3813 | ||
@@ -3961,7 +4264,7 @@ static struct bin_attribute sysfs_mbox_attr = { | |||
3961 | .name = "mbox", | 4264 | .name = "mbox", |
3962 | .mode = S_IRUSR | S_IWUSR, | 4265 | .mode = S_IRUSR | S_IWUSR, |
3963 | }, | 4266 | }, |
3964 | .size = MAILBOX_CMD_SIZE, | 4267 | .size = MAILBOX_SYSFS_MAX, |
3965 | .read = sysfs_mbox_read, | 4268 | .read = sysfs_mbox_read, |
3966 | .write = sysfs_mbox_write, | 4269 | .write = sysfs_mbox_write, |
3967 | }; | 4270 | }; |
@@ -4705,6 +5008,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
4705 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); | 5008 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); |
4706 | lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); | 5009 | lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); |
4707 | lpfc_aer_support_init(phba, lpfc_aer_support); | 5010 | lpfc_aer_support_init(phba, lpfc_aer_support); |
5011 | lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn); | ||
4708 | lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); | 5012 | lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); |
4709 | lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); | 5013 | lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); |
4710 | phba->cfg_enable_dss = 1; | 5014 | phba->cfg_enable_dss = 1; |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 853e5042f39c..7fb0ba4cbfa7 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/list.h> | ||
26 | 27 | ||
27 | #include <scsi/scsi.h> | 28 | #include <scsi/scsi.h> |
28 | #include <scsi/scsi_host.h> | 29 | #include <scsi/scsi_host.h> |
@@ -79,8 +80,7 @@ struct lpfc_bsg_iocb { | |||
79 | struct lpfc_bsg_mbox { | 80 | struct lpfc_bsg_mbox { |
80 | LPFC_MBOXQ_t *pmboxq; | 81 | LPFC_MBOXQ_t *pmboxq; |
81 | MAILBOX_t *mb; | 82 | MAILBOX_t *mb; |
82 | struct lpfc_dmabuf *rxbmp; /* for BIU diags */ | 83 | struct lpfc_dmabuf *dmabuffers; /* for BIU diags */ |
83 | struct lpfc_dmabufext *dmp; /* for BIU diags */ | ||
84 | uint8_t *ext; /* extended mailbox data */ | 84 | uint8_t *ext; /* extended mailbox data */ |
85 | uint32_t mbOffset; /* from app */ | 85 | uint32_t mbOffset; /* from app */ |
86 | uint32_t inExtWLen; /* from app */ | 86 | uint32_t inExtWLen; /* from app */ |
@@ -332,6 +332,8 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job) | |||
332 | cmd->ulpLe = 1; | 332 | cmd->ulpLe = 1; |
333 | cmd->ulpClass = CLASS3; | 333 | cmd->ulpClass = CLASS3; |
334 | cmd->ulpContext = ndlp->nlp_rpi; | 334 | cmd->ulpContext = ndlp->nlp_rpi; |
335 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
336 | cmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; | ||
335 | cmd->ulpOwner = OWN_CHIP; | 337 | cmd->ulpOwner = OWN_CHIP; |
336 | cmdiocbq->vport = phba->pport; | 338 | cmdiocbq->vport = phba->pport; |
337 | cmdiocbq->context3 = bmp; | 339 | cmdiocbq->context3 = bmp; |
@@ -1336,6 +1338,10 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag, | |||
1336 | } | 1338 | } |
1337 | 1339 | ||
1338 | icmd->un.ulpWord[3] = ndlp->nlp_rpi; | 1340 | icmd->un.ulpWord[3] = ndlp->nlp_rpi; |
1341 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
1342 | icmd->ulpContext = | ||
1343 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; | ||
1344 | |||
1339 | /* The exchange is done, mark the entry as invalid */ | 1345 | /* The exchange is done, mark the entry as invalid */ |
1340 | phba->ct_ctx[tag].flags &= ~UNSOL_VALID; | 1346 | phba->ct_ctx[tag].flags &= ~UNSOL_VALID; |
1341 | } else | 1347 | } else |
@@ -1463,11 +1469,91 @@ send_mgmt_rsp_exit: | |||
1463 | } | 1469 | } |
1464 | 1470 | ||
1465 | /** | 1471 | /** |
1466 | * lpfc_bsg_diag_mode - process a LPFC_BSG_VENDOR_DIAG_MODE bsg vendor command | 1472 | * lpfc_bsg_diag_mode_enter - process preparing into device diag loopback mode |
1473 | * @phba: Pointer to HBA context object. | ||
1467 | * @job: LPFC_BSG_VENDOR_DIAG_MODE | 1474 | * @job: LPFC_BSG_VENDOR_DIAG_MODE |
1468 | * | 1475 | * |
1469 | * This function is responsible for placing a port into diagnostic loopback | 1476 | * This function is responsible for preparing driver for diag loopback |
1470 | * mode in order to perform a diagnostic loopback test. | 1477 | * on device. |
1478 | */ | ||
1479 | static int | ||
1480 | lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba, struct fc_bsg_job *job) | ||
1481 | { | ||
1482 | struct lpfc_vport **vports; | ||
1483 | struct Scsi_Host *shost; | ||
1484 | struct lpfc_sli *psli; | ||
1485 | struct lpfc_sli_ring *pring; | ||
1486 | int i = 0; | ||
1487 | |||
1488 | psli = &phba->sli; | ||
1489 | if (!psli) | ||
1490 | return -ENODEV; | ||
1491 | |||
1492 | pring = &psli->ring[LPFC_FCP_RING]; | ||
1493 | if (!pring) | ||
1494 | return -ENODEV; | ||
1495 | |||
1496 | if ((phba->link_state == LPFC_HBA_ERROR) || | ||
1497 | (psli->sli_flag & LPFC_BLOCK_MGMT_IO) || | ||
1498 | (!(psli->sli_flag & LPFC_SLI_ACTIVE))) | ||
1499 | return -EACCES; | ||
1500 | |||
1501 | vports = lpfc_create_vport_work_array(phba); | ||
1502 | if (vports) { | ||
1503 | for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | ||
1504 | shost = lpfc_shost_from_vport(vports[i]); | ||
1505 | scsi_block_requests(shost); | ||
1506 | } | ||
1507 | lpfc_destroy_vport_work_array(phba, vports); | ||
1508 | } else { | ||
1509 | shost = lpfc_shost_from_vport(phba->pport); | ||
1510 | scsi_block_requests(shost); | ||
1511 | } | ||
1512 | |||
1513 | while (pring->txcmplq_cnt) { | ||
1514 | if (i++ > 500) /* wait up to 5 seconds */ | ||
1515 | break; | ||
1516 | msleep(10); | ||
1517 | } | ||
1518 | return 0; | ||
1519 | } | ||
1520 | |||
1521 | /** | ||
1522 | * lpfc_bsg_diag_mode_exit - exit process from device diag loopback mode | ||
1523 | * @phba: Pointer to HBA context object. | ||
1524 | * @job: LPFC_BSG_VENDOR_DIAG_MODE | ||
1525 | * | ||
1526 | * This function is responsible for driver exit processing of setting up | ||
1527 | * diag loopback mode on device. | ||
1528 | */ | ||
1529 | static void | ||
1530 | lpfc_bsg_diag_mode_exit(struct lpfc_hba *phba) | ||
1531 | { | ||
1532 | struct Scsi_Host *shost; | ||
1533 | struct lpfc_vport **vports; | ||
1534 | int i; | ||
1535 | |||
1536 | vports = lpfc_create_vport_work_array(phba); | ||
1537 | if (vports) { | ||
1538 | for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | ||
1539 | shost = lpfc_shost_from_vport(vports[i]); | ||
1540 | scsi_unblock_requests(shost); | ||
1541 | } | ||
1542 | lpfc_destroy_vport_work_array(phba, vports); | ||
1543 | } else { | ||
1544 | shost = lpfc_shost_from_vport(phba->pport); | ||
1545 | scsi_unblock_requests(shost); | ||
1546 | } | ||
1547 | return; | ||
1548 | } | ||
1549 | |||
1550 | /** | ||
1551 | * lpfc_sli3_bsg_diag_loopback_mode - process an sli3 bsg vendor command | ||
1552 | * @phba: Pointer to HBA context object. | ||
1553 | * @job: LPFC_BSG_VENDOR_DIAG_MODE | ||
1554 | * | ||
1555 | * This function is responsible for placing an sli3 port into diagnostic | ||
1556 | * loopback mode in order to perform a diagnostic loopback test. | ||
1471 | * All new scsi requests are blocked, a small delay is used to allow the | 1557 | * All new scsi requests are blocked, a small delay is used to allow the |
1472 | * scsi requests to complete then the link is brought down. If the link is | 1558 | * scsi requests to complete then the link is brought down. If the link is |
1473 | * is placed in loopback mode then scsi requests are again allowed | 1559 | * is placed in loopback mode then scsi requests are again allowed |
@@ -1475,17 +1561,11 @@ send_mgmt_rsp_exit: | |||
1475 | * All of this is done in-line. | 1561 | * All of this is done in-line. |
1476 | */ | 1562 | */ |
1477 | static int | 1563 | static int |
1478 | lpfc_bsg_diag_mode(struct fc_bsg_job *job) | 1564 | lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job) |
1479 | { | 1565 | { |
1480 | struct Scsi_Host *shost = job->shost; | ||
1481 | struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; | ||
1482 | struct lpfc_hba *phba = vport->phba; | ||
1483 | struct diag_mode_set *loopback_mode; | 1566 | struct diag_mode_set *loopback_mode; |
1484 | struct lpfc_sli *psli = &phba->sli; | ||
1485 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_FCP_RING]; | ||
1486 | uint32_t link_flags; | 1567 | uint32_t link_flags; |
1487 | uint32_t timeout; | 1568 | uint32_t timeout; |
1488 | struct lpfc_vport **vports; | ||
1489 | LPFC_MBOXQ_t *pmboxq; | 1569 | LPFC_MBOXQ_t *pmboxq; |
1490 | int mbxstatus; | 1570 | int mbxstatus; |
1491 | int i = 0; | 1571 | int i = 0; |
@@ -1494,53 +1574,33 @@ lpfc_bsg_diag_mode(struct fc_bsg_job *job) | |||
1494 | /* no data to return just the return code */ | 1574 | /* no data to return just the return code */ |
1495 | job->reply->reply_payload_rcv_len = 0; | 1575 | job->reply->reply_payload_rcv_len = 0; |
1496 | 1576 | ||
1497 | if (job->request_len < | 1577 | if (job->request_len < sizeof(struct fc_bsg_request) + |
1498 | sizeof(struct fc_bsg_request) + sizeof(struct diag_mode_set)) { | 1578 | sizeof(struct diag_mode_set)) { |
1499 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | 1579 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, |
1500 | "2738 Received DIAG MODE request below minimum " | 1580 | "2738 Received DIAG MODE request size:%d " |
1501 | "size\n"); | 1581 | "below the minimum size:%d\n", |
1582 | job->request_len, | ||
1583 | (int)(sizeof(struct fc_bsg_request) + | ||
1584 | sizeof(struct diag_mode_set))); | ||
1502 | rc = -EINVAL; | 1585 | rc = -EINVAL; |
1503 | goto job_error; | 1586 | goto job_error; |
1504 | } | 1587 | } |
1505 | 1588 | ||
1589 | rc = lpfc_bsg_diag_mode_enter(phba, job); | ||
1590 | if (rc) | ||
1591 | goto job_error; | ||
1592 | |||
1593 | /* bring the link to diagnostic mode */ | ||
1506 | loopback_mode = (struct diag_mode_set *) | 1594 | loopback_mode = (struct diag_mode_set *) |
1507 | job->request->rqst_data.h_vendor.vendor_cmd; | 1595 | job->request->rqst_data.h_vendor.vendor_cmd; |
1508 | link_flags = loopback_mode->type; | 1596 | link_flags = loopback_mode->type; |
1509 | timeout = loopback_mode->timeout * 100; | 1597 | timeout = loopback_mode->timeout * 100; |
1510 | 1598 | ||
1511 | if ((phba->link_state == LPFC_HBA_ERROR) || | ||
1512 | (psli->sli_flag & LPFC_BLOCK_MGMT_IO) || | ||
1513 | (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { | ||
1514 | rc = -EACCES; | ||
1515 | goto job_error; | ||
1516 | } | ||
1517 | |||
1518 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1599 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1519 | if (!pmboxq) { | 1600 | if (!pmboxq) { |
1520 | rc = -ENOMEM; | 1601 | rc = -ENOMEM; |
1521 | goto job_error; | 1602 | goto loopback_mode_exit; |
1522 | } | ||
1523 | |||
1524 | vports = lpfc_create_vport_work_array(phba); | ||
1525 | if (vports) { | ||
1526 | for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | ||
1527 | shost = lpfc_shost_from_vport(vports[i]); | ||
1528 | scsi_block_requests(shost); | ||
1529 | } | ||
1530 | |||
1531 | lpfc_destroy_vport_work_array(phba, vports); | ||
1532 | } else { | ||
1533 | shost = lpfc_shost_from_vport(phba->pport); | ||
1534 | scsi_block_requests(shost); | ||
1535 | } | 1603 | } |
1536 | |||
1537 | while (pring->txcmplq_cnt) { | ||
1538 | if (i++ > 500) /* wait up to 5 seconds */ | ||
1539 | break; | ||
1540 | |||
1541 | msleep(10); | ||
1542 | } | ||
1543 | |||
1544 | memset((void *)pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | 1604 | memset((void *)pmboxq, 0, sizeof(LPFC_MBOXQ_t)); |
1545 | pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK; | 1605 | pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK; |
1546 | pmboxq->u.mb.mbxOwner = OWN_HOST; | 1606 | pmboxq->u.mb.mbxOwner = OWN_HOST; |
@@ -1594,22 +1654,186 @@ lpfc_bsg_diag_mode(struct fc_bsg_job *job) | |||
1594 | rc = -ENODEV; | 1654 | rc = -ENODEV; |
1595 | 1655 | ||
1596 | loopback_mode_exit: | 1656 | loopback_mode_exit: |
1597 | vports = lpfc_create_vport_work_array(phba); | 1657 | lpfc_bsg_diag_mode_exit(phba); |
1598 | if (vports) { | 1658 | |
1599 | for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 1659 | /* |
1600 | shost = lpfc_shost_from_vport(vports[i]); | 1660 | * Let SLI layer release mboxq if mbox command completed after timeout. |
1601 | scsi_unblock_requests(shost); | 1661 | */ |
1662 | if (mbxstatus != MBX_TIMEOUT) | ||
1663 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
1664 | |||
1665 | job_error: | ||
1666 | /* make error code available to userspace */ | ||
1667 | job->reply->result = rc; | ||
1668 | /* complete the job back to userspace if no error */ | ||
1669 | if (rc == 0) | ||
1670 | job->job_done(job); | ||
1671 | return rc; | ||
1672 | } | ||
1673 | |||
1674 | /** | ||
1675 | * lpfc_sli4_bsg_set_link_diag_state - set sli4 link diag state | ||
1676 | * @phba: Pointer to HBA context object. | ||
1677 | * @diag: Flag for set link to diag or nomral operation state. | ||
1678 | * | ||
1679 | * This function is responsible for issuing a sli4 mailbox command for setting | ||
1680 | * link to either diag state or normal operation state. | ||
1681 | */ | ||
1682 | static int | ||
1683 | lpfc_sli4_bsg_set_link_diag_state(struct lpfc_hba *phba, uint32_t diag) | ||
1684 | { | ||
1685 | LPFC_MBOXQ_t *pmboxq; | ||
1686 | struct lpfc_mbx_set_link_diag_state *link_diag_state; | ||
1687 | uint32_t req_len, alloc_len; | ||
1688 | int mbxstatus = MBX_SUCCESS, rc; | ||
1689 | |||
1690 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1691 | if (!pmboxq) | ||
1692 | return -ENOMEM; | ||
1693 | |||
1694 | req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) - | ||
1695 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
1696 | alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
1697 | LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE, | ||
1698 | req_len, LPFC_SLI4_MBX_EMBED); | ||
1699 | if (alloc_len != req_len) { | ||
1700 | rc = -ENOMEM; | ||
1701 | goto link_diag_state_set_out; | ||
1702 | } | ||
1703 | link_diag_state = &pmboxq->u.mqe.un.link_diag_state; | ||
1704 | bf_set(lpfc_mbx_set_diag_state_link_num, &link_diag_state->u.req, | ||
1705 | phba->sli4_hba.link_state.number); | ||
1706 | bf_set(lpfc_mbx_set_diag_state_link_type, &link_diag_state->u.req, | ||
1707 | phba->sli4_hba.link_state.type); | ||
1708 | if (diag) | ||
1709 | bf_set(lpfc_mbx_set_diag_state_diag, | ||
1710 | &link_diag_state->u.req, 1); | ||
1711 | else | ||
1712 | bf_set(lpfc_mbx_set_diag_state_diag, | ||
1713 | &link_diag_state->u.req, 0); | ||
1714 | |||
1715 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO); | ||
1716 | |||
1717 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->u.mb.mbxStatus == 0)) | ||
1718 | rc = 0; | ||
1719 | else | ||
1720 | rc = -ENODEV; | ||
1721 | |||
1722 | link_diag_state_set_out: | ||
1723 | if (pmboxq && (mbxstatus != MBX_TIMEOUT)) | ||
1724 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
1725 | |||
1726 | return rc; | ||
1727 | } | ||
1728 | |||
1729 | /** | ||
1730 | * lpfc_sli4_bsg_diag_loopback_mode - process an sli4 bsg vendor command | ||
1731 | * @phba: Pointer to HBA context object. | ||
1732 | * @job: LPFC_BSG_VENDOR_DIAG_MODE | ||
1733 | * | ||
1734 | * This function is responsible for placing an sli4 port into diagnostic | ||
1735 | * loopback mode in order to perform a diagnostic loopback test. | ||
1736 | */ | ||
1737 | static int | ||
1738 | lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job) | ||
1739 | { | ||
1740 | struct diag_mode_set *loopback_mode; | ||
1741 | uint32_t link_flags, timeout, req_len, alloc_len; | ||
1742 | struct lpfc_mbx_set_link_diag_loopback *link_diag_loopback; | ||
1743 | LPFC_MBOXQ_t *pmboxq = NULL; | ||
1744 | int mbxstatus, i, rc = 0; | ||
1745 | |||
1746 | /* no data to return just the return code */ | ||
1747 | job->reply->reply_payload_rcv_len = 0; | ||
1748 | |||
1749 | if (job->request_len < sizeof(struct fc_bsg_request) + | ||
1750 | sizeof(struct diag_mode_set)) { | ||
1751 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
1752 | "3011 Received DIAG MODE request size:%d " | ||
1753 | "below the minimum size:%d\n", | ||
1754 | job->request_len, | ||
1755 | (int)(sizeof(struct fc_bsg_request) + | ||
1756 | sizeof(struct diag_mode_set))); | ||
1757 | rc = -EINVAL; | ||
1758 | goto job_error; | ||
1759 | } | ||
1760 | |||
1761 | rc = lpfc_bsg_diag_mode_enter(phba, job); | ||
1762 | if (rc) | ||
1763 | goto job_error; | ||
1764 | |||
1765 | /* bring the link to diagnostic mode */ | ||
1766 | loopback_mode = (struct diag_mode_set *) | ||
1767 | job->request->rqst_data.h_vendor.vendor_cmd; | ||
1768 | link_flags = loopback_mode->type; | ||
1769 | timeout = loopback_mode->timeout * 100; | ||
1770 | |||
1771 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1); | ||
1772 | if (rc) | ||
1773 | goto loopback_mode_exit; | ||
1774 | |||
1775 | /* wait for link down before proceeding */ | ||
1776 | i = 0; | ||
1777 | while (phba->link_state != LPFC_LINK_DOWN) { | ||
1778 | if (i++ > timeout) { | ||
1779 | rc = -ETIMEDOUT; | ||
1780 | goto loopback_mode_exit; | ||
1781 | } | ||
1782 | msleep(10); | ||
1783 | } | ||
1784 | /* set up loopback mode */ | ||
1785 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1786 | if (!pmboxq) { | ||
1787 | rc = -ENOMEM; | ||
1788 | goto loopback_mode_exit; | ||
1789 | } | ||
1790 | req_len = (sizeof(struct lpfc_mbx_set_link_diag_loopback) - | ||
1791 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
1792 | alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
1793 | LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_LOOPBACK, | ||
1794 | req_len, LPFC_SLI4_MBX_EMBED); | ||
1795 | if (alloc_len != req_len) { | ||
1796 | rc = -ENOMEM; | ||
1797 | goto loopback_mode_exit; | ||
1798 | } | ||
1799 | link_diag_loopback = &pmboxq->u.mqe.un.link_diag_loopback; | ||
1800 | bf_set(lpfc_mbx_set_diag_state_link_num, | ||
1801 | &link_diag_loopback->u.req, phba->sli4_hba.link_state.number); | ||
1802 | bf_set(lpfc_mbx_set_diag_state_link_type, | ||
1803 | &link_diag_loopback->u.req, phba->sli4_hba.link_state.type); | ||
1804 | if (link_flags == INTERNAL_LOOP_BACK) | ||
1805 | bf_set(lpfc_mbx_set_diag_lpbk_type, | ||
1806 | &link_diag_loopback->u.req, | ||
1807 | LPFC_DIAG_LOOPBACK_TYPE_INTERNAL); | ||
1808 | else | ||
1809 | bf_set(lpfc_mbx_set_diag_lpbk_type, | ||
1810 | &link_diag_loopback->u.req, | ||
1811 | LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL); | ||
1812 | |||
1813 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO); | ||
1814 | if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus)) | ||
1815 | rc = -ENODEV; | ||
1816 | else { | ||
1817 | phba->link_flag |= LS_LOOPBACK_MODE; | ||
1818 | /* wait for the link attention interrupt */ | ||
1819 | msleep(100); | ||
1820 | i = 0; | ||
1821 | while (phba->link_state != LPFC_HBA_READY) { | ||
1822 | if (i++ > timeout) { | ||
1823 | rc = -ETIMEDOUT; | ||
1824 | break; | ||
1825 | } | ||
1826 | msleep(10); | ||
1602 | } | 1827 | } |
1603 | lpfc_destroy_vport_work_array(phba, vports); | ||
1604 | } else { | ||
1605 | shost = lpfc_shost_from_vport(phba->pport); | ||
1606 | scsi_unblock_requests(shost); | ||
1607 | } | 1828 | } |
1608 | 1829 | ||
1830 | loopback_mode_exit: | ||
1831 | lpfc_bsg_diag_mode_exit(phba); | ||
1832 | |||
1609 | /* | 1833 | /* |
1610 | * Let SLI layer release mboxq if mbox command completed after timeout. | 1834 | * Let SLI layer release mboxq if mbox command completed after timeout. |
1611 | */ | 1835 | */ |
1612 | if (mbxstatus != MBX_TIMEOUT) | 1836 | if (pmboxq && (mbxstatus != MBX_TIMEOUT)) |
1613 | mempool_free(pmboxq, phba->mbox_mem_pool); | 1837 | mempool_free(pmboxq, phba->mbox_mem_pool); |
1614 | 1838 | ||
1615 | job_error: | 1839 | job_error: |
@@ -1622,6 +1846,234 @@ job_error: | |||
1622 | } | 1846 | } |
1623 | 1847 | ||
1624 | /** | 1848 | /** |
1849 | * lpfc_bsg_diag_loopback_mode - bsg vendor command for diag loopback mode | ||
1850 | * @job: LPFC_BSG_VENDOR_DIAG_MODE | ||
1851 | * | ||
1852 | * This function is responsible for responding to check and dispatch bsg diag | ||
1853 | * command from the user to proper driver action routines. | ||
1854 | */ | ||
1855 | static int | ||
1856 | lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job) | ||
1857 | { | ||
1858 | struct Scsi_Host *shost; | ||
1859 | struct lpfc_vport *vport; | ||
1860 | struct lpfc_hba *phba; | ||
1861 | int rc; | ||
1862 | |||
1863 | shost = job->shost; | ||
1864 | if (!shost) | ||
1865 | return -ENODEV; | ||
1866 | vport = (struct lpfc_vport *)job->shost->hostdata; | ||
1867 | if (!vport) | ||
1868 | return -ENODEV; | ||
1869 | phba = vport->phba; | ||
1870 | if (!phba) | ||
1871 | return -ENODEV; | ||
1872 | |||
1873 | if (phba->sli_rev < LPFC_SLI_REV4) | ||
1874 | rc = lpfc_sli3_bsg_diag_loopback_mode(phba, job); | ||
1875 | else if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | ||
1876 | LPFC_SLI_INTF_IF_TYPE_2) | ||
1877 | rc = lpfc_sli4_bsg_diag_loopback_mode(phba, job); | ||
1878 | else | ||
1879 | rc = -ENODEV; | ||
1880 | |||
1881 | return rc; | ||
1882 | |||
1883 | } | ||
1884 | |||
1885 | /** | ||
1886 | * lpfc_sli4_bsg_diag_mode_end - sli4 bsg vendor command for ending diag mode | ||
1887 | * @job: LPFC_BSG_VENDOR_DIAG_MODE_END | ||
1888 | * | ||
1889 | * This function is responsible for responding to check and dispatch bsg diag | ||
1890 | * command from the user to proper driver action routines. | ||
1891 | */ | ||
1892 | static int | ||
1893 | lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job) | ||
1894 | { | ||
1895 | struct Scsi_Host *shost; | ||
1896 | struct lpfc_vport *vport; | ||
1897 | struct lpfc_hba *phba; | ||
1898 | int rc; | ||
1899 | |||
1900 | shost = job->shost; | ||
1901 | if (!shost) | ||
1902 | return -ENODEV; | ||
1903 | vport = (struct lpfc_vport *)job->shost->hostdata; | ||
1904 | if (!vport) | ||
1905 | return -ENODEV; | ||
1906 | phba = vport->phba; | ||
1907 | if (!phba) | ||
1908 | return -ENODEV; | ||
1909 | |||
1910 | if (phba->sli_rev < LPFC_SLI_REV4) | ||
1911 | return -ENODEV; | ||
1912 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
1913 | LPFC_SLI_INTF_IF_TYPE_2) | ||
1914 | return -ENODEV; | ||
1915 | |||
1916 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0); | ||
1917 | |||
1918 | if (!rc) | ||
1919 | rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT); | ||
1920 | |||
1921 | return rc; | ||
1922 | } | ||
1923 | |||
1924 | /** | ||
1925 | * lpfc_sli4_bsg_link_diag_test - sli4 bsg vendor command for diag link test | ||
1926 | * @job: LPFC_BSG_VENDOR_DIAG_LINK_TEST | ||
1927 | * | ||
1928 | * This function is to perform SLI4 diag link test request from the user | ||
1929 | * applicaiton. | ||
1930 | */ | ||
1931 | static int | ||
1932 | lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job) | ||
1933 | { | ||
1934 | struct Scsi_Host *shost; | ||
1935 | struct lpfc_vport *vport; | ||
1936 | struct lpfc_hba *phba; | ||
1937 | LPFC_MBOXQ_t *pmboxq; | ||
1938 | struct sli4_link_diag *link_diag_test_cmd; | ||
1939 | uint32_t req_len, alloc_len; | ||
1940 | uint32_t timeout; | ||
1941 | struct lpfc_mbx_run_link_diag_test *run_link_diag_test; | ||
1942 | union lpfc_sli4_cfg_shdr *shdr; | ||
1943 | uint32_t shdr_status, shdr_add_status; | ||
1944 | struct diag_status *diag_status_reply; | ||
1945 | int mbxstatus, rc = 0; | ||
1946 | |||
1947 | shost = job->shost; | ||
1948 | if (!shost) { | ||
1949 | rc = -ENODEV; | ||
1950 | goto job_error; | ||
1951 | } | ||
1952 | vport = (struct lpfc_vport *)job->shost->hostdata; | ||
1953 | if (!vport) { | ||
1954 | rc = -ENODEV; | ||
1955 | goto job_error; | ||
1956 | } | ||
1957 | phba = vport->phba; | ||
1958 | if (!phba) { | ||
1959 | rc = -ENODEV; | ||
1960 | goto job_error; | ||
1961 | } | ||
1962 | |||
1963 | if (phba->sli_rev < LPFC_SLI_REV4) { | ||
1964 | rc = -ENODEV; | ||
1965 | goto job_error; | ||
1966 | } | ||
1967 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
1968 | LPFC_SLI_INTF_IF_TYPE_2) { | ||
1969 | rc = -ENODEV; | ||
1970 | goto job_error; | ||
1971 | } | ||
1972 | |||
1973 | if (job->request_len < sizeof(struct fc_bsg_request) + | ||
1974 | sizeof(struct sli4_link_diag)) { | ||
1975 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
1976 | "3013 Received LINK DIAG TEST request " | ||
1977 | " size:%d below the minimum size:%d\n", | ||
1978 | job->request_len, | ||
1979 | (int)(sizeof(struct fc_bsg_request) + | ||
1980 | sizeof(struct sli4_link_diag))); | ||
1981 | rc = -EINVAL; | ||
1982 | goto job_error; | ||
1983 | } | ||
1984 | |||
1985 | rc = lpfc_bsg_diag_mode_enter(phba, job); | ||
1986 | if (rc) | ||
1987 | goto job_error; | ||
1988 | |||
1989 | link_diag_test_cmd = (struct sli4_link_diag *) | ||
1990 | job->request->rqst_data.h_vendor.vendor_cmd; | ||
1991 | timeout = link_diag_test_cmd->timeout * 100; | ||
1992 | |||
1993 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1); | ||
1994 | |||
1995 | if (rc) | ||
1996 | goto job_error; | ||
1997 | |||
1998 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1999 | if (!pmboxq) { | ||
2000 | rc = -ENOMEM; | ||
2001 | goto link_diag_test_exit; | ||
2002 | } | ||
2003 | |||
2004 | req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) - | ||
2005 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
2006 | alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
2007 | LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE, | ||
2008 | req_len, LPFC_SLI4_MBX_EMBED); | ||
2009 | if (alloc_len != req_len) { | ||
2010 | rc = -ENOMEM; | ||
2011 | goto link_diag_test_exit; | ||
2012 | } | ||
2013 | run_link_diag_test = &pmboxq->u.mqe.un.link_diag_test; | ||
2014 | bf_set(lpfc_mbx_run_diag_test_link_num, &run_link_diag_test->u.req, | ||
2015 | phba->sli4_hba.link_state.number); | ||
2016 | bf_set(lpfc_mbx_run_diag_test_link_type, &run_link_diag_test->u.req, | ||
2017 | phba->sli4_hba.link_state.type); | ||
2018 | bf_set(lpfc_mbx_run_diag_test_test_id, &run_link_diag_test->u.req, | ||
2019 | link_diag_test_cmd->test_id); | ||
2020 | bf_set(lpfc_mbx_run_diag_test_loops, &run_link_diag_test->u.req, | ||
2021 | link_diag_test_cmd->loops); | ||
2022 | bf_set(lpfc_mbx_run_diag_test_test_ver, &run_link_diag_test->u.req, | ||
2023 | link_diag_test_cmd->test_version); | ||
2024 | bf_set(lpfc_mbx_run_diag_test_err_act, &run_link_diag_test->u.req, | ||
2025 | link_diag_test_cmd->error_action); | ||
2026 | |||
2027 | mbxstatus = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | ||
2028 | |||
2029 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
2030 | &pmboxq->u.mqe.un.sli4_config.header.cfg_shdr; | ||
2031 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
2032 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
2033 | if (shdr_status || shdr_add_status || mbxstatus) { | ||
2034 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
2035 | "3010 Run link diag test mailbox failed with " | ||
2036 | "mbx_status x%x status x%x, add_status x%x\n", | ||
2037 | mbxstatus, shdr_status, shdr_add_status); | ||
2038 | } | ||
2039 | |||
2040 | diag_status_reply = (struct diag_status *) | ||
2041 | job->reply->reply_data.vendor_reply.vendor_rsp; | ||
2042 | |||
2043 | if (job->reply_len < | ||
2044 | sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) { | ||
2045 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
2046 | "3012 Received Run link diag test reply " | ||
2047 | "below minimum size (%d): reply_len:%d\n", | ||
2048 | (int)(sizeof(struct fc_bsg_request) + | ||
2049 | sizeof(struct diag_status)), | ||
2050 | job->reply_len); | ||
2051 | rc = -EINVAL; | ||
2052 | goto job_error; | ||
2053 | } | ||
2054 | |||
2055 | diag_status_reply->mbox_status = mbxstatus; | ||
2056 | diag_status_reply->shdr_status = shdr_status; | ||
2057 | diag_status_reply->shdr_add_status = shdr_add_status; | ||
2058 | |||
2059 | link_diag_test_exit: | ||
2060 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0); | ||
2061 | |||
2062 | if (pmboxq) | ||
2063 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
2064 | |||
2065 | lpfc_bsg_diag_mode_exit(phba); | ||
2066 | |||
2067 | job_error: | ||
2068 | /* make error code available to userspace */ | ||
2069 | job->reply->result = rc; | ||
2070 | /* complete the job back to userspace if no error */ | ||
2071 | if (rc == 0) | ||
2072 | job->job_done(job); | ||
2073 | return rc; | ||
2074 | } | ||
2075 | |||
2076 | /** | ||
1625 | * lpfcdiag_loop_self_reg - obtains a remote port login id | 2077 | * lpfcdiag_loop_self_reg - obtains a remote port login id |
1626 | * @phba: Pointer to HBA context object | 2078 | * @phba: Pointer to HBA context object |
1627 | * @rpi: Pointer to a remote port login id | 2079 | * @rpi: Pointer to a remote port login id |
@@ -1851,6 +2303,86 @@ err_get_xri_exit: | |||
1851 | } | 2303 | } |
1852 | 2304 | ||
1853 | /** | 2305 | /** |
2306 | * lpfc_bsg_dma_page_alloc - allocate a bsg mbox page sized dma buffers | ||
2307 | * @phba: Pointer to HBA context object | ||
2308 | * | ||
2309 | * This function allocates BSG_MBOX_SIZE (4KB) page size dma buffer and. | ||
2310 | * retruns the pointer to the buffer. | ||
2311 | **/ | ||
2312 | static struct lpfc_dmabuf * | ||
2313 | lpfc_bsg_dma_page_alloc(struct lpfc_hba *phba) | ||
2314 | { | ||
2315 | struct lpfc_dmabuf *dmabuf; | ||
2316 | struct pci_dev *pcidev = phba->pcidev; | ||
2317 | |||
2318 | /* allocate dma buffer struct */ | ||
2319 | dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
2320 | if (!dmabuf) | ||
2321 | return NULL; | ||
2322 | |||
2323 | INIT_LIST_HEAD(&dmabuf->list); | ||
2324 | |||
2325 | /* now, allocate dma buffer */ | ||
2326 | dmabuf->virt = dma_alloc_coherent(&pcidev->dev, BSG_MBOX_SIZE, | ||
2327 | &(dmabuf->phys), GFP_KERNEL); | ||
2328 | |||
2329 | if (!dmabuf->virt) { | ||
2330 | kfree(dmabuf); | ||
2331 | return NULL; | ||
2332 | } | ||
2333 | memset((uint8_t *)dmabuf->virt, 0, BSG_MBOX_SIZE); | ||
2334 | |||
2335 | return dmabuf; | ||
2336 | } | ||
2337 | |||
2338 | /** | ||
2339 | * lpfc_bsg_dma_page_free - free a bsg mbox page sized dma buffer | ||
2340 | * @phba: Pointer to HBA context object. | ||
2341 | * @dmabuf: Pointer to the bsg mbox page sized dma buffer descriptor. | ||
2342 | * | ||
2343 | * This routine just simply frees a dma buffer and its associated buffer | ||
2344 | * descriptor referred by @dmabuf. | ||
2345 | **/ | ||
2346 | static void | ||
2347 | lpfc_bsg_dma_page_free(struct lpfc_hba *phba, struct lpfc_dmabuf *dmabuf) | ||
2348 | { | ||
2349 | struct pci_dev *pcidev = phba->pcidev; | ||
2350 | |||
2351 | if (!dmabuf) | ||
2352 | return; | ||
2353 | |||
2354 | if (dmabuf->virt) | ||
2355 | dma_free_coherent(&pcidev->dev, BSG_MBOX_SIZE, | ||
2356 | dmabuf->virt, dmabuf->phys); | ||
2357 | kfree(dmabuf); | ||
2358 | return; | ||
2359 | } | ||
2360 | |||
2361 | /** | ||
2362 | * lpfc_bsg_dma_page_list_free - free a list of bsg mbox page sized dma buffers | ||
2363 | * @phba: Pointer to HBA context object. | ||
2364 | * @dmabuf_list: Pointer to a list of bsg mbox page sized dma buffer descs. | ||
2365 | * | ||
2366 | * This routine just simply frees all dma buffers and their associated buffer | ||
2367 | * descriptors referred by @dmabuf_list. | ||
2368 | **/ | ||
2369 | static void | ||
2370 | lpfc_bsg_dma_page_list_free(struct lpfc_hba *phba, | ||
2371 | struct list_head *dmabuf_list) | ||
2372 | { | ||
2373 | struct lpfc_dmabuf *dmabuf, *next_dmabuf; | ||
2374 | |||
2375 | if (list_empty(dmabuf_list)) | ||
2376 | return; | ||
2377 | |||
2378 | list_for_each_entry_safe(dmabuf, next_dmabuf, dmabuf_list, list) { | ||
2379 | list_del_init(&dmabuf->list); | ||
2380 | lpfc_bsg_dma_page_free(phba, dmabuf); | ||
2381 | } | ||
2382 | return; | ||
2383 | } | ||
2384 | |||
2385 | /** | ||
1854 | * diag_cmd_data_alloc - fills in a bde struct with dma buffers | 2386 | * diag_cmd_data_alloc - fills in a bde struct with dma buffers |
1855 | * @phba: Pointer to HBA context object | 2387 | * @phba: Pointer to HBA context object |
1856 | * @bpl: Pointer to 64 bit bde structure | 2388 | * @bpl: Pointer to 64 bit bde structure |
@@ -2067,7 +2599,7 @@ err_post_rxbufs_exit: | |||
2067 | } | 2599 | } |
2068 | 2600 | ||
2069 | /** | 2601 | /** |
2070 | * lpfc_bsg_diag_test - with a port in loopback issues a Ct cmd to itself | 2602 | * lpfc_bsg_diag_loopback_run - run loopback on a port by issue ct cmd to itself |
2071 | * @job: LPFC_BSG_VENDOR_DIAG_TEST fc_bsg_job | 2603 | * @job: LPFC_BSG_VENDOR_DIAG_TEST fc_bsg_job |
2072 | * | 2604 | * |
2073 | * This function receives a user data buffer to be transmitted and received on | 2605 | * This function receives a user data buffer to be transmitted and received on |
@@ -2086,7 +2618,7 @@ err_post_rxbufs_exit: | |||
2086 | * of loopback mode. | 2618 | * of loopback mode. |
2087 | **/ | 2619 | **/ |
2088 | static int | 2620 | static int |
2089 | lpfc_bsg_diag_test(struct fc_bsg_job *job) | 2621 | lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job) |
2090 | { | 2622 | { |
2091 | struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; | 2623 | struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; |
2092 | struct lpfc_hba *phba = vport->phba; | 2624 | struct lpfc_hba *phba = vport->phba; |
@@ -2411,7 +2943,7 @@ job_error: | |||
2411 | } | 2943 | } |
2412 | 2944 | ||
2413 | /** | 2945 | /** |
2414 | * lpfc_bsg_wake_mbox_wait - lpfc_bsg_issue_mbox mbox completion handler | 2946 | * lpfc_bsg_issue_mbox_cmpl - lpfc_bsg_issue_mbox mbox completion handler |
2415 | * @phba: Pointer to HBA context object. | 2947 | * @phba: Pointer to HBA context object. |
2416 | * @pmboxq: Pointer to mailbox command. | 2948 | * @pmboxq: Pointer to mailbox command. |
2417 | * | 2949 | * |
@@ -2422,15 +2954,13 @@ job_error: | |||
2422 | * of the mailbox. | 2954 | * of the mailbox. |
2423 | **/ | 2955 | **/ |
2424 | void | 2956 | void |
2425 | lpfc_bsg_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | 2957 | lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) |
2426 | { | 2958 | { |
2427 | struct bsg_job_data *dd_data; | 2959 | struct bsg_job_data *dd_data; |
2428 | struct fc_bsg_job *job; | 2960 | struct fc_bsg_job *job; |
2429 | struct lpfc_mbx_nembed_cmd *nembed_sge; | ||
2430 | uint32_t size; | 2961 | uint32_t size; |
2431 | unsigned long flags; | 2962 | unsigned long flags; |
2432 | uint8_t *to; | 2963 | uint8_t *pmb, *pmb_buf; |
2433 | uint8_t *from; | ||
2434 | 2964 | ||
2435 | spin_lock_irqsave(&phba->ct_ev_lock, flags); | 2965 | spin_lock_irqsave(&phba->ct_ev_lock, flags); |
2436 | dd_data = pmboxq->context1; | 2966 | dd_data = pmboxq->context1; |
@@ -2440,62 +2970,21 @@ lpfc_bsg_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
2440 | return; | 2970 | return; |
2441 | } | 2971 | } |
2442 | 2972 | ||
2443 | /* build the outgoing buffer to do an sg copy | 2973 | /* |
2444 | * the format is the response mailbox followed by any extended | 2974 | * The outgoing buffer is readily referred from the dma buffer, |
2445 | * mailbox data | 2975 | * just need to get header part from mailboxq structure. |
2446 | */ | 2976 | */ |
2447 | from = (uint8_t *)&pmboxq->u.mb; | 2977 | pmb = (uint8_t *)&pmboxq->u.mb; |
2448 | to = (uint8_t *)dd_data->context_un.mbox.mb; | 2978 | pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb; |
2449 | memcpy(to, from, sizeof(MAILBOX_t)); | 2979 | memcpy(pmb_buf, pmb, sizeof(MAILBOX_t)); |
2450 | if (pmboxq->u.mb.mbxStatus == MBX_SUCCESS) { | ||
2451 | /* copy the extended data if any, count is in words */ | ||
2452 | if (dd_data->context_un.mbox.outExtWLen) { | ||
2453 | from = (uint8_t *)dd_data->context_un.mbox.ext; | ||
2454 | to += sizeof(MAILBOX_t); | ||
2455 | size = dd_data->context_un.mbox.outExtWLen * | ||
2456 | sizeof(uint32_t); | ||
2457 | memcpy(to, from, size); | ||
2458 | } else if (pmboxq->u.mb.mbxCommand == MBX_RUN_BIU_DIAG64) { | ||
2459 | from = (uint8_t *)dd_data->context_un.mbox. | ||
2460 | dmp->dma.virt; | ||
2461 | to += sizeof(MAILBOX_t); | ||
2462 | size = dd_data->context_un.mbox.dmp->size; | ||
2463 | memcpy(to, from, size); | ||
2464 | } else if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
2465 | (pmboxq->u.mb.mbxCommand == MBX_DUMP_MEMORY)) { | ||
2466 | from = (uint8_t *)dd_data->context_un.mbox.dmp->dma. | ||
2467 | virt; | ||
2468 | to += sizeof(MAILBOX_t); | ||
2469 | size = pmboxq->u.mb.un.varWords[5]; | ||
2470 | memcpy(to, from, size); | ||
2471 | } else if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
2472 | (pmboxq->u.mb.mbxCommand == MBX_SLI4_CONFIG)) { | ||
2473 | nembed_sge = (struct lpfc_mbx_nembed_cmd *) | ||
2474 | &pmboxq->u.mb.un.varWords[0]; | ||
2475 | |||
2476 | from = (uint8_t *)dd_data->context_un.mbox.dmp->dma. | ||
2477 | virt; | ||
2478 | to += sizeof(MAILBOX_t); | ||
2479 | size = nembed_sge->sge[0].length; | ||
2480 | memcpy(to, from, size); | ||
2481 | } else if (pmboxq->u.mb.mbxCommand == MBX_READ_EVENT_LOG) { | ||
2482 | from = (uint8_t *)dd_data->context_un. | ||
2483 | mbox.dmp->dma.virt; | ||
2484 | to += sizeof(MAILBOX_t); | ||
2485 | size = dd_data->context_un.mbox.dmp->size; | ||
2486 | memcpy(to, from, size); | ||
2487 | } | ||
2488 | } | ||
2489 | 2980 | ||
2490 | from = (uint8_t *)dd_data->context_un.mbox.mb; | ||
2491 | job = dd_data->context_un.mbox.set_job; | 2981 | job = dd_data->context_un.mbox.set_job; |
2492 | if (job) { | 2982 | if (job) { |
2493 | size = job->reply_payload.payload_len; | 2983 | size = job->reply_payload.payload_len; |
2494 | job->reply->reply_payload_rcv_len = | 2984 | job->reply->reply_payload_rcv_len = |
2495 | sg_copy_from_buffer(job->reply_payload.sg_list, | 2985 | sg_copy_from_buffer(job->reply_payload.sg_list, |
2496 | job->reply_payload.sg_cnt, | 2986 | job->reply_payload.sg_cnt, |
2497 | from, size); | 2987 | pmb_buf, size); |
2498 | job->reply->result = 0; | ||
2499 | /* need to hold the lock until we set job->dd_data to NULL | 2988 | /* need to hold the lock until we set job->dd_data to NULL |
2500 | * to hold off the timeout handler returning to the mid-layer | 2989 | * to hold off the timeout handler returning to the mid-layer |
2501 | * while we are still processing the job. | 2990 | * while we are still processing the job. |
@@ -2503,28 +2992,19 @@ lpfc_bsg_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
2503 | job->dd_data = NULL; | 2992 | job->dd_data = NULL; |
2504 | dd_data->context_un.mbox.set_job = NULL; | 2993 | dd_data->context_un.mbox.set_job = NULL; |
2505 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | 2994 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); |
2506 | job->job_done(job); | ||
2507 | } else { | 2995 | } else { |
2508 | dd_data->context_un.mbox.set_job = NULL; | 2996 | dd_data->context_un.mbox.set_job = NULL; |
2509 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | 2997 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); |
2510 | } | 2998 | } |
2511 | 2999 | ||
2512 | kfree(dd_data->context_un.mbox.mb); | ||
2513 | mempool_free(dd_data->context_un.mbox.pmboxq, phba->mbox_mem_pool); | 3000 | mempool_free(dd_data->context_un.mbox.pmboxq, phba->mbox_mem_pool); |
2514 | kfree(dd_data->context_un.mbox.ext); | 3001 | lpfc_bsg_dma_page_free(phba, dd_data->context_un.mbox.dmabuffers); |
2515 | if (dd_data->context_un.mbox.dmp) { | ||
2516 | dma_free_coherent(&phba->pcidev->dev, | ||
2517 | dd_data->context_un.mbox.dmp->size, | ||
2518 | dd_data->context_un.mbox.dmp->dma.virt, | ||
2519 | dd_data->context_un.mbox.dmp->dma.phys); | ||
2520 | kfree(dd_data->context_un.mbox.dmp); | ||
2521 | } | ||
2522 | if (dd_data->context_un.mbox.rxbmp) { | ||
2523 | lpfc_mbuf_free(phba, dd_data->context_un.mbox.rxbmp->virt, | ||
2524 | dd_data->context_un.mbox.rxbmp->phys); | ||
2525 | kfree(dd_data->context_un.mbox.rxbmp); | ||
2526 | } | ||
2527 | kfree(dd_data); | 3002 | kfree(dd_data); |
3003 | |||
3004 | if (job) { | ||
3005 | job->reply->result = 0; | ||
3006 | job->job_done(job); | ||
3007 | } | ||
2528 | return; | 3008 | return; |
2529 | } | 3009 | } |
2530 | 3010 | ||
@@ -2619,6 +3099,1006 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba, | |||
2619 | } | 3099 | } |
2620 | 3100 | ||
2621 | /** | 3101 | /** |
3102 | * lpfc_bsg_mbox_ext_cleanup - clean up context of multi-buffer mbox session | ||
3103 | * @phba: Pointer to HBA context object. | ||
3104 | * | ||
3105 | * This is routine clean up and reset BSG handling of multi-buffer mbox | ||
3106 | * command session. | ||
3107 | **/ | ||
3108 | static void | ||
3109 | lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba) | ||
3110 | { | ||
3111 | if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE) | ||
3112 | return; | ||
3113 | |||
3114 | /* free all memory, including dma buffers */ | ||
3115 | lpfc_bsg_dma_page_list_free(phba, | ||
3116 | &phba->mbox_ext_buf_ctx.ext_dmabuf_list); | ||
3117 | lpfc_bsg_dma_page_free(phba, phba->mbox_ext_buf_ctx.mbx_dmabuf); | ||
3118 | /* multi-buffer write mailbox command pass-through complete */ | ||
3119 | memset((char *)&phba->mbox_ext_buf_ctx, 0, | ||
3120 | sizeof(struct lpfc_mbox_ext_buf_ctx)); | ||
3121 | INIT_LIST_HEAD(&phba->mbox_ext_buf_ctx.ext_dmabuf_list); | ||
3122 | |||
3123 | return; | ||
3124 | } | ||
3125 | |||
3126 | /** | ||
3127 | * lpfc_bsg_issue_mbox_ext_handle_job - job handler for multi-buffer mbox cmpl | ||
3128 | * @phba: Pointer to HBA context object. | ||
3129 | * @pmboxq: Pointer to mailbox command. | ||
3130 | * | ||
3131 | * This is routine handles BSG job for mailbox commands completions with | ||
3132 | * multiple external buffers. | ||
3133 | **/ | ||
3134 | static struct fc_bsg_job * | ||
3135 | lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | ||
3136 | { | ||
3137 | struct bsg_job_data *dd_data; | ||
3138 | struct fc_bsg_job *job; | ||
3139 | uint8_t *pmb, *pmb_buf; | ||
3140 | unsigned long flags; | ||
3141 | uint32_t size; | ||
3142 | int rc = 0; | ||
3143 | |||
3144 | spin_lock_irqsave(&phba->ct_ev_lock, flags); | ||
3145 | dd_data = pmboxq->context1; | ||
3146 | /* has the job already timed out? */ | ||
3147 | if (!dd_data) { | ||
3148 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | ||
3149 | job = NULL; | ||
3150 | goto job_done_out; | ||
3151 | } | ||
3152 | |||
3153 | /* | ||
3154 | * The outgoing buffer is readily referred from the dma buffer, | ||
3155 | * just need to get header part from mailboxq structure. | ||
3156 | */ | ||
3157 | pmb = (uint8_t *)&pmboxq->u.mb; | ||
3158 | pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb; | ||
3159 | memcpy(pmb_buf, pmb, sizeof(MAILBOX_t)); | ||
3160 | |||
3161 | job = dd_data->context_un.mbox.set_job; | ||
3162 | if (job) { | ||
3163 | size = job->reply_payload.payload_len; | ||
3164 | job->reply->reply_payload_rcv_len = | ||
3165 | sg_copy_from_buffer(job->reply_payload.sg_list, | ||
3166 | job->reply_payload.sg_cnt, | ||
3167 | pmb_buf, size); | ||
3168 | /* result for successful */ | ||
3169 | job->reply->result = 0; | ||
3170 | job->dd_data = NULL; | ||
3171 | /* need to hold the lock util we set job->dd_data to NULL | ||
3172 | * to hold off the timeout handler from midlayer to take | ||
3173 | * any action. | ||
3174 | */ | ||
3175 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | ||
3176 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3177 | "2937 SLI_CONFIG ext-buffer maibox command " | ||
3178 | "(x%x/x%x) complete bsg job done, bsize:%d\n", | ||
3179 | phba->mbox_ext_buf_ctx.nembType, | ||
3180 | phba->mbox_ext_buf_ctx.mboxType, size); | ||
3181 | } else | ||
3182 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | ||
3183 | |||
3184 | job_done_out: | ||
3185 | if (!job) | ||
3186 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3187 | "2938 SLI_CONFIG ext-buffer maibox " | ||
3188 | "command (x%x/x%x) failure, rc:x%x\n", | ||
3189 | phba->mbox_ext_buf_ctx.nembType, | ||
3190 | phba->mbox_ext_buf_ctx.mboxType, rc); | ||
3191 | /* state change */ | ||
3192 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_DONE; | ||
3193 | kfree(dd_data); | ||
3194 | |||
3195 | return job; | ||
3196 | } | ||
3197 | |||
3198 | /** | ||
3199 | * lpfc_bsg_issue_read_mbox_ext_cmpl - compl handler for multi-buffer read mbox | ||
3200 | * @phba: Pointer to HBA context object. | ||
3201 | * @pmboxq: Pointer to mailbox command. | ||
3202 | * | ||
3203 | * This is completion handler function for mailbox read commands with multiple | ||
3204 | * external buffers. | ||
3205 | **/ | ||
3206 | static void | ||
3207 | lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | ||
3208 | { | ||
3209 | struct fc_bsg_job *job; | ||
3210 | |||
3211 | /* handle the BSG job with mailbox command */ | ||
3212 | if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS) | ||
3213 | pmboxq->u.mb.mbxStatus = MBXERR_ERROR; | ||
3214 | |||
3215 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3216 | "2939 SLI_CONFIG ext-buffer rd maibox command " | ||
3217 | "complete, ctxState:x%x, mbxStatus:x%x\n", | ||
3218 | phba->mbox_ext_buf_ctx.state, pmboxq->u.mb.mbxStatus); | ||
3219 | |||
3220 | job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq); | ||
3221 | |||
3222 | if (pmboxq->u.mb.mbxStatus || phba->mbox_ext_buf_ctx.numBuf == 1) | ||
3223 | lpfc_bsg_mbox_ext_session_reset(phba); | ||
3224 | |||
3225 | /* free base driver mailbox structure memory */ | ||
3226 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
3227 | |||
3228 | /* complete the bsg job if we have it */ | ||
3229 | if (job) | ||
3230 | job->job_done(job); | ||
3231 | |||
3232 | return; | ||
3233 | } | ||
3234 | |||
3235 | /** | ||
3236 | * lpfc_bsg_issue_write_mbox_ext_cmpl - cmpl handler for multi-buffer write mbox | ||
3237 | * @phba: Pointer to HBA context object. | ||
3238 | * @pmboxq: Pointer to mailbox command. | ||
3239 | * | ||
3240 | * This is completion handler function for mailbox write commands with multiple | ||
3241 | * external buffers. | ||
3242 | **/ | ||
3243 | static void | ||
3244 | lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | ||
3245 | { | ||
3246 | struct fc_bsg_job *job; | ||
3247 | |||
3248 | /* handle the BSG job with the mailbox command */ | ||
3249 | if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS) | ||
3250 | pmboxq->u.mb.mbxStatus = MBXERR_ERROR; | ||
3251 | |||
3252 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3253 | "2940 SLI_CONFIG ext-buffer wr maibox command " | ||
3254 | "complete, ctxState:x%x, mbxStatus:x%x\n", | ||
3255 | phba->mbox_ext_buf_ctx.state, pmboxq->u.mb.mbxStatus); | ||
3256 | |||
3257 | job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq); | ||
3258 | |||
3259 | /* free all memory, including dma buffers */ | ||
3260 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
3261 | lpfc_bsg_mbox_ext_session_reset(phba); | ||
3262 | |||
3263 | /* complete the bsg job if we have it */ | ||
3264 | if (job) | ||
3265 | job->job_done(job); | ||
3266 | |||
3267 | return; | ||
3268 | } | ||
3269 | |||
3270 | static void | ||
3271 | lpfc_bsg_sli_cfg_dma_desc_setup(struct lpfc_hba *phba, enum nemb_type nemb_tp, | ||
3272 | uint32_t index, struct lpfc_dmabuf *mbx_dmabuf, | ||
3273 | struct lpfc_dmabuf *ext_dmabuf) | ||
3274 | { | ||
3275 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3276 | |||
3277 | /* pointer to the start of mailbox command */ | ||
3278 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)mbx_dmabuf->virt; | ||
3279 | |||
3280 | if (nemb_tp == nemb_mse) { | ||
3281 | if (index == 0) { | ||
3282 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3283 | mse[index].pa_hi = | ||
3284 | putPaddrHigh(mbx_dmabuf->phys + | ||
3285 | sizeof(MAILBOX_t)); | ||
3286 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3287 | mse[index].pa_lo = | ||
3288 | putPaddrLow(mbx_dmabuf->phys + | ||
3289 | sizeof(MAILBOX_t)); | ||
3290 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3291 | "2943 SLI_CONFIG(mse)[%d], " | ||
3292 | "bufLen:%d, addrHi:x%x, addrLo:x%x\n", | ||
3293 | index, | ||
3294 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3295 | mse[index].buf_len, | ||
3296 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3297 | mse[index].pa_hi, | ||
3298 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3299 | mse[index].pa_lo); | ||
3300 | } else { | ||
3301 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3302 | mse[index].pa_hi = | ||
3303 | putPaddrHigh(ext_dmabuf->phys); | ||
3304 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3305 | mse[index].pa_lo = | ||
3306 | putPaddrLow(ext_dmabuf->phys); | ||
3307 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3308 | "2944 SLI_CONFIG(mse)[%d], " | ||
3309 | "bufLen:%d, addrHi:x%x, addrLo:x%x\n", | ||
3310 | index, | ||
3311 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3312 | mse[index].buf_len, | ||
3313 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3314 | mse[index].pa_hi, | ||
3315 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3316 | mse[index].pa_lo); | ||
3317 | } | ||
3318 | } else { | ||
3319 | if (index == 0) { | ||
3320 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3321 | hbd[index].pa_hi = | ||
3322 | putPaddrHigh(mbx_dmabuf->phys + | ||
3323 | sizeof(MAILBOX_t)); | ||
3324 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3325 | hbd[index].pa_lo = | ||
3326 | putPaddrLow(mbx_dmabuf->phys + | ||
3327 | sizeof(MAILBOX_t)); | ||
3328 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3329 | "3007 SLI_CONFIG(hbd)[%d], " | ||
3330 | "bufLen:%d, addrHi:x%x, addrLo:x%x\n", | ||
3331 | index, | ||
3332 | bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len, | ||
3333 | &sli_cfg_mbx->un. | ||
3334 | sli_config_emb1_subsys.hbd[index]), | ||
3335 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3336 | hbd[index].pa_hi, | ||
3337 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3338 | hbd[index].pa_lo); | ||
3339 | |||
3340 | } else { | ||
3341 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3342 | hbd[index].pa_hi = | ||
3343 | putPaddrHigh(ext_dmabuf->phys); | ||
3344 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3345 | hbd[index].pa_lo = | ||
3346 | putPaddrLow(ext_dmabuf->phys); | ||
3347 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3348 | "3008 SLI_CONFIG(hbd)[%d], " | ||
3349 | "bufLen:%d, addrHi:x%x, addrLo:x%x\n", | ||
3350 | index, | ||
3351 | bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len, | ||
3352 | &sli_cfg_mbx->un. | ||
3353 | sli_config_emb1_subsys.hbd[index]), | ||
3354 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3355 | hbd[index].pa_hi, | ||
3356 | sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3357 | hbd[index].pa_lo); | ||
3358 | } | ||
3359 | } | ||
3360 | return; | ||
3361 | } | ||
3362 | |||
3363 | /** | ||
3364 | * lpfc_bsg_sli_cfg_mse_read_cmd_ext - sli_config non-embedded mailbox cmd read | ||
3365 | * @phba: Pointer to HBA context object. | ||
3366 | * @mb: Pointer to a BSG mailbox object. | ||
3367 | * @nemb_tp: Enumerate of non-embedded mailbox command type. | ||
3368 | * @dmabuff: Pointer to a DMA buffer descriptor. | ||
3369 | * | ||
3370 | * This routine performs SLI_CONFIG (0x9B) read mailbox command operation with | ||
3371 | * non-embedded external bufffers. | ||
3372 | **/ | ||
3373 | static int | ||
3374 | lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | ||
3375 | enum nemb_type nemb_tp, | ||
3376 | struct lpfc_dmabuf *dmabuf) | ||
3377 | { | ||
3378 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3379 | struct dfc_mbox_req *mbox_req; | ||
3380 | struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf; | ||
3381 | uint32_t ext_buf_cnt, ext_buf_index; | ||
3382 | struct lpfc_dmabuf *ext_dmabuf = NULL; | ||
3383 | struct bsg_job_data *dd_data = NULL; | ||
3384 | LPFC_MBOXQ_t *pmboxq = NULL; | ||
3385 | MAILBOX_t *pmb; | ||
3386 | uint8_t *pmbx; | ||
3387 | int rc, i; | ||
3388 | |||
3389 | mbox_req = | ||
3390 | (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd; | ||
3391 | |||
3392 | /* pointer to the start of mailbox command */ | ||
3393 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; | ||
3394 | |||
3395 | if (nemb_tp == nemb_mse) { | ||
3396 | ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt, | ||
3397 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr); | ||
3398 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) { | ||
3399 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3400 | "2945 Handled SLI_CONFIG(mse) rd, " | ||
3401 | "ext_buf_cnt(%d) out of range(%d)\n", | ||
3402 | ext_buf_cnt, | ||
3403 | LPFC_MBX_SLI_CONFIG_MAX_MSE); | ||
3404 | rc = -ERANGE; | ||
3405 | goto job_error; | ||
3406 | } | ||
3407 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3408 | "2941 Handled SLI_CONFIG(mse) rd, " | ||
3409 | "ext_buf_cnt:%d\n", ext_buf_cnt); | ||
3410 | } else { | ||
3411 | /* sanity check on interface type for support */ | ||
3412 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
3413 | LPFC_SLI_INTF_IF_TYPE_2) { | ||
3414 | rc = -ENODEV; | ||
3415 | goto job_error; | ||
3416 | } | ||
3417 | /* nemb_tp == nemb_hbd */ | ||
3418 | ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count; | ||
3419 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) { | ||
3420 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3421 | "2946 Handled SLI_CONFIG(hbd) rd, " | ||
3422 | "ext_buf_cnt(%d) out of range(%d)\n", | ||
3423 | ext_buf_cnt, | ||
3424 | LPFC_MBX_SLI_CONFIG_MAX_HBD); | ||
3425 | rc = -ERANGE; | ||
3426 | goto job_error; | ||
3427 | } | ||
3428 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3429 | "2942 Handled SLI_CONFIG(hbd) rd, " | ||
3430 | "ext_buf_cnt:%d\n", ext_buf_cnt); | ||
3431 | } | ||
3432 | |||
3433 | /* reject non-embedded mailbox command with none external buffer */ | ||
3434 | if (ext_buf_cnt == 0) { | ||
3435 | rc = -EPERM; | ||
3436 | goto job_error; | ||
3437 | } else if (ext_buf_cnt > 1) { | ||
3438 | /* additional external read buffers */ | ||
3439 | for (i = 1; i < ext_buf_cnt; i++) { | ||
3440 | ext_dmabuf = lpfc_bsg_dma_page_alloc(phba); | ||
3441 | if (!ext_dmabuf) { | ||
3442 | rc = -ENOMEM; | ||
3443 | goto job_error; | ||
3444 | } | ||
3445 | list_add_tail(&ext_dmabuf->list, | ||
3446 | &phba->mbox_ext_buf_ctx.ext_dmabuf_list); | ||
3447 | } | ||
3448 | } | ||
3449 | |||
3450 | /* bsg tracking structure */ | ||
3451 | dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); | ||
3452 | if (!dd_data) { | ||
3453 | rc = -ENOMEM; | ||
3454 | goto job_error; | ||
3455 | } | ||
3456 | |||
3457 | /* mailbox command structure for base driver */ | ||
3458 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
3459 | if (!pmboxq) { | ||
3460 | rc = -ENOMEM; | ||
3461 | goto job_error; | ||
3462 | } | ||
3463 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | ||
3464 | |||
3465 | /* for the first external buffer */ | ||
3466 | lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf); | ||
3467 | |||
3468 | /* for the rest of external buffer descriptors if any */ | ||
3469 | if (ext_buf_cnt > 1) { | ||
3470 | ext_buf_index = 1; | ||
3471 | list_for_each_entry_safe(curr_dmabuf, next_dmabuf, | ||
3472 | &phba->mbox_ext_buf_ctx.ext_dmabuf_list, list) { | ||
3473 | lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, | ||
3474 | ext_buf_index, dmabuf, | ||
3475 | curr_dmabuf); | ||
3476 | ext_buf_index++; | ||
3477 | } | ||
3478 | } | ||
3479 | |||
3480 | /* construct base driver mbox command */ | ||
3481 | pmb = &pmboxq->u.mb; | ||
3482 | pmbx = (uint8_t *)dmabuf->virt; | ||
3483 | memcpy(pmb, pmbx, sizeof(*pmb)); | ||
3484 | pmb->mbxOwner = OWN_HOST; | ||
3485 | pmboxq->vport = phba->pport; | ||
3486 | |||
3487 | /* multi-buffer handling context */ | ||
3488 | phba->mbox_ext_buf_ctx.nembType = nemb_tp; | ||
3489 | phba->mbox_ext_buf_ctx.mboxType = mbox_rd; | ||
3490 | phba->mbox_ext_buf_ctx.numBuf = ext_buf_cnt; | ||
3491 | phba->mbox_ext_buf_ctx.mbxTag = mbox_req->extMboxTag; | ||
3492 | phba->mbox_ext_buf_ctx.seqNum = mbox_req->extSeqNum; | ||
3493 | phba->mbox_ext_buf_ctx.mbx_dmabuf = dmabuf; | ||
3494 | |||
3495 | /* callback for multi-buffer read mailbox command */ | ||
3496 | pmboxq->mbox_cmpl = lpfc_bsg_issue_read_mbox_ext_cmpl; | ||
3497 | |||
3498 | /* context fields to callback function */ | ||
3499 | pmboxq->context1 = dd_data; | ||
3500 | dd_data->type = TYPE_MBOX; | ||
3501 | dd_data->context_un.mbox.pmboxq = pmboxq; | ||
3502 | dd_data->context_un.mbox.mb = (MAILBOX_t *)pmbx; | ||
3503 | dd_data->context_un.mbox.set_job = job; | ||
3504 | job->dd_data = dd_data; | ||
3505 | |||
3506 | /* state change */ | ||
3507 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT; | ||
3508 | |||
3509 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | ||
3510 | if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) { | ||
3511 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3512 | "2947 Issued SLI_CONFIG ext-buffer " | ||
3513 | "maibox command, rc:x%x\n", rc); | ||
3514 | return 1; | ||
3515 | } | ||
3516 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3517 | "2948 Failed to issue SLI_CONFIG ext-buffer " | ||
3518 | "maibox command, rc:x%x\n", rc); | ||
3519 | rc = -EPIPE; | ||
3520 | |||
3521 | job_error: | ||
3522 | if (pmboxq) | ||
3523 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
3524 | lpfc_bsg_dma_page_list_free(phba, | ||
3525 | &phba->mbox_ext_buf_ctx.ext_dmabuf_list); | ||
3526 | kfree(dd_data); | ||
3527 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_IDLE; | ||
3528 | return rc; | ||
3529 | } | ||
3530 | |||
3531 | /** | ||
3532 | * lpfc_bsg_sli_cfg_write_cmd_ext - sli_config non-embedded mailbox cmd write | ||
3533 | * @phba: Pointer to HBA context object. | ||
3534 | * @mb: Pointer to a BSG mailbox object. | ||
3535 | * @dmabuff: Pointer to a DMA buffer descriptor. | ||
3536 | * | ||
3537 | * This routine performs SLI_CONFIG (0x9B) write mailbox command operation with | ||
3538 | * non-embedded external bufffers. | ||
3539 | **/ | ||
3540 | static int | ||
3541 | lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | ||
3542 | enum nemb_type nemb_tp, | ||
3543 | struct lpfc_dmabuf *dmabuf) | ||
3544 | { | ||
3545 | struct dfc_mbox_req *mbox_req; | ||
3546 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3547 | uint32_t ext_buf_cnt; | ||
3548 | struct bsg_job_data *dd_data = NULL; | ||
3549 | LPFC_MBOXQ_t *pmboxq = NULL; | ||
3550 | MAILBOX_t *pmb; | ||
3551 | uint8_t *mbx; | ||
3552 | int rc = 0, i; | ||
3553 | |||
3554 | mbox_req = | ||
3555 | (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd; | ||
3556 | |||
3557 | /* pointer to the start of mailbox command */ | ||
3558 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; | ||
3559 | |||
3560 | if (nemb_tp == nemb_mse) { | ||
3561 | ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt, | ||
3562 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr); | ||
3563 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) { | ||
3564 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3565 | "2953 Handled SLI_CONFIG(mse) wr, " | ||
3566 | "ext_buf_cnt(%d) out of range(%d)\n", | ||
3567 | ext_buf_cnt, | ||
3568 | LPFC_MBX_SLI_CONFIG_MAX_MSE); | ||
3569 | return -ERANGE; | ||
3570 | } | ||
3571 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3572 | "2949 Handled SLI_CONFIG(mse) wr, " | ||
3573 | "ext_buf_cnt:%d\n", ext_buf_cnt); | ||
3574 | } else { | ||
3575 | /* sanity check on interface type for support */ | ||
3576 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
3577 | LPFC_SLI_INTF_IF_TYPE_2) | ||
3578 | return -ENODEV; | ||
3579 | /* nemb_tp == nemb_hbd */ | ||
3580 | ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count; | ||
3581 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) { | ||
3582 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3583 | "2954 Handled SLI_CONFIG(hbd) wr, " | ||
3584 | "ext_buf_cnt(%d) out of range(%d)\n", | ||
3585 | ext_buf_cnt, | ||
3586 | LPFC_MBX_SLI_CONFIG_MAX_HBD); | ||
3587 | return -ERANGE; | ||
3588 | } | ||
3589 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3590 | "2950 Handled SLI_CONFIG(hbd) wr, " | ||
3591 | "ext_buf_cnt:%d\n", ext_buf_cnt); | ||
3592 | } | ||
3593 | |||
3594 | if (ext_buf_cnt == 0) | ||
3595 | return -EPERM; | ||
3596 | |||
3597 | /* for the first external buffer */ | ||
3598 | lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf); | ||
3599 | |||
3600 | /* log for looking forward */ | ||
3601 | for (i = 1; i < ext_buf_cnt; i++) { | ||
3602 | if (nemb_tp == nemb_mse) | ||
3603 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3604 | "2951 SLI_CONFIG(mse), buf[%d]-length:%d\n", | ||
3605 | i, sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3606 | mse[i].buf_len); | ||
3607 | else | ||
3608 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3609 | "2952 SLI_CONFIG(hbd), buf[%d]-length:%d\n", | ||
3610 | i, bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len, | ||
3611 | &sli_cfg_mbx->un.sli_config_emb1_subsys. | ||
3612 | hbd[i])); | ||
3613 | } | ||
3614 | |||
3615 | /* multi-buffer handling context */ | ||
3616 | phba->mbox_ext_buf_ctx.nembType = nemb_tp; | ||
3617 | phba->mbox_ext_buf_ctx.mboxType = mbox_wr; | ||
3618 | phba->mbox_ext_buf_ctx.numBuf = ext_buf_cnt; | ||
3619 | phba->mbox_ext_buf_ctx.mbxTag = mbox_req->extMboxTag; | ||
3620 | phba->mbox_ext_buf_ctx.seqNum = mbox_req->extSeqNum; | ||
3621 | phba->mbox_ext_buf_ctx.mbx_dmabuf = dmabuf; | ||
3622 | |||
3623 | if (ext_buf_cnt == 1) { | ||
3624 | /* bsg tracking structure */ | ||
3625 | dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); | ||
3626 | if (!dd_data) { | ||
3627 | rc = -ENOMEM; | ||
3628 | goto job_error; | ||
3629 | } | ||
3630 | |||
3631 | /* mailbox command structure for base driver */ | ||
3632 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
3633 | if (!pmboxq) { | ||
3634 | rc = -ENOMEM; | ||
3635 | goto job_error; | ||
3636 | } | ||
3637 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | ||
3638 | pmb = &pmboxq->u.mb; | ||
3639 | mbx = (uint8_t *)dmabuf->virt; | ||
3640 | memcpy(pmb, mbx, sizeof(*pmb)); | ||
3641 | pmb->mbxOwner = OWN_HOST; | ||
3642 | pmboxq->vport = phba->pport; | ||
3643 | |||
3644 | /* callback for multi-buffer read mailbox command */ | ||
3645 | pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl; | ||
3646 | |||
3647 | /* context fields to callback function */ | ||
3648 | pmboxq->context1 = dd_data; | ||
3649 | dd_data->type = TYPE_MBOX; | ||
3650 | dd_data->context_un.mbox.pmboxq = pmboxq; | ||
3651 | dd_data->context_un.mbox.mb = (MAILBOX_t *)mbx; | ||
3652 | dd_data->context_un.mbox.set_job = job; | ||
3653 | job->dd_data = dd_data; | ||
3654 | |||
3655 | /* state change */ | ||
3656 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT; | ||
3657 | |||
3658 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | ||
3659 | if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) { | ||
3660 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3661 | "2955 Issued SLI_CONFIG ext-buffer " | ||
3662 | "maibox command, rc:x%x\n", rc); | ||
3663 | return 1; | ||
3664 | } | ||
3665 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3666 | "2956 Failed to issue SLI_CONFIG ext-buffer " | ||
3667 | "maibox command, rc:x%x\n", rc); | ||
3668 | rc = -EPIPE; | ||
3669 | } | ||
3670 | |||
3671 | job_error: | ||
3672 | if (pmboxq) | ||
3673 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
3674 | kfree(dd_data); | ||
3675 | |||
3676 | return rc; | ||
3677 | } | ||
3678 | |||
3679 | /** | ||
3680 | * lpfc_bsg_handle_sli_cfg_mbox - handle sli-cfg mailbox cmd with ext buffer | ||
3681 | * @phba: Pointer to HBA context object. | ||
3682 | * @mb: Pointer to a BSG mailbox object. | ||
3683 | * @dmabuff: Pointer to a DMA buffer descriptor. | ||
3684 | * | ||
3685 | * This routine handles SLI_CONFIG (0x9B) mailbox command with non-embedded | ||
3686 | * external bufffers, including both 0x9B with non-embedded MSEs and 0x9B | ||
3687 | * with embedded sussystem 0x1 and opcodes with external HBDs. | ||
3688 | **/ | ||
3689 | static int | ||
3690 | lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | ||
3691 | struct lpfc_dmabuf *dmabuf) | ||
3692 | { | ||
3693 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3694 | uint32_t subsys; | ||
3695 | uint32_t opcode; | ||
3696 | int rc = SLI_CONFIG_NOT_HANDLED; | ||
3697 | |||
3698 | /* state change */ | ||
3699 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_HOST; | ||
3700 | |||
3701 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; | ||
3702 | |||
3703 | if (!bsg_bf_get(lpfc_mbox_hdr_emb, | ||
3704 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr)) { | ||
3705 | subsys = bsg_bf_get(lpfc_emb0_subcmnd_subsys, | ||
3706 | &sli_cfg_mbx->un.sli_config_emb0_subsys); | ||
3707 | opcode = bsg_bf_get(lpfc_emb0_subcmnd_opcode, | ||
3708 | &sli_cfg_mbx->un.sli_config_emb0_subsys); | ||
3709 | if (subsys == SLI_CONFIG_SUBSYS_FCOE) { | ||
3710 | switch (opcode) { | ||
3711 | case FCOE_OPCODE_READ_FCF: | ||
3712 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3713 | "2957 Handled SLI_CONFIG " | ||
3714 | "subsys_fcoe, opcode:x%x\n", | ||
3715 | opcode); | ||
3716 | rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job, | ||
3717 | nemb_mse, dmabuf); | ||
3718 | break; | ||
3719 | case FCOE_OPCODE_ADD_FCF: | ||
3720 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3721 | "2958 Handled SLI_CONFIG " | ||
3722 | "subsys_fcoe, opcode:x%x\n", | ||
3723 | opcode); | ||
3724 | rc = lpfc_bsg_sli_cfg_write_cmd_ext(phba, job, | ||
3725 | nemb_mse, dmabuf); | ||
3726 | break; | ||
3727 | default: | ||
3728 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3729 | "2959 Not handled SLI_CONFIG " | ||
3730 | "subsys_fcoe, opcode:x%x\n", | ||
3731 | opcode); | ||
3732 | rc = SLI_CONFIG_NOT_HANDLED; | ||
3733 | break; | ||
3734 | } | ||
3735 | } else { | ||
3736 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3737 | "2977 Handled SLI_CONFIG " | ||
3738 | "subsys:x%d, opcode:x%x\n", | ||
3739 | subsys, opcode); | ||
3740 | rc = SLI_CONFIG_NOT_HANDLED; | ||
3741 | } | ||
3742 | } else { | ||
3743 | subsys = bsg_bf_get(lpfc_emb1_subcmnd_subsys, | ||
3744 | &sli_cfg_mbx->un.sli_config_emb1_subsys); | ||
3745 | opcode = bsg_bf_get(lpfc_emb1_subcmnd_opcode, | ||
3746 | &sli_cfg_mbx->un.sli_config_emb1_subsys); | ||
3747 | if (subsys == SLI_CONFIG_SUBSYS_COMN) { | ||
3748 | switch (opcode) { | ||
3749 | case COMN_OPCODE_READ_OBJECT: | ||
3750 | case COMN_OPCODE_READ_OBJECT_LIST: | ||
3751 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3752 | "2960 Handled SLI_CONFIG " | ||
3753 | "subsys_comn, opcode:x%x\n", | ||
3754 | opcode); | ||
3755 | rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job, | ||
3756 | nemb_hbd, dmabuf); | ||
3757 | break; | ||
3758 | case COMN_OPCODE_WRITE_OBJECT: | ||
3759 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3760 | "2961 Handled SLI_CONFIG " | ||
3761 | "subsys_comn, opcode:x%x\n", | ||
3762 | opcode); | ||
3763 | rc = lpfc_bsg_sli_cfg_write_cmd_ext(phba, job, | ||
3764 | nemb_hbd, dmabuf); | ||
3765 | break; | ||
3766 | default: | ||
3767 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3768 | "2962 Not handled SLI_CONFIG " | ||
3769 | "subsys_comn, opcode:x%x\n", | ||
3770 | opcode); | ||
3771 | rc = SLI_CONFIG_NOT_HANDLED; | ||
3772 | break; | ||
3773 | } | ||
3774 | } else { | ||
3775 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3776 | "2978 Handled SLI_CONFIG " | ||
3777 | "subsys:x%d, opcode:x%x\n", | ||
3778 | subsys, opcode); | ||
3779 | rc = SLI_CONFIG_NOT_HANDLED; | ||
3780 | } | ||
3781 | } | ||
3782 | return rc; | ||
3783 | } | ||
3784 | |||
3785 | /** | ||
3786 | * lpfc_bsg_mbox_ext_abort_req - request to abort mbox command with ext buffers | ||
3787 | * @phba: Pointer to HBA context object. | ||
3788 | * | ||
3789 | * This routine is for requesting to abort a pass-through mailbox command with | ||
3790 | * multiple external buffers due to error condition. | ||
3791 | **/ | ||
3792 | static void | ||
3793 | lpfc_bsg_mbox_ext_abort(struct lpfc_hba *phba) | ||
3794 | { | ||
3795 | if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_PORT) | ||
3796 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_ABTS; | ||
3797 | else | ||
3798 | lpfc_bsg_mbox_ext_session_reset(phba); | ||
3799 | return; | ||
3800 | } | ||
3801 | |||
3802 | /** | ||
3803 | * lpfc_bsg_read_ebuf_get - get the next mailbox read external buffer | ||
3804 | * @phba: Pointer to HBA context object. | ||
3805 | * @dmabuf: Pointer to a DMA buffer descriptor. | ||
3806 | * | ||
3807 | * This routine extracts the next mailbox read external buffer back to | ||
3808 | * user space through BSG. | ||
3809 | **/ | ||
3810 | static int | ||
3811 | lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job) | ||
3812 | { | ||
3813 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3814 | struct lpfc_dmabuf *dmabuf; | ||
3815 | uint8_t *pbuf; | ||
3816 | uint32_t size; | ||
3817 | uint32_t index; | ||
3818 | |||
3819 | index = phba->mbox_ext_buf_ctx.seqNum; | ||
3820 | phba->mbox_ext_buf_ctx.seqNum++; | ||
3821 | |||
3822 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *) | ||
3823 | phba->mbox_ext_buf_ctx.mbx_dmabuf->virt; | ||
3824 | |||
3825 | if (phba->mbox_ext_buf_ctx.nembType == nemb_mse) { | ||
3826 | size = bsg_bf_get(lpfc_mbox_sli_config_mse_len, | ||
3827 | &sli_cfg_mbx->un.sli_config_emb0_subsys.mse[index]); | ||
3828 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3829 | "2963 SLI_CONFIG (mse) ext-buffer rd get " | ||
3830 | "buffer[%d], size:%d\n", index, size); | ||
3831 | } else { | ||
3832 | size = bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len, | ||
3833 | &sli_cfg_mbx->un.sli_config_emb1_subsys.hbd[index]); | ||
3834 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3835 | "2964 SLI_CONFIG (hbd) ext-buffer rd get " | ||
3836 | "buffer[%d], size:%d\n", index, size); | ||
3837 | } | ||
3838 | if (list_empty(&phba->mbox_ext_buf_ctx.ext_dmabuf_list)) | ||
3839 | return -EPIPE; | ||
3840 | dmabuf = list_first_entry(&phba->mbox_ext_buf_ctx.ext_dmabuf_list, | ||
3841 | struct lpfc_dmabuf, list); | ||
3842 | list_del_init(&dmabuf->list); | ||
3843 | pbuf = (uint8_t *)dmabuf->virt; | ||
3844 | job->reply->reply_payload_rcv_len = | ||
3845 | sg_copy_from_buffer(job->reply_payload.sg_list, | ||
3846 | job->reply_payload.sg_cnt, | ||
3847 | pbuf, size); | ||
3848 | |||
3849 | lpfc_bsg_dma_page_free(phba, dmabuf); | ||
3850 | |||
3851 | if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) { | ||
3852 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3853 | "2965 SLI_CONFIG (hbd) ext-buffer rd mbox " | ||
3854 | "command session done\n"); | ||
3855 | lpfc_bsg_mbox_ext_session_reset(phba); | ||
3856 | } | ||
3857 | |||
3858 | job->reply->result = 0; | ||
3859 | job->job_done(job); | ||
3860 | |||
3861 | return SLI_CONFIG_HANDLED; | ||
3862 | } | ||
3863 | |||
3864 | /** | ||
3865 | * lpfc_bsg_write_ebuf_set - set the next mailbox write external buffer | ||
3866 | * @phba: Pointer to HBA context object. | ||
3867 | * @dmabuf: Pointer to a DMA buffer descriptor. | ||
3868 | * | ||
3869 | * This routine sets up the next mailbox read external buffer obtained | ||
3870 | * from user space through BSG. | ||
3871 | **/ | ||
3872 | static int | ||
3873 | lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job, | ||
3874 | struct lpfc_dmabuf *dmabuf) | ||
3875 | { | ||
3876 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3877 | struct bsg_job_data *dd_data = NULL; | ||
3878 | LPFC_MBOXQ_t *pmboxq = NULL; | ||
3879 | MAILBOX_t *pmb; | ||
3880 | enum nemb_type nemb_tp; | ||
3881 | uint8_t *pbuf; | ||
3882 | uint32_t size; | ||
3883 | uint32_t index; | ||
3884 | int rc; | ||
3885 | |||
3886 | index = phba->mbox_ext_buf_ctx.seqNum; | ||
3887 | phba->mbox_ext_buf_ctx.seqNum++; | ||
3888 | nemb_tp = phba->mbox_ext_buf_ctx.nembType; | ||
3889 | |||
3890 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *) | ||
3891 | phba->mbox_ext_buf_ctx.mbx_dmabuf->virt; | ||
3892 | |||
3893 | dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); | ||
3894 | if (!dd_data) { | ||
3895 | rc = -ENOMEM; | ||
3896 | goto job_error; | ||
3897 | } | ||
3898 | |||
3899 | pbuf = (uint8_t *)dmabuf->virt; | ||
3900 | size = job->request_payload.payload_len; | ||
3901 | sg_copy_to_buffer(job->request_payload.sg_list, | ||
3902 | job->request_payload.sg_cnt, | ||
3903 | pbuf, size); | ||
3904 | |||
3905 | if (phba->mbox_ext_buf_ctx.nembType == nemb_mse) { | ||
3906 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3907 | "2966 SLI_CONFIG (mse) ext-buffer wr set " | ||
3908 | "buffer[%d], size:%d\n", | ||
3909 | phba->mbox_ext_buf_ctx.seqNum, size); | ||
3910 | |||
3911 | } else { | ||
3912 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3913 | "2967 SLI_CONFIG (hbd) ext-buffer wr set " | ||
3914 | "buffer[%d], size:%d\n", | ||
3915 | phba->mbox_ext_buf_ctx.seqNum, size); | ||
3916 | |||
3917 | } | ||
3918 | |||
3919 | /* set up external buffer descriptor and add to external buffer list */ | ||
3920 | lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, index, | ||
3921 | phba->mbox_ext_buf_ctx.mbx_dmabuf, | ||
3922 | dmabuf); | ||
3923 | list_add_tail(&dmabuf->list, &phba->mbox_ext_buf_ctx.ext_dmabuf_list); | ||
3924 | |||
3925 | if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) { | ||
3926 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3927 | "2968 SLI_CONFIG ext-buffer wr all %d " | ||
3928 | "ebuffers received\n", | ||
3929 | phba->mbox_ext_buf_ctx.numBuf); | ||
3930 | /* mailbox command structure for base driver */ | ||
3931 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
3932 | if (!pmboxq) { | ||
3933 | rc = -ENOMEM; | ||
3934 | goto job_error; | ||
3935 | } | ||
3936 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | ||
3937 | pbuf = (uint8_t *)phba->mbox_ext_buf_ctx.mbx_dmabuf->virt; | ||
3938 | pmb = &pmboxq->u.mb; | ||
3939 | memcpy(pmb, pbuf, sizeof(*pmb)); | ||
3940 | pmb->mbxOwner = OWN_HOST; | ||
3941 | pmboxq->vport = phba->pport; | ||
3942 | |||
3943 | /* callback for multi-buffer write mailbox command */ | ||
3944 | pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl; | ||
3945 | |||
3946 | /* context fields to callback function */ | ||
3947 | pmboxq->context1 = dd_data; | ||
3948 | dd_data->type = TYPE_MBOX; | ||
3949 | dd_data->context_un.mbox.pmboxq = pmboxq; | ||
3950 | dd_data->context_un.mbox.mb = (MAILBOX_t *)pbuf; | ||
3951 | dd_data->context_un.mbox.set_job = job; | ||
3952 | job->dd_data = dd_data; | ||
3953 | |||
3954 | /* state change */ | ||
3955 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT; | ||
3956 | |||
3957 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | ||
3958 | if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) { | ||
3959 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3960 | "2969 Issued SLI_CONFIG ext-buffer " | ||
3961 | "maibox command, rc:x%x\n", rc); | ||
3962 | return 1; | ||
3963 | } | ||
3964 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
3965 | "2970 Failed to issue SLI_CONFIG ext-buffer " | ||
3966 | "maibox command, rc:x%x\n", rc); | ||
3967 | rc = -EPIPE; | ||
3968 | goto job_error; | ||
3969 | } | ||
3970 | |||
3971 | /* wait for additoinal external buffers */ | ||
3972 | job->reply->result = 0; | ||
3973 | job->job_done(job); | ||
3974 | return SLI_CONFIG_HANDLED; | ||
3975 | |||
3976 | job_error: | ||
3977 | lpfc_bsg_dma_page_free(phba, dmabuf); | ||
3978 | kfree(dd_data); | ||
3979 | |||
3980 | return rc; | ||
3981 | } | ||
3982 | |||
3983 | /** | ||
3984 | * lpfc_bsg_handle_sli_cfg_ebuf - handle ext buffer with sli-cfg mailbox cmd | ||
3985 | * @phba: Pointer to HBA context object. | ||
3986 | * @mb: Pointer to a BSG mailbox object. | ||
3987 | * @dmabuff: Pointer to a DMA buffer descriptor. | ||
3988 | * | ||
3989 | * This routine handles the external buffer with SLI_CONFIG (0x9B) mailbox | ||
3990 | * command with multiple non-embedded external buffers. | ||
3991 | **/ | ||
3992 | static int | ||
3993 | lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct fc_bsg_job *job, | ||
3994 | struct lpfc_dmabuf *dmabuf) | ||
3995 | { | ||
3996 | int rc; | ||
3997 | |||
3998 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3999 | "2971 SLI_CONFIG buffer (type:x%x)\n", | ||
4000 | phba->mbox_ext_buf_ctx.mboxType); | ||
4001 | |||
4002 | if (phba->mbox_ext_buf_ctx.mboxType == mbox_rd) { | ||
4003 | if (phba->mbox_ext_buf_ctx.state != LPFC_BSG_MBOX_DONE) { | ||
4004 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
4005 | "2972 SLI_CONFIG rd buffer state " | ||
4006 | "mismatch:x%x\n", | ||
4007 | phba->mbox_ext_buf_ctx.state); | ||
4008 | lpfc_bsg_mbox_ext_abort(phba); | ||
4009 | return -EPIPE; | ||
4010 | } | ||
4011 | rc = lpfc_bsg_read_ebuf_get(phba, job); | ||
4012 | if (rc == SLI_CONFIG_HANDLED) | ||
4013 | lpfc_bsg_dma_page_free(phba, dmabuf); | ||
4014 | } else { /* phba->mbox_ext_buf_ctx.mboxType == mbox_wr */ | ||
4015 | if (phba->mbox_ext_buf_ctx.state != LPFC_BSG_MBOX_HOST) { | ||
4016 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
4017 | "2973 SLI_CONFIG wr buffer state " | ||
4018 | "mismatch:x%x\n", | ||
4019 | phba->mbox_ext_buf_ctx.state); | ||
4020 | lpfc_bsg_mbox_ext_abort(phba); | ||
4021 | return -EPIPE; | ||
4022 | } | ||
4023 | rc = lpfc_bsg_write_ebuf_set(phba, job, dmabuf); | ||
4024 | } | ||
4025 | return rc; | ||
4026 | } | ||
4027 | |||
4028 | /** | ||
4029 | * lpfc_bsg_handle_sli_cfg_ext - handle sli-cfg mailbox with external buffer | ||
4030 | * @phba: Pointer to HBA context object. | ||
4031 | * @mb: Pointer to a BSG mailbox object. | ||
4032 | * @dmabuff: Pointer to a DMA buffer descriptor. | ||
4033 | * | ||
4034 | * This routine checkes and handles non-embedded multi-buffer SLI_CONFIG | ||
4035 | * (0x9B) mailbox commands and external buffers. | ||
4036 | **/ | ||
4037 | static int | ||
4038 | lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | ||
4039 | struct lpfc_dmabuf *dmabuf) | ||
4040 | { | ||
4041 | struct dfc_mbox_req *mbox_req; | ||
4042 | int rc; | ||
4043 | |||
4044 | mbox_req = | ||
4045 | (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd; | ||
4046 | |||
4047 | /* mbox command with/without single external buffer */ | ||
4048 | if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0) | ||
4049 | return SLI_CONFIG_NOT_HANDLED; | ||
4050 | |||
4051 | /* mbox command and first external buffer */ | ||
4052 | if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE) { | ||
4053 | if (mbox_req->extSeqNum == 1) { | ||
4054 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
4055 | "2974 SLI_CONFIG mailbox: tag:%d, " | ||
4056 | "seq:%d\n", mbox_req->extMboxTag, | ||
4057 | mbox_req->extSeqNum); | ||
4058 | rc = lpfc_bsg_handle_sli_cfg_mbox(phba, job, dmabuf); | ||
4059 | return rc; | ||
4060 | } else | ||
4061 | goto sli_cfg_ext_error; | ||
4062 | } | ||
4063 | |||
4064 | /* | ||
4065 | * handle additional external buffers | ||
4066 | */ | ||
4067 | |||
4068 | /* check broken pipe conditions */ | ||
4069 | if (mbox_req->extMboxTag != phba->mbox_ext_buf_ctx.mbxTag) | ||
4070 | goto sli_cfg_ext_error; | ||
4071 | if (mbox_req->extSeqNum > phba->mbox_ext_buf_ctx.numBuf) | ||
4072 | goto sli_cfg_ext_error; | ||
4073 | if (mbox_req->extSeqNum != phba->mbox_ext_buf_ctx.seqNum + 1) | ||
4074 | goto sli_cfg_ext_error; | ||
4075 | |||
4076 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
4077 | "2975 SLI_CONFIG mailbox external buffer: " | ||
4078 | "extSta:x%x, tag:%d, seq:%d\n", | ||
4079 | phba->mbox_ext_buf_ctx.state, mbox_req->extMboxTag, | ||
4080 | mbox_req->extSeqNum); | ||
4081 | rc = lpfc_bsg_handle_sli_cfg_ebuf(phba, job, dmabuf); | ||
4082 | return rc; | ||
4083 | |||
4084 | sli_cfg_ext_error: | ||
4085 | /* all other cases, broken pipe */ | ||
4086 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | ||
4087 | "2976 SLI_CONFIG mailbox broken pipe: " | ||
4088 | "ctxSta:x%x, ctxNumBuf:%d " | ||
4089 | "ctxTag:%d, ctxSeq:%d, tag:%d, seq:%d\n", | ||
4090 | phba->mbox_ext_buf_ctx.state, | ||
4091 | phba->mbox_ext_buf_ctx.numBuf, | ||
4092 | phba->mbox_ext_buf_ctx.mbxTag, | ||
4093 | phba->mbox_ext_buf_ctx.seqNum, | ||
4094 | mbox_req->extMboxTag, mbox_req->extSeqNum); | ||
4095 | |||
4096 | lpfc_bsg_mbox_ext_session_reset(phba); | ||
4097 | |||
4098 | return -EPIPE; | ||
4099 | } | ||
4100 | |||
4101 | /** | ||
2622 | * lpfc_bsg_issue_mbox - issues a mailbox command on behalf of an app | 4102 | * lpfc_bsg_issue_mbox - issues a mailbox command on behalf of an app |
2623 | * @phba: Pointer to HBA context object. | 4103 | * @phba: Pointer to HBA context object. |
2624 | * @mb: Pointer to a mailbox object. | 4104 | * @mb: Pointer to a mailbox object. |
@@ -2638,22 +4118,21 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2638 | LPFC_MBOXQ_t *pmboxq = NULL; /* internal mailbox queue */ | 4118 | LPFC_MBOXQ_t *pmboxq = NULL; /* internal mailbox queue */ |
2639 | MAILBOX_t *pmb; /* shortcut to the pmboxq mailbox */ | 4119 | MAILBOX_t *pmb; /* shortcut to the pmboxq mailbox */ |
2640 | /* a 4k buffer to hold the mb and extended data from/to the bsg */ | 4120 | /* a 4k buffer to hold the mb and extended data from/to the bsg */ |
2641 | MAILBOX_t *mb = NULL; | 4121 | uint8_t *pmbx = NULL; |
2642 | struct bsg_job_data *dd_data = NULL; /* bsg data tracking structure */ | 4122 | struct bsg_job_data *dd_data = NULL; /* bsg data tracking structure */ |
2643 | uint32_t size; | 4123 | struct lpfc_dmabuf *dmabuf = NULL; |
2644 | struct lpfc_dmabuf *rxbmp = NULL; /* for biu diag */ | 4124 | struct dfc_mbox_req *mbox_req; |
2645 | struct lpfc_dmabufext *dmp = NULL; /* for biu diag */ | ||
2646 | struct ulp_bde64 *rxbpl = NULL; | ||
2647 | struct dfc_mbox_req *mbox_req = (struct dfc_mbox_req *) | ||
2648 | job->request->rqst_data.h_vendor.vendor_cmd; | ||
2649 | struct READ_EVENT_LOG_VAR *rdEventLog; | 4125 | struct READ_EVENT_LOG_VAR *rdEventLog; |
2650 | uint32_t transmit_length, receive_length, mode; | 4126 | uint32_t transmit_length, receive_length, mode; |
4127 | struct lpfc_mbx_sli4_config *sli4_config; | ||
2651 | struct lpfc_mbx_nembed_cmd *nembed_sge; | 4128 | struct lpfc_mbx_nembed_cmd *nembed_sge; |
2652 | struct mbox_header *header; | 4129 | struct mbox_header *header; |
2653 | struct ulp_bde64 *bde; | 4130 | struct ulp_bde64 *bde; |
2654 | uint8_t *ext = NULL; | 4131 | uint8_t *ext = NULL; |
2655 | int rc = 0; | 4132 | int rc = 0; |
2656 | uint8_t *from; | 4133 | uint8_t *from; |
4134 | uint32_t size; | ||
4135 | |||
2657 | 4136 | ||
2658 | /* in case no data is transferred */ | 4137 | /* in case no data is transferred */ |
2659 | job->reply->reply_payload_rcv_len = 0; | 4138 | job->reply->reply_payload_rcv_len = 0; |
@@ -2665,6 +4144,18 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2665 | goto job_done; | 4144 | goto job_done; |
2666 | } | 4145 | } |
2667 | 4146 | ||
4147 | /* | ||
4148 | * Don't allow mailbox commands to be sent when blocked or when in | ||
4149 | * the middle of discovery | ||
4150 | */ | ||
4151 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | ||
4152 | rc = -EAGAIN; | ||
4153 | goto job_done; | ||
4154 | } | ||
4155 | |||
4156 | mbox_req = | ||
4157 | (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd; | ||
4158 | |||
2668 | /* check if requested extended data lengths are valid */ | 4159 | /* check if requested extended data lengths are valid */ |
2669 | if ((mbox_req->inExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t)) || | 4160 | if ((mbox_req->inExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t)) || |
2670 | (mbox_req->outExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t))) { | 4161 | (mbox_req->outExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t))) { |
@@ -2672,6 +4163,32 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2672 | goto job_done; | 4163 | goto job_done; |
2673 | } | 4164 | } |
2674 | 4165 | ||
4166 | dmabuf = lpfc_bsg_dma_page_alloc(phba); | ||
4167 | if (!dmabuf || !dmabuf->virt) { | ||
4168 | rc = -ENOMEM; | ||
4169 | goto job_done; | ||
4170 | } | ||
4171 | |||
4172 | /* Get the mailbox command or external buffer from BSG */ | ||
4173 | pmbx = (uint8_t *)dmabuf->virt; | ||
4174 | size = job->request_payload.payload_len; | ||
4175 | sg_copy_to_buffer(job->request_payload.sg_list, | ||
4176 | job->request_payload.sg_cnt, pmbx, size); | ||
4177 | |||
4178 | /* Handle possible SLI_CONFIG with non-embedded payloads */ | ||
4179 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
4180 | rc = lpfc_bsg_handle_sli_cfg_ext(phba, job, dmabuf); | ||
4181 | if (rc == SLI_CONFIG_HANDLED) | ||
4182 | goto job_cont; | ||
4183 | if (rc) | ||
4184 | goto job_done; | ||
4185 | /* SLI_CONFIG_NOT_HANDLED for other mailbox commands */ | ||
4186 | } | ||
4187 | |||
4188 | rc = lpfc_bsg_check_cmd_access(phba, (MAILBOX_t *)pmbx, vport); | ||
4189 | if (rc != 0) | ||
4190 | goto job_done; /* must be negative */ | ||
4191 | |||
2675 | /* allocate our bsg tracking structure */ | 4192 | /* allocate our bsg tracking structure */ |
2676 | dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); | 4193 | dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); |
2677 | if (!dd_data) { | 4194 | if (!dd_data) { |
@@ -2681,12 +4198,6 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2681 | goto job_done; | 4198 | goto job_done; |
2682 | } | 4199 | } |
2683 | 4200 | ||
2684 | mb = kzalloc(BSG_MBOX_SIZE, GFP_KERNEL); | ||
2685 | if (!mb) { | ||
2686 | rc = -ENOMEM; | ||
2687 | goto job_done; | ||
2688 | } | ||
2689 | |||
2690 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4201 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2691 | if (!pmboxq) { | 4202 | if (!pmboxq) { |
2692 | rc = -ENOMEM; | 4203 | rc = -ENOMEM; |
@@ -2694,17 +4205,8 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2694 | } | 4205 | } |
2695 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | 4206 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); |
2696 | 4207 | ||
2697 | size = job->request_payload.payload_len; | ||
2698 | sg_copy_to_buffer(job->request_payload.sg_list, | ||
2699 | job->request_payload.sg_cnt, | ||
2700 | mb, size); | ||
2701 | |||
2702 | rc = lpfc_bsg_check_cmd_access(phba, mb, vport); | ||
2703 | if (rc != 0) | ||
2704 | goto job_done; /* must be negative */ | ||
2705 | |||
2706 | pmb = &pmboxq->u.mb; | 4208 | pmb = &pmboxq->u.mb; |
2707 | memcpy(pmb, mb, sizeof(*pmb)); | 4209 | memcpy(pmb, pmbx, sizeof(*pmb)); |
2708 | pmb->mbxOwner = OWN_HOST; | 4210 | pmb->mbxOwner = OWN_HOST; |
2709 | pmboxq->vport = vport; | 4211 | pmboxq->vport = vport; |
2710 | 4212 | ||
@@ -2721,30 +4223,13 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2721 | "0x%x while in stopped state.\n", | 4223 | "0x%x while in stopped state.\n", |
2722 | pmb->mbxCommand); | 4224 | pmb->mbxCommand); |
2723 | 4225 | ||
2724 | /* Don't allow mailbox commands to be sent when blocked | ||
2725 | * or when in the middle of discovery | ||
2726 | */ | ||
2727 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | ||
2728 | rc = -EAGAIN; | ||
2729 | goto job_done; | ||
2730 | } | ||
2731 | |||
2732 | /* extended mailbox commands will need an extended buffer */ | 4226 | /* extended mailbox commands will need an extended buffer */ |
2733 | if (mbox_req->inExtWLen || mbox_req->outExtWLen) { | 4227 | if (mbox_req->inExtWLen || mbox_req->outExtWLen) { |
2734 | ext = kzalloc(MAILBOX_EXT_SIZE, GFP_KERNEL); | ||
2735 | if (!ext) { | ||
2736 | rc = -ENOMEM; | ||
2737 | goto job_done; | ||
2738 | } | ||
2739 | |||
2740 | /* any data for the device? */ | 4228 | /* any data for the device? */ |
2741 | if (mbox_req->inExtWLen) { | 4229 | if (mbox_req->inExtWLen) { |
2742 | from = (uint8_t *)mb; | 4230 | from = pmbx; |
2743 | from += sizeof(MAILBOX_t); | 4231 | ext = from + sizeof(MAILBOX_t); |
2744 | memcpy((uint8_t *)ext, from, | ||
2745 | mbox_req->inExtWLen * sizeof(uint32_t)); | ||
2746 | } | 4232 | } |
2747 | |||
2748 | pmboxq->context2 = ext; | 4233 | pmboxq->context2 = ext; |
2749 | pmboxq->in_ext_byte_len = | 4234 | pmboxq->in_ext_byte_len = |
2750 | mbox_req->inExtWLen * sizeof(uint32_t); | 4235 | mbox_req->inExtWLen * sizeof(uint32_t); |
@@ -2768,46 +4253,17 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2768 | rc = -ERANGE; | 4253 | rc = -ERANGE; |
2769 | goto job_done; | 4254 | goto job_done; |
2770 | } | 4255 | } |
2771 | |||
2772 | rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
2773 | if (!rxbmp) { | ||
2774 | rc = -ENOMEM; | ||
2775 | goto job_done; | ||
2776 | } | ||
2777 | |||
2778 | rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); | ||
2779 | if (!rxbmp->virt) { | ||
2780 | rc = -ENOMEM; | ||
2781 | goto job_done; | ||
2782 | } | ||
2783 | |||
2784 | INIT_LIST_HEAD(&rxbmp->list); | ||
2785 | rxbpl = (struct ulp_bde64 *) rxbmp->virt; | ||
2786 | dmp = diag_cmd_data_alloc(phba, rxbpl, transmit_length, 0); | ||
2787 | if (!dmp) { | ||
2788 | rc = -ENOMEM; | ||
2789 | goto job_done; | ||
2790 | } | ||
2791 | |||
2792 | INIT_LIST_HEAD(&dmp->dma.list); | ||
2793 | pmb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = | 4256 | pmb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = |
2794 | putPaddrHigh(dmp->dma.phys); | 4257 | putPaddrHigh(dmabuf->phys + sizeof(MAILBOX_t)); |
2795 | pmb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = | 4258 | pmb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = |
2796 | putPaddrLow(dmp->dma.phys); | 4259 | putPaddrLow(dmabuf->phys + sizeof(MAILBOX_t)); |
2797 | 4260 | ||
2798 | pmb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = | 4261 | pmb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = |
2799 | putPaddrHigh(dmp->dma.phys + | 4262 | putPaddrHigh(dmabuf->phys + sizeof(MAILBOX_t) |
2800 | pmb->un.varBIUdiag.un.s2. | 4263 | + pmb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize); |
2801 | xmit_bde64.tus.f.bdeSize); | ||
2802 | pmb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = | 4264 | pmb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = |
2803 | putPaddrLow(dmp->dma.phys + | 4265 | putPaddrLow(dmabuf->phys + sizeof(MAILBOX_t) |
2804 | pmb->un.varBIUdiag.un.s2. | 4266 | + pmb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize); |
2805 | xmit_bde64.tus.f.bdeSize); | ||
2806 | |||
2807 | /* copy the transmit data found in the mailbox extension area */ | ||
2808 | from = (uint8_t *)mb; | ||
2809 | from += sizeof(MAILBOX_t); | ||
2810 | memcpy((uint8_t *)dmp->dma.virt, from, transmit_length); | ||
2811 | } else if (pmb->mbxCommand == MBX_READ_EVENT_LOG) { | 4267 | } else if (pmb->mbxCommand == MBX_READ_EVENT_LOG) { |
2812 | rdEventLog = &pmb->un.varRdEventLog; | 4268 | rdEventLog = &pmb->un.varRdEventLog; |
2813 | receive_length = rdEventLog->rcv_bde64.tus.f.bdeSize; | 4269 | receive_length = rdEventLog->rcv_bde64.tus.f.bdeSize; |
@@ -2823,33 +4279,10 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2823 | 4279 | ||
2824 | /* mode zero uses a bde like biu diags command */ | 4280 | /* mode zero uses a bde like biu diags command */ |
2825 | if (mode == 0) { | 4281 | if (mode == 0) { |
2826 | 4282 | pmb->un.varWords[3] = putPaddrLow(dmabuf->phys | |
2827 | /* rebuild the command for sli4 using our own buffers | 4283 | + sizeof(MAILBOX_t)); |
2828 | * like we do for biu diags | 4284 | pmb->un.varWords[4] = putPaddrHigh(dmabuf->phys |
2829 | */ | 4285 | + sizeof(MAILBOX_t)); |
2830 | |||
2831 | rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
2832 | if (!rxbmp) { | ||
2833 | rc = -ENOMEM; | ||
2834 | goto job_done; | ||
2835 | } | ||
2836 | |||
2837 | rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); | ||
2838 | rxbpl = (struct ulp_bde64 *) rxbmp->virt; | ||
2839 | if (rxbpl) { | ||
2840 | INIT_LIST_HEAD(&rxbmp->list); | ||
2841 | dmp = diag_cmd_data_alloc(phba, rxbpl, | ||
2842 | receive_length, 0); | ||
2843 | } | ||
2844 | |||
2845 | if (!dmp) { | ||
2846 | rc = -ENOMEM; | ||
2847 | goto job_done; | ||
2848 | } | ||
2849 | |||
2850 | INIT_LIST_HEAD(&dmp->dma.list); | ||
2851 | pmb->un.varWords[3] = putPaddrLow(dmp->dma.phys); | ||
2852 | pmb->un.varWords[4] = putPaddrHigh(dmp->dma.phys); | ||
2853 | } | 4286 | } |
2854 | } else if (phba->sli_rev == LPFC_SLI_REV4) { | 4287 | } else if (phba->sli_rev == LPFC_SLI_REV4) { |
2855 | if (pmb->mbxCommand == MBX_DUMP_MEMORY) { | 4288 | if (pmb->mbxCommand == MBX_DUMP_MEMORY) { |
@@ -2860,36 +4293,14 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2860 | /* receive length cannot be greater than mailbox | 4293 | /* receive length cannot be greater than mailbox |
2861 | * extension size | 4294 | * extension size |
2862 | */ | 4295 | */ |
2863 | if ((receive_length == 0) || | 4296 | if (receive_length == 0) { |
2864 | (receive_length > MAILBOX_EXT_SIZE)) { | ||
2865 | rc = -ERANGE; | 4297 | rc = -ERANGE; |
2866 | goto job_done; | 4298 | goto job_done; |
2867 | } | 4299 | } |
2868 | 4300 | pmb->un.varWords[3] = putPaddrLow(dmabuf->phys | |
2869 | rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 4301 | + sizeof(MAILBOX_t)); |
2870 | if (!rxbmp) { | 4302 | pmb->un.varWords[4] = putPaddrHigh(dmabuf->phys |
2871 | rc = -ENOMEM; | 4303 | + sizeof(MAILBOX_t)); |
2872 | goto job_done; | ||
2873 | } | ||
2874 | |||
2875 | rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); | ||
2876 | if (!rxbmp->virt) { | ||
2877 | rc = -ENOMEM; | ||
2878 | goto job_done; | ||
2879 | } | ||
2880 | |||
2881 | INIT_LIST_HEAD(&rxbmp->list); | ||
2882 | rxbpl = (struct ulp_bde64 *) rxbmp->virt; | ||
2883 | dmp = diag_cmd_data_alloc(phba, rxbpl, receive_length, | ||
2884 | 0); | ||
2885 | if (!dmp) { | ||
2886 | rc = -ENOMEM; | ||
2887 | goto job_done; | ||
2888 | } | ||
2889 | |||
2890 | INIT_LIST_HEAD(&dmp->dma.list); | ||
2891 | pmb->un.varWords[3] = putPaddrLow(dmp->dma.phys); | ||
2892 | pmb->un.varWords[4] = putPaddrHigh(dmp->dma.phys); | ||
2893 | } else if ((pmb->mbxCommand == MBX_UPDATE_CFG) && | 4304 | } else if ((pmb->mbxCommand == MBX_UPDATE_CFG) && |
2894 | pmb->un.varUpdateCfg.co) { | 4305 | pmb->un.varUpdateCfg.co) { |
2895 | bde = (struct ulp_bde64 *)&pmb->un.varWords[4]; | 4306 | bde = (struct ulp_bde64 *)&pmb->un.varWords[4]; |
@@ -2899,102 +4310,53 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
2899 | rc = -ERANGE; | 4310 | rc = -ERANGE; |
2900 | goto job_done; | 4311 | goto job_done; |
2901 | } | 4312 | } |
2902 | 4313 | bde->addrHigh = putPaddrHigh(dmabuf->phys | |
2903 | rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 4314 | + sizeof(MAILBOX_t)); |
2904 | if (!rxbmp) { | 4315 | bde->addrLow = putPaddrLow(dmabuf->phys |
2905 | rc = -ENOMEM; | 4316 | + sizeof(MAILBOX_t)); |
2906 | goto job_done; | ||
2907 | } | ||
2908 | |||
2909 | rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); | ||
2910 | if (!rxbmp->virt) { | ||
2911 | rc = -ENOMEM; | ||
2912 | goto job_done; | ||
2913 | } | ||
2914 | |||
2915 | INIT_LIST_HEAD(&rxbmp->list); | ||
2916 | rxbpl = (struct ulp_bde64 *) rxbmp->virt; | ||
2917 | dmp = diag_cmd_data_alloc(phba, rxbpl, | ||
2918 | bde->tus.f.bdeSize, 0); | ||
2919 | if (!dmp) { | ||
2920 | rc = -ENOMEM; | ||
2921 | goto job_done; | ||
2922 | } | ||
2923 | |||
2924 | INIT_LIST_HEAD(&dmp->dma.list); | ||
2925 | bde->addrHigh = putPaddrHigh(dmp->dma.phys); | ||
2926 | bde->addrLow = putPaddrLow(dmp->dma.phys); | ||
2927 | |||
2928 | /* copy the transmit data found in the mailbox | ||
2929 | * extension area | ||
2930 | */ | ||
2931 | from = (uint8_t *)mb; | ||
2932 | from += sizeof(MAILBOX_t); | ||
2933 | memcpy((uint8_t *)dmp->dma.virt, from, | ||
2934 | bde->tus.f.bdeSize); | ||
2935 | } else if (pmb->mbxCommand == MBX_SLI4_CONFIG) { | 4317 | } else if (pmb->mbxCommand == MBX_SLI4_CONFIG) { |
2936 | /* rebuild the command for sli4 using our own buffers | 4318 | /* Handling non-embedded SLI_CONFIG mailbox command */ |
2937 | * like we do for biu diags | 4319 | sli4_config = &pmboxq->u.mqe.un.sli4_config; |
2938 | */ | 4320 | if (!bf_get(lpfc_mbox_hdr_emb, |
2939 | header = (struct mbox_header *)&pmb->un.varWords[0]; | 4321 | &sli4_config->header.cfg_mhdr)) { |
2940 | nembed_sge = (struct lpfc_mbx_nembed_cmd *) | 4322 | /* rebuild the command for sli4 using our |
2941 | &pmb->un.varWords[0]; | 4323 | * own buffers like we do for biu diags |
2942 | receive_length = nembed_sge->sge[0].length; | 4324 | */ |
2943 | 4325 | header = (struct mbox_header *) | |
2944 | /* receive length cannot be greater than mailbox | 4326 | &pmb->un.varWords[0]; |
2945 | * extension size | 4327 | nembed_sge = (struct lpfc_mbx_nembed_cmd *) |
2946 | */ | 4328 | &pmb->un.varWords[0]; |
2947 | if ((receive_length == 0) || | 4329 | receive_length = nembed_sge->sge[0].length; |
2948 | (receive_length > MAILBOX_EXT_SIZE)) { | 4330 | |
2949 | rc = -ERANGE; | 4331 | /* receive length cannot be greater than |
2950 | goto job_done; | 4332 | * mailbox extension size |
2951 | } | 4333 | */ |
2952 | 4334 | if ((receive_length == 0) || | |
2953 | rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 4335 | (receive_length > MAILBOX_EXT_SIZE)) { |
2954 | if (!rxbmp) { | 4336 | rc = -ERANGE; |
2955 | rc = -ENOMEM; | 4337 | goto job_done; |
2956 | goto job_done; | 4338 | } |
2957 | } | ||
2958 | |||
2959 | rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); | ||
2960 | if (!rxbmp->virt) { | ||
2961 | rc = -ENOMEM; | ||
2962 | goto job_done; | ||
2963 | } | ||
2964 | 4339 | ||
2965 | INIT_LIST_HEAD(&rxbmp->list); | 4340 | nembed_sge->sge[0].pa_hi = |
2966 | rxbpl = (struct ulp_bde64 *) rxbmp->virt; | 4341 | putPaddrHigh(dmabuf->phys |
2967 | dmp = diag_cmd_data_alloc(phba, rxbpl, receive_length, | 4342 | + sizeof(MAILBOX_t)); |
2968 | 0); | 4343 | nembed_sge->sge[0].pa_lo = |
2969 | if (!dmp) { | 4344 | putPaddrLow(dmabuf->phys |
2970 | rc = -ENOMEM; | 4345 | + sizeof(MAILBOX_t)); |
2971 | goto job_done; | ||
2972 | } | 4346 | } |
2973 | |||
2974 | INIT_LIST_HEAD(&dmp->dma.list); | ||
2975 | nembed_sge->sge[0].pa_hi = putPaddrHigh(dmp->dma.phys); | ||
2976 | nembed_sge->sge[0].pa_lo = putPaddrLow(dmp->dma.phys); | ||
2977 | /* copy the transmit data found in the mailbox | ||
2978 | * extension area | ||
2979 | */ | ||
2980 | from = (uint8_t *)mb; | ||
2981 | from += sizeof(MAILBOX_t); | ||
2982 | memcpy((uint8_t *)dmp->dma.virt, from, | ||
2983 | header->cfg_mhdr.payload_length); | ||
2984 | } | 4347 | } |
2985 | } | 4348 | } |
2986 | 4349 | ||
2987 | dd_data->context_un.mbox.rxbmp = rxbmp; | 4350 | dd_data->context_un.mbox.dmabuffers = dmabuf; |
2988 | dd_data->context_un.mbox.dmp = dmp; | ||
2989 | 4351 | ||
2990 | /* setup wake call as IOCB callback */ | 4352 | /* setup wake call as IOCB callback */ |
2991 | pmboxq->mbox_cmpl = lpfc_bsg_wake_mbox_wait; | 4353 | pmboxq->mbox_cmpl = lpfc_bsg_issue_mbox_cmpl; |
2992 | 4354 | ||
2993 | /* setup context field to pass wait_queue pointer to wake function */ | 4355 | /* setup context field to pass wait_queue pointer to wake function */ |
2994 | pmboxq->context1 = dd_data; | 4356 | pmboxq->context1 = dd_data; |
2995 | dd_data->type = TYPE_MBOX; | 4357 | dd_data->type = TYPE_MBOX; |
2996 | dd_data->context_un.mbox.pmboxq = pmboxq; | 4358 | dd_data->context_un.mbox.pmboxq = pmboxq; |
2997 | dd_data->context_un.mbox.mb = mb; | 4359 | dd_data->context_un.mbox.mb = (MAILBOX_t *)pmbx; |
2998 | dd_data->context_un.mbox.set_job = job; | 4360 | dd_data->context_un.mbox.set_job = job; |
2999 | dd_data->context_un.mbox.ext = ext; | 4361 | dd_data->context_un.mbox.ext = ext; |
3000 | dd_data->context_un.mbox.mbOffset = mbox_req->mbOffset; | 4362 | dd_data->context_un.mbox.mbOffset = mbox_req->mbOffset; |
@@ -3011,11 +4373,11 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3011 | } | 4373 | } |
3012 | 4374 | ||
3013 | /* job finished, copy the data */ | 4375 | /* job finished, copy the data */ |
3014 | memcpy(mb, pmb, sizeof(*pmb)); | 4376 | memcpy(pmbx, pmb, sizeof(*pmb)); |
3015 | job->reply->reply_payload_rcv_len = | 4377 | job->reply->reply_payload_rcv_len = |
3016 | sg_copy_from_buffer(job->reply_payload.sg_list, | 4378 | sg_copy_from_buffer(job->reply_payload.sg_list, |
3017 | job->reply_payload.sg_cnt, | 4379 | job->reply_payload.sg_cnt, |
3018 | mb, size); | 4380 | pmbx, size); |
3019 | /* not waiting mbox already done */ | 4381 | /* not waiting mbox already done */ |
3020 | rc = 0; | 4382 | rc = 0; |
3021 | goto job_done; | 4383 | goto job_done; |
@@ -3027,22 +4389,12 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3027 | 4389 | ||
3028 | job_done: | 4390 | job_done: |
3029 | /* common exit for error or job completed inline */ | 4391 | /* common exit for error or job completed inline */ |
3030 | kfree(mb); | ||
3031 | if (pmboxq) | 4392 | if (pmboxq) |
3032 | mempool_free(pmboxq, phba->mbox_mem_pool); | 4393 | mempool_free(pmboxq, phba->mbox_mem_pool); |
3033 | kfree(ext); | 4394 | lpfc_bsg_dma_page_free(phba, dmabuf); |
3034 | if (dmp) { | ||
3035 | dma_free_coherent(&phba->pcidev->dev, | ||
3036 | dmp->size, dmp->dma.virt, | ||
3037 | dmp->dma.phys); | ||
3038 | kfree(dmp); | ||
3039 | } | ||
3040 | if (rxbmp) { | ||
3041 | lpfc_mbuf_free(phba, rxbmp->virt, rxbmp->phys); | ||
3042 | kfree(rxbmp); | ||
3043 | } | ||
3044 | kfree(dd_data); | 4395 | kfree(dd_data); |
3045 | 4396 | ||
4397 | job_cont: | ||
3046 | return rc; | 4398 | return rc; |
3047 | } | 4399 | } |
3048 | 4400 | ||
@@ -3055,37 +4407,28 @@ lpfc_bsg_mbox_cmd(struct fc_bsg_job *job) | |||
3055 | { | 4407 | { |
3056 | struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; | 4408 | struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; |
3057 | struct lpfc_hba *phba = vport->phba; | 4409 | struct lpfc_hba *phba = vport->phba; |
4410 | struct dfc_mbox_req *mbox_req; | ||
3058 | int rc = 0; | 4411 | int rc = 0; |
3059 | 4412 | ||
3060 | /* in case no data is transferred */ | 4413 | /* mix-and-match backward compatibility */ |
3061 | job->reply->reply_payload_rcv_len = 0; | 4414 | job->reply->reply_payload_rcv_len = 0; |
3062 | if (job->request_len < | 4415 | if (job->request_len < |
3063 | sizeof(struct fc_bsg_request) + sizeof(struct dfc_mbox_req)) { | 4416 | sizeof(struct fc_bsg_request) + sizeof(struct dfc_mbox_req)) { |
3064 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | 4417 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
3065 | "2737 Received MBOX_REQ request below " | 4418 | "2737 Mix-and-match backward compability " |
3066 | "minimum size\n"); | 4419 | "between MBOX_REQ old size:%d and " |
3067 | rc = -EINVAL; | 4420 | "new request size:%d\n", |
3068 | goto job_error; | 4421 | (int)(job->request_len - |
3069 | } | 4422 | sizeof(struct fc_bsg_request)), |
3070 | 4423 | (int)sizeof(struct dfc_mbox_req)); | |
3071 | if (job->request_payload.payload_len != BSG_MBOX_SIZE) { | 4424 | mbox_req = (struct dfc_mbox_req *) |
3072 | rc = -EINVAL; | 4425 | job->request->rqst_data.h_vendor.vendor_cmd; |
3073 | goto job_error; | 4426 | mbox_req->extMboxTag = 0; |
3074 | } | 4427 | mbox_req->extSeqNum = 0; |
3075 | |||
3076 | if (job->reply_payload.payload_len != BSG_MBOX_SIZE) { | ||
3077 | rc = -EINVAL; | ||
3078 | goto job_error; | ||
3079 | } | ||
3080 | |||
3081 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | ||
3082 | rc = -EAGAIN; | ||
3083 | goto job_error; | ||
3084 | } | 4428 | } |
3085 | 4429 | ||
3086 | rc = lpfc_bsg_issue_mbox(phba, job, vport); | 4430 | rc = lpfc_bsg_issue_mbox(phba, job, vport); |
3087 | 4431 | ||
3088 | job_error: | ||
3089 | if (rc == 0) { | 4432 | if (rc == 0) { |
3090 | /* job done */ | 4433 | /* job done */ |
3091 | job->reply->result = 0; | 4434 | job->reply->result = 0; |
@@ -3416,10 +4759,16 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job) | |||
3416 | rc = lpfc_bsg_send_mgmt_rsp(job); | 4759 | rc = lpfc_bsg_send_mgmt_rsp(job); |
3417 | break; | 4760 | break; |
3418 | case LPFC_BSG_VENDOR_DIAG_MODE: | 4761 | case LPFC_BSG_VENDOR_DIAG_MODE: |
3419 | rc = lpfc_bsg_diag_mode(job); | 4762 | rc = lpfc_bsg_diag_loopback_mode(job); |
4763 | break; | ||
4764 | case LPFC_BSG_VENDOR_DIAG_MODE_END: | ||
4765 | rc = lpfc_sli4_bsg_diag_mode_end(job); | ||
4766 | break; | ||
4767 | case LPFC_BSG_VENDOR_DIAG_RUN_LOOPBACK: | ||
4768 | rc = lpfc_bsg_diag_loopback_run(job); | ||
3420 | break; | 4769 | break; |
3421 | case LPFC_BSG_VENDOR_DIAG_TEST: | 4770 | case LPFC_BSG_VENDOR_LINK_DIAG_TEST: |
3422 | rc = lpfc_bsg_diag_test(job); | 4771 | rc = lpfc_sli4_bsg_link_diag_test(job); |
3423 | break; | 4772 | break; |
3424 | case LPFC_BSG_VENDOR_GET_MGMT_REV: | 4773 | case LPFC_BSG_VENDOR_GET_MGMT_REV: |
3425 | rc = lpfc_bsg_get_dfc_rev(job); | 4774 | rc = lpfc_bsg_get_dfc_rev(job); |
@@ -3538,6 +4887,8 @@ lpfc_bsg_timeout(struct fc_bsg_job *job) | |||
3538 | /* the mbox completion handler can now be run */ | 4887 | /* the mbox completion handler can now be run */ |
3539 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | 4888 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); |
3540 | job->job_done(job); | 4889 | job->job_done(job); |
4890 | if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_PORT) | ||
4891 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_ABTS; | ||
3541 | break; | 4892 | break; |
3542 | case TYPE_MENLO: | 4893 | case TYPE_MENLO: |
3543 | menlo = &dd_data->context_un.menlo; | 4894 | menlo = &dd_data->context_un.menlo; |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h index b542aca6f5ae..c8c2b47ea886 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.h +++ b/drivers/scsi/lpfc/lpfc_bsg.h | |||
@@ -24,15 +24,17 @@ | |||
24 | * These are the vendor unique structures passed in using the bsg | 24 | * These are the vendor unique structures passed in using the bsg |
25 | * FC_BSG_HST_VENDOR message code type. | 25 | * FC_BSG_HST_VENDOR message code type. |
26 | */ | 26 | */ |
27 | #define LPFC_BSG_VENDOR_SET_CT_EVENT 1 | 27 | #define LPFC_BSG_VENDOR_SET_CT_EVENT 1 |
28 | #define LPFC_BSG_VENDOR_GET_CT_EVENT 2 | 28 | #define LPFC_BSG_VENDOR_GET_CT_EVENT 2 |
29 | #define LPFC_BSG_VENDOR_SEND_MGMT_RESP 3 | 29 | #define LPFC_BSG_VENDOR_SEND_MGMT_RESP 3 |
30 | #define LPFC_BSG_VENDOR_DIAG_MODE 4 | 30 | #define LPFC_BSG_VENDOR_DIAG_MODE 4 |
31 | #define LPFC_BSG_VENDOR_DIAG_TEST 5 | 31 | #define LPFC_BSG_VENDOR_DIAG_RUN_LOOPBACK 5 |
32 | #define LPFC_BSG_VENDOR_GET_MGMT_REV 6 | 32 | #define LPFC_BSG_VENDOR_GET_MGMT_REV 6 |
33 | #define LPFC_BSG_VENDOR_MBOX 7 | 33 | #define LPFC_BSG_VENDOR_MBOX 7 |
34 | #define LPFC_BSG_VENDOR_MENLO_CMD 8 | 34 | #define LPFC_BSG_VENDOR_MENLO_CMD 8 |
35 | #define LPFC_BSG_VENDOR_MENLO_DATA 9 | 35 | #define LPFC_BSG_VENDOR_MENLO_DATA 9 |
36 | #define LPFC_BSG_VENDOR_DIAG_MODE_END 10 | ||
37 | #define LPFC_BSG_VENDOR_LINK_DIAG_TEST 11 | ||
36 | 38 | ||
37 | struct set_ct_event { | 39 | struct set_ct_event { |
38 | uint32_t command; | 40 | uint32_t command; |
@@ -67,10 +69,25 @@ struct diag_mode_set { | |||
67 | uint32_t timeout; | 69 | uint32_t timeout; |
68 | }; | 70 | }; |
69 | 71 | ||
72 | struct sli4_link_diag { | ||
73 | uint32_t command; | ||
74 | uint32_t timeout; | ||
75 | uint32_t test_id; | ||
76 | uint32_t loops; | ||
77 | uint32_t test_version; | ||
78 | uint32_t error_action; | ||
79 | }; | ||
80 | |||
70 | struct diag_mode_test { | 81 | struct diag_mode_test { |
71 | uint32_t command; | 82 | uint32_t command; |
72 | }; | 83 | }; |
73 | 84 | ||
85 | struct diag_status { | ||
86 | uint32_t mbox_status; | ||
87 | uint32_t shdr_status; | ||
88 | uint32_t shdr_add_status; | ||
89 | }; | ||
90 | |||
74 | #define LPFC_WWNN_TYPE 0 | 91 | #define LPFC_WWNN_TYPE 0 |
75 | #define LPFC_WWPN_TYPE 1 | 92 | #define LPFC_WWPN_TYPE 1 |
76 | 93 | ||
@@ -92,11 +109,15 @@ struct get_mgmt_rev_reply { | |||
92 | }; | 109 | }; |
93 | 110 | ||
94 | #define BSG_MBOX_SIZE 4096 /* mailbox command plus extended data */ | 111 | #define BSG_MBOX_SIZE 4096 /* mailbox command plus extended data */ |
112 | |||
113 | /* BSG mailbox request header */ | ||
95 | struct dfc_mbox_req { | 114 | struct dfc_mbox_req { |
96 | uint32_t command; | 115 | uint32_t command; |
97 | uint32_t mbOffset; | 116 | uint32_t mbOffset; |
98 | uint32_t inExtWLen; | 117 | uint32_t inExtWLen; |
99 | uint32_t outExtWLen; | 118 | uint32_t outExtWLen; |
119 | uint32_t extMboxTag; | ||
120 | uint32_t extSeqNum; | ||
100 | }; | 121 | }; |
101 | 122 | ||
102 | /* Used for menlo command or menlo data. The xri is only used for menlo data */ | 123 | /* Used for menlo command or menlo data. The xri is only used for menlo data */ |
@@ -171,7 +192,7 @@ struct lpfc_sli_config_mse { | |||
171 | #define lpfc_mbox_sli_config_mse_len_WORD buf_len | 192 | #define lpfc_mbox_sli_config_mse_len_WORD buf_len |
172 | }; | 193 | }; |
173 | 194 | ||
174 | struct lpfc_sli_config_subcmd_hbd { | 195 | struct lpfc_sli_config_hbd { |
175 | uint32_t buf_len; | 196 | uint32_t buf_len; |
176 | #define lpfc_mbox_sli_config_ecmn_hbd_len_SHIFT 0 | 197 | #define lpfc_mbox_sli_config_ecmn_hbd_len_SHIFT 0 |
177 | #define lpfc_mbox_sli_config_ecmn_hbd_len_MASK 0xffffff | 198 | #define lpfc_mbox_sli_config_ecmn_hbd_len_MASK 0xffffff |
@@ -194,21 +215,39 @@ struct lpfc_sli_config_hdr { | |||
194 | uint32_t reserved5; | 215 | uint32_t reserved5; |
195 | }; | 216 | }; |
196 | 217 | ||
197 | struct lpfc_sli_config_generic { | 218 | struct lpfc_sli_config_emb0_subsys { |
198 | struct lpfc_sli_config_hdr sli_config_hdr; | 219 | struct lpfc_sli_config_hdr sli_config_hdr; |
199 | #define LPFC_MBX_SLI_CONFIG_MAX_MSE 19 | 220 | #define LPFC_MBX_SLI_CONFIG_MAX_MSE 19 |
200 | struct lpfc_sli_config_mse mse[LPFC_MBX_SLI_CONFIG_MAX_MSE]; | 221 | struct lpfc_sli_config_mse mse[LPFC_MBX_SLI_CONFIG_MAX_MSE]; |
222 | uint32_t padding; | ||
223 | uint32_t word64; | ||
224 | #define lpfc_emb0_subcmnd_opcode_SHIFT 0 | ||
225 | #define lpfc_emb0_subcmnd_opcode_MASK 0xff | ||
226 | #define lpfc_emb0_subcmnd_opcode_WORD word64 | ||
227 | #define lpfc_emb0_subcmnd_subsys_SHIFT 8 | ||
228 | #define lpfc_emb0_subcmnd_subsys_MASK 0xff | ||
229 | #define lpfc_emb0_subcmnd_subsys_WORD word64 | ||
230 | /* Subsystem FCOE (0x0C) OpCodes */ | ||
231 | #define SLI_CONFIG_SUBSYS_FCOE 0x0C | ||
232 | #define FCOE_OPCODE_READ_FCF 0x08 | ||
233 | #define FCOE_OPCODE_ADD_FCF 0x09 | ||
201 | }; | 234 | }; |
202 | 235 | ||
203 | struct lpfc_sli_config_subcmnd { | 236 | struct lpfc_sli_config_emb1_subsys { |
204 | struct lpfc_sli_config_hdr sli_config_hdr; | 237 | struct lpfc_sli_config_hdr sli_config_hdr; |
205 | uint32_t word6; | 238 | uint32_t word6; |
206 | #define lpfc_subcmnd_opcode_SHIFT 0 | 239 | #define lpfc_emb1_subcmnd_opcode_SHIFT 0 |
207 | #define lpfc_subcmnd_opcode_MASK 0xff | 240 | #define lpfc_emb1_subcmnd_opcode_MASK 0xff |
208 | #define lpfc_subcmnd_opcode_WORD word6 | 241 | #define lpfc_emb1_subcmnd_opcode_WORD word6 |
209 | #define lpfc_subcmnd_subsys_SHIFT 8 | 242 | #define lpfc_emb1_subcmnd_subsys_SHIFT 8 |
210 | #define lpfc_subcmnd_subsys_MASK 0xff | 243 | #define lpfc_emb1_subcmnd_subsys_MASK 0xff |
211 | #define lpfc_subcmnd_subsys_WORD word6 | 244 | #define lpfc_emb1_subcmnd_subsys_WORD word6 |
245 | /* Subsystem COMN (0x01) OpCodes */ | ||
246 | #define SLI_CONFIG_SUBSYS_COMN 0x01 | ||
247 | #define COMN_OPCODE_READ_OBJECT 0xAB | ||
248 | #define COMN_OPCODE_WRITE_OBJECT 0xAC | ||
249 | #define COMN_OPCODE_READ_OBJECT_LIST 0xAD | ||
250 | #define COMN_OPCODE_DELETE_OBJECT 0xAE | ||
212 | uint32_t timeout; | 251 | uint32_t timeout; |
213 | uint32_t request_length; | 252 | uint32_t request_length; |
214 | uint32_t word9; | 253 | uint32_t word9; |
@@ -222,8 +261,8 @@ struct lpfc_sli_config_subcmnd { | |||
222 | uint32_t rd_offset; | 261 | uint32_t rd_offset; |
223 | uint32_t obj_name[26]; | 262 | uint32_t obj_name[26]; |
224 | uint32_t hbd_count; | 263 | uint32_t hbd_count; |
225 | #define LPFC_MBX_SLI_CONFIG_MAX_HBD 10 | 264 | #define LPFC_MBX_SLI_CONFIG_MAX_HBD 8 |
226 | struct lpfc_sli_config_subcmd_hbd hbd[LPFC_MBX_SLI_CONFIG_MAX_HBD]; | 265 | struct lpfc_sli_config_hbd hbd[LPFC_MBX_SLI_CONFIG_MAX_HBD]; |
227 | }; | 266 | }; |
228 | 267 | ||
229 | struct lpfc_sli_config_mbox { | 268 | struct lpfc_sli_config_mbox { |
@@ -235,7 +274,11 @@ struct lpfc_sli_config_mbox { | |||
235 | #define lpfc_mqe_command_MASK 0x000000FF | 274 | #define lpfc_mqe_command_MASK 0x000000FF |
236 | #define lpfc_mqe_command_WORD word0 | 275 | #define lpfc_mqe_command_WORD word0 |
237 | union { | 276 | union { |
238 | struct lpfc_sli_config_generic sli_config_generic; | 277 | struct lpfc_sli_config_emb0_subsys sli_config_emb0_subsys; |
239 | struct lpfc_sli_config_subcmnd sli_config_subcmnd; | 278 | struct lpfc_sli_config_emb1_subsys sli_config_emb1_subsys; |
240 | } un; | 279 | } un; |
241 | }; | 280 | }; |
281 | |||
282 | /* driver only */ | ||
283 | #define SLI_CONFIG_NOT_HANDLED 0 | ||
284 | #define SLI_CONFIG_HANDLED 1 | ||
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index f0b332f4eedb..fc20c247f36b 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -55,6 +55,8 @@ void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *); | |||
55 | void lpfc_supported_pages(struct lpfcMboxq *); | 55 | void lpfc_supported_pages(struct lpfcMboxq *); |
56 | void lpfc_pc_sli4_params(struct lpfcMboxq *); | 56 | void lpfc_pc_sli4_params(struct lpfcMboxq *); |
57 | int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *); | 57 | int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *); |
58 | int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *, | ||
59 | uint16_t, uint16_t, bool); | ||
58 | int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *); | 60 | int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *); |
59 | struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); | 61 | struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); |
60 | void lpfc_cleanup_rcv_buffers(struct lpfc_vport *); | 62 | void lpfc_cleanup_rcv_buffers(struct lpfc_vport *); |
@@ -171,6 +173,7 @@ void lpfc_delayed_disc_tmo(unsigned long); | |||
171 | void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); | 173 | void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); |
172 | 174 | ||
173 | int lpfc_config_port_prep(struct lpfc_hba *); | 175 | int lpfc_config_port_prep(struct lpfc_hba *); |
176 | void lpfc_update_vport_wwn(struct lpfc_vport *vport); | ||
174 | int lpfc_config_port_post(struct lpfc_hba *); | 177 | int lpfc_config_port_post(struct lpfc_hba *); |
175 | int lpfc_hba_down_prep(struct lpfc_hba *); | 178 | int lpfc_hba_down_prep(struct lpfc_hba *); |
176 | int lpfc_hba_down_post(struct lpfc_hba *); | 179 | int lpfc_hba_down_post(struct lpfc_hba *); |
@@ -365,6 +368,10 @@ extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t, | |||
365 | uint32_t, uint32_t); | 368 | uint32_t, uint32_t); |
366 | extern struct lpfc_hbq_init *lpfc_hbq_defs[]; | 369 | extern struct lpfc_hbq_init *lpfc_hbq_defs[]; |
367 | 370 | ||
371 | /* SLI4 if_type 2 externs. */ | ||
372 | int lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *); | ||
373 | int lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *); | ||
374 | |||
368 | /* externs BlockGuard */ | 375 | /* externs BlockGuard */ |
369 | extern char *_dump_buf_data; | 376 | extern char *_dump_buf_data; |
370 | extern unsigned long _dump_buf_data_order; | 377 | extern unsigned long _dump_buf_data_order; |
@@ -429,3 +436,6 @@ void lpfc_cleanup_wt_rrqs(struct lpfc_hba *); | |||
429 | void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *); | 436 | void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *); |
430 | struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, | 437 | struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, |
431 | uint32_t); | 438 | uint32_t); |
439 | int lpfc_wr_object(struct lpfc_hba *, struct list_head *, uint32_t, uint32_t *); | ||
440 | /* functions to support SR-IOV */ | ||
441 | int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int); | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index d9edfd90d7ff..779b88e1469d 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -352,6 +352,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, | |||
352 | icmd->ulpLe = 1; | 352 | icmd->ulpLe = 1; |
353 | icmd->ulpClass = CLASS3; | 353 | icmd->ulpClass = CLASS3; |
354 | icmd->ulpContext = ndlp->nlp_rpi; | 354 | icmd->ulpContext = ndlp->nlp_rpi; |
355 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
356 | icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; | ||
355 | 357 | ||
356 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | 358 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { |
357 | /* For GEN_REQUEST64_CR, use the RPI */ | 359 | /* For GEN_REQUEST64_CR, use the RPI */ |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index c93fca058603..ffe82d169b40 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -1665,7 +1665,8 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, | |||
1665 | /* Get fast-path complete queue information */ | 1665 | /* Get fast-path complete queue information */ |
1666 | len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, | 1666 | len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, |
1667 | "Fast-path FCP CQ information:\n"); | 1667 | "Fast-path FCP CQ information:\n"); |
1668 | for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) { | 1668 | fcp_qidx = 0; |
1669 | do { | ||
1669 | len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, | 1670 | len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, |
1670 | "Associated EQID[%02d]:\n", | 1671 | "Associated EQID[%02d]:\n", |
1671 | phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid); | 1672 | phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid); |
@@ -1678,7 +1679,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, | |||
1678 | phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size, | 1679 | phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size, |
1679 | phba->sli4_hba.fcp_cq[fcp_qidx]->host_index, | 1680 | phba->sli4_hba.fcp_cq[fcp_qidx]->host_index, |
1680 | phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index); | 1681 | phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index); |
1681 | } | 1682 | } while (++fcp_qidx < phba->cfg_fcp_eq_count); |
1682 | len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n"); | 1683 | len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n"); |
1683 | 1684 | ||
1684 | /* Get mailbox queue information */ | 1685 | /* Get mailbox queue information */ |
@@ -2012,7 +2013,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, | |||
2012 | goto pass_check; | 2013 | goto pass_check; |
2013 | } | 2014 | } |
2014 | /* FCP complete queue */ | 2015 | /* FCP complete queue */ |
2015 | for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) { | 2016 | qidx = 0; |
2017 | do { | ||
2016 | if (phba->sli4_hba.fcp_cq[qidx]->queue_id == queid) { | 2018 | if (phba->sli4_hba.fcp_cq[qidx]->queue_id == queid) { |
2017 | /* Sanity check */ | 2019 | /* Sanity check */ |
2018 | rc = lpfc_idiag_que_param_check( | 2020 | rc = lpfc_idiag_que_param_check( |
@@ -2024,7 +2026,7 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, | |||
2024 | phba->sli4_hba.fcp_cq[qidx]; | 2026 | phba->sli4_hba.fcp_cq[qidx]; |
2025 | goto pass_check; | 2027 | goto pass_check; |
2026 | } | 2028 | } |
2027 | } | 2029 | } while (++qidx < phba->cfg_fcp_eq_count); |
2028 | goto error_out; | 2030 | goto error_out; |
2029 | break; | 2031 | break; |
2030 | case LPFC_IDIAG_MQ: | 2032 | case LPFC_IDIAG_MQ: |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e2c452467c8b..32a084534f3e 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -250,7 +250,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
250 | icmd->un.elsreq64.myID = vport->fc_myDID; | 250 | icmd->un.elsreq64.myID = vport->fc_myDID; |
251 | 251 | ||
252 | /* For ELS_REQUEST64_CR, use the VPI by default */ | 252 | /* For ELS_REQUEST64_CR, use the VPI by default */ |
253 | icmd->ulpContext = vport->vpi + phba->vpi_base; | 253 | icmd->ulpContext = phba->vpi_ids[vport->vpi]; |
254 | icmd->ulpCt_h = 0; | 254 | icmd->ulpCt_h = 0; |
255 | /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ | 255 | /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ |
256 | if (elscmd == ELS_CMD_ECHO) | 256 | if (elscmd == ELS_CMD_ECHO) |
@@ -454,6 +454,7 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) | |||
454 | rc = -ENOMEM; | 454 | rc = -ENOMEM; |
455 | goto fail_free_dmabuf; | 455 | goto fail_free_dmabuf; |
456 | } | 456 | } |
457 | |||
457 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 458 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
458 | if (!mboxq) { | 459 | if (!mboxq) { |
459 | rc = -ENOMEM; | 460 | rc = -ENOMEM; |
@@ -6585,6 +6586,26 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) | |||
6585 | { | 6586 | { |
6586 | struct lpfc_vport *vport; | 6587 | struct lpfc_vport *vport; |
6587 | unsigned long flags; | 6588 | unsigned long flags; |
6589 | int i; | ||
6590 | |||
6591 | /* The physical ports are always vpi 0 - translate is unnecessary. */ | ||
6592 | if (vpi > 0) { | ||
6593 | /* | ||
6594 | * Translate the physical vpi to the logical vpi. The | ||
6595 | * vport stores the logical vpi. | ||
6596 | */ | ||
6597 | for (i = 0; i < phba->max_vpi; i++) { | ||
6598 | if (vpi == phba->vpi_ids[i]) | ||
6599 | break; | ||
6600 | } | ||
6601 | |||
6602 | if (i >= phba->max_vpi) { | ||
6603 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
6604 | "2936 Could not find Vport mapped " | ||
6605 | "to vpi %d\n", vpi); | ||
6606 | return NULL; | ||
6607 | } | ||
6608 | } | ||
6588 | 6609 | ||
6589 | spin_lock_irqsave(&phba->hbalock, flags); | 6610 | spin_lock_irqsave(&phba->hbalock, flags); |
6590 | list_for_each_entry(vport, &phba->port_list, listentry) { | 6611 | list_for_each_entry(vport, &phba->port_list, listentry) { |
@@ -6641,8 +6662,9 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6641 | vport = phba->pport; | 6662 | vport = phba->pport; |
6642 | else | 6663 | else |
6643 | vport = lpfc_find_vport_by_vpid(phba, | 6664 | vport = lpfc_find_vport_by_vpid(phba, |
6644 | icmd->unsli3.rcvsli3.vpi - phba->vpi_base); | 6665 | icmd->unsli3.rcvsli3.vpi); |
6645 | } | 6666 | } |
6667 | |||
6646 | /* If there are no BDEs associated | 6668 | /* If there are no BDEs associated |
6647 | * with this IOCB, there is nothing to do. | 6669 | * with this IOCB, there is nothing to do. |
6648 | */ | 6670 | */ |
@@ -7222,7 +7244,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
7222 | elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1; | 7244 | elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1; |
7223 | elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ; | 7245 | elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ; |
7224 | /* Set the ulpContext to the vpi */ | 7246 | /* Set the ulpContext to the vpi */ |
7225 | elsiocb->iocb.ulpContext = vport->vpi + phba->vpi_base; | 7247 | elsiocb->iocb.ulpContext = phba->vpi_ids[vport->vpi]; |
7226 | } else { | 7248 | } else { |
7227 | /* For FDISC, Let FDISC rsp set the NPortID for this VPI */ | 7249 | /* For FDISC, Let FDISC rsp set the NPortID for this VPI */ |
7228 | icmd->ulpCt_h = 1; | 7250 | icmd->ulpCt_h = 1; |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 7a35df5e2038..18d0dbfda2bc 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -881,7 +881,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
881 | /* Clean up any firmware default rpi's */ | 881 | /* Clean up any firmware default rpi's */ |
882 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 882 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
883 | if (mb) { | 883 | if (mb) { |
884 | lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb); | 884 | lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb); |
885 | mb->vport = vport; | 885 | mb->vport = vport; |
886 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 886 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
887 | if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT) | 887 | if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT) |
@@ -2690,16 +2690,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2690 | 2690 | ||
2691 | memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt, | 2691 | memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt, |
2692 | sizeof (struct serv_parm)); | 2692 | sizeof (struct serv_parm)); |
2693 | if (phba->cfg_soft_wwnn) | 2693 | lpfc_update_vport_wwn(vport); |
2694 | u64_to_wwn(phba->cfg_soft_wwnn, | ||
2695 | vport->fc_sparam.nodeName.u.wwn); | ||
2696 | if (phba->cfg_soft_wwpn) | ||
2697 | u64_to_wwn(phba->cfg_soft_wwpn, | ||
2698 | vport->fc_sparam.portName.u.wwn); | ||
2699 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, | ||
2700 | sizeof(vport->fc_nodename)); | ||
2701 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, | ||
2702 | sizeof(vport->fc_portname)); | ||
2703 | if (vport->port_type == LPFC_PHYSICAL_PORT) { | 2694 | if (vport->port_type == LPFC_PHYSICAL_PORT) { |
2704 | memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn)); | 2695 | memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn)); |
2705 | memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn)); | 2696 | memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn)); |
@@ -3430,7 +3421,8 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3430 | return; | 3421 | return; |
3431 | } | 3422 | } |
3432 | 3423 | ||
3433 | ndlp->nlp_rpi = mb->un.varWords[0]; | 3424 | if (phba->sli_rev < LPFC_SLI_REV4) |
3425 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
3434 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; | 3426 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; |
3435 | ndlp->nlp_type |= NLP_FABRIC; | 3427 | ndlp->nlp_type |= NLP_FABRIC; |
3436 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 3428 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
@@ -3504,7 +3496,8 @@ out: | |||
3504 | return; | 3496 | return; |
3505 | } | 3497 | } |
3506 | 3498 | ||
3507 | ndlp->nlp_rpi = mb->un.varWords[0]; | 3499 | if (phba->sli_rev < LPFC_SLI_REV4) |
3500 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
3508 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; | 3501 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; |
3509 | ndlp->nlp_type |= NLP_FABRIC; | 3502 | ndlp->nlp_type |= NLP_FABRIC; |
3510 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 3503 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
@@ -3591,7 +3584,6 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
3591 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) | 3584 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) |
3592 | rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; | 3585 | rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; |
3593 | 3586 | ||
3594 | |||
3595 | if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) | 3587 | if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) |
3596 | fc_remote_port_rolechg(rport, rport_ids.roles); | 3588 | fc_remote_port_rolechg(rport, rport_ids.roles); |
3597 | 3589 | ||
@@ -4106,11 +4098,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4106 | struct lpfc_hba *phba = vport->phba; | 4098 | struct lpfc_hba *phba = vport->phba; |
4107 | LPFC_MBOXQ_t *mbox; | 4099 | LPFC_MBOXQ_t *mbox; |
4108 | int rc; | 4100 | int rc; |
4101 | uint16_t rpi; | ||
4109 | 4102 | ||
4110 | if (ndlp->nlp_flag & NLP_RPI_REGISTERED) { | 4103 | if (ndlp->nlp_flag & NLP_RPI_REGISTERED) { |
4111 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4104 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4112 | if (mbox) { | 4105 | if (mbox) { |
4113 | lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox); | 4106 | /* SLI4 ports require the physical rpi value. */ |
4107 | rpi = ndlp->nlp_rpi; | ||
4108 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
4109 | rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; | ||
4110 | lpfc_unreg_login(phba, vport->vpi, rpi, mbox); | ||
4114 | mbox->vport = vport; | 4111 | mbox->vport = vport; |
4115 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4112 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
4116 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4113 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
@@ -4179,7 +4176,8 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport) | |||
4179 | 4176 | ||
4180 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4177 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4181 | if (mbox) { | 4178 | if (mbox) { |
4182 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); | 4179 | lpfc_unreg_login(phba, vport->vpi, LPFC_UNREG_ALL_RPIS_VPORT, |
4180 | mbox); | ||
4183 | mbox->vport = vport; | 4181 | mbox->vport = vport; |
4184 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4182 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
4185 | mbox->context1 = NULL; | 4183 | mbox->context1 = NULL; |
@@ -4203,7 +4201,8 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) | |||
4203 | 4201 | ||
4204 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4202 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4205 | if (mbox) { | 4203 | if (mbox) { |
4206 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); | 4204 | lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS, |
4205 | mbox); | ||
4207 | mbox->vport = vport; | 4206 | mbox->vport = vport; |
4208 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4207 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
4209 | mbox->context1 = NULL; | 4208 | mbox->context1 = NULL; |
@@ -4653,10 +4652,7 @@ lpfc_disc_start(struct lpfc_vport *vport) | |||
4653 | if (num_sent) | 4652 | if (num_sent) |
4654 | return; | 4653 | return; |
4655 | 4654 | ||
4656 | /* | 4655 | /* Register the VPI for SLI3, NON-NPIV only. */ |
4657 | * For SLI3, cmpl_reg_vpi will set port_state to READY, and | ||
4658 | * continue discovery. | ||
4659 | */ | ||
4660 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 4656 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
4661 | !(vport->fc_flag & FC_PT2PT) && | 4657 | !(vport->fc_flag & FC_PT2PT) && |
4662 | !(vport->fc_flag & FC_RSCN_MODE) && | 4658 | !(vport->fc_flag & FC_RSCN_MODE) && |
@@ -4943,7 +4939,7 @@ restart_disc: | |||
4943 | if (phba->sli_rev < LPFC_SLI_REV4) { | 4939 | if (phba->sli_rev < LPFC_SLI_REV4) { |
4944 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 4940 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
4945 | lpfc_issue_reg_vpi(phba, vport); | 4941 | lpfc_issue_reg_vpi(phba, vport); |
4946 | else { /* NPIV Not enabled */ | 4942 | else { |
4947 | lpfc_issue_clear_la(phba, vport); | 4943 | lpfc_issue_clear_la(phba, vport); |
4948 | vport->port_state = LPFC_VPORT_READY; | 4944 | vport->port_state = LPFC_VPORT_READY; |
4949 | } | 4945 | } |
@@ -5069,7 +5065,8 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5069 | pmb->context1 = NULL; | 5065 | pmb->context1 = NULL; |
5070 | pmb->context2 = NULL; | 5066 | pmb->context2 = NULL; |
5071 | 5067 | ||
5072 | ndlp->nlp_rpi = mb->un.varWords[0]; | 5068 | if (phba->sli_rev < LPFC_SLI_REV4) |
5069 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
5073 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; | 5070 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; |
5074 | ndlp->nlp_type |= NLP_FABRIC; | 5071 | ndlp->nlp_type |= NLP_FABRIC; |
5075 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 5072 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
@@ -5354,6 +5351,17 @@ lpfc_fcf_inuse(struct lpfc_hba *phba) | |||
5354 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 5351 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
5355 | shost = lpfc_shost_from_vport(vports[i]); | 5352 | shost = lpfc_shost_from_vport(vports[i]); |
5356 | spin_lock_irq(shost->host_lock); | 5353 | spin_lock_irq(shost->host_lock); |
5354 | /* | ||
5355 | * IF the CVL_RCVD bit is not set then we have sent the | ||
5356 | * flogi. | ||
5357 | * If dev_loss fires while we are waiting we do not want to | ||
5358 | * unreg the fcf. | ||
5359 | */ | ||
5360 | if (!(vports[i]->fc_flag & FC_VPORT_CVL_RCVD)) { | ||
5361 | spin_unlock_irq(shost->host_lock); | ||
5362 | ret = 1; | ||
5363 | goto out; | ||
5364 | } | ||
5357 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | 5365 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { |
5358 | if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport && | 5366 | if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport && |
5359 | (ndlp->rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | 5367 | (ndlp->rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 86b6f7e6686a..9059524cf225 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -64,6 +64,8 @@ | |||
64 | #define SLI3_IOCB_CMD_SIZE 128 | 64 | #define SLI3_IOCB_CMD_SIZE 128 |
65 | #define SLI3_IOCB_RSP_SIZE 64 | 65 | #define SLI3_IOCB_RSP_SIZE 64 |
66 | 66 | ||
67 | #define LPFC_UNREG_ALL_RPIS_VPORT 0xffff | ||
68 | #define LPFC_UNREG_ALL_DFLT_RPIS 0xffffffff | ||
67 | 69 | ||
68 | /* vendor ID used in SCSI netlink calls */ | 70 | /* vendor ID used in SCSI netlink calls */ |
69 | #define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX) | 71 | #define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX) |
@@ -903,6 +905,8 @@ struct RRQ { /* Structure is in Big Endian format */ | |||
903 | #define rrq_rxid_WORD rrq_exchg | 905 | #define rrq_rxid_WORD rrq_exchg |
904 | }; | 906 | }; |
905 | 907 | ||
908 | #define LPFC_MAX_VFN_PER_PFN 255 /* Maximum VFs allowed per ARI */ | ||
909 | #define LPFC_DEF_VFN_PER_PFN 0 /* Default VFs due to platform limitation*/ | ||
906 | 910 | ||
907 | struct RTV_RSP { /* Structure is in Big Endian format */ | 911 | struct RTV_RSP { /* Structure is in Big Endian format */ |
908 | uint32_t ratov; | 912 | uint32_t ratov; |
@@ -1199,7 +1203,9 @@ typedef struct { | |||
1199 | #define PCI_DEVICE_ID_BALIUS 0xe131 | 1203 | #define PCI_DEVICE_ID_BALIUS 0xe131 |
1200 | #define PCI_DEVICE_ID_PROTEUS_PF 0xe180 | 1204 | #define PCI_DEVICE_ID_PROTEUS_PF 0xe180 |
1201 | #define PCI_DEVICE_ID_LANCER_FC 0xe200 | 1205 | #define PCI_DEVICE_ID_LANCER_FC 0xe200 |
1206 | #define PCI_DEVICE_ID_LANCER_FC_VF 0xe208 | ||
1202 | #define PCI_DEVICE_ID_LANCER_FCOE 0xe260 | 1207 | #define PCI_DEVICE_ID_LANCER_FCOE 0xe260 |
1208 | #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268 | ||
1203 | #define PCI_DEVICE_ID_SAT_SMB 0xf011 | 1209 | #define PCI_DEVICE_ID_SAT_SMB 0xf011 |
1204 | #define PCI_DEVICE_ID_SAT_MID 0xf015 | 1210 | #define PCI_DEVICE_ID_SAT_MID 0xf015 |
1205 | #define PCI_DEVICE_ID_RFLY 0xf095 | 1211 | #define PCI_DEVICE_ID_RFLY 0xf095 |
@@ -3021,7 +3027,7 @@ typedef struct { | |||
3021 | #define MAILBOX_EXT_SIZE (MAILBOX_EXT_WSIZE * sizeof(uint32_t)) | 3027 | #define MAILBOX_EXT_SIZE (MAILBOX_EXT_WSIZE * sizeof(uint32_t)) |
3022 | #define MAILBOX_HBA_EXT_OFFSET 0x100 | 3028 | #define MAILBOX_HBA_EXT_OFFSET 0x100 |
3023 | /* max mbox xmit size is a page size for sysfs IO operations */ | 3029 | /* max mbox xmit size is a page size for sysfs IO operations */ |
3024 | #define MAILBOX_MAX_XMIT_SIZE PAGE_SIZE | 3030 | #define MAILBOX_SYSFS_MAX 4096 |
3025 | 3031 | ||
3026 | typedef union { | 3032 | typedef union { |
3027 | uint32_t varWords[MAILBOX_CMD_WSIZE - 1]; /* first word is type/ | 3033 | uint32_t varWords[MAILBOX_CMD_WSIZE - 1]; /* first word is type/ |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 4dff668ebdad..11e26a26b5d1 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -170,6 +170,25 @@ struct lpfc_sli_intf { | |||
170 | #define LPFC_PCI_FUNC3 3 | 170 | #define LPFC_PCI_FUNC3 3 |
171 | #define LPFC_PCI_FUNC4 4 | 171 | #define LPFC_PCI_FUNC4 4 |
172 | 172 | ||
173 | /* SLI4 interface type-2 control register offsets */ | ||
174 | #define LPFC_CTL_PORT_SEM_OFFSET 0x400 | ||
175 | #define LPFC_CTL_PORT_STA_OFFSET 0x404 | ||
176 | #define LPFC_CTL_PORT_CTL_OFFSET 0x408 | ||
177 | #define LPFC_CTL_PORT_ER1_OFFSET 0x40C | ||
178 | #define LPFC_CTL_PORT_ER2_OFFSET 0x410 | ||
179 | #define LPFC_CTL_PDEV_CTL_OFFSET 0x414 | ||
180 | |||
181 | /* Some SLI4 interface type-2 PDEV_CTL register bits */ | ||
182 | #define LPFC_CTL_PDEV_CTL_DRST 0x00000001 | ||
183 | #define LPFC_CTL_PDEV_CTL_FRST 0x00000002 | ||
184 | #define LPFC_CTL_PDEV_CTL_DD 0x00000004 | ||
185 | #define LPFC_CTL_PDEV_CTL_LC 0x00000008 | ||
186 | #define LPFC_CTL_PDEV_CTL_FRL_ALL 0x00 | ||
187 | #define LPFC_CTL_PDEV_CTL_FRL_FC_FCOE 0x10 | ||
188 | #define LPFC_CTL_PDEV_CTL_FRL_NIC 0x20 | ||
189 | |||
190 | #define LPFC_FW_DUMP_REQUEST (LPFC_CTL_PDEV_CTL_DD | LPFC_CTL_PDEV_CTL_FRST) | ||
191 | |||
173 | /* Active interrupt test count */ | 192 | /* Active interrupt test count */ |
174 | #define LPFC_ACT_INTR_CNT 4 | 193 | #define LPFC_ACT_INTR_CNT 4 |
175 | 194 | ||
@@ -210,9 +229,26 @@ struct ulp_bde64 { | |||
210 | 229 | ||
211 | struct lpfc_sli4_flags { | 230 | struct lpfc_sli4_flags { |
212 | uint32_t word0; | 231 | uint32_t word0; |
213 | #define lpfc_fip_flag_SHIFT 0 | 232 | #define lpfc_idx_rsrc_rdy_SHIFT 0 |
214 | #define lpfc_fip_flag_MASK 0x00000001 | 233 | #define lpfc_idx_rsrc_rdy_MASK 0x00000001 |
215 | #define lpfc_fip_flag_WORD word0 | 234 | #define lpfc_idx_rsrc_rdy_WORD word0 |
235 | #define LPFC_IDX_RSRC_RDY 1 | ||
236 | #define lpfc_xri_rsrc_rdy_SHIFT 1 | ||
237 | #define lpfc_xri_rsrc_rdy_MASK 0x00000001 | ||
238 | #define lpfc_xri_rsrc_rdy_WORD word0 | ||
239 | #define LPFC_XRI_RSRC_RDY 1 | ||
240 | #define lpfc_rpi_rsrc_rdy_SHIFT 2 | ||
241 | #define lpfc_rpi_rsrc_rdy_MASK 0x00000001 | ||
242 | #define lpfc_rpi_rsrc_rdy_WORD word0 | ||
243 | #define LPFC_RPI_RSRC_RDY 1 | ||
244 | #define lpfc_vpi_rsrc_rdy_SHIFT 3 | ||
245 | #define lpfc_vpi_rsrc_rdy_MASK 0x00000001 | ||
246 | #define lpfc_vpi_rsrc_rdy_WORD word0 | ||
247 | #define LPFC_VPI_RSRC_RDY 1 | ||
248 | #define lpfc_vfi_rsrc_rdy_SHIFT 4 | ||
249 | #define lpfc_vfi_rsrc_rdy_MASK 0x00000001 | ||
250 | #define lpfc_vfi_rsrc_rdy_WORD word0 | ||
251 | #define LPFC_VFI_RSRC_RDY 1 | ||
216 | }; | 252 | }; |
217 | 253 | ||
218 | struct sli4_bls_rsp { | 254 | struct sli4_bls_rsp { |
@@ -739,6 +775,12 @@ union lpfc_sli4_cfg_shdr { | |||
739 | #define lpfc_mbox_hdr_version_SHIFT 0 | 775 | #define lpfc_mbox_hdr_version_SHIFT 0 |
740 | #define lpfc_mbox_hdr_version_MASK 0x000000FF | 776 | #define lpfc_mbox_hdr_version_MASK 0x000000FF |
741 | #define lpfc_mbox_hdr_version_WORD word9 | 777 | #define lpfc_mbox_hdr_version_WORD word9 |
778 | #define lpfc_mbox_hdr_pf_num_SHIFT 16 | ||
779 | #define lpfc_mbox_hdr_pf_num_MASK 0x000000FF | ||
780 | #define lpfc_mbox_hdr_pf_num_WORD word9 | ||
781 | #define lpfc_mbox_hdr_vh_num_SHIFT 24 | ||
782 | #define lpfc_mbox_hdr_vh_num_MASK 0x000000FF | ||
783 | #define lpfc_mbox_hdr_vh_num_WORD word9 | ||
742 | #define LPFC_Q_CREATE_VERSION_2 2 | 784 | #define LPFC_Q_CREATE_VERSION_2 2 |
743 | #define LPFC_Q_CREATE_VERSION_1 1 | 785 | #define LPFC_Q_CREATE_VERSION_1 1 |
744 | #define LPFC_Q_CREATE_VERSION_0 0 | 786 | #define LPFC_Q_CREATE_VERSION_0 0 |
@@ -766,12 +808,22 @@ union lpfc_sli4_cfg_shdr { | |||
766 | } response; | 808 | } response; |
767 | }; | 809 | }; |
768 | 810 | ||
769 | /* Mailbox structures */ | 811 | /* Mailbox Header structures. |
812 | * struct mbox_header is defined for first generation SLI4_CFG mailbox | ||
813 | * calls deployed for BE-based ports. | ||
814 | * | ||
815 | * struct sli4_mbox_header is defined for second generation SLI4 | ||
816 | * ports that don't deploy the SLI4_CFG mechanism. | ||
817 | */ | ||
770 | struct mbox_header { | 818 | struct mbox_header { |
771 | struct lpfc_sli4_cfg_mhdr cfg_mhdr; | 819 | struct lpfc_sli4_cfg_mhdr cfg_mhdr; |
772 | union lpfc_sli4_cfg_shdr cfg_shdr; | 820 | union lpfc_sli4_cfg_shdr cfg_shdr; |
773 | }; | 821 | }; |
774 | 822 | ||
823 | #define LPFC_EXTENT_LOCAL 0 | ||
824 | #define LPFC_TIMEOUT_DEFAULT 0 | ||
825 | #define LPFC_EXTENT_VERSION_DEFAULT 0 | ||
826 | |||
775 | /* Subsystem Definitions */ | 827 | /* Subsystem Definitions */ |
776 | #define LPFC_MBOX_SUBSYSTEM_COMMON 0x1 | 828 | #define LPFC_MBOX_SUBSYSTEM_COMMON 0x1 |
777 | #define LPFC_MBOX_SUBSYSTEM_FCOE 0xC | 829 | #define LPFC_MBOX_SUBSYSTEM_FCOE 0xC |
@@ -794,6 +846,13 @@ struct mbox_header { | |||
794 | #define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A | 846 | #define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A |
795 | #define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D | 847 | #define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D |
796 | #define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A | 848 | #define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A |
849 | #define LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO 0x9A | ||
850 | #define LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT 0x9B | ||
851 | #define LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT 0x9C | ||
852 | #define LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT 0x9D | ||
853 | #define LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG 0xA0 | ||
854 | #define LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG 0xA4 | ||
855 | #define LPFC_MBOX_OPCODE_WRITE_OBJECT 0xAC | ||
797 | #define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5 | 856 | #define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5 |
798 | 857 | ||
799 | /* FCoE Opcodes */ | 858 | /* FCoE Opcodes */ |
@@ -808,6 +867,8 @@ struct mbox_header { | |||
808 | #define LPFC_MBOX_OPCODE_FCOE_DELETE_FCF 0x0A | 867 | #define LPFC_MBOX_OPCODE_FCOE_DELETE_FCF 0x0A |
809 | #define LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE 0x0B | 868 | #define LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE 0x0B |
810 | #define LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF 0x10 | 869 | #define LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF 0x10 |
870 | #define LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE 0x22 | ||
871 | #define LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_LOOPBACK 0x23 | ||
811 | 872 | ||
812 | /* Mailbox command structures */ | 873 | /* Mailbox command structures */ |
813 | struct eq_context { | 874 | struct eq_context { |
@@ -1210,6 +1271,187 @@ struct lpfc_mbx_mq_destroy { | |||
1210 | } u; | 1271 | } u; |
1211 | }; | 1272 | }; |
1212 | 1273 | ||
1274 | /* Start Gen 2 SLI4 Mailbox definitions: */ | ||
1275 | |||
1276 | /* Define allocate-ready Gen 2 SLI4 FCoE Resource Extent Types. */ | ||
1277 | #define LPFC_RSC_TYPE_FCOE_VFI 0x20 | ||
1278 | #define LPFC_RSC_TYPE_FCOE_VPI 0x21 | ||
1279 | #define LPFC_RSC_TYPE_FCOE_RPI 0x22 | ||
1280 | #define LPFC_RSC_TYPE_FCOE_XRI 0x23 | ||
1281 | |||
1282 | struct lpfc_mbx_get_rsrc_extent_info { | ||
1283 | struct mbox_header header; | ||
1284 | union { | ||
1285 | struct { | ||
1286 | uint32_t word4; | ||
1287 | #define lpfc_mbx_get_rsrc_extent_info_type_SHIFT 0 | ||
1288 | #define lpfc_mbx_get_rsrc_extent_info_type_MASK 0x0000FFFF | ||
1289 | #define lpfc_mbx_get_rsrc_extent_info_type_WORD word4 | ||
1290 | } req; | ||
1291 | struct { | ||
1292 | uint32_t word4; | ||
1293 | #define lpfc_mbx_get_rsrc_extent_info_cnt_SHIFT 0 | ||
1294 | #define lpfc_mbx_get_rsrc_extent_info_cnt_MASK 0x0000FFFF | ||
1295 | #define lpfc_mbx_get_rsrc_extent_info_cnt_WORD word4 | ||
1296 | #define lpfc_mbx_get_rsrc_extent_info_size_SHIFT 16 | ||
1297 | #define lpfc_mbx_get_rsrc_extent_info_size_MASK 0x0000FFFF | ||
1298 | #define lpfc_mbx_get_rsrc_extent_info_size_WORD word4 | ||
1299 | } rsp; | ||
1300 | } u; | ||
1301 | }; | ||
1302 | |||
1303 | struct lpfc_id_range { | ||
1304 | uint32_t word5; | ||
1305 | #define lpfc_mbx_rsrc_id_word4_0_SHIFT 0 | ||
1306 | #define lpfc_mbx_rsrc_id_word4_0_MASK 0x0000FFFF | ||
1307 | #define lpfc_mbx_rsrc_id_word4_0_WORD word5 | ||
1308 | #define lpfc_mbx_rsrc_id_word4_1_SHIFT 16 | ||
1309 | #define lpfc_mbx_rsrc_id_word4_1_MASK 0x0000FFFF | ||
1310 | #define lpfc_mbx_rsrc_id_word4_1_WORD word5 | ||
1311 | }; | ||
1312 | |||
1313 | struct lpfc_mbx_set_link_diag_state { | ||
1314 | struct mbox_header header; | ||
1315 | union { | ||
1316 | struct { | ||
1317 | uint32_t word0; | ||
1318 | #define lpfc_mbx_set_diag_state_diag_SHIFT 0 | ||
1319 | #define lpfc_mbx_set_diag_state_diag_MASK 0x00000001 | ||
1320 | #define lpfc_mbx_set_diag_state_diag_WORD word0 | ||
1321 | #define lpfc_mbx_set_diag_state_link_num_SHIFT 16 | ||
1322 | #define lpfc_mbx_set_diag_state_link_num_MASK 0x0000003F | ||
1323 | #define lpfc_mbx_set_diag_state_link_num_WORD word0 | ||
1324 | #define lpfc_mbx_set_diag_state_link_type_SHIFT 22 | ||
1325 | #define lpfc_mbx_set_diag_state_link_type_MASK 0x00000003 | ||
1326 | #define lpfc_mbx_set_diag_state_link_type_WORD word0 | ||
1327 | } req; | ||
1328 | struct { | ||
1329 | uint32_t word0; | ||
1330 | } rsp; | ||
1331 | } u; | ||
1332 | }; | ||
1333 | |||
1334 | struct lpfc_mbx_set_link_diag_loopback { | ||
1335 | struct mbox_header header; | ||
1336 | union { | ||
1337 | struct { | ||
1338 | uint32_t word0; | ||
1339 | #define lpfc_mbx_set_diag_lpbk_type_SHIFT 0 | ||
1340 | #define lpfc_mbx_set_diag_lpbk_type_MASK 0x00000001 | ||
1341 | #define lpfc_mbx_set_diag_lpbk_type_WORD word0 | ||
1342 | #define LPFC_DIAG_LOOPBACK_TYPE_DISABLE 0x0 | ||
1343 | #define LPFC_DIAG_LOOPBACK_TYPE_INTERNAL 0x1 | ||
1344 | #define LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL 0x2 | ||
1345 | #define lpfc_mbx_set_diag_lpbk_link_num_SHIFT 16 | ||
1346 | #define lpfc_mbx_set_diag_lpbk_link_num_MASK 0x0000003F | ||
1347 | #define lpfc_mbx_set_diag_lpbk_link_num_WORD word0 | ||
1348 | #define lpfc_mbx_set_diag_lpbk_link_type_SHIFT 22 | ||
1349 | #define lpfc_mbx_set_diag_lpbk_link_type_MASK 0x00000003 | ||
1350 | #define lpfc_mbx_set_diag_lpbk_link_type_WORD word0 | ||
1351 | } req; | ||
1352 | struct { | ||
1353 | uint32_t word0; | ||
1354 | } rsp; | ||
1355 | } u; | ||
1356 | }; | ||
1357 | |||
1358 | struct lpfc_mbx_run_link_diag_test { | ||
1359 | struct mbox_header header; | ||
1360 | union { | ||
1361 | struct { | ||
1362 | uint32_t word0; | ||
1363 | #define lpfc_mbx_run_diag_test_link_num_SHIFT 16 | ||
1364 | #define lpfc_mbx_run_diag_test_link_num_MASK 0x0000003F | ||
1365 | #define lpfc_mbx_run_diag_test_link_num_WORD word0 | ||
1366 | #define lpfc_mbx_run_diag_test_link_type_SHIFT 22 | ||
1367 | #define lpfc_mbx_run_diag_test_link_type_MASK 0x00000003 | ||
1368 | #define lpfc_mbx_run_diag_test_link_type_WORD word0 | ||
1369 | uint32_t word1; | ||
1370 | #define lpfc_mbx_run_diag_test_test_id_SHIFT 0 | ||
1371 | #define lpfc_mbx_run_diag_test_test_id_MASK 0x0000FFFF | ||
1372 | #define lpfc_mbx_run_diag_test_test_id_WORD word1 | ||
1373 | #define lpfc_mbx_run_diag_test_loops_SHIFT 16 | ||
1374 | #define lpfc_mbx_run_diag_test_loops_MASK 0x0000FFFF | ||
1375 | #define lpfc_mbx_run_diag_test_loops_WORD word1 | ||
1376 | uint32_t word2; | ||
1377 | #define lpfc_mbx_run_diag_test_test_ver_SHIFT 0 | ||
1378 | #define lpfc_mbx_run_diag_test_test_ver_MASK 0x0000FFFF | ||
1379 | #define lpfc_mbx_run_diag_test_test_ver_WORD word2 | ||
1380 | #define lpfc_mbx_run_diag_test_err_act_SHIFT 16 | ||
1381 | #define lpfc_mbx_run_diag_test_err_act_MASK 0x000000FF | ||
1382 | #define lpfc_mbx_run_diag_test_err_act_WORD word2 | ||
1383 | } req; | ||
1384 | struct { | ||
1385 | uint32_t word0; | ||
1386 | } rsp; | ||
1387 | } u; | ||
1388 | }; | ||
1389 | |||
1390 | /* | ||
1391 | * struct lpfc_mbx_alloc_rsrc_extents: | ||
1392 | * A mbox is generically 256 bytes long. An SLI4_CONFIG mailbox requires | ||
1393 | * 6 words of header + 4 words of shared subcommand header + | ||
1394 | * 1 words of Extent-Opcode-specific header = 11 words or 44 bytes total. | ||
1395 | * | ||
1396 | * An embedded version of SLI4_CONFIG therefore has 256 - 44 = 212 bytes | ||
1397 | * for extents payload. | ||
1398 | * | ||
1399 | * 212/2 (bytes per extent) = 106 extents. | ||
1400 | * 106/2 (extents per word) = 53 words. | ||
1401 | * lpfc_id_range id is statically size to 53. | ||
1402 | * | ||
1403 | * This mailbox definition is used for ALLOC or GET_ALLOCATED | ||
1404 | * extent ranges. For ALLOC, the type and cnt are required. | ||
1405 | * For GET_ALLOCATED, only the type is required. | ||
1406 | */ | ||
1407 | struct lpfc_mbx_alloc_rsrc_extents { | ||
1408 | struct mbox_header header; | ||
1409 | union { | ||
1410 | struct { | ||
1411 | uint32_t word4; | ||
1412 | #define lpfc_mbx_alloc_rsrc_extents_type_SHIFT 0 | ||
1413 | #define lpfc_mbx_alloc_rsrc_extents_type_MASK 0x0000FFFF | ||
1414 | #define lpfc_mbx_alloc_rsrc_extents_type_WORD word4 | ||
1415 | #define lpfc_mbx_alloc_rsrc_extents_cnt_SHIFT 16 | ||
1416 | #define lpfc_mbx_alloc_rsrc_extents_cnt_MASK 0x0000FFFF | ||
1417 | #define lpfc_mbx_alloc_rsrc_extents_cnt_WORD word4 | ||
1418 | } req; | ||
1419 | struct { | ||
1420 | uint32_t word4; | ||
1421 | #define lpfc_mbx_rsrc_cnt_SHIFT 0 | ||
1422 | #define lpfc_mbx_rsrc_cnt_MASK 0x0000FFFF | ||
1423 | #define lpfc_mbx_rsrc_cnt_WORD word4 | ||
1424 | struct lpfc_id_range id[53]; | ||
1425 | } rsp; | ||
1426 | } u; | ||
1427 | }; | ||
1428 | |||
1429 | /* | ||
1430 | * This is the non-embedded version of ALLOC or GET RSRC_EXTENTS. Word4 in this | ||
1431 | * structure shares the same SHIFT/MASK/WORD defines provided in the | ||
1432 | * mbx_alloc_rsrc_extents and mbx_get_alloc_rsrc_extents, word4, provided in | ||
1433 | * the structures defined above. This non-embedded structure provides for the | ||
1434 | * maximum number of extents supported by the port. | ||
1435 | */ | ||
1436 | struct lpfc_mbx_nembed_rsrc_extent { | ||
1437 | union lpfc_sli4_cfg_shdr cfg_shdr; | ||
1438 | uint32_t word4; | ||
1439 | struct lpfc_id_range id; | ||
1440 | }; | ||
1441 | |||
1442 | struct lpfc_mbx_dealloc_rsrc_extents { | ||
1443 | struct mbox_header header; | ||
1444 | struct { | ||
1445 | uint32_t word4; | ||
1446 | #define lpfc_mbx_dealloc_rsrc_extents_type_SHIFT 0 | ||
1447 | #define lpfc_mbx_dealloc_rsrc_extents_type_MASK 0x0000FFFF | ||
1448 | #define lpfc_mbx_dealloc_rsrc_extents_type_WORD word4 | ||
1449 | } req; | ||
1450 | |||
1451 | }; | ||
1452 | |||
1453 | /* Start SLI4 FCoE specific mbox structures. */ | ||
1454 | |||
1213 | struct lpfc_mbx_post_hdr_tmpl { | 1455 | struct lpfc_mbx_post_hdr_tmpl { |
1214 | struct mbox_header header; | 1456 | struct mbox_header header; |
1215 | uint32_t word10; | 1457 | uint32_t word10; |
@@ -1229,7 +1471,7 @@ struct sli4_sge { /* SLI-4 */ | |||
1229 | 1471 | ||
1230 | uint32_t word2; | 1472 | uint32_t word2; |
1231 | #define lpfc_sli4_sge_offset_SHIFT 0 /* Offset of buffer - Not used*/ | 1473 | #define lpfc_sli4_sge_offset_SHIFT 0 /* Offset of buffer - Not used*/ |
1232 | #define lpfc_sli4_sge_offset_MASK 0x00FFFFFF | 1474 | #define lpfc_sli4_sge_offset_MASK 0x1FFFFFFF |
1233 | #define lpfc_sli4_sge_offset_WORD word2 | 1475 | #define lpfc_sli4_sge_offset_WORD word2 |
1234 | #define lpfc_sli4_sge_last_SHIFT 31 /* Last SEG in the SGL sets | 1476 | #define lpfc_sli4_sge_last_SHIFT 31 /* Last SEG in the SGL sets |
1235 | this flag !! */ | 1477 | this flag !! */ |
@@ -1773,61 +2015,31 @@ struct lpfc_mbx_read_rev { | |||
1773 | 2015 | ||
1774 | struct lpfc_mbx_read_config { | 2016 | struct lpfc_mbx_read_config { |
1775 | uint32_t word1; | 2017 | uint32_t word1; |
1776 | #define lpfc_mbx_rd_conf_max_bbc_SHIFT 0 | 2018 | #define lpfc_mbx_rd_conf_extnts_inuse_SHIFT 31 |
1777 | #define lpfc_mbx_rd_conf_max_bbc_MASK 0x000000FF | 2019 | #define lpfc_mbx_rd_conf_extnts_inuse_MASK 0x00000001 |
1778 | #define lpfc_mbx_rd_conf_max_bbc_WORD word1 | 2020 | #define lpfc_mbx_rd_conf_extnts_inuse_WORD word1 |
1779 | #define lpfc_mbx_rd_conf_init_bbc_SHIFT 8 | ||
1780 | #define lpfc_mbx_rd_conf_init_bbc_MASK 0x000000FF | ||
1781 | #define lpfc_mbx_rd_conf_init_bbc_WORD word1 | ||
1782 | uint32_t word2; | 2021 | uint32_t word2; |
1783 | #define lpfc_mbx_rd_conf_nport_did_SHIFT 0 | ||
1784 | #define lpfc_mbx_rd_conf_nport_did_MASK 0x00FFFFFF | ||
1785 | #define lpfc_mbx_rd_conf_nport_did_WORD word2 | ||
1786 | #define lpfc_mbx_rd_conf_topology_SHIFT 24 | 2022 | #define lpfc_mbx_rd_conf_topology_SHIFT 24 |
1787 | #define lpfc_mbx_rd_conf_topology_MASK 0x000000FF | 2023 | #define lpfc_mbx_rd_conf_topology_MASK 0x000000FF |
1788 | #define lpfc_mbx_rd_conf_topology_WORD word2 | 2024 | #define lpfc_mbx_rd_conf_topology_WORD word2 |
1789 | uint32_t word3; | 2025 | uint32_t rsvd_3; |
1790 | #define lpfc_mbx_rd_conf_ao_SHIFT 0 | ||
1791 | #define lpfc_mbx_rd_conf_ao_MASK 0x00000001 | ||
1792 | #define lpfc_mbx_rd_conf_ao_WORD word3 | ||
1793 | #define lpfc_mbx_rd_conf_bb_scn_SHIFT 8 | ||
1794 | #define lpfc_mbx_rd_conf_bb_scn_MASK 0x0000000F | ||
1795 | #define lpfc_mbx_rd_conf_bb_scn_WORD word3 | ||
1796 | #define lpfc_mbx_rd_conf_cbb_scn_SHIFT 12 | ||
1797 | #define lpfc_mbx_rd_conf_cbb_scn_MASK 0x0000000F | ||
1798 | #define lpfc_mbx_rd_conf_cbb_scn_WORD word3 | ||
1799 | #define lpfc_mbx_rd_conf_mc_SHIFT 29 | ||
1800 | #define lpfc_mbx_rd_conf_mc_MASK 0x00000001 | ||
1801 | #define lpfc_mbx_rd_conf_mc_WORD word3 | ||
1802 | uint32_t word4; | 2026 | uint32_t word4; |
1803 | #define lpfc_mbx_rd_conf_e_d_tov_SHIFT 0 | 2027 | #define lpfc_mbx_rd_conf_e_d_tov_SHIFT 0 |
1804 | #define lpfc_mbx_rd_conf_e_d_tov_MASK 0x0000FFFF | 2028 | #define lpfc_mbx_rd_conf_e_d_tov_MASK 0x0000FFFF |
1805 | #define lpfc_mbx_rd_conf_e_d_tov_WORD word4 | 2029 | #define lpfc_mbx_rd_conf_e_d_tov_WORD word4 |
1806 | uint32_t word5; | 2030 | uint32_t rsvd_5; |
1807 | #define lpfc_mbx_rd_conf_lp_tov_SHIFT 0 | ||
1808 | #define lpfc_mbx_rd_conf_lp_tov_MASK 0x0000FFFF | ||
1809 | #define lpfc_mbx_rd_conf_lp_tov_WORD word5 | ||
1810 | uint32_t word6; | 2031 | uint32_t word6; |
1811 | #define lpfc_mbx_rd_conf_r_a_tov_SHIFT 0 | 2032 | #define lpfc_mbx_rd_conf_r_a_tov_SHIFT 0 |
1812 | #define lpfc_mbx_rd_conf_r_a_tov_MASK 0x0000FFFF | 2033 | #define lpfc_mbx_rd_conf_r_a_tov_MASK 0x0000FFFF |
1813 | #define lpfc_mbx_rd_conf_r_a_tov_WORD word6 | 2034 | #define lpfc_mbx_rd_conf_r_a_tov_WORD word6 |
1814 | uint32_t word7; | 2035 | uint32_t rsvd_7; |
1815 | #define lpfc_mbx_rd_conf_r_t_tov_SHIFT 0 | 2036 | uint32_t rsvd_8; |
1816 | #define lpfc_mbx_rd_conf_r_t_tov_MASK 0x000000FF | ||
1817 | #define lpfc_mbx_rd_conf_r_t_tov_WORD word7 | ||
1818 | uint32_t word8; | ||
1819 | #define lpfc_mbx_rd_conf_al_tov_SHIFT 0 | ||
1820 | #define lpfc_mbx_rd_conf_al_tov_MASK 0x0000000F | ||
1821 | #define lpfc_mbx_rd_conf_al_tov_WORD word8 | ||
1822 | uint32_t word9; | 2037 | uint32_t word9; |
1823 | #define lpfc_mbx_rd_conf_lmt_SHIFT 0 | 2038 | #define lpfc_mbx_rd_conf_lmt_SHIFT 0 |
1824 | #define lpfc_mbx_rd_conf_lmt_MASK 0x0000FFFF | 2039 | #define lpfc_mbx_rd_conf_lmt_MASK 0x0000FFFF |
1825 | #define lpfc_mbx_rd_conf_lmt_WORD word9 | 2040 | #define lpfc_mbx_rd_conf_lmt_WORD word9 |
1826 | uint32_t word10; | 2041 | uint32_t rsvd_10; |
1827 | #define lpfc_mbx_rd_conf_max_alpa_SHIFT 0 | 2042 | uint32_t rsvd_11; |
1828 | #define lpfc_mbx_rd_conf_max_alpa_MASK 0x000000FF | ||
1829 | #define lpfc_mbx_rd_conf_max_alpa_WORD word10 | ||
1830 | uint32_t word11_rsvd; | ||
1831 | uint32_t word12; | 2043 | uint32_t word12; |
1832 | #define lpfc_mbx_rd_conf_xri_base_SHIFT 0 | 2044 | #define lpfc_mbx_rd_conf_xri_base_SHIFT 0 |
1833 | #define lpfc_mbx_rd_conf_xri_base_MASK 0x0000FFFF | 2045 | #define lpfc_mbx_rd_conf_xri_base_MASK 0x0000FFFF |
@@ -1857,9 +2069,6 @@ struct lpfc_mbx_read_config { | |||
1857 | #define lpfc_mbx_rd_conf_vfi_count_MASK 0x0000FFFF | 2069 | #define lpfc_mbx_rd_conf_vfi_count_MASK 0x0000FFFF |
1858 | #define lpfc_mbx_rd_conf_vfi_count_WORD word15 | 2070 | #define lpfc_mbx_rd_conf_vfi_count_WORD word15 |
1859 | uint32_t word16; | 2071 | uint32_t word16; |
1860 | #define lpfc_mbx_rd_conf_fcfi_base_SHIFT 0 | ||
1861 | #define lpfc_mbx_rd_conf_fcfi_base_MASK 0x0000FFFF | ||
1862 | #define lpfc_mbx_rd_conf_fcfi_base_WORD word16 | ||
1863 | #define lpfc_mbx_rd_conf_fcfi_count_SHIFT 16 | 2072 | #define lpfc_mbx_rd_conf_fcfi_count_SHIFT 16 |
1864 | #define lpfc_mbx_rd_conf_fcfi_count_MASK 0x0000FFFF | 2073 | #define lpfc_mbx_rd_conf_fcfi_count_MASK 0x0000FFFF |
1865 | #define lpfc_mbx_rd_conf_fcfi_count_WORD word16 | 2074 | #define lpfc_mbx_rd_conf_fcfi_count_WORD word16 |
@@ -2169,6 +2378,12 @@ struct lpfc_sli4_parameters { | |||
2169 | #define cfg_fcoe_SHIFT 0 | 2378 | #define cfg_fcoe_SHIFT 0 |
2170 | #define cfg_fcoe_MASK 0x00000001 | 2379 | #define cfg_fcoe_MASK 0x00000001 |
2171 | #define cfg_fcoe_WORD word12 | 2380 | #define cfg_fcoe_WORD word12 |
2381 | #define cfg_ext_SHIFT 1 | ||
2382 | #define cfg_ext_MASK 0x00000001 | ||
2383 | #define cfg_ext_WORD word12 | ||
2384 | #define cfg_hdrr_SHIFT 2 | ||
2385 | #define cfg_hdrr_MASK 0x00000001 | ||
2386 | #define cfg_hdrr_WORD word12 | ||
2172 | #define cfg_phwq_SHIFT 15 | 2387 | #define cfg_phwq_SHIFT 15 |
2173 | #define cfg_phwq_MASK 0x00000001 | 2388 | #define cfg_phwq_MASK 0x00000001 |
2174 | #define cfg_phwq_WORD word12 | 2389 | #define cfg_phwq_WORD word12 |
@@ -2198,6 +2413,145 @@ struct lpfc_mbx_get_sli4_parameters { | |||
2198 | struct lpfc_sli4_parameters sli4_parameters; | 2413 | struct lpfc_sli4_parameters sli4_parameters; |
2199 | }; | 2414 | }; |
2200 | 2415 | ||
2416 | struct lpfc_rscr_desc_generic { | ||
2417 | #define LPFC_RSRC_DESC_WSIZE 18 | ||
2418 | uint32_t desc[LPFC_RSRC_DESC_WSIZE]; | ||
2419 | }; | ||
2420 | |||
2421 | struct lpfc_rsrc_desc_pcie { | ||
2422 | uint32_t word0; | ||
2423 | #define lpfc_rsrc_desc_pcie_type_SHIFT 0 | ||
2424 | #define lpfc_rsrc_desc_pcie_type_MASK 0x000000ff | ||
2425 | #define lpfc_rsrc_desc_pcie_type_WORD word0 | ||
2426 | #define LPFC_RSRC_DESC_TYPE_PCIE 0x40 | ||
2427 | uint32_t word1; | ||
2428 | #define lpfc_rsrc_desc_pcie_pfnum_SHIFT 0 | ||
2429 | #define lpfc_rsrc_desc_pcie_pfnum_MASK 0x000000ff | ||
2430 | #define lpfc_rsrc_desc_pcie_pfnum_WORD word1 | ||
2431 | uint32_t reserved; | ||
2432 | uint32_t word3; | ||
2433 | #define lpfc_rsrc_desc_pcie_sriov_sta_SHIFT 0 | ||
2434 | #define lpfc_rsrc_desc_pcie_sriov_sta_MASK 0x000000ff | ||
2435 | #define lpfc_rsrc_desc_pcie_sriov_sta_WORD word3 | ||
2436 | #define lpfc_rsrc_desc_pcie_pf_sta_SHIFT 8 | ||
2437 | #define lpfc_rsrc_desc_pcie_pf_sta_MASK 0x000000ff | ||
2438 | #define lpfc_rsrc_desc_pcie_pf_sta_WORD word3 | ||
2439 | #define lpfc_rsrc_desc_pcie_pf_type_SHIFT 16 | ||
2440 | #define lpfc_rsrc_desc_pcie_pf_type_MASK 0x000000ff | ||
2441 | #define lpfc_rsrc_desc_pcie_pf_type_WORD word3 | ||
2442 | uint32_t word4; | ||
2443 | #define lpfc_rsrc_desc_pcie_nr_virtfn_SHIFT 0 | ||
2444 | #define lpfc_rsrc_desc_pcie_nr_virtfn_MASK 0x0000ffff | ||
2445 | #define lpfc_rsrc_desc_pcie_nr_virtfn_WORD word4 | ||
2446 | }; | ||
2447 | |||
2448 | struct lpfc_rsrc_desc_fcfcoe { | ||
2449 | uint32_t word0; | ||
2450 | #define lpfc_rsrc_desc_fcfcoe_type_SHIFT 0 | ||
2451 | #define lpfc_rsrc_desc_fcfcoe_type_MASK 0x000000ff | ||
2452 | #define lpfc_rsrc_desc_fcfcoe_type_WORD word0 | ||
2453 | #define LPFC_RSRC_DESC_TYPE_FCFCOE 0x43 | ||
2454 | uint32_t word1; | ||
2455 | #define lpfc_rsrc_desc_fcfcoe_vfnum_SHIFT 0 | ||
2456 | #define lpfc_rsrc_desc_fcfcoe_vfnum_MASK 0x000000ff | ||
2457 | #define lpfc_rsrc_desc_fcfcoe_vfnum_WORD word1 | ||
2458 | #define lpfc_rsrc_desc_fcfcoe_pfnum_SHIFT 16 | ||
2459 | #define lpfc_rsrc_desc_fcfcoe_pfnum_MASK 0x000007ff | ||
2460 | #define lpfc_rsrc_desc_fcfcoe_pfnum_WORD word1 | ||
2461 | uint32_t word2; | ||
2462 | #define lpfc_rsrc_desc_fcfcoe_rpi_cnt_SHIFT 0 | ||
2463 | #define lpfc_rsrc_desc_fcfcoe_rpi_cnt_MASK 0x0000ffff | ||
2464 | #define lpfc_rsrc_desc_fcfcoe_rpi_cnt_WORD word2 | ||
2465 | #define lpfc_rsrc_desc_fcfcoe_xri_cnt_SHIFT 16 | ||
2466 | #define lpfc_rsrc_desc_fcfcoe_xri_cnt_MASK 0x0000ffff | ||
2467 | #define lpfc_rsrc_desc_fcfcoe_xri_cnt_WORD word2 | ||
2468 | uint32_t word3; | ||
2469 | #define lpfc_rsrc_desc_fcfcoe_wq_cnt_SHIFT 0 | ||
2470 | #define lpfc_rsrc_desc_fcfcoe_wq_cnt_MASK 0x0000ffff | ||
2471 | #define lpfc_rsrc_desc_fcfcoe_wq_cnt_WORD word3 | ||
2472 | #define lpfc_rsrc_desc_fcfcoe_rq_cnt_SHIFT 16 | ||
2473 | #define lpfc_rsrc_desc_fcfcoe_rq_cnt_MASK 0x0000ffff | ||
2474 | #define lpfc_rsrc_desc_fcfcoe_rq_cnt_WORD word3 | ||
2475 | uint32_t word4; | ||
2476 | #define lpfc_rsrc_desc_fcfcoe_cq_cnt_SHIFT 0 | ||
2477 | #define lpfc_rsrc_desc_fcfcoe_cq_cnt_MASK 0x0000ffff | ||
2478 | #define lpfc_rsrc_desc_fcfcoe_cq_cnt_WORD word4 | ||
2479 | #define lpfc_rsrc_desc_fcfcoe_vpi_cnt_SHIFT 16 | ||
2480 | #define lpfc_rsrc_desc_fcfcoe_vpi_cnt_MASK 0x0000ffff | ||
2481 | #define lpfc_rsrc_desc_fcfcoe_vpi_cnt_WORD word4 | ||
2482 | uint32_t word5; | ||
2483 | #define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_SHIFT 0 | ||
2484 | #define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_MASK 0x0000ffff | ||
2485 | #define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_WORD word5 | ||
2486 | #define lpfc_rsrc_desc_fcfcoe_vfi_cnt_SHIFT 16 | ||
2487 | #define lpfc_rsrc_desc_fcfcoe_vfi_cnt_MASK 0x0000ffff | ||
2488 | #define lpfc_rsrc_desc_fcfcoe_vfi_cnt_WORD word5 | ||
2489 | uint32_t word6; | ||
2490 | uint32_t word7; | ||
2491 | uint32_t word8; | ||
2492 | uint32_t word9; | ||
2493 | uint32_t word10; | ||
2494 | uint32_t word11; | ||
2495 | uint32_t word12; | ||
2496 | uint32_t word13; | ||
2497 | #define lpfc_rsrc_desc_fcfcoe_lnk_nr_SHIFT 0 | ||
2498 | #define lpfc_rsrc_desc_fcfcoe_lnk_nr_MASK 0x0000003f | ||
2499 | #define lpfc_rsrc_desc_fcfcoe_lnk_nr_WORD word13 | ||
2500 | #define lpfc_rsrc_desc_fcfcoe_lnk_tp_SHIFT 6 | ||
2501 | #define lpfc_rsrc_desc_fcfcoe_lnk_tp_MASK 0x00000003 | ||
2502 | #define lpfc_rsrc_desc_fcfcoe_lnk_tp_WORD word13 | ||
2503 | #define lpfc_rsrc_desc_fcfcoe_lmc_SHIFT 8 | ||
2504 | #define lpfc_rsrc_desc_fcfcoe_lmc_MASK 0x00000001 | ||
2505 | #define lpfc_rsrc_desc_fcfcoe_lmc_WORD word13 | ||
2506 | #define lpfc_rsrc_desc_fcfcoe_lld_SHIFT 9 | ||
2507 | #define lpfc_rsrc_desc_fcfcoe_lld_MASK 0x00000001 | ||
2508 | #define lpfc_rsrc_desc_fcfcoe_lld_WORD word13 | ||
2509 | #define lpfc_rsrc_desc_fcfcoe_eq_cnt_SHIFT 16 | ||
2510 | #define lpfc_rsrc_desc_fcfcoe_eq_cnt_MASK 0x0000ffff | ||
2511 | #define lpfc_rsrc_desc_fcfcoe_eq_cnt_WORD word13 | ||
2512 | }; | ||
2513 | |||
2514 | struct lpfc_func_cfg { | ||
2515 | #define LPFC_RSRC_DESC_MAX_NUM 2 | ||
2516 | uint32_t rsrc_desc_count; | ||
2517 | struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM]; | ||
2518 | }; | ||
2519 | |||
2520 | struct lpfc_mbx_get_func_cfg { | ||
2521 | struct mbox_header header; | ||
2522 | #define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE 0x0 | ||
2523 | #define LPFC_CFG_TYPE_FACTURY_DEFAULT 0x1 | ||
2524 | #define LPFC_CFG_TYPE_CURRENT_ACTIVE 0x2 | ||
2525 | struct lpfc_func_cfg func_cfg; | ||
2526 | }; | ||
2527 | |||
2528 | struct lpfc_prof_cfg { | ||
2529 | #define LPFC_RSRC_DESC_MAX_NUM 2 | ||
2530 | uint32_t rsrc_desc_count; | ||
2531 | struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM]; | ||
2532 | }; | ||
2533 | |||
2534 | struct lpfc_mbx_get_prof_cfg { | ||
2535 | struct mbox_header header; | ||
2536 | #define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE 0x0 | ||
2537 | #define LPFC_CFG_TYPE_FACTURY_DEFAULT 0x1 | ||
2538 | #define LPFC_CFG_TYPE_CURRENT_ACTIVE 0x2 | ||
2539 | union { | ||
2540 | struct { | ||
2541 | uint32_t word10; | ||
2542 | #define lpfc_mbx_get_prof_cfg_prof_id_SHIFT 0 | ||
2543 | #define lpfc_mbx_get_prof_cfg_prof_id_MASK 0x000000ff | ||
2544 | #define lpfc_mbx_get_prof_cfg_prof_id_WORD word10 | ||
2545 | #define lpfc_mbx_get_prof_cfg_prof_tp_SHIFT 8 | ||
2546 | #define lpfc_mbx_get_prof_cfg_prof_tp_MASK 0x00000003 | ||
2547 | #define lpfc_mbx_get_prof_cfg_prof_tp_WORD word10 | ||
2548 | } request; | ||
2549 | struct { | ||
2550 | struct lpfc_prof_cfg prof_cfg; | ||
2551 | } response; | ||
2552 | } u; | ||
2553 | }; | ||
2554 | |||
2201 | /* Mailbox Completion Queue Error Messages */ | 2555 | /* Mailbox Completion Queue Error Messages */ |
2202 | #define MB_CQE_STATUS_SUCCESS 0x0 | 2556 | #define MB_CQE_STATUS_SUCCESS 0x0 |
2203 | #define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1 | 2557 | #define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1 |
@@ -2206,6 +2560,29 @@ struct lpfc_mbx_get_sli4_parameters { | |||
2206 | #define MB_CEQ_STATUS_QUEUE_FLUSHING 0x4 | 2560 | #define MB_CEQ_STATUS_QUEUE_FLUSHING 0x4 |
2207 | #define MB_CQE_STATUS_DMA_FAILED 0x5 | 2561 | #define MB_CQE_STATUS_DMA_FAILED 0x5 |
2208 | 2562 | ||
2563 | #define LPFC_MBX_WR_CONFIG_MAX_BDE 8 | ||
2564 | struct lpfc_mbx_wr_object { | ||
2565 | struct mbox_header header; | ||
2566 | union { | ||
2567 | struct { | ||
2568 | uint32_t word4; | ||
2569 | #define lpfc_wr_object_eof_SHIFT 31 | ||
2570 | #define lpfc_wr_object_eof_MASK 0x00000001 | ||
2571 | #define lpfc_wr_object_eof_WORD word4 | ||
2572 | #define lpfc_wr_object_write_length_SHIFT 0 | ||
2573 | #define lpfc_wr_object_write_length_MASK 0x00FFFFFF | ||
2574 | #define lpfc_wr_object_write_length_WORD word4 | ||
2575 | uint32_t write_offset; | ||
2576 | uint32_t object_name[26]; | ||
2577 | uint32_t bde_count; | ||
2578 | struct ulp_bde64 bde[LPFC_MBX_WR_CONFIG_MAX_BDE]; | ||
2579 | } request; | ||
2580 | struct { | ||
2581 | uint32_t actual_write_length; | ||
2582 | } response; | ||
2583 | } u; | ||
2584 | }; | ||
2585 | |||
2209 | /* mailbox queue entry structure */ | 2586 | /* mailbox queue entry structure */ |
2210 | struct lpfc_mqe { | 2587 | struct lpfc_mqe { |
2211 | uint32_t word0; | 2588 | uint32_t word0; |
@@ -2241,6 +2618,9 @@ struct lpfc_mqe { | |||
2241 | struct lpfc_mbx_cq_destroy cq_destroy; | 2618 | struct lpfc_mbx_cq_destroy cq_destroy; |
2242 | struct lpfc_mbx_wq_destroy wq_destroy; | 2619 | struct lpfc_mbx_wq_destroy wq_destroy; |
2243 | struct lpfc_mbx_rq_destroy rq_destroy; | 2620 | struct lpfc_mbx_rq_destroy rq_destroy; |
2621 | struct lpfc_mbx_get_rsrc_extent_info rsrc_extent_info; | ||
2622 | struct lpfc_mbx_alloc_rsrc_extents alloc_rsrc_extents; | ||
2623 | struct lpfc_mbx_dealloc_rsrc_extents dealloc_rsrc_extents; | ||
2244 | struct lpfc_mbx_post_sgl_pages post_sgl_pages; | 2624 | struct lpfc_mbx_post_sgl_pages post_sgl_pages; |
2245 | struct lpfc_mbx_nembed_cmd nembed_cmd; | 2625 | struct lpfc_mbx_nembed_cmd nembed_cmd; |
2246 | struct lpfc_mbx_read_rev read_rev; | 2626 | struct lpfc_mbx_read_rev read_rev; |
@@ -2252,7 +2632,13 @@ struct lpfc_mqe { | |||
2252 | struct lpfc_mbx_supp_pages supp_pages; | 2632 | struct lpfc_mbx_supp_pages supp_pages; |
2253 | struct lpfc_mbx_pc_sli4_params sli4_params; | 2633 | struct lpfc_mbx_pc_sli4_params sli4_params; |
2254 | struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; | 2634 | struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; |
2635 | struct lpfc_mbx_set_link_diag_state link_diag_state; | ||
2636 | struct lpfc_mbx_set_link_diag_loopback link_diag_loopback; | ||
2637 | struct lpfc_mbx_run_link_diag_test link_diag_test; | ||
2638 | struct lpfc_mbx_get_func_cfg get_func_cfg; | ||
2639 | struct lpfc_mbx_get_prof_cfg get_prof_cfg; | ||
2255 | struct lpfc_mbx_nop nop; | 2640 | struct lpfc_mbx_nop nop; |
2641 | struct lpfc_mbx_wr_object wr_object; | ||
2256 | } un; | 2642 | } un; |
2257 | }; | 2643 | }; |
2258 | 2644 | ||
@@ -2458,7 +2844,7 @@ struct lpfc_bmbx_create { | |||
2458 | #define SGL_ALIGN_SZ 64 | 2844 | #define SGL_ALIGN_SZ 64 |
2459 | #define SGL_PAGE_SIZE 4096 | 2845 | #define SGL_PAGE_SIZE 4096 |
2460 | /* align SGL addr on a size boundary - adjust address up */ | 2846 | /* align SGL addr on a size boundary - adjust address up */ |
2461 | #define NO_XRI ((uint16_t)-1) | 2847 | #define NO_XRI 0xffff |
2462 | 2848 | ||
2463 | struct wqe_common { | 2849 | struct wqe_common { |
2464 | uint32_t word6; | 2850 | uint32_t word6; |
@@ -2798,9 +3184,28 @@ union lpfc_wqe { | |||
2798 | struct gen_req64_wqe gen_req; | 3184 | struct gen_req64_wqe gen_req; |
2799 | }; | 3185 | }; |
2800 | 3186 | ||
3187 | #define LPFC_GROUP_OJECT_MAGIC_NUM 0xfeaa0001 | ||
3188 | #define LPFC_FILE_TYPE_GROUP 0xf7 | ||
3189 | #define LPFC_FILE_ID_GROUP 0xa2 | ||
3190 | struct lpfc_grp_hdr { | ||
3191 | uint32_t size; | ||
3192 | uint32_t magic_number; | ||
3193 | uint32_t word2; | ||
3194 | #define lpfc_grp_hdr_file_type_SHIFT 24 | ||
3195 | #define lpfc_grp_hdr_file_type_MASK 0x000000FF | ||
3196 | #define lpfc_grp_hdr_file_type_WORD word2 | ||
3197 | #define lpfc_grp_hdr_id_SHIFT 16 | ||
3198 | #define lpfc_grp_hdr_id_MASK 0x000000FF | ||
3199 | #define lpfc_grp_hdr_id_WORD word2 | ||
3200 | uint8_t rev_name[128]; | ||
3201 | }; | ||
3202 | |||
2801 | #define FCP_COMMAND 0x0 | 3203 | #define FCP_COMMAND 0x0 |
2802 | #define FCP_COMMAND_DATA_OUT 0x1 | 3204 | #define FCP_COMMAND_DATA_OUT 0x1 |
2803 | #define ELS_COMMAND_NON_FIP 0xC | 3205 | #define ELS_COMMAND_NON_FIP 0xC |
2804 | #define ELS_COMMAND_FIP 0xD | 3206 | #define ELS_COMMAND_FIP 0xD |
2805 | #define OTHER_COMMAND 0x8 | 3207 | #define OTHER_COMMAND 0x8 |
2806 | 3208 | ||
3209 | #define LPFC_FW_DUMP 1 | ||
3210 | #define LPFC_FW_RESET 2 | ||
3211 | #define LPFC_DV_RESET 3 | ||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7dda036a1af3..148b98ddbb1d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/ctype.h> | 30 | #include <linux/ctype.h> |
31 | #include <linux/aer.h> | 31 | #include <linux/aer.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/firmware.h> | ||
33 | 34 | ||
34 | #include <scsi/scsi.h> | 35 | #include <scsi/scsi.h> |
35 | #include <scsi/scsi_device.h> | 36 | #include <scsi/scsi_device.h> |
@@ -211,7 +212,6 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
211 | lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL); | 212 | lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL); |
212 | if (!lpfc_vpd_data) | 213 | if (!lpfc_vpd_data) |
213 | goto out_free_mbox; | 214 | goto out_free_mbox; |
214 | |||
215 | do { | 215 | do { |
216 | lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD); | 216 | lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD); |
217 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | 217 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); |
@@ -309,6 +309,45 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
309 | } | 309 | } |
310 | 310 | ||
311 | /** | 311 | /** |
312 | * lpfc_update_vport_wwn - Updates the fc_nodename, fc_portname, | ||
313 | * cfg_soft_wwnn, cfg_soft_wwpn | ||
314 | * @vport: pointer to lpfc vport data structure. | ||
315 | * | ||
316 | * | ||
317 | * Return codes | ||
318 | * None. | ||
319 | **/ | ||
320 | void | ||
321 | lpfc_update_vport_wwn(struct lpfc_vport *vport) | ||
322 | { | ||
323 | /* If the soft name exists then update it using the service params */ | ||
324 | if (vport->phba->cfg_soft_wwnn) | ||
325 | u64_to_wwn(vport->phba->cfg_soft_wwnn, | ||
326 | vport->fc_sparam.nodeName.u.wwn); | ||
327 | if (vport->phba->cfg_soft_wwpn) | ||
328 | u64_to_wwn(vport->phba->cfg_soft_wwpn, | ||
329 | vport->fc_sparam.portName.u.wwn); | ||
330 | |||
331 | /* | ||
332 | * If the name is empty or there exists a soft name | ||
333 | * then copy the service params name, otherwise use the fc name | ||
334 | */ | ||
335 | if (vport->fc_nodename.u.wwn[0] == 0 || vport->phba->cfg_soft_wwnn) | ||
336 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, | ||
337 | sizeof(struct lpfc_name)); | ||
338 | else | ||
339 | memcpy(&vport->fc_sparam.nodeName, &vport->fc_nodename, | ||
340 | sizeof(struct lpfc_name)); | ||
341 | |||
342 | if (vport->fc_portname.u.wwn[0] == 0 || vport->phba->cfg_soft_wwpn) | ||
343 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, | ||
344 | sizeof(struct lpfc_name)); | ||
345 | else | ||
346 | memcpy(&vport->fc_sparam.portName, &vport->fc_portname, | ||
347 | sizeof(struct lpfc_name)); | ||
348 | } | ||
349 | |||
350 | /** | ||
312 | * lpfc_config_port_post - Perform lpfc initialization after config port | 351 | * lpfc_config_port_post - Perform lpfc initialization after config port |
313 | * @phba: pointer to lpfc hba data structure. | 352 | * @phba: pointer to lpfc hba data structure. |
314 | * | 353 | * |
@@ -377,17 +416,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
377 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 416 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
378 | kfree(mp); | 417 | kfree(mp); |
379 | pmb->context1 = NULL; | 418 | pmb->context1 = NULL; |
380 | 419 | lpfc_update_vport_wwn(vport); | |
381 | if (phba->cfg_soft_wwnn) | ||
382 | u64_to_wwn(phba->cfg_soft_wwnn, | ||
383 | vport->fc_sparam.nodeName.u.wwn); | ||
384 | if (phba->cfg_soft_wwpn) | ||
385 | u64_to_wwn(phba->cfg_soft_wwpn, | ||
386 | vport->fc_sparam.portName.u.wwn); | ||
387 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, | ||
388 | sizeof (struct lpfc_name)); | ||
389 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, | ||
390 | sizeof (struct lpfc_name)); | ||
391 | 420 | ||
392 | /* Update the fc_host data structures with new wwn. */ | 421 | /* Update the fc_host data structures with new wwn. */ |
393 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); | 422 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); |
@@ -573,7 +602,6 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
573 | /* Clear all pending interrupts */ | 602 | /* Clear all pending interrupts */ |
574 | writel(0xffffffff, phba->HAregaddr); | 603 | writel(0xffffffff, phba->HAregaddr); |
575 | readl(phba->HAregaddr); /* flush */ | 604 | readl(phba->HAregaddr); /* flush */ |
576 | |||
577 | phba->link_state = LPFC_HBA_ERROR; | 605 | phba->link_state = LPFC_HBA_ERROR; |
578 | if (rc != MBX_BUSY) | 606 | if (rc != MBX_BUSY) |
579 | mempool_free(pmb, phba->mbox_mem_pool); | 607 | mempool_free(pmb, phba->mbox_mem_pool); |
@@ -1755,7 +1783,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1755 | && descp && descp[0] != '\0') | 1783 | && descp && descp[0] != '\0') |
1756 | return; | 1784 | return; |
1757 | 1785 | ||
1758 | if (phba->lmt & LMT_10Gb) | 1786 | if (phba->lmt & LMT_16Gb) |
1787 | max_speed = 16; | ||
1788 | else if (phba->lmt & LMT_10Gb) | ||
1759 | max_speed = 10; | 1789 | max_speed = 10; |
1760 | else if (phba->lmt & LMT_8Gb) | 1790 | else if (phba->lmt & LMT_8Gb) |
1761 | max_speed = 8; | 1791 | max_speed = 8; |
@@ -1922,12 +1952,13 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1922 | "Fibre Channel Adapter"}; | 1952 | "Fibre Channel Adapter"}; |
1923 | break; | 1953 | break; |
1924 | case PCI_DEVICE_ID_LANCER_FC: | 1954 | case PCI_DEVICE_ID_LANCER_FC: |
1925 | oneConnect = 1; | 1955 | case PCI_DEVICE_ID_LANCER_FC_VF: |
1926 | m = (typeof(m)){"Undefined", "PCIe", "Fibre Channel Adapter"}; | 1956 | m = (typeof(m)){"LPe16000", "PCIe", "Fibre Channel Adapter"}; |
1927 | break; | 1957 | break; |
1928 | case PCI_DEVICE_ID_LANCER_FCOE: | 1958 | case PCI_DEVICE_ID_LANCER_FCOE: |
1959 | case PCI_DEVICE_ID_LANCER_FCOE_VF: | ||
1929 | oneConnect = 1; | 1960 | oneConnect = 1; |
1930 | m = (typeof(m)){"Undefined", "PCIe", "FCoE"}; | 1961 | m = (typeof(m)){"OCe50100", "PCIe", "FCoE"}; |
1931 | break; | 1962 | break; |
1932 | default: | 1963 | default: |
1933 | m = (typeof(m)){"Unknown", "", ""}; | 1964 | m = (typeof(m)){"Unknown", "", ""}; |
@@ -1936,7 +1967,8 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1936 | 1967 | ||
1937 | if (mdp && mdp[0] == '\0') | 1968 | if (mdp && mdp[0] == '\0') |
1938 | snprintf(mdp, 79,"%s", m.name); | 1969 | snprintf(mdp, 79,"%s", m.name); |
1939 | /* oneConnect hba requires special processing, they are all initiators | 1970 | /* |
1971 | * oneConnect hba requires special processing, they are all initiators | ||
1940 | * and we put the port number on the end | 1972 | * and we put the port number on the end |
1941 | */ | 1973 | */ |
1942 | if (descp && descp[0] == '\0') { | 1974 | if (descp && descp[0] == '\0') { |
@@ -2656,6 +2688,7 @@ lpfc_scsi_free(struct lpfc_hba *phba) | |||
2656 | kfree(io); | 2688 | kfree(io); |
2657 | phba->total_iocbq_bufs--; | 2689 | phba->total_iocbq_bufs--; |
2658 | } | 2690 | } |
2691 | |||
2659 | spin_unlock_irq(&phba->hbalock); | 2692 | spin_unlock_irq(&phba->hbalock); |
2660 | return 0; | 2693 | return 0; |
2661 | } | 2694 | } |
@@ -3612,6 +3645,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, | |||
3612 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, | 3645 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
3613 | "2718 Clear Virtual Link Received for VPI 0x%x" | 3646 | "2718 Clear Virtual Link Received for VPI 0x%x" |
3614 | " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag); | 3647 | " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag); |
3648 | |||
3615 | vport = lpfc_find_vport_by_vpid(phba, | 3649 | vport = lpfc_find_vport_by_vpid(phba, |
3616 | acqe_fip->index - phba->vpi_base); | 3650 | acqe_fip->index - phba->vpi_base); |
3617 | ndlp = lpfc_sli4_perform_vport_cvl(vport); | 3651 | ndlp = lpfc_sli4_perform_vport_cvl(vport); |
@@ -3935,6 +3969,10 @@ lpfc_enable_pci_dev(struct lpfc_hba *phba) | |||
3935 | pci_try_set_mwi(pdev); | 3969 | pci_try_set_mwi(pdev); |
3936 | pci_save_state(pdev); | 3970 | pci_save_state(pdev); |
3937 | 3971 | ||
3972 | /* PCIe EEH recovery on powerpc platforms needs fundamental reset */ | ||
3973 | if (pci_find_capability(pdev, PCI_CAP_ID_EXP)) | ||
3974 | pdev->needs_freset = 1; | ||
3975 | |||
3938 | return 0; | 3976 | return 0; |
3939 | 3977 | ||
3940 | out_disable_device: | 3978 | out_disable_device: |
@@ -3997,6 +4035,36 @@ lpfc_reset_hba(struct lpfc_hba *phba) | |||
3997 | } | 4035 | } |
3998 | 4036 | ||
3999 | /** | 4037 | /** |
4038 | * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions | ||
4039 | * @phba: pointer to lpfc hba data structure. | ||
4040 | * @nr_vfn: number of virtual functions to be enabled. | ||
4041 | * | ||
4042 | * This function enables the PCI SR-IOV virtual functions to a physical | ||
4043 | * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to | ||
4044 | * enable the number of virtual functions to the physical function. As | ||
4045 | * not all devices support SR-IOV, the return code from the pci_enable_sriov() | ||
4046 | * API call does not considered as an error condition for most of the device. | ||
4047 | **/ | ||
4048 | int | ||
4049 | lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn) | ||
4050 | { | ||
4051 | struct pci_dev *pdev = phba->pcidev; | ||
4052 | int rc; | ||
4053 | |||
4054 | rc = pci_enable_sriov(pdev, nr_vfn); | ||
4055 | if (rc) { | ||
4056 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
4057 | "2806 Failed to enable sriov on this device " | ||
4058 | "with vfn number nr_vf:%d, rc:%d\n", | ||
4059 | nr_vfn, rc); | ||
4060 | } else | ||
4061 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
4062 | "2807 Successful enable sriov on this device " | ||
4063 | "with vfn number nr_vf:%d\n", nr_vfn); | ||
4064 | return rc; | ||
4065 | } | ||
4066 | |||
4067 | /** | ||
4000 | * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev. | 4068 | * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev. |
4001 | * @phba: pointer to lpfc hba data structure. | 4069 | * @phba: pointer to lpfc hba data structure. |
4002 | * | 4070 | * |
@@ -4011,6 +4079,7 @@ static int | |||
4011 | lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) | 4079 | lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) |
4012 | { | 4080 | { |
4013 | struct lpfc_sli *psli; | 4081 | struct lpfc_sli *psli; |
4082 | int rc; | ||
4014 | 4083 | ||
4015 | /* | 4084 | /* |
4016 | * Initialize timers used by driver | 4085 | * Initialize timers used by driver |
@@ -4085,6 +4154,23 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) | |||
4085 | if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ)) | 4154 | if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ)) |
4086 | return -ENOMEM; | 4155 | return -ENOMEM; |
4087 | 4156 | ||
4157 | /* | ||
4158 | * Enable sr-iov virtual functions if supported and configured | ||
4159 | * through the module parameter. | ||
4160 | */ | ||
4161 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
4162 | rc = lpfc_sli_probe_sriov_nr_virtfn(phba, | ||
4163 | phba->cfg_sriov_nr_virtfn); | ||
4164 | if (rc) { | ||
4165 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
4166 | "2808 Requested number of SR-IOV " | ||
4167 | "virtual functions (%d) is not " | ||
4168 | "supported\n", | ||
4169 | phba->cfg_sriov_nr_virtfn); | ||
4170 | phba->cfg_sriov_nr_virtfn = 0; | ||
4171 | } | ||
4172 | } | ||
4173 | |||
4088 | return 0; | 4174 | return 0; |
4089 | } | 4175 | } |
4090 | 4176 | ||
@@ -4161,6 +4247,14 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4161 | phba->fcf.redisc_wait.data = (unsigned long)phba; | 4247 | phba->fcf.redisc_wait.data = (unsigned long)phba; |
4162 | 4248 | ||
4163 | /* | 4249 | /* |
4250 | * Control structure for handling external multi-buffer mailbox | ||
4251 | * command pass-through. | ||
4252 | */ | ||
4253 | memset((uint8_t *)&phba->mbox_ext_buf_ctx, 0, | ||
4254 | sizeof(struct lpfc_mbox_ext_buf_ctx)); | ||
4255 | INIT_LIST_HEAD(&phba->mbox_ext_buf_ctx.ext_dmabuf_list); | ||
4256 | |||
4257 | /* | ||
4164 | * We need to do a READ_CONFIG mailbox command here before | 4258 | * We need to do a READ_CONFIG mailbox command here before |
4165 | * calling lpfc_get_cfgparam. For VFs this will report the | 4259 | * calling lpfc_get_cfgparam. For VFs this will report the |
4166 | * MAX_XRI, MAX_VPI, MAX_RPI, MAX_IOCB, and MAX_VFI settings. | 4260 | * MAX_XRI, MAX_VPI, MAX_RPI, MAX_IOCB, and MAX_VFI settings. |
@@ -4233,7 +4327,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4233 | spin_lock_init(&phba->sli4_hba.abts_sgl_list_lock); | 4327 | spin_lock_init(&phba->sli4_hba.abts_sgl_list_lock); |
4234 | 4328 | ||
4235 | /* | 4329 | /* |
4236 | * Initialize dirver internal slow-path work queues | 4330 | * Initialize driver internal slow-path work queues |
4237 | */ | 4331 | */ |
4238 | 4332 | ||
4239 | /* Driver internel slow-path CQ Event pool */ | 4333 | /* Driver internel slow-path CQ Event pool */ |
@@ -4249,6 +4343,12 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4249 | /* Receive queue CQ Event work queue list */ | 4343 | /* Receive queue CQ Event work queue list */ |
4250 | INIT_LIST_HEAD(&phba->sli4_hba.sp_unsol_work_queue); | 4344 | INIT_LIST_HEAD(&phba->sli4_hba.sp_unsol_work_queue); |
4251 | 4345 | ||
4346 | /* Initialize extent block lists. */ | ||
4347 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_blk_list); | ||
4348 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_xri_blk_list); | ||
4349 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list); | ||
4350 | INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list); | ||
4351 | |||
4252 | /* Initialize the driver internal SLI layer lists. */ | 4352 | /* Initialize the driver internal SLI layer lists. */ |
4253 | lpfc_sli_setup(phba); | 4353 | lpfc_sli_setup(phba); |
4254 | lpfc_sli_queue_setup(phba); | 4354 | lpfc_sli_queue_setup(phba); |
@@ -4323,9 +4423,19 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4323 | } | 4423 | } |
4324 | /* | 4424 | /* |
4325 | * Get sli4 parameters that override parameters from Port capabilities. | 4425 | * Get sli4 parameters that override parameters from Port capabilities. |
4326 | * If this call fails it is not a critical error so continue loading. | 4426 | * If this call fails, it isn't critical unless the SLI4 parameters come |
4427 | * back in conflict. | ||
4327 | */ | 4428 | */ |
4328 | lpfc_get_sli4_parameters(phba, mboxq); | 4429 | rc = lpfc_get_sli4_parameters(phba, mboxq); |
4430 | if (rc) { | ||
4431 | if (phba->sli4_hba.extents_in_use && | ||
4432 | phba->sli4_hba.rpi_hdrs_in_use) { | ||
4433 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4434 | "2999 Unsupported SLI4 Parameters " | ||
4435 | "Extents and RPI headers enabled.\n"); | ||
4436 | goto out_free_bsmbx; | ||
4437 | } | ||
4438 | } | ||
4329 | mempool_free(mboxq, phba->mbox_mem_pool); | 4439 | mempool_free(mboxq, phba->mbox_mem_pool); |
4330 | /* Create all the SLI4 queues */ | 4440 | /* Create all the SLI4 queues */ |
4331 | rc = lpfc_sli4_queue_create(phba); | 4441 | rc = lpfc_sli4_queue_create(phba); |
@@ -4350,7 +4460,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4350 | "1430 Failed to initialize sgl list.\n"); | 4460 | "1430 Failed to initialize sgl list.\n"); |
4351 | goto out_free_sgl_list; | 4461 | goto out_free_sgl_list; |
4352 | } | 4462 | } |
4353 | |||
4354 | rc = lpfc_sli4_init_rpi_hdrs(phba); | 4463 | rc = lpfc_sli4_init_rpi_hdrs(phba); |
4355 | if (rc) { | 4464 | if (rc) { |
4356 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4465 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -4366,6 +4475,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4366 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4475 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
4367 | "2759 Failed allocate memory for FCF round " | 4476 | "2759 Failed allocate memory for FCF round " |
4368 | "robin failover bmask\n"); | 4477 | "robin failover bmask\n"); |
4478 | rc = -ENOMEM; | ||
4369 | goto out_remove_rpi_hdrs; | 4479 | goto out_remove_rpi_hdrs; |
4370 | } | 4480 | } |
4371 | 4481 | ||
@@ -4375,6 +4485,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4375 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4485 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
4376 | "2572 Failed allocate memory for fast-path " | 4486 | "2572 Failed allocate memory for fast-path " |
4377 | "per-EQ handle array\n"); | 4487 | "per-EQ handle array\n"); |
4488 | rc = -ENOMEM; | ||
4378 | goto out_free_fcf_rr_bmask; | 4489 | goto out_free_fcf_rr_bmask; |
4379 | } | 4490 | } |
4380 | 4491 | ||
@@ -4384,9 +4495,27 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
4384 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4495 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
4385 | "2573 Failed allocate memory for msi-x " | 4496 | "2573 Failed allocate memory for msi-x " |
4386 | "interrupt vector entries\n"); | 4497 | "interrupt vector entries\n"); |
4498 | rc = -ENOMEM; | ||
4387 | goto out_free_fcp_eq_hdl; | 4499 | goto out_free_fcp_eq_hdl; |
4388 | } | 4500 | } |
4389 | 4501 | ||
4502 | /* | ||
4503 | * Enable sr-iov virtual functions if supported and configured | ||
4504 | * through the module parameter. | ||
4505 | */ | ||
4506 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
4507 | rc = lpfc_sli_probe_sriov_nr_virtfn(phba, | ||
4508 | phba->cfg_sriov_nr_virtfn); | ||
4509 | if (rc) { | ||
4510 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
4511 | "3020 Requested number of SR-IOV " | ||
4512 | "virtual functions (%d) is not " | ||
4513 | "supported\n", | ||
4514 | phba->cfg_sriov_nr_virtfn); | ||
4515 | phba->cfg_sriov_nr_virtfn = 0; | ||
4516 | } | ||
4517 | } | ||
4518 | |||
4390 | return rc; | 4519 | return rc; |
4391 | 4520 | ||
4392 | out_free_fcp_eq_hdl: | 4521 | out_free_fcp_eq_hdl: |
@@ -4449,6 +4578,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) | |||
4449 | lpfc_sli4_cq_event_release_all(phba); | 4578 | lpfc_sli4_cq_event_release_all(phba); |
4450 | lpfc_sli4_cq_event_pool_destroy(phba); | 4579 | lpfc_sli4_cq_event_pool_destroy(phba); |
4451 | 4580 | ||
4581 | /* Release resource identifiers. */ | ||
4582 | lpfc_sli4_dealloc_resource_identifiers(phba); | ||
4583 | |||
4452 | /* Free the bsmbx region. */ | 4584 | /* Free the bsmbx region. */ |
4453 | lpfc_destroy_bootstrap_mbox(phba); | 4585 | lpfc_destroy_bootstrap_mbox(phba); |
4454 | 4586 | ||
@@ -4649,6 +4781,7 @@ lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count) | |||
4649 | "Unloading driver.\n", __func__); | 4781 | "Unloading driver.\n", __func__); |
4650 | goto out_free_iocbq; | 4782 | goto out_free_iocbq; |
4651 | } | 4783 | } |
4784 | iocbq_entry->sli4_lxritag = NO_XRI; | ||
4652 | iocbq_entry->sli4_xritag = NO_XRI; | 4785 | iocbq_entry->sli4_xritag = NO_XRI; |
4653 | 4786 | ||
4654 | spin_lock_irq(&phba->hbalock); | 4787 | spin_lock_irq(&phba->hbalock); |
@@ -4746,7 +4879,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba) | |||
4746 | 4879 | ||
4747 | els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); | 4880 | els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); |
4748 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 4881 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
4749 | "2400 lpfc_init_sgl_list els %d.\n", | 4882 | "2400 ELS XRI count %d.\n", |
4750 | els_xri_cnt); | 4883 | els_xri_cnt); |
4751 | /* Initialize and populate the sglq list per host/VF. */ | 4884 | /* Initialize and populate the sglq list per host/VF. */ |
4752 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list); | 4885 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list); |
@@ -4779,7 +4912,6 @@ lpfc_init_sgl_list(struct lpfc_hba *phba) | |||
4779 | phba->sli4_hba.scsi_xri_max = | 4912 | phba->sli4_hba.scsi_xri_max = |
4780 | phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt; | 4913 | phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt; |
4781 | phba->sli4_hba.scsi_xri_cnt = 0; | 4914 | phba->sli4_hba.scsi_xri_cnt = 0; |
4782 | |||
4783 | phba->sli4_hba.lpfc_scsi_psb_array = | 4915 | phba->sli4_hba.lpfc_scsi_psb_array = |
4784 | kzalloc((sizeof(struct lpfc_scsi_buf *) * | 4916 | kzalloc((sizeof(struct lpfc_scsi_buf *) * |
4785 | phba->sli4_hba.scsi_xri_max), GFP_KERNEL); | 4917 | phba->sli4_hba.scsi_xri_max), GFP_KERNEL); |
@@ -4802,13 +4934,6 @@ lpfc_init_sgl_list(struct lpfc_hba *phba) | |||
4802 | goto out_free_mem; | 4934 | goto out_free_mem; |
4803 | } | 4935 | } |
4804 | 4936 | ||
4805 | sglq_entry->sli4_xritag = lpfc_sli4_next_xritag(phba); | ||
4806 | if (sglq_entry->sli4_xritag == NO_XRI) { | ||
4807 | kfree(sglq_entry); | ||
4808 | printk(KERN_ERR "%s: failed to allocate XRI.\n" | ||
4809 | "Unloading driver.\n", __func__); | ||
4810 | goto out_free_mem; | ||
4811 | } | ||
4812 | sglq_entry->buff_type = GEN_BUFF_TYPE; | 4937 | sglq_entry->buff_type = GEN_BUFF_TYPE; |
4813 | sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, &sglq_entry->phys); | 4938 | sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, &sglq_entry->phys); |
4814 | if (sglq_entry->virt == NULL) { | 4939 | if (sglq_entry->virt == NULL) { |
@@ -4857,24 +4982,20 @@ int | |||
4857 | lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba) | 4982 | lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba) |
4858 | { | 4983 | { |
4859 | int rc = 0; | 4984 | int rc = 0; |
4860 | int longs; | ||
4861 | uint16_t rpi_count; | ||
4862 | struct lpfc_rpi_hdr *rpi_hdr; | 4985 | struct lpfc_rpi_hdr *rpi_hdr; |
4863 | 4986 | ||
4864 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list); | 4987 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list); |
4865 | |||
4866 | /* | 4988 | /* |
4867 | * Provision an rpi bitmask range for discovery. The total count | 4989 | * If the SLI4 port supports extents, posting the rpi header isn't |
4868 | * is the difference between max and base + 1. | 4990 | * required. Set the expected maximum count and let the actual value |
4991 | * get set when extents are fully allocated. | ||
4869 | */ | 4992 | */ |
4870 | rpi_count = phba->sli4_hba.max_cfg_param.rpi_base + | 4993 | if (!phba->sli4_hba.rpi_hdrs_in_use) { |
4871 | phba->sli4_hba.max_cfg_param.max_rpi - 1; | 4994 | phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.max_rpi; |
4872 | 4995 | return rc; | |
4873 | longs = ((rpi_count) + BITS_PER_LONG - 1) / BITS_PER_LONG; | 4996 | } |
4874 | phba->sli4_hba.rpi_bmask = kzalloc(longs * sizeof(unsigned long), | 4997 | if (phba->sli4_hba.extents_in_use) |
4875 | GFP_KERNEL); | 4998 | return -EIO; |
4876 | if (!phba->sli4_hba.rpi_bmask) | ||
4877 | return -ENOMEM; | ||
4878 | 4999 | ||
4879 | rpi_hdr = lpfc_sli4_create_rpi_hdr(phba); | 5000 | rpi_hdr = lpfc_sli4_create_rpi_hdr(phba); |
4880 | if (!rpi_hdr) { | 5001 | if (!rpi_hdr) { |
@@ -4908,11 +5029,28 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) | |||
4908 | struct lpfc_rpi_hdr *rpi_hdr; | 5029 | struct lpfc_rpi_hdr *rpi_hdr; |
4909 | uint32_t rpi_count; | 5030 | uint32_t rpi_count; |
4910 | 5031 | ||
5032 | /* | ||
5033 | * If the SLI4 port supports extents, posting the rpi header isn't | ||
5034 | * required. Set the expected maximum count and let the actual value | ||
5035 | * get set when extents are fully allocated. | ||
5036 | */ | ||
5037 | if (!phba->sli4_hba.rpi_hdrs_in_use) | ||
5038 | return NULL; | ||
5039 | if (phba->sli4_hba.extents_in_use) | ||
5040 | return NULL; | ||
5041 | |||
5042 | /* The limit on the logical index is just the max_rpi count. */ | ||
4911 | rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base + | 5043 | rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base + |
4912 | phba->sli4_hba.max_cfg_param.max_rpi - 1; | 5044 | phba->sli4_hba.max_cfg_param.max_rpi - 1; |
4913 | 5045 | ||
4914 | spin_lock_irq(&phba->hbalock); | 5046 | spin_lock_irq(&phba->hbalock); |
4915 | curr_rpi_range = phba->sli4_hba.next_rpi; | 5047 | /* |
5048 | * Establish the starting RPI in this header block. The starting | ||
5049 | * rpi is normalized to a zero base because the physical rpi is | ||
5050 | * port based. | ||
5051 | */ | ||
5052 | curr_rpi_range = phba->sli4_hba.next_rpi - | ||
5053 | phba->sli4_hba.max_cfg_param.rpi_base; | ||
4916 | spin_unlock_irq(&phba->hbalock); | 5054 | spin_unlock_irq(&phba->hbalock); |
4917 | 5055 | ||
4918 | /* | 5056 | /* |
@@ -4925,6 +5063,8 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) | |||
4925 | else | 5063 | else |
4926 | rpi_count = LPFC_RPI_HDR_COUNT; | 5064 | rpi_count = LPFC_RPI_HDR_COUNT; |
4927 | 5065 | ||
5066 | if (!rpi_count) | ||
5067 | return NULL; | ||
4928 | /* | 5068 | /* |
4929 | * First allocate the protocol header region for the port. The | 5069 | * First allocate the protocol header region for the port. The |
4930 | * port expects a 4KB DMA-mapped memory region that is 4K aligned. | 5070 | * port expects a 4KB DMA-mapped memory region that is 4K aligned. |
@@ -4957,12 +5097,14 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) | |||
4957 | rpi_hdr->len = LPFC_HDR_TEMPLATE_SIZE; | 5097 | rpi_hdr->len = LPFC_HDR_TEMPLATE_SIZE; |
4958 | rpi_hdr->page_count = 1; | 5098 | rpi_hdr->page_count = 1; |
4959 | spin_lock_irq(&phba->hbalock); | 5099 | spin_lock_irq(&phba->hbalock); |
4960 | rpi_hdr->start_rpi = phba->sli4_hba.next_rpi; | 5100 | |
5101 | /* The rpi_hdr stores the logical index only. */ | ||
5102 | rpi_hdr->start_rpi = curr_rpi_range; | ||
4961 | list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list); | 5103 | list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list); |
4962 | 5104 | ||
4963 | /* | 5105 | /* |
4964 | * The next_rpi stores the next module-64 rpi value to post | 5106 | * The next_rpi stores the next logical module-64 rpi value used |
4965 | * in any subsequent rpi memory region postings. | 5107 | * to post physical rpis in subsequent rpi postings. |
4966 | */ | 5108 | */ |
4967 | phba->sli4_hba.next_rpi += rpi_count; | 5109 | phba->sli4_hba.next_rpi += rpi_count; |
4968 | spin_unlock_irq(&phba->hbalock); | 5110 | spin_unlock_irq(&phba->hbalock); |
@@ -4981,15 +5123,18 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) | |||
4981 | * @phba: pointer to lpfc hba data structure. | 5123 | * @phba: pointer to lpfc hba data structure. |
4982 | * | 5124 | * |
4983 | * This routine is invoked to remove all memory resources allocated | 5125 | * This routine is invoked to remove all memory resources allocated |
4984 | * to support rpis. This routine presumes the caller has released all | 5126 | * to support rpis for SLI4 ports not supporting extents. This routine |
4985 | * rpis consumed by fabric or port logins and is prepared to have | 5127 | * presumes the caller has released all rpis consumed by fabric or port |
4986 | * the header pages removed. | 5128 | * logins and is prepared to have the header pages removed. |
4987 | **/ | 5129 | **/ |
4988 | void | 5130 | void |
4989 | lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba) | 5131 | lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba) |
4990 | { | 5132 | { |
4991 | struct lpfc_rpi_hdr *rpi_hdr, *next_rpi_hdr; | 5133 | struct lpfc_rpi_hdr *rpi_hdr, *next_rpi_hdr; |
4992 | 5134 | ||
5135 | if (!phba->sli4_hba.rpi_hdrs_in_use) | ||
5136 | goto exit; | ||
5137 | |||
4993 | list_for_each_entry_safe(rpi_hdr, next_rpi_hdr, | 5138 | list_for_each_entry_safe(rpi_hdr, next_rpi_hdr, |
4994 | &phba->sli4_hba.lpfc_rpi_hdr_list, list) { | 5139 | &phba->sli4_hba.lpfc_rpi_hdr_list, list) { |
4995 | list_del(&rpi_hdr->list); | 5140 | list_del(&rpi_hdr->list); |
@@ -4998,9 +5143,9 @@ lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba) | |||
4998 | kfree(rpi_hdr->dmabuf); | 5143 | kfree(rpi_hdr->dmabuf); |
4999 | kfree(rpi_hdr); | 5144 | kfree(rpi_hdr); |
5000 | } | 5145 | } |
5001 | 5146 | exit: | |
5002 | phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base; | 5147 | /* There are no rpis available to the port now. */ |
5003 | memset(phba->sli4_hba.rpi_bmask, 0, sizeof(*phba->sli4_hba.rpi_bmask)); | 5148 | phba->sli4_hba.next_rpi = 0; |
5004 | } | 5149 | } |
5005 | 5150 | ||
5006 | /** | 5151 | /** |
@@ -5487,7 +5632,8 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) | |||
5487 | /* Final checks. The port status should be clean. */ | 5632 | /* Final checks. The port status should be clean. */ |
5488 | if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, | 5633 | if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, |
5489 | ®_data.word0) || | 5634 | ®_data.word0) || |
5490 | bf_get(lpfc_sliport_status_err, ®_data)) { | 5635 | (bf_get(lpfc_sliport_status_err, ®_data) && |
5636 | !bf_get(lpfc_sliport_status_rn, ®_data))) { | ||
5491 | phba->work_status[0] = | 5637 | phba->work_status[0] = |
5492 | readl(phba->sli4_hba.u.if_type2. | 5638 | readl(phba->sli4_hba.u.if_type2. |
5493 | ERR1regaddr); | 5639 | ERR1regaddr); |
@@ -5741,7 +5887,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5741 | { | 5887 | { |
5742 | LPFC_MBOXQ_t *pmb; | 5888 | LPFC_MBOXQ_t *pmb; |
5743 | struct lpfc_mbx_read_config *rd_config; | 5889 | struct lpfc_mbx_read_config *rd_config; |
5744 | uint32_t rc = 0; | 5890 | union lpfc_sli4_cfg_shdr *shdr; |
5891 | uint32_t shdr_status, shdr_add_status; | ||
5892 | struct lpfc_mbx_get_func_cfg *get_func_cfg; | ||
5893 | struct lpfc_rsrc_desc_fcfcoe *desc; | ||
5894 | uint32_t desc_count; | ||
5895 | int length, i, rc = 0; | ||
5745 | 5896 | ||
5746 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5897 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
5747 | if (!pmb) { | 5898 | if (!pmb) { |
@@ -5763,6 +5914,8 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5763 | rc = -EIO; | 5914 | rc = -EIO; |
5764 | } else { | 5915 | } else { |
5765 | rd_config = &pmb->u.mqe.un.rd_config; | 5916 | rd_config = &pmb->u.mqe.un.rd_config; |
5917 | phba->sli4_hba.extents_in_use = | ||
5918 | bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config); | ||
5766 | phba->sli4_hba.max_cfg_param.max_xri = | 5919 | phba->sli4_hba.max_cfg_param.max_xri = |
5767 | bf_get(lpfc_mbx_rd_conf_xri_count, rd_config); | 5920 | bf_get(lpfc_mbx_rd_conf_xri_count, rd_config); |
5768 | phba->sli4_hba.max_cfg_param.xri_base = | 5921 | phba->sli4_hba.max_cfg_param.xri_base = |
@@ -5781,8 +5934,6 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5781 | bf_get(lpfc_mbx_rd_conf_vfi_base, rd_config); | 5934 | bf_get(lpfc_mbx_rd_conf_vfi_base, rd_config); |
5782 | phba->sli4_hba.max_cfg_param.max_fcfi = | 5935 | phba->sli4_hba.max_cfg_param.max_fcfi = |
5783 | bf_get(lpfc_mbx_rd_conf_fcfi_count, rd_config); | 5936 | bf_get(lpfc_mbx_rd_conf_fcfi_count, rd_config); |
5784 | phba->sli4_hba.max_cfg_param.fcfi_base = | ||
5785 | bf_get(lpfc_mbx_rd_conf_fcfi_base, rd_config); | ||
5786 | phba->sli4_hba.max_cfg_param.max_eq = | 5937 | phba->sli4_hba.max_cfg_param.max_eq = |
5787 | bf_get(lpfc_mbx_rd_conf_eq_count, rd_config); | 5938 | bf_get(lpfc_mbx_rd_conf_eq_count, rd_config); |
5788 | phba->sli4_hba.max_cfg_param.max_rq = | 5939 | phba->sli4_hba.max_cfg_param.max_rq = |
@@ -5800,11 +5951,13 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5800 | (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0; | 5951 | (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0; |
5801 | phba->max_vports = phba->max_vpi; | 5952 | phba->max_vports = phba->max_vpi; |
5802 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 5953 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
5803 | "2003 cfg params XRI(B:%d M:%d), " | 5954 | "2003 cfg params Extents? %d " |
5955 | "XRI(B:%d M:%d), " | ||
5804 | "VPI(B:%d M:%d) " | 5956 | "VPI(B:%d M:%d) " |
5805 | "VFI(B:%d M:%d) " | 5957 | "VFI(B:%d M:%d) " |
5806 | "RPI(B:%d M:%d) " | 5958 | "RPI(B:%d M:%d) " |
5807 | "FCFI(B:%d M:%d)\n", | 5959 | "FCFI(Count:%d)\n", |
5960 | phba->sli4_hba.extents_in_use, | ||
5808 | phba->sli4_hba.max_cfg_param.xri_base, | 5961 | phba->sli4_hba.max_cfg_param.xri_base, |
5809 | phba->sli4_hba.max_cfg_param.max_xri, | 5962 | phba->sli4_hba.max_cfg_param.max_xri, |
5810 | phba->sli4_hba.max_cfg_param.vpi_base, | 5963 | phba->sli4_hba.max_cfg_param.vpi_base, |
@@ -5813,10 +5966,11 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5813 | phba->sli4_hba.max_cfg_param.max_vfi, | 5966 | phba->sli4_hba.max_cfg_param.max_vfi, |
5814 | phba->sli4_hba.max_cfg_param.rpi_base, | 5967 | phba->sli4_hba.max_cfg_param.rpi_base, |
5815 | phba->sli4_hba.max_cfg_param.max_rpi, | 5968 | phba->sli4_hba.max_cfg_param.max_rpi, |
5816 | phba->sli4_hba.max_cfg_param.fcfi_base, | ||
5817 | phba->sli4_hba.max_cfg_param.max_fcfi); | 5969 | phba->sli4_hba.max_cfg_param.max_fcfi); |
5818 | } | 5970 | } |
5819 | mempool_free(pmb, phba->mbox_mem_pool); | 5971 | |
5972 | if (rc) | ||
5973 | goto read_cfg_out; | ||
5820 | 5974 | ||
5821 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ | 5975 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ |
5822 | if (phba->cfg_hba_queue_depth > | 5976 | if (phba->cfg_hba_queue_depth > |
@@ -5825,6 +5979,65 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5825 | phba->cfg_hba_queue_depth = | 5979 | phba->cfg_hba_queue_depth = |
5826 | phba->sli4_hba.max_cfg_param.max_xri - | 5980 | phba->sli4_hba.max_cfg_param.max_xri - |
5827 | lpfc_sli4_get_els_iocb_cnt(phba); | 5981 | lpfc_sli4_get_els_iocb_cnt(phba); |
5982 | |||
5983 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
5984 | LPFC_SLI_INTF_IF_TYPE_2) | ||
5985 | goto read_cfg_out; | ||
5986 | |||
5987 | /* get the pf# and vf# for SLI4 if_type 2 port */ | ||
5988 | length = (sizeof(struct lpfc_mbx_get_func_cfg) - | ||
5989 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
5990 | lpfc_sli4_config(phba, pmb, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
5991 | LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG, | ||
5992 | length, LPFC_SLI4_MBX_EMBED); | ||
5993 | |||
5994 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | ||
5995 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
5996 | &pmb->u.mqe.un.sli4_config.header.cfg_shdr; | ||
5997 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
5998 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
5999 | if (rc || shdr_status || shdr_add_status) { | ||
6000 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
6001 | "3026 Mailbox failed , mbxCmd x%x " | ||
6002 | "GET_FUNCTION_CONFIG, mbxStatus x%x\n", | ||
6003 | bf_get(lpfc_mqe_command, &pmb->u.mqe), | ||
6004 | bf_get(lpfc_mqe_status, &pmb->u.mqe)); | ||
6005 | rc = -EIO; | ||
6006 | goto read_cfg_out; | ||
6007 | } | ||
6008 | |||
6009 | /* search for fc_fcoe resrouce descriptor */ | ||
6010 | get_func_cfg = &pmb->u.mqe.un.get_func_cfg; | ||
6011 | desc_count = get_func_cfg->func_cfg.rsrc_desc_count; | ||
6012 | |||
6013 | for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) { | ||
6014 | desc = (struct lpfc_rsrc_desc_fcfcoe *) | ||
6015 | &get_func_cfg->func_cfg.desc[i]; | ||
6016 | if (LPFC_RSRC_DESC_TYPE_FCFCOE == | ||
6017 | bf_get(lpfc_rsrc_desc_pcie_type, desc)) { | ||
6018 | phba->sli4_hba.iov.pf_number = | ||
6019 | bf_get(lpfc_rsrc_desc_fcfcoe_pfnum, desc); | ||
6020 | phba->sli4_hba.iov.vf_number = | ||
6021 | bf_get(lpfc_rsrc_desc_fcfcoe_vfnum, desc); | ||
6022 | break; | ||
6023 | } | ||
6024 | } | ||
6025 | |||
6026 | if (i < LPFC_RSRC_DESC_MAX_NUM) | ||
6027 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
6028 | "3027 GET_FUNCTION_CONFIG: pf_number:%d, " | ||
6029 | "vf_number:%d\n", phba->sli4_hba.iov.pf_number, | ||
6030 | phba->sli4_hba.iov.vf_number); | ||
6031 | else { | ||
6032 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
6033 | "3028 GET_FUNCTION_CONFIG: failed to find " | ||
6034 | "Resrouce Descriptor:x%x\n", | ||
6035 | LPFC_RSRC_DESC_TYPE_FCFCOE); | ||
6036 | rc = -EIO; | ||
6037 | } | ||
6038 | |||
6039 | read_cfg_out: | ||
6040 | mempool_free(pmb, phba->mbox_mem_pool); | ||
5828 | return rc; | 6041 | return rc; |
5829 | } | 6042 | } |
5830 | 6043 | ||
@@ -6229,8 +6442,10 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba) | |||
6229 | phba->sli4_hba.mbx_cq = NULL; | 6442 | phba->sli4_hba.mbx_cq = NULL; |
6230 | 6443 | ||
6231 | /* Release FCP response complete queue */ | 6444 | /* Release FCP response complete queue */ |
6232 | for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) | 6445 | fcp_qidx = 0; |
6446 | do | ||
6233 | lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_qidx]); | 6447 | lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_qidx]); |
6448 | while (++fcp_qidx < phba->cfg_fcp_eq_count); | ||
6234 | kfree(phba->sli4_hba.fcp_cq); | 6449 | kfree(phba->sli4_hba.fcp_cq); |
6235 | phba->sli4_hba.fcp_cq = NULL; | 6450 | phba->sli4_hba.fcp_cq = NULL; |
6236 | 6451 | ||
@@ -6353,16 +6568,24 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) | |||
6353 | phba->sli4_hba.sp_eq->queue_id); | 6568 | phba->sli4_hba.sp_eq->queue_id); |
6354 | 6569 | ||
6355 | /* Set up fast-path FCP Response Complete Queue */ | 6570 | /* Set up fast-path FCP Response Complete Queue */ |
6356 | for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) { | 6571 | fcp_cqidx = 0; |
6572 | do { | ||
6357 | if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) { | 6573 | if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) { |
6358 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 6574 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
6359 | "0526 Fast-path FCP CQ (%d) not " | 6575 | "0526 Fast-path FCP CQ (%d) not " |
6360 | "allocated\n", fcp_cqidx); | 6576 | "allocated\n", fcp_cqidx); |
6361 | goto out_destroy_fcp_cq; | 6577 | goto out_destroy_fcp_cq; |
6362 | } | 6578 | } |
6363 | rc = lpfc_cq_create(phba, phba->sli4_hba.fcp_cq[fcp_cqidx], | 6579 | if (phba->cfg_fcp_eq_count) |
6364 | phba->sli4_hba.fp_eq[fcp_cqidx], | 6580 | rc = lpfc_cq_create(phba, |
6365 | LPFC_WCQ, LPFC_FCP); | 6581 | phba->sli4_hba.fcp_cq[fcp_cqidx], |
6582 | phba->sli4_hba.fp_eq[fcp_cqidx], | ||
6583 | LPFC_WCQ, LPFC_FCP); | ||
6584 | else | ||
6585 | rc = lpfc_cq_create(phba, | ||
6586 | phba->sli4_hba.fcp_cq[fcp_cqidx], | ||
6587 | phba->sli4_hba.sp_eq, | ||
6588 | LPFC_WCQ, LPFC_FCP); | ||
6366 | if (rc) { | 6589 | if (rc) { |
6367 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 6590 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
6368 | "0527 Failed setup of fast-path FCP " | 6591 | "0527 Failed setup of fast-path FCP " |
@@ -6371,12 +6594,15 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) | |||
6371 | } | 6594 | } |
6372 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 6595 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
6373 | "2588 FCP CQ setup: cq[%d]-id=%d, " | 6596 | "2588 FCP CQ setup: cq[%d]-id=%d, " |
6374 | "parent eq[%d]-id=%d\n", | 6597 | "parent %seq[%d]-id=%d\n", |
6375 | fcp_cqidx, | 6598 | fcp_cqidx, |
6376 | phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id, | 6599 | phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id, |
6600 | (phba->cfg_fcp_eq_count) ? "" : "sp_", | ||
6377 | fcp_cqidx, | 6601 | fcp_cqidx, |
6378 | phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id); | 6602 | (phba->cfg_fcp_eq_count) ? |
6379 | } | 6603 | phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id : |
6604 | phba->sli4_hba.sp_eq->queue_id); | ||
6605 | } while (++fcp_cqidx < phba->cfg_fcp_eq_count); | ||
6380 | 6606 | ||
6381 | /* | 6607 | /* |
6382 | * Set up all the Work Queues (WQs) | 6608 | * Set up all the Work Queues (WQs) |
@@ -6445,7 +6671,9 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) | |||
6445 | fcp_cq_index, | 6671 | fcp_cq_index, |
6446 | phba->sli4_hba.fcp_cq[fcp_cq_index]->queue_id); | 6672 | phba->sli4_hba.fcp_cq[fcp_cq_index]->queue_id); |
6447 | /* Round robin FCP Work Queue's Completion Queue assignment */ | 6673 | /* Round robin FCP Work Queue's Completion Queue assignment */ |
6448 | fcp_cq_index = ((fcp_cq_index + 1) % phba->cfg_fcp_eq_count); | 6674 | if (phba->cfg_fcp_eq_count) |
6675 | fcp_cq_index = ((fcp_cq_index + 1) % | ||
6676 | phba->cfg_fcp_eq_count); | ||
6449 | } | 6677 | } |
6450 | 6678 | ||
6451 | /* | 6679 | /* |
@@ -6827,6 +7055,8 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) | |||
6827 | if (rdy_chk < 1000) | 7055 | if (rdy_chk < 1000) |
6828 | break; | 7056 | break; |
6829 | } | 7057 | } |
7058 | /* delay driver action following IF_TYPE_2 function reset */ | ||
7059 | msleep(100); | ||
6830 | break; | 7060 | break; |
6831 | case LPFC_SLI_INTF_IF_TYPE_1: | 7061 | case LPFC_SLI_INTF_IF_TYPE_1: |
6832 | default: | 7062 | default: |
@@ -7419,11 +7649,15 @@ enable_msix_vectors: | |||
7419 | /* | 7649 | /* |
7420 | * Assign MSI-X vectors to interrupt handlers | 7650 | * Assign MSI-X vectors to interrupt handlers |
7421 | */ | 7651 | */ |
7422 | 7652 | if (vectors > 1) | |
7423 | /* The first vector must associated to slow-path handler for MQ */ | 7653 | rc = request_irq(phba->sli4_hba.msix_entries[0].vector, |
7424 | rc = request_irq(phba->sli4_hba.msix_entries[0].vector, | 7654 | &lpfc_sli4_sp_intr_handler, IRQF_SHARED, |
7425 | &lpfc_sli4_sp_intr_handler, IRQF_SHARED, | 7655 | LPFC_SP_DRIVER_HANDLER_NAME, phba); |
7426 | LPFC_SP_DRIVER_HANDLER_NAME, phba); | 7656 | else |
7657 | /* All Interrupts need to be handled by one EQ */ | ||
7658 | rc = request_irq(phba->sli4_hba.msix_entries[0].vector, | ||
7659 | &lpfc_sli4_intr_handler, IRQF_SHARED, | ||
7660 | LPFC_DRIVER_NAME, phba); | ||
7427 | if (rc) { | 7661 | if (rc) { |
7428 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 7662 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
7429 | "0485 MSI-X slow-path request_irq failed " | 7663 | "0485 MSI-X slow-path request_irq failed " |
@@ -7765,6 +7999,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) | |||
7765 | { | 7999 | { |
7766 | int wait_cnt = 0; | 8000 | int wait_cnt = 0; |
7767 | LPFC_MBOXQ_t *mboxq; | 8001 | LPFC_MBOXQ_t *mboxq; |
8002 | struct pci_dev *pdev = phba->pcidev; | ||
7768 | 8003 | ||
7769 | lpfc_stop_hba_timers(phba); | 8004 | lpfc_stop_hba_timers(phba); |
7770 | phba->sli4_hba.intr_enable = 0; | 8005 | phba->sli4_hba.intr_enable = 0; |
@@ -7804,6 +8039,10 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) | |||
7804 | /* Disable PCI subsystem interrupt */ | 8039 | /* Disable PCI subsystem interrupt */ |
7805 | lpfc_sli4_disable_intr(phba); | 8040 | lpfc_sli4_disable_intr(phba); |
7806 | 8041 | ||
8042 | /* Disable SR-IOV if enabled */ | ||
8043 | if (phba->cfg_sriov_nr_virtfn) | ||
8044 | pci_disable_sriov(pdev); | ||
8045 | |||
7807 | /* Stop kthread signal shall trigger work_done one more time */ | 8046 | /* Stop kthread signal shall trigger work_done one more time */ |
7808 | kthread_stop(phba->worker_thread); | 8047 | kthread_stop(phba->worker_thread); |
7809 | 8048 | ||
@@ -7878,6 +8117,11 @@ lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
7878 | sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); | 8117 | sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); |
7879 | sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); | 8118 | sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); |
7880 | sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); | 8119 | sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); |
8120 | |||
8121 | /* Make sure that sge_supp_len can be handled by the driver */ | ||
8122 | if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) | ||
8123 | sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; | ||
8124 | |||
7881 | return rc; | 8125 | return rc; |
7882 | } | 8126 | } |
7883 | 8127 | ||
@@ -7902,6 +8146,13 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
7902 | int length; | 8146 | int length; |
7903 | struct lpfc_sli4_parameters *mbx_sli4_parameters; | 8147 | struct lpfc_sli4_parameters *mbx_sli4_parameters; |
7904 | 8148 | ||
8149 | /* | ||
8150 | * By default, the driver assumes the SLI4 port requires RPI | ||
8151 | * header postings. The SLI4_PARAM response will correct this | ||
8152 | * assumption. | ||
8153 | */ | ||
8154 | phba->sli4_hba.rpi_hdrs_in_use = 1; | ||
8155 | |||
7905 | /* Read the port's SLI4 Config Parameters */ | 8156 | /* Read the port's SLI4 Config Parameters */ |
7906 | length = (sizeof(struct lpfc_mbx_get_sli4_parameters) - | 8157 | length = (sizeof(struct lpfc_mbx_get_sli4_parameters) - |
7907 | sizeof(struct lpfc_sli4_cfg_mhdr)); | 8158 | sizeof(struct lpfc_sli4_cfg_mhdr)); |
@@ -7938,6 +8189,13 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
7938 | mbx_sli4_parameters); | 8189 | mbx_sli4_parameters); |
7939 | sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align, | 8190 | sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align, |
7940 | mbx_sli4_parameters); | 8191 | mbx_sli4_parameters); |
8192 | phba->sli4_hba.extents_in_use = bf_get(cfg_ext, mbx_sli4_parameters); | ||
8193 | phba->sli4_hba.rpi_hdrs_in_use = bf_get(cfg_hdrr, mbx_sli4_parameters); | ||
8194 | |||
8195 | /* Make sure that sge_supp_len can be handled by the driver */ | ||
8196 | if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) | ||
8197 | sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; | ||
8198 | |||
7941 | return 0; | 8199 | return 0; |
7942 | } | 8200 | } |
7943 | 8201 | ||
@@ -8173,6 +8431,10 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
8173 | 8431 | ||
8174 | lpfc_debugfs_terminate(vport); | 8432 | lpfc_debugfs_terminate(vport); |
8175 | 8433 | ||
8434 | /* Disable SR-IOV if enabled */ | ||
8435 | if (phba->cfg_sriov_nr_virtfn) | ||
8436 | pci_disable_sriov(pdev); | ||
8437 | |||
8176 | /* Disable interrupt */ | 8438 | /* Disable interrupt */ |
8177 | lpfc_sli_disable_intr(phba); | 8439 | lpfc_sli_disable_intr(phba); |
8178 | 8440 | ||
@@ -8565,6 +8827,97 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) | |||
8565 | } | 8827 | } |
8566 | 8828 | ||
8567 | /** | 8829 | /** |
8830 | * lpfc_write_firmware - attempt to write a firmware image to the port | ||
8831 | * @phba: pointer to lpfc hba data structure. | ||
8832 | * @fw: pointer to firmware image returned from request_firmware. | ||
8833 | * | ||
8834 | * returns the number of bytes written if write is successful. | ||
8835 | * returns a negative error value if there were errors. | ||
8836 | * returns 0 if firmware matches currently active firmware on port. | ||
8837 | **/ | ||
8838 | int | ||
8839 | lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | ||
8840 | { | ||
8841 | char fwrev[32]; | ||
8842 | struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data; | ||
8843 | struct list_head dma_buffer_list; | ||
8844 | int i, rc = 0; | ||
8845 | struct lpfc_dmabuf *dmabuf, *next; | ||
8846 | uint32_t offset = 0, temp_offset = 0; | ||
8847 | |||
8848 | INIT_LIST_HEAD(&dma_buffer_list); | ||
8849 | if ((image->magic_number != LPFC_GROUP_OJECT_MAGIC_NUM) || | ||
8850 | (bf_get(lpfc_grp_hdr_file_type, image) != LPFC_FILE_TYPE_GROUP) || | ||
8851 | (bf_get(lpfc_grp_hdr_id, image) != LPFC_FILE_ID_GROUP) || | ||
8852 | (image->size != fw->size)) { | ||
8853 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8854 | "3022 Invalid FW image found. " | ||
8855 | "Magic:%d Type:%x ID:%x\n", | ||
8856 | image->magic_number, | ||
8857 | bf_get(lpfc_grp_hdr_file_type, image), | ||
8858 | bf_get(lpfc_grp_hdr_id, image)); | ||
8859 | return -EINVAL; | ||
8860 | } | ||
8861 | lpfc_decode_firmware_rev(phba, fwrev, 1); | ||
8862 | if (strncmp(fwrev, image->rev_name, strnlen(fwrev, 16))) { | ||
8863 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8864 | "3023 Updating Firmware. Current Version:%s " | ||
8865 | "New Version:%s\n", | ||
8866 | fwrev, image->rev_name); | ||
8867 | for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { | ||
8868 | dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), | ||
8869 | GFP_KERNEL); | ||
8870 | if (!dmabuf) { | ||
8871 | rc = -ENOMEM; | ||
8872 | goto out; | ||
8873 | } | ||
8874 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, | ||
8875 | SLI4_PAGE_SIZE, | ||
8876 | &dmabuf->phys, | ||
8877 | GFP_KERNEL); | ||
8878 | if (!dmabuf->virt) { | ||
8879 | kfree(dmabuf); | ||
8880 | rc = -ENOMEM; | ||
8881 | goto out; | ||
8882 | } | ||
8883 | list_add_tail(&dmabuf->list, &dma_buffer_list); | ||
8884 | } | ||
8885 | while (offset < fw->size) { | ||
8886 | temp_offset = offset; | ||
8887 | list_for_each_entry(dmabuf, &dma_buffer_list, list) { | ||
8888 | if (offset + SLI4_PAGE_SIZE > fw->size) { | ||
8889 | temp_offset += fw->size - offset; | ||
8890 | memcpy(dmabuf->virt, | ||
8891 | fw->data + temp_offset, | ||
8892 | fw->size - offset); | ||
8893 | break; | ||
8894 | } | ||
8895 | temp_offset += SLI4_PAGE_SIZE; | ||
8896 | memcpy(dmabuf->virt, fw->data + temp_offset, | ||
8897 | SLI4_PAGE_SIZE); | ||
8898 | } | ||
8899 | rc = lpfc_wr_object(phba, &dma_buffer_list, | ||
8900 | (fw->size - offset), &offset); | ||
8901 | if (rc) { | ||
8902 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8903 | "3024 Firmware update failed. " | ||
8904 | "%d\n", rc); | ||
8905 | goto out; | ||
8906 | } | ||
8907 | } | ||
8908 | rc = offset; | ||
8909 | } | ||
8910 | out: | ||
8911 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { | ||
8912 | list_del(&dmabuf->list); | ||
8913 | dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE, | ||
8914 | dmabuf->virt, dmabuf->phys); | ||
8915 | kfree(dmabuf); | ||
8916 | } | ||
8917 | return rc; | ||
8918 | } | ||
8919 | |||
8920 | /** | ||
8568 | * lpfc_pci_probe_one_s4 - PCI probe func to reg SLI-4 device to PCI subsys | 8921 | * lpfc_pci_probe_one_s4 - PCI probe func to reg SLI-4 device to PCI subsys |
8569 | * @pdev: pointer to PCI device | 8922 | * @pdev: pointer to PCI device |
8570 | * @pid: pointer to PCI device identifier | 8923 | * @pid: pointer to PCI device identifier |
@@ -8591,6 +8944,10 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8591 | int error; | 8944 | int error; |
8592 | uint32_t cfg_mode, intr_mode; | 8945 | uint32_t cfg_mode, intr_mode; |
8593 | int mcnt; | 8946 | int mcnt; |
8947 | int adjusted_fcp_eq_count; | ||
8948 | int fcp_qidx; | ||
8949 | const struct firmware *fw; | ||
8950 | uint8_t file_name[16]; | ||
8594 | 8951 | ||
8595 | /* Allocate memory for HBA structure */ | 8952 | /* Allocate memory for HBA structure */ |
8596 | phba = lpfc_hba_alloc(pdev); | 8953 | phba = lpfc_hba_alloc(pdev); |
@@ -8688,11 +9045,25 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8688 | error = -ENODEV; | 9045 | error = -ENODEV; |
8689 | goto out_free_sysfs_attr; | 9046 | goto out_free_sysfs_attr; |
8690 | } | 9047 | } |
8691 | /* Default to single FCP EQ for non-MSI-X */ | 9048 | /* Default to single EQ for non-MSI-X */ |
8692 | if (phba->intr_type != MSIX) | 9049 | if (phba->intr_type != MSIX) |
8693 | phba->cfg_fcp_eq_count = 1; | 9050 | adjusted_fcp_eq_count = 0; |
8694 | else if (phba->sli4_hba.msix_vec_nr < phba->cfg_fcp_eq_count) | 9051 | else if (phba->sli4_hba.msix_vec_nr < |
8695 | phba->cfg_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1; | 9052 | phba->cfg_fcp_eq_count + 1) |
9053 | adjusted_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1; | ||
9054 | else | ||
9055 | adjusted_fcp_eq_count = phba->cfg_fcp_eq_count; | ||
9056 | /* Free unused EQs */ | ||
9057 | for (fcp_qidx = adjusted_fcp_eq_count; | ||
9058 | fcp_qidx < phba->cfg_fcp_eq_count; | ||
9059 | fcp_qidx++) { | ||
9060 | lpfc_sli4_queue_free(phba->sli4_hba.fp_eq[fcp_qidx]); | ||
9061 | /* do not delete the first fcp_cq */ | ||
9062 | if (fcp_qidx) | ||
9063 | lpfc_sli4_queue_free( | ||
9064 | phba->sli4_hba.fcp_cq[fcp_qidx]); | ||
9065 | } | ||
9066 | phba->cfg_fcp_eq_count = adjusted_fcp_eq_count; | ||
8696 | /* Set up SLI-4 HBA */ | 9067 | /* Set up SLI-4 HBA */ |
8697 | if (lpfc_sli4_hba_setup(phba)) { | 9068 | if (lpfc_sli4_hba_setup(phba)) { |
8698 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9069 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -8731,6 +9102,14 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8731 | /* Perform post initialization setup */ | 9102 | /* Perform post initialization setup */ |
8732 | lpfc_post_init_setup(phba); | 9103 | lpfc_post_init_setup(phba); |
8733 | 9104 | ||
9105 | /* check for firmware upgrade or downgrade */ | ||
9106 | snprintf(file_name, 16, "%s.grp", phba->ModelName); | ||
9107 | error = request_firmware(&fw, file_name, &phba->pcidev->dev); | ||
9108 | if (!error) { | ||
9109 | lpfc_write_firmware(phba, fw); | ||
9110 | release_firmware(fw); | ||
9111 | } | ||
9112 | |||
8734 | /* Check if there are static vports to be created. */ | 9113 | /* Check if there are static vports to be created. */ |
8735 | lpfc_create_static_vport(phba); | 9114 | lpfc_create_static_vport(phba); |
8736 | 9115 | ||
@@ -9498,6 +9877,10 @@ static struct pci_device_id lpfc_id_table[] = { | |||
9498 | PCI_ANY_ID, PCI_ANY_ID, }, | 9877 | PCI_ANY_ID, PCI_ANY_ID, }, |
9499 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE, | 9878 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE, |
9500 | PCI_ANY_ID, PCI_ANY_ID, }, | 9879 | PCI_ANY_ID, PCI_ANY_ID, }, |
9880 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FC_VF, | ||
9881 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
9882 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE_VF, | ||
9883 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
9501 | { 0 } | 9884 | { 0 } |
9502 | }; | 9885 | }; |
9503 | 9886 | ||
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index e6ce9033f85e..556767028353 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -610,7 +610,8 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) | |||
610 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); | 610 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); |
611 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); | 611 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); |
612 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); | 612 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); |
613 | mb->un.varRdSparm.vpi = vpi + phba->vpi_base; | 613 | if (phba->sli_rev >= LPFC_SLI_REV3) |
614 | mb->un.varRdSparm.vpi = phba->vpi_ids[vpi]; | ||
614 | 615 | ||
615 | /* save address for completion */ | 616 | /* save address for completion */ |
616 | pmb->context1 = mp; | 617 | pmb->context1 = mp; |
@@ -643,9 +644,10 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did, | |||
643 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 644 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
644 | 645 | ||
645 | mb->un.varUnregDID.did = did; | 646 | mb->un.varUnregDID.did = did; |
646 | if (vpi != 0xffff) | ||
647 | vpi += phba->vpi_base; | ||
648 | mb->un.varUnregDID.vpi = vpi; | 647 | mb->un.varUnregDID.vpi = vpi; |
648 | if ((vpi != 0xffff) && | ||
649 | (phba->sli_rev == LPFC_SLI_REV4)) | ||
650 | mb->un.varUnregDID.vpi = phba->vpi_ids[vpi]; | ||
649 | 651 | ||
650 | mb->mbxCommand = MBX_UNREG_D_ID; | 652 | mb->mbxCommand = MBX_UNREG_D_ID; |
651 | mb->mbxOwner = OWN_HOST; | 653 | mb->mbxOwner = OWN_HOST; |
@@ -738,12 +740,10 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, | |||
738 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 740 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
739 | 741 | ||
740 | mb->un.varRegLogin.rpi = 0; | 742 | mb->un.varRegLogin.rpi = 0; |
741 | if (phba->sli_rev == LPFC_SLI_REV4) { | 743 | if (phba->sli_rev == LPFC_SLI_REV4) |
742 | mb->un.varRegLogin.rpi = rpi; | 744 | mb->un.varRegLogin.rpi = phba->sli4_hba.rpi_ids[rpi]; |
743 | if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR) | 745 | if (phba->sli_rev >= LPFC_SLI_REV3) |
744 | return 1; | 746 | mb->un.varRegLogin.vpi = phba->vpi_ids[vpi]; |
745 | } | ||
746 | mb->un.varRegLogin.vpi = vpi + phba->vpi_base; | ||
747 | mb->un.varRegLogin.did = did; | 747 | mb->un.varRegLogin.did = did; |
748 | mb->mbxOwner = OWN_HOST; | 748 | mb->mbxOwner = OWN_HOST; |
749 | /* Get a buffer to hold NPorts Service Parameters */ | 749 | /* Get a buffer to hold NPorts Service Parameters */ |
@@ -757,7 +757,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, | |||
757 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | 757 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, |
758 | "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, " | 758 | "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, " |
759 | "rpi x%x\n", vpi, did, rpi); | 759 | "rpi x%x\n", vpi, did, rpi); |
760 | return (1); | 760 | return 1; |
761 | } | 761 | } |
762 | INIT_LIST_HEAD(&mp->list); | 762 | INIT_LIST_HEAD(&mp->list); |
763 | sparam = mp->virt; | 763 | sparam = mp->virt; |
@@ -773,7 +773,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, | |||
773 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); | 773 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); |
774 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); | 774 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); |
775 | 775 | ||
776 | return (0); | 776 | return 0; |
777 | } | 777 | } |
778 | 778 | ||
779 | /** | 779 | /** |
@@ -789,6 +789,9 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, | |||
789 | * | 789 | * |
790 | * This routine prepares the mailbox command for unregistering remote port | 790 | * This routine prepares the mailbox command for unregistering remote port |
791 | * login. | 791 | * login. |
792 | * | ||
793 | * For SLI4 ports, the rpi passed to this function must be the physical | ||
794 | * rpi value, not the logical index. | ||
792 | **/ | 795 | **/ |
793 | void | 796 | void |
794 | lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, | 797 | lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, |
@@ -799,9 +802,10 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, | |||
799 | mb = &pmb->u.mb; | 802 | mb = &pmb->u.mb; |
800 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 803 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
801 | 804 | ||
802 | mb->un.varUnregLogin.rpi = (uint16_t) rpi; | 805 | mb->un.varUnregLogin.rpi = rpi; |
803 | mb->un.varUnregLogin.rsvd1 = 0; | 806 | mb->un.varUnregLogin.rsvd1 = 0; |
804 | mb->un.varUnregLogin.vpi = vpi + phba->vpi_base; | 807 | if (phba->sli_rev >= LPFC_SLI_REV3) |
808 | mb->un.varUnregLogin.vpi = phba->vpi_ids[vpi]; | ||
805 | 809 | ||
806 | mb->mbxCommand = MBX_UNREG_LOGIN; | 810 | mb->mbxCommand = MBX_UNREG_LOGIN; |
807 | mb->mbxOwner = OWN_HOST; | 811 | mb->mbxOwner = OWN_HOST; |
@@ -825,9 +829,16 @@ lpfc_sli4_unreg_all_rpis(struct lpfc_vport *vport) | |||
825 | 829 | ||
826 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 830 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
827 | if (mbox) { | 831 | if (mbox) { |
828 | lpfc_unreg_login(phba, vport->vpi, | 832 | /* |
829 | vport->vpi + phba->vpi_base, mbox); | 833 | * For SLI4 functions, the rpi field is overloaded for |
830 | mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000 ; | 834 | * the vport context unreg all. This routine passes |
835 | * 0 for the rpi field in lpfc_unreg_login for compatibility | ||
836 | * with SLI3 and then overrides the rpi field with the | ||
837 | * expected value for SLI4. | ||
838 | */ | ||
839 | lpfc_unreg_login(phba, vport->vpi, phba->vpi_ids[vport->vpi], | ||
840 | mbox); | ||
841 | mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000; | ||
831 | mbox->vport = vport; | 842 | mbox->vport = vport; |
832 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 843 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
833 | mbox->context1 = NULL; | 844 | mbox->context1 = NULL; |
@@ -865,9 +876,13 @@ lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) | |||
865 | if ((phba->sli_rev == LPFC_SLI_REV4) && | 876 | if ((phba->sli_rev == LPFC_SLI_REV4) && |
866 | !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) | 877 | !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) |
867 | mb->un.varRegVpi.upd = 1; | 878 | mb->un.varRegVpi.upd = 1; |
868 | mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; | 879 | |
880 | mb->un.varRegVpi.vpi = phba->vpi_ids[vport->vpi]; | ||
869 | mb->un.varRegVpi.sid = vport->fc_myDID; | 881 | mb->un.varRegVpi.sid = vport->fc_myDID; |
870 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; | 882 | if (phba->sli_rev == LPFC_SLI_REV4) |
883 | mb->un.varRegVpi.vfi = phba->sli4_hba.vfi_ids[vport->vfi]; | ||
884 | else | ||
885 | mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; | ||
871 | memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname, | 886 | memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname, |
872 | sizeof(struct lpfc_name)); | 887 | sizeof(struct lpfc_name)); |
873 | mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]); | 888 | mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]); |
@@ -901,10 +916,10 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) | |||
901 | MAILBOX_t *mb = &pmb->u.mb; | 916 | MAILBOX_t *mb = &pmb->u.mb; |
902 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 917 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
903 | 918 | ||
904 | if (phba->sli_rev < LPFC_SLI_REV4) | 919 | if (phba->sli_rev == LPFC_SLI_REV3) |
905 | mb->un.varUnregVpi.vpi = vpi + phba->vpi_base; | 920 | mb->un.varUnregVpi.vpi = phba->vpi_ids[vpi]; |
906 | else | 921 | else if (phba->sli_rev >= LPFC_SLI_REV4) |
907 | mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base; | 922 | mb->un.varUnregVpi.sli4_vpi = phba->vpi_ids[vpi]; |
908 | 923 | ||
909 | mb->mbxCommand = MBX_UNREG_VPI; | 924 | mb->mbxCommand = MBX_UNREG_VPI; |
910 | mb->mbxOwner = OWN_HOST; | 925 | mb->mbxOwner = OWN_HOST; |
@@ -1735,12 +1750,12 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, | |||
1735 | return length; | 1750 | return length; |
1736 | } | 1751 | } |
1737 | 1752 | ||
1738 | /* Setup for the none-embedded mbox command */ | 1753 | /* Setup for the non-embedded mbox command */ |
1739 | pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE; | 1754 | pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE; |
1740 | pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ? | 1755 | pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ? |
1741 | LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount; | 1756 | LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount; |
1742 | /* Allocate record for keeping SGE virtual addresses */ | 1757 | /* Allocate record for keeping SGE virtual addresses */ |
1743 | mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt), | 1758 | mbox->sge_array = kzalloc(sizeof(struct lpfc_mbx_nembed_sge_virt), |
1744 | GFP_KERNEL); | 1759 | GFP_KERNEL); |
1745 | if (!mbox->sge_array) { | 1760 | if (!mbox->sge_array) { |
1746 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 1761 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
@@ -1790,12 +1805,87 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, | |||
1790 | /* The sub-header is in DMA memory, which needs endian converstion */ | 1805 | /* The sub-header is in DMA memory, which needs endian converstion */ |
1791 | if (cfg_shdr) | 1806 | if (cfg_shdr) |
1792 | lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr, | 1807 | lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr, |
1793 | sizeof(union lpfc_sli4_cfg_shdr)); | 1808 | sizeof(union lpfc_sli4_cfg_shdr)); |
1794 | |||
1795 | return alloc_len; | 1809 | return alloc_len; |
1796 | } | 1810 | } |
1797 | 1811 | ||
1798 | /** | 1812 | /** |
1813 | * lpfc_sli4_mbox_rsrc_extent - Initialize the opcode resource extent. | ||
1814 | * @phba: pointer to lpfc hba data structure. | ||
1815 | * @mbox: pointer to an allocated lpfc mbox resource. | ||
1816 | * @exts_count: the number of extents, if required, to allocate. | ||
1817 | * @rsrc_type: the resource extent type. | ||
1818 | * @emb: true if LPFC_SLI4_MBX_EMBED. false if LPFC_SLI4_MBX_NEMBED. | ||
1819 | * | ||
1820 | * This routine completes the subcommand header for SLI4 resource extent | ||
1821 | * mailbox commands. It is called after lpfc_sli4_config. The caller must | ||
1822 | * pass an allocated mailbox and the attributes required to initialize the | ||
1823 | * mailbox correctly. | ||
1824 | * | ||
1825 | * Return: the actual length of the mbox command allocated. | ||
1826 | **/ | ||
1827 | int | ||
1828 | lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *phba, struct lpfcMboxq *mbox, | ||
1829 | uint16_t exts_count, uint16_t rsrc_type, bool emb) | ||
1830 | { | ||
1831 | uint8_t opcode = 0; | ||
1832 | struct lpfc_mbx_nembed_rsrc_extent *n_rsrc_extnt = NULL; | ||
1833 | void *virtaddr = NULL; | ||
1834 | |||
1835 | /* Set up SLI4 ioctl command header fields */ | ||
1836 | if (emb == LPFC_SLI4_MBX_NEMBED) { | ||
1837 | /* Get the first SGE entry from the non-embedded DMA memory */ | ||
1838 | virtaddr = mbox->sge_array->addr[0]; | ||
1839 | if (virtaddr == NULL) | ||
1840 | return 1; | ||
1841 | n_rsrc_extnt = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr; | ||
1842 | } | ||
1843 | |||
1844 | /* | ||
1845 | * The resource type is common to all extent Opcodes and resides in the | ||
1846 | * same position. | ||
1847 | */ | ||
1848 | if (emb == LPFC_SLI4_MBX_EMBED) | ||
1849 | bf_set(lpfc_mbx_alloc_rsrc_extents_type, | ||
1850 | &mbox->u.mqe.un.alloc_rsrc_extents.u.req, | ||
1851 | rsrc_type); | ||
1852 | else { | ||
1853 | /* This is DMA data. Byteswap is required. */ | ||
1854 | bf_set(lpfc_mbx_alloc_rsrc_extents_type, | ||
1855 | n_rsrc_extnt, rsrc_type); | ||
1856 | lpfc_sli_pcimem_bcopy(&n_rsrc_extnt->word4, | ||
1857 | &n_rsrc_extnt->word4, | ||
1858 | sizeof(uint32_t)); | ||
1859 | } | ||
1860 | |||
1861 | /* Complete the initialization for the particular Opcode. */ | ||
1862 | opcode = lpfc_sli4_mbox_opcode_get(phba, mbox); | ||
1863 | switch (opcode) { | ||
1864 | case LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT: | ||
1865 | if (emb == LPFC_SLI4_MBX_EMBED) | ||
1866 | bf_set(lpfc_mbx_alloc_rsrc_extents_cnt, | ||
1867 | &mbox->u.mqe.un.alloc_rsrc_extents.u.req, | ||
1868 | exts_count); | ||
1869 | else | ||
1870 | bf_set(lpfc_mbx_alloc_rsrc_extents_cnt, | ||
1871 | n_rsrc_extnt, exts_count); | ||
1872 | break; | ||
1873 | case LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT: | ||
1874 | case LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO: | ||
1875 | case LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT: | ||
1876 | /* Initialization is complete.*/ | ||
1877 | break; | ||
1878 | default: | ||
1879 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1880 | "2929 Resource Extent Opcode x%x is " | ||
1881 | "unsupported\n", opcode); | ||
1882 | return 1; | ||
1883 | } | ||
1884 | |||
1885 | return 0; | ||
1886 | } | ||
1887 | |||
1888 | /** | ||
1799 | * lpfc_sli4_mbox_opcode_get - Get the opcode from a sli4 mailbox command | 1889 | * lpfc_sli4_mbox_opcode_get - Get the opcode from a sli4 mailbox command |
1800 | * @phba: pointer to lpfc hba data structure. | 1890 | * @phba: pointer to lpfc hba data structure. |
1801 | * @mbox: pointer to lpfc mbox command. | 1891 | * @mbox: pointer to lpfc mbox command. |
@@ -1939,9 +2029,12 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) | |||
1939 | bf_set(lpfc_init_vfi_vr, init_vfi, 1); | 2029 | bf_set(lpfc_init_vfi_vr, init_vfi, 1); |
1940 | bf_set(lpfc_init_vfi_vt, init_vfi, 1); | 2030 | bf_set(lpfc_init_vfi_vt, init_vfi, 1); |
1941 | bf_set(lpfc_init_vfi_vp, init_vfi, 1); | 2031 | bf_set(lpfc_init_vfi_vp, init_vfi, 1); |
1942 | bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base); | 2032 | bf_set(lpfc_init_vfi_vfi, init_vfi, |
1943 | bf_set(lpfc_init_vpi_vpi, init_vfi, vport->vpi + vport->phba->vpi_base); | 2033 | vport->phba->sli4_hba.vfi_ids[vport->vfi]); |
1944 | bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi); | 2034 | bf_set(lpfc_init_vpi_vpi, init_vfi, |
2035 | vport->phba->vpi_ids[vport->vpi]); | ||
2036 | bf_set(lpfc_init_vfi_fcfi, init_vfi, | ||
2037 | vport->phba->fcf.fcfi); | ||
1945 | } | 2038 | } |
1946 | 2039 | ||
1947 | /** | 2040 | /** |
@@ -1964,9 +2057,10 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) | |||
1964 | reg_vfi = &mbox->u.mqe.un.reg_vfi; | 2057 | reg_vfi = &mbox->u.mqe.un.reg_vfi; |
1965 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI); | 2058 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI); |
1966 | bf_set(lpfc_reg_vfi_vp, reg_vfi, 1); | 2059 | bf_set(lpfc_reg_vfi_vp, reg_vfi, 1); |
1967 | bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base); | 2060 | bf_set(lpfc_reg_vfi_vfi, reg_vfi, |
2061 | vport->phba->sli4_hba.vfi_ids[vport->vfi]); | ||
1968 | bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi); | 2062 | bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi); |
1969 | bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base); | 2063 | bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->phba->vpi_ids[vport->vpi]); |
1970 | memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name)); | 2064 | memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name)); |
1971 | reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]); | 2065 | reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]); |
1972 | reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]); | 2066 | reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]); |
@@ -1997,9 +2091,9 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi) | |||
1997 | memset(mbox, 0, sizeof(*mbox)); | 2091 | memset(mbox, 0, sizeof(*mbox)); |
1998 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI); | 2092 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI); |
1999 | bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi, | 2093 | bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi, |
2000 | vpi + phba->vpi_base); | 2094 | phba->vpi_ids[vpi]); |
2001 | bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi, | 2095 | bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi, |
2002 | phba->pport->vfi + phba->vfi_base); | 2096 | phba->sli4_hba.vfi_ids[phba->pport->vfi]); |
2003 | } | 2097 | } |
2004 | 2098 | ||
2005 | /** | 2099 | /** |
@@ -2019,7 +2113,7 @@ lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) | |||
2019 | memset(mbox, 0, sizeof(*mbox)); | 2113 | memset(mbox, 0, sizeof(*mbox)); |
2020 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); | 2114 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI); |
2021 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, | 2115 | bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, |
2022 | vport->vfi + vport->phba->vfi_base); | 2116 | vport->phba->sli4_hba.vfi_ids[vport->vfi]); |
2023 | } | 2117 | } |
2024 | 2118 | ||
2025 | /** | 2119 | /** |
@@ -2131,12 +2225,14 @@ lpfc_unreg_fcfi(struct lpfcMboxq *mbox, uint16_t fcfi) | |||
2131 | void | 2225 | void |
2132 | lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) | 2226 | lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) |
2133 | { | 2227 | { |
2228 | struct lpfc_hba *phba = ndlp->phba; | ||
2134 | struct lpfc_mbx_resume_rpi *resume_rpi; | 2229 | struct lpfc_mbx_resume_rpi *resume_rpi; |
2135 | 2230 | ||
2136 | memset(mbox, 0, sizeof(*mbox)); | 2231 | memset(mbox, 0, sizeof(*mbox)); |
2137 | resume_rpi = &mbox->u.mqe.un.resume_rpi; | 2232 | resume_rpi = &mbox->u.mqe.un.resume_rpi; |
2138 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI); | 2233 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI); |
2139 | bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi); | 2234 | bf_set(lpfc_resume_rpi_index, resume_rpi, |
2235 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); | ||
2140 | bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI); | 2236 | bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI); |
2141 | resume_rpi->event_tag = ndlp->phba->fc_eventTag; | 2237 | resume_rpi->event_tag = ndlp->phba->fc_eventTag; |
2142 | } | 2238 | } |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index cbb48ee8b0bb..10d5b5e41499 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -62,7 +62,6 @@ int | |||
62 | lpfc_mem_alloc(struct lpfc_hba *phba, int align) | 62 | lpfc_mem_alloc(struct lpfc_hba *phba, int align) |
63 | { | 63 | { |
64 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 64 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
65 | int longs; | ||
66 | int i; | 65 | int i; |
67 | 66 | ||
68 | if (phba->sli_rev == LPFC_SLI_REV4) | 67 | if (phba->sli_rev == LPFC_SLI_REV4) |
@@ -138,17 +137,8 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) | |||
138 | phba->lpfc_hrb_pool = NULL; | 137 | phba->lpfc_hrb_pool = NULL; |
139 | phba->lpfc_drb_pool = NULL; | 138 | phba->lpfc_drb_pool = NULL; |
140 | } | 139 | } |
141 | /* vpi zero is reserved for the physical port so add 1 to max */ | ||
142 | longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
143 | phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL); | ||
144 | if (!phba->vpi_bmask) | ||
145 | goto fail_free_dbq_pool; | ||
146 | 140 | ||
147 | return 0; | 141 | return 0; |
148 | |||
149 | fail_free_dbq_pool: | ||
150 | pci_pool_destroy(phba->lpfc_drb_pool); | ||
151 | phba->lpfc_drb_pool = NULL; | ||
152 | fail_free_hrb_pool: | 142 | fail_free_hrb_pool: |
153 | pci_pool_destroy(phba->lpfc_hrb_pool); | 143 | pci_pool_destroy(phba->lpfc_hrb_pool); |
154 | phba->lpfc_hrb_pool = NULL; | 144 | phba->lpfc_hrb_pool = NULL; |
@@ -191,9 +181,6 @@ lpfc_mem_free(struct lpfc_hba *phba) | |||
191 | int i; | 181 | int i; |
192 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 182 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
193 | 183 | ||
194 | /* Free VPI bitmask memory */ | ||
195 | kfree(phba->vpi_bmask); | ||
196 | |||
197 | /* Free HBQ pools */ | 184 | /* Free HBQ pools */ |
198 | lpfc_sli_hbqbuf_free_all(phba); | 185 | lpfc_sli_hbqbuf_free_all(phba); |
199 | if (phba->lpfc_drb_pool) | 186 | if (phba->lpfc_drb_pool) |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 0d92d4205ea6..2ddd02f7c603 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -350,11 +350,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
350 | ndlp->nlp_maxframe = | 350 | ndlp->nlp_maxframe = |
351 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; | 351 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; |
352 | 352 | ||
353 | /* | 353 | /* no need to reg_login if we are already in one of these states */ |
354 | * Need to unreg_login if we are already in one of these states and | ||
355 | * change to NPR state. This will block the port until after the ACC | ||
356 | * completes and the reg_login is issued and completed. | ||
357 | */ | ||
358 | switch (ndlp->nlp_state) { | 354 | switch (ndlp->nlp_state) { |
359 | case NLP_STE_NPR_NODE: | 355 | case NLP_STE_NPR_NODE: |
360 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) | 356 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) |
@@ -363,9 +359,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
363 | case NLP_STE_PRLI_ISSUE: | 359 | case NLP_STE_PRLI_ISSUE: |
364 | case NLP_STE_UNMAPPED_NODE: | 360 | case NLP_STE_UNMAPPED_NODE: |
365 | case NLP_STE_MAPPED_NODE: | 361 | case NLP_STE_MAPPED_NODE: |
366 | lpfc_unreg_rpi(vport, ndlp); | 362 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); |
367 | ndlp->nlp_prev_state = ndlp->nlp_state; | 363 | return 1; |
368 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | ||
369 | } | 364 | } |
370 | 365 | ||
371 | if ((vport->fc_flag & FC_PT2PT) && | 366 | if ((vport->fc_flag & FC_PT2PT) && |
@@ -657,6 +652,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
657 | lpfc_unreg_rpi(vport, ndlp); | 652 | lpfc_unreg_rpi(vport, ndlp); |
658 | return 0; | 653 | return 0; |
659 | } | 654 | } |
655 | |||
660 | /** | 656 | /** |
661 | * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd. | 657 | * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd. |
662 | * @phba : Pointer to lpfc_hba structure. | 658 | * @phba : Pointer to lpfc_hba structure. |
@@ -1399,8 +1395,11 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1399 | if (mb->mbxStatus) { | 1395 | if (mb->mbxStatus) { |
1400 | /* RegLogin failed */ | 1396 | /* RegLogin failed */ |
1401 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 1397 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
1402 | "0246 RegLogin failed Data: x%x x%x x%x\n", | 1398 | "0246 RegLogin failed Data: x%x x%x x%x x%x " |
1403 | did, mb->mbxStatus, vport->port_state); | 1399 | "x%x\n", |
1400 | did, mb->mbxStatus, vport->port_state, | ||
1401 | mb->un.varRegLogin.vpi, | ||
1402 | mb->un.varRegLogin.rpi); | ||
1404 | /* | 1403 | /* |
1405 | * If RegLogin failed due to lack of HBA resources do not | 1404 | * If RegLogin failed due to lack of HBA resources do not |
1406 | * retry discovery. | 1405 | * retry discovery. |
@@ -1424,7 +1423,10 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1424 | return ndlp->nlp_state; | 1423 | return ndlp->nlp_state; |
1425 | } | 1424 | } |
1426 | 1425 | ||
1427 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1426 | /* SLI4 ports have preallocated logical rpis. */ |
1427 | if (vport->phba->sli_rev < LPFC_SLI_REV4) | ||
1428 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
1429 | |||
1428 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; | 1430 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; |
1429 | 1431 | ||
1430 | /* Only if we are not a fabric nport do we issue PRLI */ | 1432 | /* Only if we are not a fabric nport do we issue PRLI */ |
@@ -2025,7 +2027,9 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport, | |||
2025 | MAILBOX_t *mb = &pmb->u.mb; | 2027 | MAILBOX_t *mb = &pmb->u.mb; |
2026 | 2028 | ||
2027 | if (!mb->mbxStatus) { | 2029 | if (!mb->mbxStatus) { |
2028 | ndlp->nlp_rpi = mb->un.varWords[0]; | 2030 | /* SLI4 ports have preallocated logical rpis. */ |
2031 | if (vport->phba->sli_rev < LPFC_SLI_REV4) | ||
2032 | ndlp->nlp_rpi = mb->un.varWords[0]; | ||
2029 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; | 2033 | ndlp->nlp_flag |= NLP_RPI_REGISTERED; |
2030 | } else { | 2034 | } else { |
2031 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { | 2035 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 84e4481b2406..3ccc97496ebf 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -743,7 +743,14 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba) | |||
743 | if (bcnt == 0) | 743 | if (bcnt == 0) |
744 | continue; | 744 | continue; |
745 | /* Now, post the SCSI buffer list sgls as a block */ | 745 | /* Now, post the SCSI buffer list sgls as a block */ |
746 | status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt); | 746 | if (!phba->sli4_hba.extents_in_use) |
747 | status = lpfc_sli4_post_scsi_sgl_block(phba, | ||
748 | &sblist, | ||
749 | bcnt); | ||
750 | else | ||
751 | status = lpfc_sli4_post_scsi_sgl_blk_ext(phba, | ||
752 | &sblist, | ||
753 | bcnt); | ||
747 | /* Reset SCSI buffer count for next round of posting */ | 754 | /* Reset SCSI buffer count for next round of posting */ |
748 | bcnt = 0; | 755 | bcnt = 0; |
749 | while (!list_empty(&sblist)) { | 756 | while (!list_empty(&sblist)) { |
@@ -787,7 +794,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
787 | dma_addr_t pdma_phys_fcp_cmd; | 794 | dma_addr_t pdma_phys_fcp_cmd; |
788 | dma_addr_t pdma_phys_fcp_rsp; | 795 | dma_addr_t pdma_phys_fcp_rsp; |
789 | dma_addr_t pdma_phys_bpl, pdma_phys_bpl1; | 796 | dma_addr_t pdma_phys_bpl, pdma_phys_bpl1; |
790 | uint16_t iotag, last_xritag = NO_XRI; | 797 | uint16_t iotag, last_xritag = NO_XRI, lxri = 0; |
791 | int status = 0, index; | 798 | int status = 0, index; |
792 | int bcnt; | 799 | int bcnt; |
793 | int non_sequential_xri = 0; | 800 | int non_sequential_xri = 0; |
@@ -823,13 +830,15 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
823 | break; | 830 | break; |
824 | } | 831 | } |
825 | 832 | ||
826 | psb->cur_iocbq.sli4_xritag = lpfc_sli4_next_xritag(phba); | 833 | lxri = lpfc_sli4_next_xritag(phba); |
827 | if (psb->cur_iocbq.sli4_xritag == NO_XRI) { | 834 | if (lxri == NO_XRI) { |
828 | pci_pool_free(phba->lpfc_scsi_dma_buf_pool, | 835 | pci_pool_free(phba->lpfc_scsi_dma_buf_pool, |
829 | psb->data, psb->dma_handle); | 836 | psb->data, psb->dma_handle); |
830 | kfree(psb); | 837 | kfree(psb); |
831 | break; | 838 | break; |
832 | } | 839 | } |
840 | psb->cur_iocbq.sli4_lxritag = lxri; | ||
841 | psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; | ||
833 | if (last_xritag != NO_XRI | 842 | if (last_xritag != NO_XRI |
834 | && psb->cur_iocbq.sli4_xritag != (last_xritag+1)) { | 843 | && psb->cur_iocbq.sli4_xritag != (last_xritag+1)) { |
835 | non_sequential_xri = 1; | 844 | non_sequential_xri = 1; |
@@ -861,6 +870,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
861 | */ | 870 | */ |
862 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd)); | 871 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd)); |
863 | sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd)); | 872 | sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd)); |
873 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
864 | bf_set(lpfc_sli4_sge_last, sgl, 0); | 874 | bf_set(lpfc_sli4_sge_last, sgl, 0); |
865 | sgl->word2 = cpu_to_le32(sgl->word2); | 875 | sgl->word2 = cpu_to_le32(sgl->word2); |
866 | sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd)); | 876 | sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd)); |
@@ -869,6 +879,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
869 | /* Setup the physical region for the FCP RSP */ | 879 | /* Setup the physical region for the FCP RSP */ |
870 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp)); | 880 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp)); |
871 | sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp)); | 881 | sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp)); |
882 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
872 | bf_set(lpfc_sli4_sge_last, sgl, 1); | 883 | bf_set(lpfc_sli4_sge_last, sgl, 1); |
873 | sgl->word2 = cpu_to_le32(sgl->word2); | 884 | sgl->word2 = cpu_to_le32(sgl->word2); |
874 | sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp)); | 885 | sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp)); |
@@ -914,7 +925,21 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
914 | } | 925 | } |
915 | } | 926 | } |
916 | if (bcnt) { | 927 | if (bcnt) { |
917 | status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt); | 928 | if (!phba->sli4_hba.extents_in_use) |
929 | status = lpfc_sli4_post_scsi_sgl_block(phba, | ||
930 | &sblist, | ||
931 | bcnt); | ||
932 | else | ||
933 | status = lpfc_sli4_post_scsi_sgl_blk_ext(phba, | ||
934 | &sblist, | ||
935 | bcnt); | ||
936 | |||
937 | if (status) { | ||
938 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
939 | "3021 SCSI SGL post error %d\n", | ||
940 | status); | ||
941 | bcnt = 0; | ||
942 | } | ||
918 | /* Reset SCSI buffer count for next round of posting */ | 943 | /* Reset SCSI buffer count for next round of posting */ |
919 | while (!list_empty(&sblist)) { | 944 | while (!list_empty(&sblist)) { |
920 | list_remove_head(&sblist, psb, struct lpfc_scsi_buf, | 945 | list_remove_head(&sblist, psb, struct lpfc_scsi_buf, |
@@ -2081,6 +2106,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
2081 | dma_len = sg_dma_len(sgel); | 2106 | dma_len = sg_dma_len(sgel); |
2082 | sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); | 2107 | sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr)); |
2083 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); | 2108 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr)); |
2109 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
2084 | if ((num_bde + 1) == nseg) | 2110 | if ((num_bde + 1) == nseg) |
2085 | bf_set(lpfc_sli4_sge_last, sgl, 1); | 2111 | bf_set(lpfc_sli4_sge_last, sgl, 1); |
2086 | else | 2112 | else |
@@ -2794,6 +2820,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
2794 | * of the scsi_cmnd request_buffer | 2820 | * of the scsi_cmnd request_buffer |
2795 | */ | 2821 | */ |
2796 | piocbq->iocb.ulpContext = pnode->nlp_rpi; | 2822 | piocbq->iocb.ulpContext = pnode->nlp_rpi; |
2823 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
2824 | piocbq->iocb.ulpContext = | ||
2825 | phba->sli4_hba.rpi_ids[pnode->nlp_rpi]; | ||
2797 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) | 2826 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) |
2798 | piocbq->iocb.ulpFCP2Rcvy = 1; | 2827 | piocbq->iocb.ulpFCP2Rcvy = 1; |
2799 | else | 2828 | else |
@@ -2807,7 +2836,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
2807 | } | 2836 | } |
2808 | 2837 | ||
2809 | /** | 2838 | /** |
2810 | * lpfc_scsi_prep_task_mgmt_cmnd - Convert SLI3 scsi TM cmd to FCP info unit | 2839 | * lpfc_scsi_prep_task_mgmt_cmd - Convert SLI3 scsi TM cmd to FCP info unit |
2811 | * @vport: The virtual port for which this call is being executed. | 2840 | * @vport: The virtual port for which this call is being executed. |
2812 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. | 2841 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. |
2813 | * @lun: Logical unit number. | 2842 | * @lun: Logical unit number. |
@@ -2851,6 +2880,10 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, | |||
2851 | lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd); | 2880 | lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd); |
2852 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; | 2881 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; |
2853 | piocb->ulpContext = ndlp->nlp_rpi; | 2882 | piocb->ulpContext = ndlp->nlp_rpi; |
2883 | if (vport->phba->sli_rev == LPFC_SLI_REV4) { | ||
2884 | piocb->ulpContext = | ||
2885 | vport->phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; | ||
2886 | } | ||
2854 | if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { | 2887 | if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { |
2855 | piocb->ulpFCP2Rcvy = 1; | 2888 | piocb->ulpFCP2Rcvy = 1; |
2856 | } | 2889 | } |
@@ -3405,9 +3438,10 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata, | |||
3405 | 3438 | ||
3406 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, | 3439 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, |
3407 | "0702 Issue %s to TGT %d LUN %d " | 3440 | "0702 Issue %s to TGT %d LUN %d " |
3408 | "rpi x%x nlp_flag x%x\n", | 3441 | "rpi x%x nlp_flag x%x Data: x%x x%x\n", |
3409 | lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, | 3442 | lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, |
3410 | pnode->nlp_rpi, pnode->nlp_flag); | 3443 | pnode->nlp_rpi, pnode->nlp_flag, iocbq->sli4_xritag, |
3444 | iocbq->iocb_flag); | ||
3411 | 3445 | ||
3412 | status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, | 3446 | status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, |
3413 | iocbq, iocbqrsp, lpfc_cmd->timeout); | 3447 | iocbq, iocbqrsp, lpfc_cmd->timeout); |
@@ -3419,10 +3453,12 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata, | |||
3419 | ret = FAILED; | 3453 | ret = FAILED; |
3420 | lpfc_cmd->status = IOSTAT_DRIVER_REJECT; | 3454 | lpfc_cmd->status = IOSTAT_DRIVER_REJECT; |
3421 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, | 3455 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, |
3422 | "0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n", | 3456 | "0727 TMF %s to TGT %d LUN %d failed (%d, %d) " |
3457 | "iocb_flag x%x\n", | ||
3423 | lpfc_taskmgmt_name(task_mgmt_cmd), | 3458 | lpfc_taskmgmt_name(task_mgmt_cmd), |
3424 | tgt_id, lun_id, iocbqrsp->iocb.ulpStatus, | 3459 | tgt_id, lun_id, iocbqrsp->iocb.ulpStatus, |
3425 | iocbqrsp->iocb.un.ulpWord[4]); | 3460 | iocbqrsp->iocb.un.ulpWord[4], |
3461 | iocbq->iocb_flag); | ||
3426 | } else if (status == IOCB_BUSY) | 3462 | } else if (status == IOCB_BUSY) |
3427 | ret = FAILED; | 3463 | ret = FAILED; |
3428 | else | 3464 | else |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fd5835e1c039..98999bbd8cbf 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -65,6 +65,9 @@ static struct lpfc_iocbq *lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *, | |||
65 | struct lpfc_iocbq *); | 65 | struct lpfc_iocbq *); |
66 | static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *, | 66 | static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *, |
67 | struct hbq_dmabuf *); | 67 | struct hbq_dmabuf *); |
68 | static int lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *, struct lpfc_queue *, | ||
69 | struct lpfc_cqe *); | ||
70 | |||
68 | static IOCB_t * | 71 | static IOCB_t * |
69 | lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) | 72 | lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) |
70 | { | 73 | { |
@@ -456,7 +459,6 @@ __lpfc_sli_get_iocbq(struct lpfc_hba *phba) | |||
456 | struct lpfc_iocbq * iocbq = NULL; | 459 | struct lpfc_iocbq * iocbq = NULL; |
457 | 460 | ||
458 | list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list); | 461 | list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list); |
459 | |||
460 | if (iocbq) | 462 | if (iocbq) |
461 | phba->iocb_cnt++; | 463 | phba->iocb_cnt++; |
462 | if (phba->iocb_cnt > phba->iocb_max) | 464 | if (phba->iocb_cnt > phba->iocb_max) |
@@ -479,13 +481,10 @@ __lpfc_sli_get_iocbq(struct lpfc_hba *phba) | |||
479 | static struct lpfc_sglq * | 481 | static struct lpfc_sglq * |
480 | __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | 482 | __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) |
481 | { | 483 | { |
482 | uint16_t adj_xri; | ||
483 | struct lpfc_sglq *sglq; | 484 | struct lpfc_sglq *sglq; |
484 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | 485 | |
485 | if (adj_xri > phba->sli4_hba.max_cfg_param.max_xri) | 486 | sglq = phba->sli4_hba.lpfc_sglq_active_list[xritag]; |
486 | return NULL; | 487 | phba->sli4_hba.lpfc_sglq_active_list[xritag] = NULL; |
487 | sglq = phba->sli4_hba.lpfc_sglq_active_list[adj_xri]; | ||
488 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = NULL; | ||
489 | return sglq; | 488 | return sglq; |
490 | } | 489 | } |
491 | 490 | ||
@@ -504,12 +503,9 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
504 | struct lpfc_sglq * | 503 | struct lpfc_sglq * |
505 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | 504 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) |
506 | { | 505 | { |
507 | uint16_t adj_xri; | ||
508 | struct lpfc_sglq *sglq; | 506 | struct lpfc_sglq *sglq; |
509 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | 507 | |
510 | if (adj_xri > phba->sli4_hba.max_cfg_param.max_xri) | 508 | sglq = phba->sli4_hba.lpfc_sglq_active_list[xritag]; |
511 | return NULL; | ||
512 | sglq = phba->sli4_hba.lpfc_sglq_active_list[adj_xri]; | ||
513 | return sglq; | 509 | return sglq; |
514 | } | 510 | } |
515 | 511 | ||
@@ -532,7 +528,6 @@ static int | |||
532 | __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 528 | __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, |
533 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | 529 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) |
534 | { | 530 | { |
535 | uint16_t adj_xri; | ||
536 | struct lpfc_node_rrq *rrq; | 531 | struct lpfc_node_rrq *rrq; |
537 | int empty; | 532 | int empty; |
538 | uint32_t did = 0; | 533 | uint32_t did = 0; |
@@ -553,21 +548,19 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
553 | /* | 548 | /* |
554 | * set the active bit even if there is no mem available. | 549 | * set the active bit even if there is no mem available. |
555 | */ | 550 | */ |
556 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | ||
557 | |||
558 | if (NLP_CHK_FREE_REQ(ndlp)) | 551 | if (NLP_CHK_FREE_REQ(ndlp)) |
559 | goto out; | 552 | goto out; |
560 | 553 | ||
561 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) | 554 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) |
562 | goto out; | 555 | goto out; |
563 | 556 | ||
564 | if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) | 557 | if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap)) |
565 | goto out; | 558 | goto out; |
566 | 559 | ||
567 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); | 560 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); |
568 | if (rrq) { | 561 | if (rrq) { |
569 | rrq->send_rrq = send_rrq; | 562 | rrq->send_rrq = send_rrq; |
570 | rrq->xritag = xritag; | 563 | rrq->xritag = phba->sli4_hba.xri_ids[xritag]; |
571 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); | 564 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); |
572 | rrq->ndlp = ndlp; | 565 | rrq->ndlp = ndlp; |
573 | rrq->nlp_DID = ndlp->nlp_DID; | 566 | rrq->nlp_DID = ndlp->nlp_DID; |
@@ -603,7 +596,6 @@ lpfc_clr_rrq_active(struct lpfc_hba *phba, | |||
603 | uint16_t xritag, | 596 | uint16_t xritag, |
604 | struct lpfc_node_rrq *rrq) | 597 | struct lpfc_node_rrq *rrq) |
605 | { | 598 | { |
606 | uint16_t adj_xri; | ||
607 | struct lpfc_nodelist *ndlp = NULL; | 599 | struct lpfc_nodelist *ndlp = NULL; |
608 | 600 | ||
609 | if ((rrq->vport) && NLP_CHK_NODE_ACT(rrq->ndlp)) | 601 | if ((rrq->vport) && NLP_CHK_NODE_ACT(rrq->ndlp)) |
@@ -619,8 +611,7 @@ lpfc_clr_rrq_active(struct lpfc_hba *phba, | |||
619 | if (!ndlp) | 611 | if (!ndlp) |
620 | goto out; | 612 | goto out; |
621 | 613 | ||
622 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | 614 | if (test_and_clear_bit(xritag, ndlp->active_rrqs.xri_bitmap)) { |
623 | if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) { | ||
624 | rrq->send_rrq = 0; | 615 | rrq->send_rrq = 0; |
625 | rrq->xritag = 0; | 616 | rrq->xritag = 0; |
626 | rrq->rrq_stop_time = 0; | 617 | rrq->rrq_stop_time = 0; |
@@ -796,12 +787,9 @@ int | |||
796 | lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 787 | lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, |
797 | uint16_t xritag) | 788 | uint16_t xritag) |
798 | { | 789 | { |
799 | uint16_t adj_xri; | ||
800 | |||
801 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | ||
802 | if (!ndlp) | 790 | if (!ndlp) |
803 | return 0; | 791 | return 0; |
804 | if (test_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) | 792 | if (test_bit(xritag, ndlp->active_rrqs.xri_bitmap)) |
805 | return 1; | 793 | return 1; |
806 | else | 794 | else |
807 | return 0; | 795 | return 0; |
@@ -841,7 +829,7 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
841 | * @piocb: Pointer to the iocbq. | 829 | * @piocb: Pointer to the iocbq. |
842 | * | 830 | * |
843 | * This function is called with hbalock held. This function | 831 | * This function is called with hbalock held. This function |
844 | * Gets a new driver sglq object from the sglq list. If the | 832 | * gets a new driver sglq object from the sglq list. If the |
845 | * list is not empty then it is successful, it returns pointer to the newly | 833 | * list is not empty then it is successful, it returns pointer to the newly |
846 | * allocated sglq object else it returns NULL. | 834 | * allocated sglq object else it returns NULL. |
847 | **/ | 835 | **/ |
@@ -851,7 +839,6 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) | |||
851 | struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list; | 839 | struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list; |
852 | struct lpfc_sglq *sglq = NULL; | 840 | struct lpfc_sglq *sglq = NULL; |
853 | struct lpfc_sglq *start_sglq = NULL; | 841 | struct lpfc_sglq *start_sglq = NULL; |
854 | uint16_t adj_xri; | ||
855 | struct lpfc_scsi_buf *lpfc_cmd; | 842 | struct lpfc_scsi_buf *lpfc_cmd; |
856 | struct lpfc_nodelist *ndlp; | 843 | struct lpfc_nodelist *ndlp; |
857 | int found = 0; | 844 | int found = 0; |
@@ -870,8 +857,6 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) | |||
870 | while (!found) { | 857 | while (!found) { |
871 | if (!sglq) | 858 | if (!sglq) |
872 | return NULL; | 859 | return NULL; |
873 | adj_xri = sglq->sli4_xritag - | ||
874 | phba->sli4_hba.max_cfg_param.xri_base; | ||
875 | if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { | 860 | if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { |
876 | /* This xri has an rrq outstanding for this DID. | 861 | /* This xri has an rrq outstanding for this DID. |
877 | * put it back in the list and get another xri. | 862 | * put it back in the list and get another xri. |
@@ -888,7 +873,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) | |||
888 | } | 873 | } |
889 | sglq->ndlp = ndlp; | 874 | sglq->ndlp = ndlp; |
890 | found = 1; | 875 | found = 1; |
891 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; | 876 | phba->sli4_hba.lpfc_sglq_active_list[sglq->sli4_lxritag] = sglq; |
892 | sglq->state = SGL_ALLOCATED; | 877 | sglq->state = SGL_ALLOCATED; |
893 | } | 878 | } |
894 | return sglq; | 879 | return sglq; |
@@ -944,7 +929,8 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
944 | if (iocbq->sli4_xritag == NO_XRI) | 929 | if (iocbq->sli4_xritag == NO_XRI) |
945 | sglq = NULL; | 930 | sglq = NULL; |
946 | else | 931 | else |
947 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); | 932 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_lxritag); |
933 | |||
948 | if (sglq) { | 934 | if (sglq) { |
949 | if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && | 935 | if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && |
950 | (sglq->state != SGL_XRI_ABORTED)) { | 936 | (sglq->state != SGL_XRI_ABORTED)) { |
@@ -971,6 +957,7 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
971 | * Clean all volatile data fields, preserve iotag and node struct. | 957 | * Clean all volatile data fields, preserve iotag and node struct. |
972 | */ | 958 | */ |
973 | memset((char *)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean); | 959 | memset((char *)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean); |
960 | iocbq->sli4_lxritag = NO_XRI; | ||
974 | iocbq->sli4_xritag = NO_XRI; | 961 | iocbq->sli4_xritag = NO_XRI; |
975 | list_add_tail(&iocbq->list, &phba->lpfc_iocb_list); | 962 | list_add_tail(&iocbq->list, &phba->lpfc_iocb_list); |
976 | } | 963 | } |
@@ -2113,7 +2100,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2113 | pmb->u.mb.mbxCommand == MBX_REG_LOGIN64 && | 2100 | pmb->u.mb.mbxCommand == MBX_REG_LOGIN64 && |
2114 | !pmb->u.mb.mbxStatus) { | 2101 | !pmb->u.mb.mbxStatus) { |
2115 | rpi = pmb->u.mb.un.varWords[0]; | 2102 | rpi = pmb->u.mb.un.varWords[0]; |
2116 | vpi = pmb->u.mb.un.varRegLogin.vpi - phba->vpi_base; | 2103 | vpi = pmb->u.mb.un.varRegLogin.vpi; |
2117 | lpfc_unreg_login(phba, vpi, rpi, pmb); | 2104 | lpfc_unreg_login(phba, vpi, rpi, pmb); |
2118 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 2105 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
2119 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 2106 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
@@ -3881,8 +3868,10 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) | |||
3881 | list_del_init(&phba->sli4_hba.els_cq->list); | 3868 | list_del_init(&phba->sli4_hba.els_cq->list); |
3882 | for (qindx = 0; qindx < phba->cfg_fcp_wq_count; qindx++) | 3869 | for (qindx = 0; qindx < phba->cfg_fcp_wq_count; qindx++) |
3883 | list_del_init(&phba->sli4_hba.fcp_wq[qindx]->list); | 3870 | list_del_init(&phba->sli4_hba.fcp_wq[qindx]->list); |
3884 | for (qindx = 0; qindx < phba->cfg_fcp_eq_count; qindx++) | 3871 | qindx = 0; |
3872 | do | ||
3885 | list_del_init(&phba->sli4_hba.fcp_cq[qindx]->list); | 3873 | list_del_init(&phba->sli4_hba.fcp_cq[qindx]->list); |
3874 | while (++qindx < phba->cfg_fcp_eq_count); | ||
3886 | spin_unlock_irq(&phba->hbalock); | 3875 | spin_unlock_irq(&phba->hbalock); |
3887 | 3876 | ||
3888 | /* Now physically reset the device */ | 3877 | /* Now physically reset the device */ |
@@ -4318,6 +4307,7 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) | |||
4318 | continue; | 4307 | continue; |
4319 | } else if (rc) | 4308 | } else if (rc) |
4320 | break; | 4309 | break; |
4310 | |||
4321 | phba->link_state = LPFC_INIT_MBX_CMDS; | 4311 | phba->link_state = LPFC_INIT_MBX_CMDS; |
4322 | lpfc_config_port(phba, pmb); | 4312 | lpfc_config_port(phba, pmb); |
4323 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | 4313 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); |
@@ -4421,7 +4411,8 @@ int | |||
4421 | lpfc_sli_hba_setup(struct lpfc_hba *phba) | 4411 | lpfc_sli_hba_setup(struct lpfc_hba *phba) |
4422 | { | 4412 | { |
4423 | uint32_t rc; | 4413 | uint32_t rc; |
4424 | int mode = 3; | 4414 | int mode = 3, i; |
4415 | int longs; | ||
4425 | 4416 | ||
4426 | switch (lpfc_sli_mode) { | 4417 | switch (lpfc_sli_mode) { |
4427 | case 2: | 4418 | case 2: |
@@ -4491,6 +4482,35 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) | |||
4491 | if (rc) | 4482 | if (rc) |
4492 | goto lpfc_sli_hba_setup_error; | 4483 | goto lpfc_sli_hba_setup_error; |
4493 | 4484 | ||
4485 | /* Initialize VPIs. */ | ||
4486 | if (phba->sli_rev == LPFC_SLI_REV3) { | ||
4487 | /* | ||
4488 | * The VPI bitmask and physical ID array are allocated | ||
4489 | * and initialized once only - at driver load. A port | ||
4490 | * reset doesn't need to reinitialize this memory. | ||
4491 | */ | ||
4492 | if ((phba->vpi_bmask == NULL) && (phba->vpi_ids == NULL)) { | ||
4493 | longs = (phba->max_vpi + BITS_PER_LONG) / BITS_PER_LONG; | ||
4494 | phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), | ||
4495 | GFP_KERNEL); | ||
4496 | if (!phba->vpi_bmask) { | ||
4497 | rc = -ENOMEM; | ||
4498 | goto lpfc_sli_hba_setup_error; | ||
4499 | } | ||
4500 | |||
4501 | phba->vpi_ids = kzalloc( | ||
4502 | (phba->max_vpi+1) * sizeof(uint16_t), | ||
4503 | GFP_KERNEL); | ||
4504 | if (!phba->vpi_ids) { | ||
4505 | kfree(phba->vpi_bmask); | ||
4506 | rc = -ENOMEM; | ||
4507 | goto lpfc_sli_hba_setup_error; | ||
4508 | } | ||
4509 | for (i = 0; i < phba->max_vpi; i++) | ||
4510 | phba->vpi_ids[i] = i; | ||
4511 | } | ||
4512 | } | ||
4513 | |||
4494 | /* Init HBQs */ | 4514 | /* Init HBQs */ |
4495 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 4515 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
4496 | rc = lpfc_sli_hbq_setup(phba); | 4516 | rc = lpfc_sli_hbq_setup(phba); |
@@ -4677,9 +4697,11 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) | |||
4677 | 4697 | ||
4678 | lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM); | 4698 | lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM); |
4679 | lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM); | 4699 | lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM); |
4680 | for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) | 4700 | fcp_eqidx = 0; |
4701 | do | ||
4681 | lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx], | 4702 | lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx], |
4682 | LPFC_QUEUE_REARM); | 4703 | LPFC_QUEUE_REARM); |
4704 | while (++fcp_eqidx < phba->cfg_fcp_eq_count); | ||
4683 | lpfc_sli4_eq_release(phba->sli4_hba.sp_eq, LPFC_QUEUE_REARM); | 4705 | lpfc_sli4_eq_release(phba->sli4_hba.sp_eq, LPFC_QUEUE_REARM); |
4684 | for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) | 4706 | for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) |
4685 | lpfc_sli4_eq_release(phba->sli4_hba.fp_eq[fcp_eqidx], | 4707 | lpfc_sli4_eq_release(phba->sli4_hba.fp_eq[fcp_eqidx], |
@@ -4687,6 +4709,803 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) | |||
4687 | } | 4709 | } |
4688 | 4710 | ||
4689 | /** | 4711 | /** |
4712 | * lpfc_sli4_get_avail_extnt_rsrc - Get available resource extent count. | ||
4713 | * @phba: Pointer to HBA context object. | ||
4714 | * @type: The resource extent type. | ||
4715 | * | ||
4716 | * This function allocates all SLI4 resource identifiers. | ||
4717 | **/ | ||
4718 | static int | ||
4719 | lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type, | ||
4720 | uint16_t *extnt_count, uint16_t *extnt_size) | ||
4721 | { | ||
4722 | int rc = 0; | ||
4723 | uint32_t length; | ||
4724 | uint32_t mbox_tmo; | ||
4725 | struct lpfc_mbx_get_rsrc_extent_info *rsrc_info; | ||
4726 | LPFC_MBOXQ_t *mbox; | ||
4727 | |||
4728 | mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4729 | if (!mbox) | ||
4730 | return -ENOMEM; | ||
4731 | |||
4732 | /* Find out how many extents are available for this resource type */ | ||
4733 | length = (sizeof(struct lpfc_mbx_get_rsrc_extent_info) - | ||
4734 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
4735 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
4736 | LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO, | ||
4737 | length, LPFC_SLI4_MBX_EMBED); | ||
4738 | |||
4739 | /* Send an extents count of 0 - the GET doesn't use it. */ | ||
4740 | rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, 0, type, | ||
4741 | LPFC_SLI4_MBX_EMBED); | ||
4742 | if (unlikely(rc)) { | ||
4743 | rc = -EIO; | ||
4744 | goto err_exit; | ||
4745 | } | ||
4746 | |||
4747 | if (!phba->sli4_hba.intr_enable) | ||
4748 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
4749 | else { | ||
4750 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
4751 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
4752 | } | ||
4753 | if (unlikely(rc)) { | ||
4754 | rc = -EIO; | ||
4755 | goto err_exit; | ||
4756 | } | ||
4757 | |||
4758 | rsrc_info = &mbox->u.mqe.un.rsrc_extent_info; | ||
4759 | if (bf_get(lpfc_mbox_hdr_status, | ||
4760 | &rsrc_info->header.cfg_shdr.response)) { | ||
4761 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT, | ||
4762 | "2930 Failed to get resource extents " | ||
4763 | "Status 0x%x Add'l Status 0x%x\n", | ||
4764 | bf_get(lpfc_mbox_hdr_status, | ||
4765 | &rsrc_info->header.cfg_shdr.response), | ||
4766 | bf_get(lpfc_mbox_hdr_add_status, | ||
4767 | &rsrc_info->header.cfg_shdr.response)); | ||
4768 | rc = -EIO; | ||
4769 | goto err_exit; | ||
4770 | } | ||
4771 | |||
4772 | *extnt_count = bf_get(lpfc_mbx_get_rsrc_extent_info_cnt, | ||
4773 | &rsrc_info->u.rsp); | ||
4774 | *extnt_size = bf_get(lpfc_mbx_get_rsrc_extent_info_size, | ||
4775 | &rsrc_info->u.rsp); | ||
4776 | err_exit: | ||
4777 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4778 | return rc; | ||
4779 | } | ||
4780 | |||
4781 | /** | ||
4782 | * lpfc_sli4_chk_avail_extnt_rsrc - Check for available SLI4 resource extents. | ||
4783 | * @phba: Pointer to HBA context object. | ||
4784 | * @type: The extent type to check. | ||
4785 | * | ||
4786 | * This function reads the current available extents from the port and checks | ||
4787 | * if the extent count or extent size has changed since the last access. | ||
4788 | * Callers use this routine post port reset to understand if there is a | ||
4789 | * extent reprovisioning requirement. | ||
4790 | * | ||
4791 | * Returns: | ||
4792 | * -Error: error indicates problem. | ||
4793 | * 1: Extent count or size has changed. | ||
4794 | * 0: No changes. | ||
4795 | **/ | ||
4796 | static int | ||
4797 | lpfc_sli4_chk_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type) | ||
4798 | { | ||
4799 | uint16_t curr_ext_cnt, rsrc_ext_cnt; | ||
4800 | uint16_t size_diff, rsrc_ext_size; | ||
4801 | int rc = 0; | ||
4802 | struct lpfc_rsrc_blks *rsrc_entry; | ||
4803 | struct list_head *rsrc_blk_list = NULL; | ||
4804 | |||
4805 | size_diff = 0; | ||
4806 | curr_ext_cnt = 0; | ||
4807 | rc = lpfc_sli4_get_avail_extnt_rsrc(phba, type, | ||
4808 | &rsrc_ext_cnt, | ||
4809 | &rsrc_ext_size); | ||
4810 | if (unlikely(rc)) | ||
4811 | return -EIO; | ||
4812 | |||
4813 | switch (type) { | ||
4814 | case LPFC_RSC_TYPE_FCOE_RPI: | ||
4815 | rsrc_blk_list = &phba->sli4_hba.lpfc_rpi_blk_list; | ||
4816 | break; | ||
4817 | case LPFC_RSC_TYPE_FCOE_VPI: | ||
4818 | rsrc_blk_list = &phba->lpfc_vpi_blk_list; | ||
4819 | break; | ||
4820 | case LPFC_RSC_TYPE_FCOE_XRI: | ||
4821 | rsrc_blk_list = &phba->sli4_hba.lpfc_xri_blk_list; | ||
4822 | break; | ||
4823 | case LPFC_RSC_TYPE_FCOE_VFI: | ||
4824 | rsrc_blk_list = &phba->sli4_hba.lpfc_vfi_blk_list; | ||
4825 | break; | ||
4826 | default: | ||
4827 | break; | ||
4828 | } | ||
4829 | |||
4830 | list_for_each_entry(rsrc_entry, rsrc_blk_list, list) { | ||
4831 | curr_ext_cnt++; | ||
4832 | if (rsrc_entry->rsrc_size != rsrc_ext_size) | ||
4833 | size_diff++; | ||
4834 | } | ||
4835 | |||
4836 | if (curr_ext_cnt != rsrc_ext_cnt || size_diff != 0) | ||
4837 | rc = 1; | ||
4838 | |||
4839 | return rc; | ||
4840 | } | ||
4841 | |||
4842 | /** | ||
4843 | * lpfc_sli4_cfg_post_extnts - | ||
4844 | * @phba: Pointer to HBA context object. | ||
4845 | * @extnt_cnt - number of available extents. | ||
4846 | * @type - the extent type (rpi, xri, vfi, vpi). | ||
4847 | * @emb - buffer to hold either MBX_EMBED or MBX_NEMBED operation. | ||
4848 | * @mbox - pointer to the caller's allocated mailbox structure. | ||
4849 | * | ||
4850 | * This function executes the extents allocation request. It also | ||
4851 | * takes care of the amount of memory needed to allocate or get the | ||
4852 | * allocated extents. It is the caller's responsibility to evaluate | ||
4853 | * the response. | ||
4854 | * | ||
4855 | * Returns: | ||
4856 | * -Error: Error value describes the condition found. | ||
4857 | * 0: if successful | ||
4858 | **/ | ||
4859 | static int | ||
4860 | lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t *extnt_cnt, | ||
4861 | uint16_t type, bool *emb, LPFC_MBOXQ_t *mbox) | ||
4862 | { | ||
4863 | int rc = 0; | ||
4864 | uint32_t req_len; | ||
4865 | uint32_t emb_len; | ||
4866 | uint32_t alloc_len, mbox_tmo; | ||
4867 | |||
4868 | /* Calculate the total requested length of the dma memory */ | ||
4869 | req_len = *extnt_cnt * sizeof(uint16_t); | ||
4870 | |||
4871 | /* | ||
4872 | * Calculate the size of an embedded mailbox. The uint32_t | ||
4873 | * accounts for extents-specific word. | ||
4874 | */ | ||
4875 | emb_len = sizeof(MAILBOX_t) - sizeof(struct mbox_header) - | ||
4876 | sizeof(uint32_t); | ||
4877 | |||
4878 | /* | ||
4879 | * Presume the allocation and response will fit into an embedded | ||
4880 | * mailbox. If not true, reconfigure to a non-embedded mailbox. | ||
4881 | */ | ||
4882 | *emb = LPFC_SLI4_MBX_EMBED; | ||
4883 | if (req_len > emb_len) { | ||
4884 | req_len = *extnt_cnt * sizeof(uint16_t) + | ||
4885 | sizeof(union lpfc_sli4_cfg_shdr) + | ||
4886 | sizeof(uint32_t); | ||
4887 | *emb = LPFC_SLI4_MBX_NEMBED; | ||
4888 | } | ||
4889 | |||
4890 | alloc_len = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
4891 | LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT, | ||
4892 | req_len, *emb); | ||
4893 | if (alloc_len < req_len) { | ||
4894 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4895 | "9000 Allocated DMA memory size (x%x) is " | ||
4896 | "less than the requested DMA memory " | ||
4897 | "size (x%x)\n", alloc_len, req_len); | ||
4898 | return -ENOMEM; | ||
4899 | } | ||
4900 | rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, *extnt_cnt, type, *emb); | ||
4901 | if (unlikely(rc)) | ||
4902 | return -EIO; | ||
4903 | |||
4904 | if (!phba->sli4_hba.intr_enable) | ||
4905 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
4906 | else { | ||
4907 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
4908 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
4909 | } | ||
4910 | |||
4911 | if (unlikely(rc)) | ||
4912 | rc = -EIO; | ||
4913 | return rc; | ||
4914 | } | ||
4915 | |||
4916 | /** | ||
4917 | * lpfc_sli4_alloc_extent - Allocate an SLI4 resource extent. | ||
4918 | * @phba: Pointer to HBA context object. | ||
4919 | * @type: The resource extent type to allocate. | ||
4920 | * | ||
4921 | * This function allocates the number of elements for the specified | ||
4922 | * resource type. | ||
4923 | **/ | ||
4924 | static int | ||
4925 | lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type) | ||
4926 | { | ||
4927 | bool emb = false; | ||
4928 | uint16_t rsrc_id_cnt, rsrc_cnt, rsrc_size; | ||
4929 | uint16_t rsrc_id, rsrc_start, j, k; | ||
4930 | uint16_t *ids; | ||
4931 | int i, rc; | ||
4932 | unsigned long longs; | ||
4933 | unsigned long *bmask; | ||
4934 | struct lpfc_rsrc_blks *rsrc_blks; | ||
4935 | LPFC_MBOXQ_t *mbox; | ||
4936 | uint32_t length; | ||
4937 | struct lpfc_id_range *id_array = NULL; | ||
4938 | void *virtaddr = NULL; | ||
4939 | struct lpfc_mbx_nembed_rsrc_extent *n_rsrc; | ||
4940 | struct lpfc_mbx_alloc_rsrc_extents *rsrc_ext; | ||
4941 | struct list_head *ext_blk_list; | ||
4942 | |||
4943 | rc = lpfc_sli4_get_avail_extnt_rsrc(phba, type, | ||
4944 | &rsrc_cnt, | ||
4945 | &rsrc_size); | ||
4946 | if (unlikely(rc)) | ||
4947 | return -EIO; | ||
4948 | |||
4949 | if ((rsrc_cnt == 0) || (rsrc_size == 0)) { | ||
4950 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT, | ||
4951 | "3009 No available Resource Extents " | ||
4952 | "for resource type 0x%x: Count: 0x%x, " | ||
4953 | "Size 0x%x\n", type, rsrc_cnt, | ||
4954 | rsrc_size); | ||
4955 | return -ENOMEM; | ||
4956 | } | ||
4957 | |||
4958 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_INIT, | ||
4959 | "2903 Available Resource Extents " | ||
4960 | "for resource type 0x%x: Count: 0x%x, " | ||
4961 | "Size 0x%x\n", type, rsrc_cnt, | ||
4962 | rsrc_size); | ||
4963 | |||
4964 | mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4965 | if (!mbox) | ||
4966 | return -ENOMEM; | ||
4967 | |||
4968 | rc = lpfc_sli4_cfg_post_extnts(phba, &rsrc_cnt, type, &emb, mbox); | ||
4969 | if (unlikely(rc)) { | ||
4970 | rc = -EIO; | ||
4971 | goto err_exit; | ||
4972 | } | ||
4973 | |||
4974 | /* | ||
4975 | * Figure out where the response is located. Then get local pointers | ||
4976 | * to the response data. The port does not guarantee to respond to | ||
4977 | * all extents counts request so update the local variable with the | ||
4978 | * allocated count from the port. | ||
4979 | */ | ||
4980 | if (emb == LPFC_SLI4_MBX_EMBED) { | ||
4981 | rsrc_ext = &mbox->u.mqe.un.alloc_rsrc_extents; | ||
4982 | id_array = &rsrc_ext->u.rsp.id[0]; | ||
4983 | rsrc_cnt = bf_get(lpfc_mbx_rsrc_cnt, &rsrc_ext->u.rsp); | ||
4984 | } else { | ||
4985 | virtaddr = mbox->sge_array->addr[0]; | ||
4986 | n_rsrc = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr; | ||
4987 | rsrc_cnt = bf_get(lpfc_mbx_rsrc_cnt, n_rsrc); | ||
4988 | id_array = &n_rsrc->id; | ||
4989 | } | ||
4990 | |||
4991 | longs = ((rsrc_cnt * rsrc_size) + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
4992 | rsrc_id_cnt = rsrc_cnt * rsrc_size; | ||
4993 | |||
4994 | /* | ||
4995 | * Based on the resource size and count, correct the base and max | ||
4996 | * resource values. | ||
4997 | */ | ||
4998 | length = sizeof(struct lpfc_rsrc_blks); | ||
4999 | switch (type) { | ||
5000 | case LPFC_RSC_TYPE_FCOE_RPI: | ||
5001 | phba->sli4_hba.rpi_bmask = kzalloc(longs * | ||
5002 | sizeof(unsigned long), | ||
5003 | GFP_KERNEL); | ||
5004 | if (unlikely(!phba->sli4_hba.rpi_bmask)) { | ||
5005 | rc = -ENOMEM; | ||
5006 | goto err_exit; | ||
5007 | } | ||
5008 | phba->sli4_hba.rpi_ids = kzalloc(rsrc_id_cnt * | ||
5009 | sizeof(uint16_t), | ||
5010 | GFP_KERNEL); | ||
5011 | if (unlikely(!phba->sli4_hba.rpi_ids)) { | ||
5012 | kfree(phba->sli4_hba.rpi_bmask); | ||
5013 | rc = -ENOMEM; | ||
5014 | goto err_exit; | ||
5015 | } | ||
5016 | |||
5017 | /* | ||
5018 | * The next_rpi was initialized with the maximum available | ||
5019 | * count but the port may allocate a smaller number. Catch | ||
5020 | * that case and update the next_rpi. | ||
5021 | */ | ||
5022 | phba->sli4_hba.next_rpi = rsrc_id_cnt; | ||
5023 | |||
5024 | /* Initialize local ptrs for common extent processing later. */ | ||
5025 | bmask = phba->sli4_hba.rpi_bmask; | ||
5026 | ids = phba->sli4_hba.rpi_ids; | ||
5027 | ext_blk_list = &phba->sli4_hba.lpfc_rpi_blk_list; | ||
5028 | break; | ||
5029 | case LPFC_RSC_TYPE_FCOE_VPI: | ||
5030 | phba->vpi_bmask = kzalloc(longs * | ||
5031 | sizeof(unsigned long), | ||
5032 | GFP_KERNEL); | ||
5033 | if (unlikely(!phba->vpi_bmask)) { | ||
5034 | rc = -ENOMEM; | ||
5035 | goto err_exit; | ||
5036 | } | ||
5037 | phba->vpi_ids = kzalloc(rsrc_id_cnt * | ||
5038 | sizeof(uint16_t), | ||
5039 | GFP_KERNEL); | ||
5040 | if (unlikely(!phba->vpi_ids)) { | ||
5041 | kfree(phba->vpi_bmask); | ||
5042 | rc = -ENOMEM; | ||
5043 | goto err_exit; | ||
5044 | } | ||
5045 | |||
5046 | /* Initialize local ptrs for common extent processing later. */ | ||
5047 | bmask = phba->vpi_bmask; | ||
5048 | ids = phba->vpi_ids; | ||
5049 | ext_blk_list = &phba->lpfc_vpi_blk_list; | ||
5050 | break; | ||
5051 | case LPFC_RSC_TYPE_FCOE_XRI: | ||
5052 | phba->sli4_hba.xri_bmask = kzalloc(longs * | ||
5053 | sizeof(unsigned long), | ||
5054 | GFP_KERNEL); | ||
5055 | if (unlikely(!phba->sli4_hba.xri_bmask)) { | ||
5056 | rc = -ENOMEM; | ||
5057 | goto err_exit; | ||
5058 | } | ||
5059 | phba->sli4_hba.xri_ids = kzalloc(rsrc_id_cnt * | ||
5060 | sizeof(uint16_t), | ||
5061 | GFP_KERNEL); | ||
5062 | if (unlikely(!phba->sli4_hba.xri_ids)) { | ||
5063 | kfree(phba->sli4_hba.xri_bmask); | ||
5064 | rc = -ENOMEM; | ||
5065 | goto err_exit; | ||
5066 | } | ||
5067 | |||
5068 | /* Initialize local ptrs for common extent processing later. */ | ||
5069 | bmask = phba->sli4_hba.xri_bmask; | ||
5070 | ids = phba->sli4_hba.xri_ids; | ||
5071 | ext_blk_list = &phba->sli4_hba.lpfc_xri_blk_list; | ||
5072 | break; | ||
5073 | case LPFC_RSC_TYPE_FCOE_VFI: | ||
5074 | phba->sli4_hba.vfi_bmask = kzalloc(longs * | ||
5075 | sizeof(unsigned long), | ||
5076 | GFP_KERNEL); | ||
5077 | if (unlikely(!phba->sli4_hba.vfi_bmask)) { | ||
5078 | rc = -ENOMEM; | ||
5079 | goto err_exit; | ||
5080 | } | ||
5081 | phba->sli4_hba.vfi_ids = kzalloc(rsrc_id_cnt * | ||
5082 | sizeof(uint16_t), | ||
5083 | GFP_KERNEL); | ||
5084 | if (unlikely(!phba->sli4_hba.vfi_ids)) { | ||
5085 | kfree(phba->sli4_hba.vfi_bmask); | ||
5086 | rc = -ENOMEM; | ||
5087 | goto err_exit; | ||
5088 | } | ||
5089 | |||
5090 | /* Initialize local ptrs for common extent processing later. */ | ||
5091 | bmask = phba->sli4_hba.vfi_bmask; | ||
5092 | ids = phba->sli4_hba.vfi_ids; | ||
5093 | ext_blk_list = &phba->sli4_hba.lpfc_vfi_blk_list; | ||
5094 | break; | ||
5095 | default: | ||
5096 | /* Unsupported Opcode. Fail call. */ | ||
5097 | id_array = NULL; | ||
5098 | bmask = NULL; | ||
5099 | ids = NULL; | ||
5100 | ext_blk_list = NULL; | ||
5101 | goto err_exit; | ||
5102 | } | ||
5103 | |||
5104 | /* | ||
5105 | * Complete initializing the extent configuration with the | ||
5106 | * allocated ids assigned to this function. The bitmask serves | ||
5107 | * as an index into the array and manages the available ids. The | ||
5108 | * array just stores the ids communicated to the port via the wqes. | ||
5109 | */ | ||
5110 | for (i = 0, j = 0, k = 0; i < rsrc_cnt; i++) { | ||
5111 | if ((i % 2) == 0) | ||
5112 | rsrc_id = bf_get(lpfc_mbx_rsrc_id_word4_0, | ||
5113 | &id_array[k]); | ||
5114 | else | ||
5115 | rsrc_id = bf_get(lpfc_mbx_rsrc_id_word4_1, | ||
5116 | &id_array[k]); | ||
5117 | |||
5118 | rsrc_blks = kzalloc(length, GFP_KERNEL); | ||
5119 | if (unlikely(!rsrc_blks)) { | ||
5120 | rc = -ENOMEM; | ||
5121 | kfree(bmask); | ||
5122 | kfree(ids); | ||
5123 | goto err_exit; | ||
5124 | } | ||
5125 | rsrc_blks->rsrc_start = rsrc_id; | ||
5126 | rsrc_blks->rsrc_size = rsrc_size; | ||
5127 | list_add_tail(&rsrc_blks->list, ext_blk_list); | ||
5128 | rsrc_start = rsrc_id; | ||
5129 | if ((type == LPFC_RSC_TYPE_FCOE_XRI) && (j == 0)) | ||
5130 | phba->sli4_hba.scsi_xri_start = rsrc_start + | ||
5131 | lpfc_sli4_get_els_iocb_cnt(phba); | ||
5132 | |||
5133 | while (rsrc_id < (rsrc_start + rsrc_size)) { | ||
5134 | ids[j] = rsrc_id; | ||
5135 | rsrc_id++; | ||
5136 | j++; | ||
5137 | } | ||
5138 | /* Entire word processed. Get next word.*/ | ||
5139 | if ((i % 2) == 1) | ||
5140 | k++; | ||
5141 | } | ||
5142 | err_exit: | ||
5143 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
5144 | return rc; | ||
5145 | } | ||
5146 | |||
5147 | /** | ||
5148 | * lpfc_sli4_dealloc_extent - Deallocate an SLI4 resource extent. | ||
5149 | * @phba: Pointer to HBA context object. | ||
5150 | * @type: the extent's type. | ||
5151 | * | ||
5152 | * This function deallocates all extents of a particular resource type. | ||
5153 | * SLI4 does not allow for deallocating a particular extent range. It | ||
5154 | * is the caller's responsibility to release all kernel memory resources. | ||
5155 | **/ | ||
5156 | static int | ||
5157 | lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type) | ||
5158 | { | ||
5159 | int rc; | ||
5160 | uint32_t length, mbox_tmo = 0; | ||
5161 | LPFC_MBOXQ_t *mbox; | ||
5162 | struct lpfc_mbx_dealloc_rsrc_extents *dealloc_rsrc; | ||
5163 | struct lpfc_rsrc_blks *rsrc_blk, *rsrc_blk_next; | ||
5164 | |||
5165 | mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
5166 | if (!mbox) | ||
5167 | return -ENOMEM; | ||
5168 | |||
5169 | /* | ||
5170 | * This function sends an embedded mailbox because it only sends the | ||
5171 | * the resource type. All extents of this type are released by the | ||
5172 | * port. | ||
5173 | */ | ||
5174 | length = (sizeof(struct lpfc_mbx_dealloc_rsrc_extents) - | ||
5175 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
5176 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
5177 | LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT, | ||
5178 | length, LPFC_SLI4_MBX_EMBED); | ||
5179 | |||
5180 | /* Send an extents count of 0 - the dealloc doesn't use it. */ | ||
5181 | rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, 0, type, | ||
5182 | LPFC_SLI4_MBX_EMBED); | ||
5183 | if (unlikely(rc)) { | ||
5184 | rc = -EIO; | ||
5185 | goto out_free_mbox; | ||
5186 | } | ||
5187 | if (!phba->sli4_hba.intr_enable) | ||
5188 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
5189 | else { | ||
5190 | mbox_tmo = lpfc_mbox_tmo_val(phba, mbox_tmo); | ||
5191 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
5192 | } | ||
5193 | if (unlikely(rc)) { | ||
5194 | rc = -EIO; | ||
5195 | goto out_free_mbox; | ||
5196 | } | ||
5197 | |||
5198 | dealloc_rsrc = &mbox->u.mqe.un.dealloc_rsrc_extents; | ||
5199 | if (bf_get(lpfc_mbox_hdr_status, | ||
5200 | &dealloc_rsrc->header.cfg_shdr.response)) { | ||
5201 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT, | ||
5202 | "2919 Failed to release resource extents " | ||
5203 | "for type %d - Status 0x%x Add'l Status 0x%x. " | ||
5204 | "Resource memory not released.\n", | ||
5205 | type, | ||
5206 | bf_get(lpfc_mbox_hdr_status, | ||
5207 | &dealloc_rsrc->header.cfg_shdr.response), | ||
5208 | bf_get(lpfc_mbox_hdr_add_status, | ||
5209 | &dealloc_rsrc->header.cfg_shdr.response)); | ||
5210 | rc = -EIO; | ||
5211 | goto out_free_mbox; | ||
5212 | } | ||
5213 | |||
5214 | /* Release kernel memory resources for the specific type. */ | ||
5215 | switch (type) { | ||
5216 | case LPFC_RSC_TYPE_FCOE_VPI: | ||
5217 | kfree(phba->vpi_bmask); | ||
5218 | kfree(phba->vpi_ids); | ||
5219 | bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5220 | list_for_each_entry_safe(rsrc_blk, rsrc_blk_next, | ||
5221 | &phba->lpfc_vpi_blk_list, list) { | ||
5222 | list_del_init(&rsrc_blk->list); | ||
5223 | kfree(rsrc_blk); | ||
5224 | } | ||
5225 | break; | ||
5226 | case LPFC_RSC_TYPE_FCOE_XRI: | ||
5227 | kfree(phba->sli4_hba.xri_bmask); | ||
5228 | kfree(phba->sli4_hba.xri_ids); | ||
5229 | bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5230 | list_for_each_entry_safe(rsrc_blk, rsrc_blk_next, | ||
5231 | &phba->sli4_hba.lpfc_xri_blk_list, list) { | ||
5232 | list_del_init(&rsrc_blk->list); | ||
5233 | kfree(rsrc_blk); | ||
5234 | } | ||
5235 | break; | ||
5236 | case LPFC_RSC_TYPE_FCOE_VFI: | ||
5237 | kfree(phba->sli4_hba.vfi_bmask); | ||
5238 | kfree(phba->sli4_hba.vfi_ids); | ||
5239 | bf_set(lpfc_vfi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5240 | list_for_each_entry_safe(rsrc_blk, rsrc_blk_next, | ||
5241 | &phba->sli4_hba.lpfc_vfi_blk_list, list) { | ||
5242 | list_del_init(&rsrc_blk->list); | ||
5243 | kfree(rsrc_blk); | ||
5244 | } | ||
5245 | break; | ||
5246 | case LPFC_RSC_TYPE_FCOE_RPI: | ||
5247 | /* RPI bitmask and physical id array are cleaned up earlier. */ | ||
5248 | list_for_each_entry_safe(rsrc_blk, rsrc_blk_next, | ||
5249 | &phba->sli4_hba.lpfc_rpi_blk_list, list) { | ||
5250 | list_del_init(&rsrc_blk->list); | ||
5251 | kfree(rsrc_blk); | ||
5252 | } | ||
5253 | break; | ||
5254 | default: | ||
5255 | break; | ||
5256 | } | ||
5257 | |||
5258 | bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5259 | |||
5260 | out_free_mbox: | ||
5261 | mempool_free(mbox, phba->mbox_mem_pool); | ||
5262 | return rc; | ||
5263 | } | ||
5264 | |||
5265 | /** | ||
5266 | * lpfc_sli4_alloc_resource_identifiers - Allocate all SLI4 resource extents. | ||
5267 | * @phba: Pointer to HBA context object. | ||
5268 | * | ||
5269 | * This function allocates all SLI4 resource identifiers. | ||
5270 | **/ | ||
5271 | int | ||
5272 | lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) | ||
5273 | { | ||
5274 | int i, rc, error = 0; | ||
5275 | uint16_t count, base; | ||
5276 | unsigned long longs; | ||
5277 | |||
5278 | if (phba->sli4_hba.extents_in_use) { | ||
5279 | /* | ||
5280 | * The port supports resource extents. The XRI, VPI, VFI, RPI | ||
5281 | * resource extent count must be read and allocated before | ||
5282 | * provisioning the resource id arrays. | ||
5283 | */ | ||
5284 | if (bf_get(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags) == | ||
5285 | LPFC_IDX_RSRC_RDY) { | ||
5286 | /* | ||
5287 | * Extent-based resources are set - the driver could | ||
5288 | * be in a port reset. Figure out if any corrective | ||
5289 | * actions need to be taken. | ||
5290 | */ | ||
5291 | rc = lpfc_sli4_chk_avail_extnt_rsrc(phba, | ||
5292 | LPFC_RSC_TYPE_FCOE_VFI); | ||
5293 | if (rc != 0) | ||
5294 | error++; | ||
5295 | rc = lpfc_sli4_chk_avail_extnt_rsrc(phba, | ||
5296 | LPFC_RSC_TYPE_FCOE_VPI); | ||
5297 | if (rc != 0) | ||
5298 | error++; | ||
5299 | rc = lpfc_sli4_chk_avail_extnt_rsrc(phba, | ||
5300 | LPFC_RSC_TYPE_FCOE_XRI); | ||
5301 | if (rc != 0) | ||
5302 | error++; | ||
5303 | rc = lpfc_sli4_chk_avail_extnt_rsrc(phba, | ||
5304 | LPFC_RSC_TYPE_FCOE_RPI); | ||
5305 | if (rc != 0) | ||
5306 | error++; | ||
5307 | |||
5308 | /* | ||
5309 | * It's possible that the number of resources | ||
5310 | * provided to this port instance changed between | ||
5311 | * resets. Detect this condition and reallocate | ||
5312 | * resources. Otherwise, there is no action. | ||
5313 | */ | ||
5314 | if (error) { | ||
5315 | lpfc_printf_log(phba, KERN_INFO, | ||
5316 | LOG_MBOX | LOG_INIT, | ||
5317 | "2931 Detected extent resource " | ||
5318 | "change. Reallocating all " | ||
5319 | "extents.\n"); | ||
5320 | rc = lpfc_sli4_dealloc_extent(phba, | ||
5321 | LPFC_RSC_TYPE_FCOE_VFI); | ||
5322 | rc = lpfc_sli4_dealloc_extent(phba, | ||
5323 | LPFC_RSC_TYPE_FCOE_VPI); | ||
5324 | rc = lpfc_sli4_dealloc_extent(phba, | ||
5325 | LPFC_RSC_TYPE_FCOE_XRI); | ||
5326 | rc = lpfc_sli4_dealloc_extent(phba, | ||
5327 | LPFC_RSC_TYPE_FCOE_RPI); | ||
5328 | } else | ||
5329 | return 0; | ||
5330 | } | ||
5331 | |||
5332 | rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI); | ||
5333 | if (unlikely(rc)) | ||
5334 | goto err_exit; | ||
5335 | |||
5336 | rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_VPI); | ||
5337 | if (unlikely(rc)) | ||
5338 | goto err_exit; | ||
5339 | |||
5340 | rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_RPI); | ||
5341 | if (unlikely(rc)) | ||
5342 | goto err_exit; | ||
5343 | |||
5344 | rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_XRI); | ||
5345 | if (unlikely(rc)) | ||
5346 | goto err_exit; | ||
5347 | bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags, | ||
5348 | LPFC_IDX_RSRC_RDY); | ||
5349 | return rc; | ||
5350 | } else { | ||
5351 | /* | ||
5352 | * The port does not support resource extents. The XRI, VPI, | ||
5353 | * VFI, RPI resource ids were determined from READ_CONFIG. | ||
5354 | * Just allocate the bitmasks and provision the resource id | ||
5355 | * arrays. If a port reset is active, the resources don't | ||
5356 | * need any action - just exit. | ||
5357 | */ | ||
5358 | if (bf_get(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags) == | ||
5359 | LPFC_IDX_RSRC_RDY) | ||
5360 | return 0; | ||
5361 | |||
5362 | /* RPIs. */ | ||
5363 | count = phba->sli4_hba.max_cfg_param.max_rpi; | ||
5364 | base = phba->sli4_hba.max_cfg_param.rpi_base; | ||
5365 | longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
5366 | phba->sli4_hba.rpi_bmask = kzalloc(longs * | ||
5367 | sizeof(unsigned long), | ||
5368 | GFP_KERNEL); | ||
5369 | if (unlikely(!phba->sli4_hba.rpi_bmask)) { | ||
5370 | rc = -ENOMEM; | ||
5371 | goto err_exit; | ||
5372 | } | ||
5373 | phba->sli4_hba.rpi_ids = kzalloc(count * | ||
5374 | sizeof(uint16_t), | ||
5375 | GFP_KERNEL); | ||
5376 | if (unlikely(!phba->sli4_hba.rpi_ids)) { | ||
5377 | rc = -ENOMEM; | ||
5378 | goto free_rpi_bmask; | ||
5379 | } | ||
5380 | |||
5381 | for (i = 0; i < count; i++) | ||
5382 | phba->sli4_hba.rpi_ids[i] = base + i; | ||
5383 | |||
5384 | /* VPIs. */ | ||
5385 | count = phba->sli4_hba.max_cfg_param.max_vpi; | ||
5386 | base = phba->sli4_hba.max_cfg_param.vpi_base; | ||
5387 | longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
5388 | phba->vpi_bmask = kzalloc(longs * | ||
5389 | sizeof(unsigned long), | ||
5390 | GFP_KERNEL); | ||
5391 | if (unlikely(!phba->vpi_bmask)) { | ||
5392 | rc = -ENOMEM; | ||
5393 | goto free_rpi_ids; | ||
5394 | } | ||
5395 | phba->vpi_ids = kzalloc(count * | ||
5396 | sizeof(uint16_t), | ||
5397 | GFP_KERNEL); | ||
5398 | if (unlikely(!phba->vpi_ids)) { | ||
5399 | rc = -ENOMEM; | ||
5400 | goto free_vpi_bmask; | ||
5401 | } | ||
5402 | |||
5403 | for (i = 0; i < count; i++) | ||
5404 | phba->vpi_ids[i] = base + i; | ||
5405 | |||
5406 | /* XRIs. */ | ||
5407 | count = phba->sli4_hba.max_cfg_param.max_xri; | ||
5408 | base = phba->sli4_hba.max_cfg_param.xri_base; | ||
5409 | longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
5410 | phba->sli4_hba.xri_bmask = kzalloc(longs * | ||
5411 | sizeof(unsigned long), | ||
5412 | GFP_KERNEL); | ||
5413 | if (unlikely(!phba->sli4_hba.xri_bmask)) { | ||
5414 | rc = -ENOMEM; | ||
5415 | goto free_vpi_ids; | ||
5416 | } | ||
5417 | phba->sli4_hba.xri_ids = kzalloc(count * | ||
5418 | sizeof(uint16_t), | ||
5419 | GFP_KERNEL); | ||
5420 | if (unlikely(!phba->sli4_hba.xri_ids)) { | ||
5421 | rc = -ENOMEM; | ||
5422 | goto free_xri_bmask; | ||
5423 | } | ||
5424 | |||
5425 | for (i = 0; i < count; i++) | ||
5426 | phba->sli4_hba.xri_ids[i] = base + i; | ||
5427 | |||
5428 | /* VFIs. */ | ||
5429 | count = phba->sli4_hba.max_cfg_param.max_vfi; | ||
5430 | base = phba->sli4_hba.max_cfg_param.vfi_base; | ||
5431 | longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
5432 | phba->sli4_hba.vfi_bmask = kzalloc(longs * | ||
5433 | sizeof(unsigned long), | ||
5434 | GFP_KERNEL); | ||
5435 | if (unlikely(!phba->sli4_hba.vfi_bmask)) { | ||
5436 | rc = -ENOMEM; | ||
5437 | goto free_xri_ids; | ||
5438 | } | ||
5439 | phba->sli4_hba.vfi_ids = kzalloc(count * | ||
5440 | sizeof(uint16_t), | ||
5441 | GFP_KERNEL); | ||
5442 | if (unlikely(!phba->sli4_hba.vfi_ids)) { | ||
5443 | rc = -ENOMEM; | ||
5444 | goto free_vfi_bmask; | ||
5445 | } | ||
5446 | |||
5447 | for (i = 0; i < count; i++) | ||
5448 | phba->sli4_hba.vfi_ids[i] = base + i; | ||
5449 | |||
5450 | /* | ||
5451 | * Mark all resources ready. An HBA reset doesn't need | ||
5452 | * to reset the initialization. | ||
5453 | */ | ||
5454 | bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags, | ||
5455 | LPFC_IDX_RSRC_RDY); | ||
5456 | return 0; | ||
5457 | } | ||
5458 | |||
5459 | free_vfi_bmask: | ||
5460 | kfree(phba->sli4_hba.vfi_bmask); | ||
5461 | free_xri_ids: | ||
5462 | kfree(phba->sli4_hba.xri_ids); | ||
5463 | free_xri_bmask: | ||
5464 | kfree(phba->sli4_hba.xri_bmask); | ||
5465 | free_vpi_ids: | ||
5466 | kfree(phba->vpi_ids); | ||
5467 | free_vpi_bmask: | ||
5468 | kfree(phba->vpi_bmask); | ||
5469 | free_rpi_ids: | ||
5470 | kfree(phba->sli4_hba.rpi_ids); | ||
5471 | free_rpi_bmask: | ||
5472 | kfree(phba->sli4_hba.rpi_bmask); | ||
5473 | err_exit: | ||
5474 | return rc; | ||
5475 | } | ||
5476 | |||
5477 | /** | ||
5478 | * lpfc_sli4_dealloc_resource_identifiers - Deallocate all SLI4 resource extents. | ||
5479 | * @phba: Pointer to HBA context object. | ||
5480 | * | ||
5481 | * This function allocates the number of elements for the specified | ||
5482 | * resource type. | ||
5483 | **/ | ||
5484 | int | ||
5485 | lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba) | ||
5486 | { | ||
5487 | if (phba->sli4_hba.extents_in_use) { | ||
5488 | lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VPI); | ||
5489 | lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_RPI); | ||
5490 | lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_XRI); | ||
5491 | lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI); | ||
5492 | } else { | ||
5493 | kfree(phba->vpi_bmask); | ||
5494 | kfree(phba->vpi_ids); | ||
5495 | bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5496 | kfree(phba->sli4_hba.xri_bmask); | ||
5497 | kfree(phba->sli4_hba.xri_ids); | ||
5498 | bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5499 | kfree(phba->sli4_hba.vfi_bmask); | ||
5500 | kfree(phba->sli4_hba.vfi_ids); | ||
5501 | bf_set(lpfc_vfi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5502 | bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
5503 | } | ||
5504 | |||
5505 | return 0; | ||
5506 | } | ||
5507 | |||
5508 | /** | ||
4690 | * lpfc_sli4_hba_setup - SLI4 device intialization PCI function | 5509 | * lpfc_sli4_hba_setup - SLI4 device intialization PCI function |
4691 | * @phba: Pointer to HBA context object. | 5510 | * @phba: Pointer to HBA context object. |
4692 | * | 5511 | * |
@@ -4708,10 +5527,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4708 | struct lpfc_vport *vport = phba->pport; | 5527 | struct lpfc_vport *vport = phba->pport; |
4709 | struct lpfc_dmabuf *mp; | 5528 | struct lpfc_dmabuf *mp; |
4710 | 5529 | ||
4711 | /* | ||
4712 | * TODO: Why does this routine execute these task in a different | ||
4713 | * order from probe? | ||
4714 | */ | ||
4715 | /* Perform a PCI function reset to start from clean */ | 5530 | /* Perform a PCI function reset to start from clean */ |
4716 | rc = lpfc_pci_function_reset(phba); | 5531 | rc = lpfc_pci_function_reset(phba); |
4717 | if (unlikely(rc)) | 5532 | if (unlikely(rc)) |
@@ -4740,7 +5555,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4740 | * to read FCoE param config regions | 5555 | * to read FCoE param config regions |
4741 | */ | 5556 | */ |
4742 | if (lpfc_sli4_read_fcoe_params(phba, mboxq)) | 5557 | if (lpfc_sli4_read_fcoe_params(phba, mboxq)) |
4743 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT, | 5558 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_INIT, |
4744 | "2570 Failed to read FCoE parameters\n"); | 5559 | "2570 Failed to read FCoE parameters\n"); |
4745 | 5560 | ||
4746 | /* Issue READ_REV to collect vpd and FW information. */ | 5561 | /* Issue READ_REV to collect vpd and FW information. */ |
@@ -4873,6 +5688,18 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4873 | phba->sli3_options |= (LPFC_SLI3_NPIV_ENABLED | LPFC_SLI3_HBQ_ENABLED); | 5688 | phba->sli3_options |= (LPFC_SLI3_NPIV_ENABLED | LPFC_SLI3_HBQ_ENABLED); |
4874 | spin_unlock_irq(&phba->hbalock); | 5689 | spin_unlock_irq(&phba->hbalock); |
4875 | 5690 | ||
5691 | /* | ||
5692 | * Allocate all resources (xri,rpi,vpi,vfi) now. Subsequent | ||
5693 | * calls depends on these resources to complete port setup. | ||
5694 | */ | ||
5695 | rc = lpfc_sli4_alloc_resource_identifiers(phba); | ||
5696 | if (rc) { | ||
5697 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
5698 | "2920 Failed to alloc Resource IDs " | ||
5699 | "rc = x%x\n", rc); | ||
5700 | goto out_free_mbox; | ||
5701 | } | ||
5702 | |||
4876 | /* Read the port's service parameters. */ | 5703 | /* Read the port's service parameters. */ |
4877 | rc = lpfc_read_sparam(phba, mboxq, vport->vpi); | 5704 | rc = lpfc_read_sparam(phba, mboxq, vport->vpi); |
4878 | if (rc) { | 5705 | if (rc) { |
@@ -4906,35 +5733,37 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4906 | goto out_free_mbox; | 5733 | goto out_free_mbox; |
4907 | } | 5734 | } |
4908 | 5735 | ||
4909 | if (phba->cfg_soft_wwnn) | 5736 | lpfc_update_vport_wwn(vport); |
4910 | u64_to_wwn(phba->cfg_soft_wwnn, | ||
4911 | vport->fc_sparam.nodeName.u.wwn); | ||
4912 | if (phba->cfg_soft_wwpn) | ||
4913 | u64_to_wwn(phba->cfg_soft_wwpn, | ||
4914 | vport->fc_sparam.portName.u.wwn); | ||
4915 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, | ||
4916 | sizeof(struct lpfc_name)); | ||
4917 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, | ||
4918 | sizeof(struct lpfc_name)); | ||
4919 | 5737 | ||
4920 | /* Update the fc_host data structures with new wwn. */ | 5738 | /* Update the fc_host data structures with new wwn. */ |
4921 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); | 5739 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); |
4922 | fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); | 5740 | fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); |
4923 | 5741 | ||
4924 | /* Register SGL pool to the device using non-embedded mailbox command */ | 5742 | /* Register SGL pool to the device using non-embedded mailbox command */ |
4925 | rc = lpfc_sli4_post_sgl_list(phba); | 5743 | if (!phba->sli4_hba.extents_in_use) { |
4926 | if (unlikely(rc)) { | 5744 | rc = lpfc_sli4_post_els_sgl_list(phba); |
4927 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 5745 | if (unlikely(rc)) { |
4928 | "0582 Error %d during sgl post operation\n", | 5746 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
4929 | rc); | 5747 | "0582 Error %d during els sgl post " |
4930 | rc = -ENODEV; | 5748 | "operation\n", rc); |
4931 | goto out_free_mbox; | 5749 | rc = -ENODEV; |
5750 | goto out_free_mbox; | ||
5751 | } | ||
5752 | } else { | ||
5753 | rc = lpfc_sli4_post_els_sgl_list_ext(phba); | ||
5754 | if (unlikely(rc)) { | ||
5755 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
5756 | "2560 Error %d during els sgl post " | ||
5757 | "operation\n", rc); | ||
5758 | rc = -ENODEV; | ||
5759 | goto out_free_mbox; | ||
5760 | } | ||
4932 | } | 5761 | } |
4933 | 5762 | ||
4934 | /* Register SCSI SGL pool to the device */ | 5763 | /* Register SCSI SGL pool to the device */ |
4935 | rc = lpfc_sli4_repost_scsi_sgl_list(phba); | 5764 | rc = lpfc_sli4_repost_scsi_sgl_list(phba); |
4936 | if (unlikely(rc)) { | 5765 | if (unlikely(rc)) { |
4937 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, | 5766 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
4938 | "0383 Error %d during scsi sgl post " | 5767 | "0383 Error %d during scsi sgl post " |
4939 | "operation\n", rc); | 5768 | "operation\n", rc); |
4940 | /* Some Scsi buffers were moved to the abort scsi list */ | 5769 | /* Some Scsi buffers were moved to the abort scsi list */ |
@@ -5747,10 +6576,15 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
5747 | lpfc_sli_pcimem_bcopy(&mbox_rgn->mcqe, &mboxq->mcqe, | 6576 | lpfc_sli_pcimem_bcopy(&mbox_rgn->mcqe, &mboxq->mcqe, |
5748 | sizeof(struct lpfc_mcqe)); | 6577 | sizeof(struct lpfc_mcqe)); |
5749 | mcqe_status = bf_get(lpfc_mcqe_status, &mbox_rgn->mcqe); | 6578 | mcqe_status = bf_get(lpfc_mcqe_status, &mbox_rgn->mcqe); |
5750 | 6579 | /* | |
5751 | /* Prefix the mailbox status with range x4000 to note SLI4 status. */ | 6580 | * When the CQE status indicates a failure and the mailbox status |
6581 | * indicates success then copy the CQE status into the mailbox status | ||
6582 | * (and prefix it with x4000). | ||
6583 | */ | ||
5752 | if (mcqe_status != MB_CQE_STATUS_SUCCESS) { | 6584 | if (mcqe_status != MB_CQE_STATUS_SUCCESS) { |
5753 | bf_set(lpfc_mqe_status, mb, LPFC_MBX_ERROR_RANGE | mcqe_status); | 6585 | if (bf_get(lpfc_mqe_status, mb) == MBX_SUCCESS) |
6586 | bf_set(lpfc_mqe_status, mb, | ||
6587 | (LPFC_MBX_ERROR_RANGE | mcqe_status)); | ||
5754 | rc = MBXERR_ERROR; | 6588 | rc = MBXERR_ERROR; |
5755 | } else | 6589 | } else |
5756 | lpfc_sli4_swap_str(phba, mboxq); | 6590 | lpfc_sli4_swap_str(phba, mboxq); |
@@ -5819,7 +6653,7 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
5819 | else | 6653 | else |
5820 | rc = -EIO; | 6654 | rc = -EIO; |
5821 | if (rc != MBX_SUCCESS) | 6655 | if (rc != MBX_SUCCESS) |
5822 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 6656 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, |
5823 | "(%d):2541 Mailbox command x%x " | 6657 | "(%d):2541 Mailbox command x%x " |
5824 | "(x%x) cannot issue Data: x%x x%x\n", | 6658 | "(x%x) cannot issue Data: x%x x%x\n", |
5825 | mboxq->vport ? mboxq->vport->vpi : 0, | 6659 | mboxq->vport ? mboxq->vport->vpi : 0, |
@@ -6307,6 +7141,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
6307 | sgl->addr_hi = bpl->addrHigh; | 7141 | sgl->addr_hi = bpl->addrHigh; |
6308 | sgl->addr_lo = bpl->addrLow; | 7142 | sgl->addr_lo = bpl->addrLow; |
6309 | 7143 | ||
7144 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
6310 | if ((i+1) == numBdes) | 7145 | if ((i+1) == numBdes) |
6311 | bf_set(lpfc_sli4_sge_last, sgl, 1); | 7146 | bf_set(lpfc_sli4_sge_last, sgl, 1); |
6312 | else | 7147 | else |
@@ -6343,6 +7178,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
6343 | cpu_to_le32(icmd->un.genreq64.bdl.addrHigh); | 7178 | cpu_to_le32(icmd->un.genreq64.bdl.addrHigh); |
6344 | sgl->addr_lo = | 7179 | sgl->addr_lo = |
6345 | cpu_to_le32(icmd->un.genreq64.bdl.addrLow); | 7180 | cpu_to_le32(icmd->un.genreq64.bdl.addrLow); |
7181 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
6346 | bf_set(lpfc_sli4_sge_last, sgl, 1); | 7182 | bf_set(lpfc_sli4_sge_last, sgl, 1); |
6347 | sgl->word2 = cpu_to_le32(sgl->word2); | 7183 | sgl->word2 = cpu_to_le32(sgl->word2); |
6348 | sgl->sge_len = | 7184 | sgl->sge_len = |
@@ -6474,7 +7310,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
6474 | els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK) | 7310 | els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK) |
6475 | >> LPFC_FIP_ELS_ID_SHIFT); | 7311 | >> LPFC_FIP_ELS_ID_SHIFT); |
6476 | } | 7312 | } |
6477 | bf_set(wqe_temp_rpi, &wqe->els_req.wqe_com, ndlp->nlp_rpi); | 7313 | bf_set(wqe_temp_rpi, &wqe->els_req.wqe_com, |
7314 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); | ||
6478 | bf_set(wqe_els_id, &wqe->els_req.wqe_com, els_id); | 7315 | bf_set(wqe_els_id, &wqe->els_req.wqe_com, els_id); |
6479 | bf_set(wqe_dbde, &wqe->els_req.wqe_com, 1); | 7316 | bf_set(wqe_dbde, &wqe->els_req.wqe_com, 1); |
6480 | bf_set(wqe_iod, &wqe->els_req.wqe_com, LPFC_WQE_IOD_READ); | 7317 | bf_set(wqe_iod, &wqe->els_req.wqe_com, LPFC_WQE_IOD_READ); |
@@ -6623,14 +7460,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
6623 | iocbq->iocb.ulpContext); | 7460 | iocbq->iocb.ulpContext); |
6624 | if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l) | 7461 | if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l) |
6625 | bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com, | 7462 | bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com, |
6626 | iocbq->vport->vpi + phba->vpi_base); | 7463 | phba->vpi_ids[iocbq->vport->vpi]); |
6627 | bf_set(wqe_dbde, &wqe->xmit_els_rsp.wqe_com, 1); | 7464 | bf_set(wqe_dbde, &wqe->xmit_els_rsp.wqe_com, 1); |
6628 | bf_set(wqe_iod, &wqe->xmit_els_rsp.wqe_com, LPFC_WQE_IOD_WRITE); | 7465 | bf_set(wqe_iod, &wqe->xmit_els_rsp.wqe_com, LPFC_WQE_IOD_WRITE); |
6629 | bf_set(wqe_qosd, &wqe->xmit_els_rsp.wqe_com, 1); | 7466 | bf_set(wqe_qosd, &wqe->xmit_els_rsp.wqe_com, 1); |
6630 | bf_set(wqe_lenloc, &wqe->xmit_els_rsp.wqe_com, | 7467 | bf_set(wqe_lenloc, &wqe->xmit_els_rsp.wqe_com, |
6631 | LPFC_WQE_LENLOC_WORD3); | 7468 | LPFC_WQE_LENLOC_WORD3); |
6632 | bf_set(wqe_ebde_cnt, &wqe->xmit_els_rsp.wqe_com, 0); | 7469 | bf_set(wqe_ebde_cnt, &wqe->xmit_els_rsp.wqe_com, 0); |
6633 | bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp, ndlp->nlp_rpi); | 7470 | bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp, |
7471 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); | ||
6634 | command_type = OTHER_COMMAND; | 7472 | command_type = OTHER_COMMAND; |
6635 | break; | 7473 | break; |
6636 | case CMD_CLOSE_XRI_CN: | 7474 | case CMD_CLOSE_XRI_CN: |
@@ -6729,6 +7567,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
6729 | return IOCB_ERROR; | 7567 | return IOCB_ERROR; |
6730 | break; | 7568 | break; |
6731 | } | 7569 | } |
7570 | |||
6732 | bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag); | 7571 | bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag); |
6733 | bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag); | 7572 | bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag); |
6734 | wqe->generic.wqe_com.abort_tag = abort_tag; | 7573 | wqe->generic.wqe_com.abort_tag = abort_tag; |
@@ -6776,7 +7615,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6776 | return IOCB_BUSY; | 7615 | return IOCB_BUSY; |
6777 | } | 7616 | } |
6778 | } else { | 7617 | } else { |
6779 | sglq = __lpfc_sli_get_sglq(phba, piocb); | 7618 | sglq = __lpfc_sli_get_sglq(phba, piocb); |
6780 | if (!sglq) { | 7619 | if (!sglq) { |
6781 | if (!(flag & SLI_IOCB_RET_IOCB)) { | 7620 | if (!(flag & SLI_IOCB_RET_IOCB)) { |
6782 | __lpfc_sli_ringtx_put(phba, | 7621 | __lpfc_sli_ringtx_put(phba, |
@@ -6789,11 +7628,11 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6789 | } | 7628 | } |
6790 | } | 7629 | } |
6791 | } else if (piocb->iocb_flag & LPFC_IO_FCP) { | 7630 | } else if (piocb->iocb_flag & LPFC_IO_FCP) { |
6792 | sglq = NULL; /* These IO's already have an XRI and | 7631 | /* These IO's already have an XRI and a mapped sgl. */ |
6793 | * a mapped sgl. | 7632 | sglq = NULL; |
6794 | */ | ||
6795 | } else { | 7633 | } else { |
6796 | /* This is a continuation of a commandi,(CX) so this | 7634 | /* |
7635 | * This is a continuation of a commandi,(CX) so this | ||
6797 | * sglq is on the active list | 7636 | * sglq is on the active list |
6798 | */ | 7637 | */ |
6799 | sglq = __lpfc_get_active_sglq(phba, piocb->sli4_xritag); | 7638 | sglq = __lpfc_get_active_sglq(phba, piocb->sli4_xritag); |
@@ -6802,8 +7641,8 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6802 | } | 7641 | } |
6803 | 7642 | ||
6804 | if (sglq) { | 7643 | if (sglq) { |
7644 | piocb->sli4_lxritag = sglq->sli4_lxritag; | ||
6805 | piocb->sli4_xritag = sglq->sli4_xritag; | 7645 | piocb->sli4_xritag = sglq->sli4_xritag; |
6806 | |||
6807 | if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocb, sglq)) | 7646 | if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocb, sglq)) |
6808 | return IOCB_ERROR; | 7647 | return IOCB_ERROR; |
6809 | } | 7648 | } |
@@ -9799,7 +10638,12 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe) | |||
9799 | break; | 10638 | break; |
9800 | case LPFC_WCQ: | 10639 | case LPFC_WCQ: |
9801 | while ((cqe = lpfc_sli4_cq_get(cq))) { | 10640 | while ((cqe = lpfc_sli4_cq_get(cq))) { |
9802 | workposted |= lpfc_sli4_sp_handle_cqe(phba, cq, cqe); | 10641 | if (cq->subtype == LPFC_FCP) |
10642 | workposted |= lpfc_sli4_fp_handle_wcqe(phba, cq, | ||
10643 | cqe); | ||
10644 | else | ||
10645 | workposted |= lpfc_sli4_sp_handle_cqe(phba, cq, | ||
10646 | cqe); | ||
9803 | if (!(++ecount % LPFC_GET_QE_REL_INT)) | 10647 | if (!(++ecount % LPFC_GET_QE_REL_INT)) |
9804 | lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM); | 10648 | lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM); |
9805 | } | 10649 | } |
@@ -11446,6 +12290,7 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, | |||
11446 | LPFC_MBOXQ_t *mbox; | 12290 | LPFC_MBOXQ_t *mbox; |
11447 | int rc; | 12291 | int rc; |
11448 | uint32_t shdr_status, shdr_add_status; | 12292 | uint32_t shdr_status, shdr_add_status; |
12293 | uint32_t mbox_tmo; | ||
11449 | union lpfc_sli4_cfg_shdr *shdr; | 12294 | union lpfc_sli4_cfg_shdr *shdr; |
11450 | 12295 | ||
11451 | if (xritag == NO_XRI) { | 12296 | if (xritag == NO_XRI) { |
@@ -11479,8 +12324,10 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, | |||
11479 | cpu_to_le32(putPaddrHigh(pdma_phys_addr1)); | 12324 | cpu_to_le32(putPaddrHigh(pdma_phys_addr1)); |
11480 | if (!phba->sli4_hba.intr_enable) | 12325 | if (!phba->sli4_hba.intr_enable) |
11481 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | 12326 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); |
11482 | else | 12327 | else { |
11483 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | 12328 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); |
12329 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
12330 | } | ||
11484 | /* The IOCTL status is embedded in the mailbox subheader. */ | 12331 | /* The IOCTL status is embedded in the mailbox subheader. */ |
11485 | shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr; | 12332 | shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr; |
11486 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 12333 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
@@ -11498,6 +12345,76 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, | |||
11498 | } | 12345 | } |
11499 | 12346 | ||
11500 | /** | 12347 | /** |
12348 | * lpfc_sli4_init_rpi_hdrs - Post the rpi header memory region to the port | ||
12349 | * @phba: pointer to lpfc hba data structure. | ||
12350 | * | ||
12351 | * This routine is invoked to post rpi header templates to the | ||
12352 | * port for those SLI4 ports that do not support extents. This routine | ||
12353 | * posts a PAGE_SIZE memory region to the port to hold up to | ||
12354 | * PAGE_SIZE modulo 64 rpi context headers. This is an initialization routine | ||
12355 | * and should be called only when interrupts are disabled. | ||
12356 | * | ||
12357 | * Return codes | ||
12358 | * 0 - successful | ||
12359 | * -ERROR - otherwise. | ||
12360 | */ | ||
12361 | uint16_t | ||
12362 | lpfc_sli4_alloc_xri(struct lpfc_hba *phba) | ||
12363 | { | ||
12364 | unsigned long xri; | ||
12365 | |||
12366 | /* | ||
12367 | * Fetch the next logical xri. Because this index is logical, | ||
12368 | * the driver starts at 0 each time. | ||
12369 | */ | ||
12370 | spin_lock_irq(&phba->hbalock); | ||
12371 | xri = find_next_zero_bit(phba->sli4_hba.xri_bmask, | ||
12372 | phba->sli4_hba.max_cfg_param.max_xri, 0); | ||
12373 | if (xri >= phba->sli4_hba.max_cfg_param.max_xri) { | ||
12374 | spin_unlock_irq(&phba->hbalock); | ||
12375 | return NO_XRI; | ||
12376 | } else { | ||
12377 | set_bit(xri, phba->sli4_hba.xri_bmask); | ||
12378 | phba->sli4_hba.max_cfg_param.xri_used++; | ||
12379 | phba->sli4_hba.xri_count++; | ||
12380 | } | ||
12381 | |||
12382 | spin_unlock_irq(&phba->hbalock); | ||
12383 | return xri; | ||
12384 | } | ||
12385 | |||
12386 | /** | ||
12387 | * lpfc_sli4_free_xri - Release an xri for reuse. | ||
12388 | * @phba: pointer to lpfc hba data structure. | ||
12389 | * | ||
12390 | * This routine is invoked to release an xri to the pool of | ||
12391 | * available rpis maintained by the driver. | ||
12392 | **/ | ||
12393 | void | ||
12394 | __lpfc_sli4_free_xri(struct lpfc_hba *phba, int xri) | ||
12395 | { | ||
12396 | if (test_and_clear_bit(xri, phba->sli4_hba.xri_bmask)) { | ||
12397 | phba->sli4_hba.xri_count--; | ||
12398 | phba->sli4_hba.max_cfg_param.xri_used--; | ||
12399 | } | ||
12400 | } | ||
12401 | |||
12402 | /** | ||
12403 | * lpfc_sli4_free_xri - Release an xri for reuse. | ||
12404 | * @phba: pointer to lpfc hba data structure. | ||
12405 | * | ||
12406 | * This routine is invoked to release an xri to the pool of | ||
12407 | * available rpis maintained by the driver. | ||
12408 | **/ | ||
12409 | void | ||
12410 | lpfc_sli4_free_xri(struct lpfc_hba *phba, int xri) | ||
12411 | { | ||
12412 | spin_lock_irq(&phba->hbalock); | ||
12413 | __lpfc_sli4_free_xri(phba, xri); | ||
12414 | spin_unlock_irq(&phba->hbalock); | ||
12415 | } | ||
12416 | |||
12417 | /** | ||
11501 | * lpfc_sli4_next_xritag - Get an xritag for the io | 12418 | * lpfc_sli4_next_xritag - Get an xritag for the io |
11502 | * @phba: Pointer to HBA context object. | 12419 | * @phba: Pointer to HBA context object. |
11503 | * | 12420 | * |
@@ -11510,30 +12427,23 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, | |||
11510 | uint16_t | 12427 | uint16_t |
11511 | lpfc_sli4_next_xritag(struct lpfc_hba *phba) | 12428 | lpfc_sli4_next_xritag(struct lpfc_hba *phba) |
11512 | { | 12429 | { |
11513 | uint16_t xritag; | 12430 | uint16_t xri_index; |
11514 | 12431 | ||
11515 | spin_lock_irq(&phba->hbalock); | 12432 | xri_index = lpfc_sli4_alloc_xri(phba); |
11516 | xritag = phba->sli4_hba.next_xri; | 12433 | if (xri_index != NO_XRI) |
11517 | if ((xritag != (uint16_t) -1) && xritag < | 12434 | return xri_index; |
11518 | (phba->sli4_hba.max_cfg_param.max_xri | 12435 | |
11519 | + phba->sli4_hba.max_cfg_param.xri_base)) { | 12436 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
11520 | phba->sli4_hba.next_xri++; | ||
11521 | phba->sli4_hba.max_cfg_param.xri_used++; | ||
11522 | spin_unlock_irq(&phba->hbalock); | ||
11523 | return xritag; | ||
11524 | } | ||
11525 | spin_unlock_irq(&phba->hbalock); | ||
11526 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
11527 | "2004 Failed to allocate XRI.last XRITAG is %d" | 12437 | "2004 Failed to allocate XRI.last XRITAG is %d" |
11528 | " Max XRI is %d, Used XRI is %d\n", | 12438 | " Max XRI is %d, Used XRI is %d\n", |
11529 | phba->sli4_hba.next_xri, | 12439 | xri_index, |
11530 | phba->sli4_hba.max_cfg_param.max_xri, | 12440 | phba->sli4_hba.max_cfg_param.max_xri, |
11531 | phba->sli4_hba.max_cfg_param.xri_used); | 12441 | phba->sli4_hba.max_cfg_param.xri_used); |
11532 | return -1; | 12442 | return NO_XRI; |
11533 | } | 12443 | } |
11534 | 12444 | ||
11535 | /** | 12445 | /** |
11536 | * lpfc_sli4_post_sgl_list - post a block of sgl list to the firmware. | 12446 | * lpfc_sli4_post_els_sgl_list - post a block of ELS sgls to the port. |
11537 | * @phba: pointer to lpfc hba data structure. | 12447 | * @phba: pointer to lpfc hba data structure. |
11538 | * | 12448 | * |
11539 | * This routine is invoked to post a block of driver's sgl pages to the | 12449 | * This routine is invoked to post a block of driver's sgl pages to the |
@@ -11542,7 +12452,7 @@ lpfc_sli4_next_xritag(struct lpfc_hba *phba) | |||
11542 | * stopped. | 12452 | * stopped. |
11543 | **/ | 12453 | **/ |
11544 | int | 12454 | int |
11545 | lpfc_sli4_post_sgl_list(struct lpfc_hba *phba) | 12455 | lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba) |
11546 | { | 12456 | { |
11547 | struct lpfc_sglq *sglq_entry; | 12457 | struct lpfc_sglq *sglq_entry; |
11548 | struct lpfc_mbx_post_uembed_sgl_page1 *sgl; | 12458 | struct lpfc_mbx_post_uembed_sgl_page1 *sgl; |
@@ -11551,7 +12461,7 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba) | |||
11551 | LPFC_MBOXQ_t *mbox; | 12461 | LPFC_MBOXQ_t *mbox; |
11552 | uint32_t reqlen, alloclen, pg_pairs; | 12462 | uint32_t reqlen, alloclen, pg_pairs; |
11553 | uint32_t mbox_tmo; | 12463 | uint32_t mbox_tmo; |
11554 | uint16_t xritag_start = 0; | 12464 | uint16_t xritag_start = 0, lxri = 0; |
11555 | int els_xri_cnt, rc = 0; | 12465 | int els_xri_cnt, rc = 0; |
11556 | uint32_t shdr_status, shdr_add_status; | 12466 | uint32_t shdr_status, shdr_add_status; |
11557 | union lpfc_sli4_cfg_shdr *shdr; | 12467 | union lpfc_sli4_cfg_shdr *shdr; |
@@ -11568,11 +12478,8 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba) | |||
11568 | return -ENOMEM; | 12478 | return -ENOMEM; |
11569 | } | 12479 | } |
11570 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 12480 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
11571 | if (!mbox) { | 12481 | if (!mbox) |
11572 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11573 | "2560 Failed to allocate mbox cmd memory\n"); | ||
11574 | return -ENOMEM; | 12482 | return -ENOMEM; |
11575 | } | ||
11576 | 12483 | ||
11577 | /* Allocate DMA memory and set up the non-embedded mailbox command */ | 12484 | /* Allocate DMA memory and set up the non-embedded mailbox command */ |
11578 | alloclen = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE, | 12485 | alloclen = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE, |
@@ -11587,15 +12494,30 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba) | |||
11587 | lpfc_sli4_mbox_cmd_free(phba, mbox); | 12494 | lpfc_sli4_mbox_cmd_free(phba, mbox); |
11588 | return -ENOMEM; | 12495 | return -ENOMEM; |
11589 | } | 12496 | } |
11590 | /* Get the first SGE entry from the non-embedded DMA memory */ | ||
11591 | viraddr = mbox->sge_array->addr[0]; | ||
11592 | |||
11593 | /* Set up the SGL pages in the non-embedded DMA pages */ | 12497 | /* Set up the SGL pages in the non-embedded DMA pages */ |
12498 | viraddr = mbox->sge_array->addr[0]; | ||
11594 | sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; | 12499 | sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; |
11595 | sgl_pg_pairs = &sgl->sgl_pg_pairs; | 12500 | sgl_pg_pairs = &sgl->sgl_pg_pairs; |
11596 | 12501 | ||
11597 | for (pg_pairs = 0; pg_pairs < els_xri_cnt; pg_pairs++) { | 12502 | for (pg_pairs = 0; pg_pairs < els_xri_cnt; pg_pairs++) { |
11598 | sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[pg_pairs]; | 12503 | sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[pg_pairs]; |
12504 | |||
12505 | /* | ||
12506 | * Assign the sglq a physical xri only if the driver has not | ||
12507 | * initialized those resources. A port reset only needs | ||
12508 | * the sglq's posted. | ||
12509 | */ | ||
12510 | if (bf_get(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags) != | ||
12511 | LPFC_XRI_RSRC_RDY) { | ||
12512 | lxri = lpfc_sli4_next_xritag(phba); | ||
12513 | if (lxri == NO_XRI) { | ||
12514 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
12515 | return -ENOMEM; | ||
12516 | } | ||
12517 | sglq_entry->sli4_lxritag = lxri; | ||
12518 | sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri]; | ||
12519 | } | ||
12520 | |||
11599 | /* Set up the sge entry */ | 12521 | /* Set up the sge entry */ |
11600 | sgl_pg_pairs->sgl_pg0_addr_lo = | 12522 | sgl_pg_pairs->sgl_pg0_addr_lo = |
11601 | cpu_to_le32(putPaddrLow(sglq_entry->phys)); | 12523 | cpu_to_le32(putPaddrLow(sglq_entry->phys)); |
@@ -11605,16 +12527,17 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba) | |||
11605 | cpu_to_le32(putPaddrLow(0)); | 12527 | cpu_to_le32(putPaddrLow(0)); |
11606 | sgl_pg_pairs->sgl_pg1_addr_hi = | 12528 | sgl_pg_pairs->sgl_pg1_addr_hi = |
11607 | cpu_to_le32(putPaddrHigh(0)); | 12529 | cpu_to_le32(putPaddrHigh(0)); |
12530 | |||
11608 | /* Keep the first xritag on the list */ | 12531 | /* Keep the first xritag on the list */ |
11609 | if (pg_pairs == 0) | 12532 | if (pg_pairs == 0) |
11610 | xritag_start = sglq_entry->sli4_xritag; | 12533 | xritag_start = sglq_entry->sli4_xritag; |
11611 | sgl_pg_pairs++; | 12534 | sgl_pg_pairs++; |
11612 | } | 12535 | } |
12536 | |||
12537 | /* Complete initialization and perform endian conversion. */ | ||
11613 | bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start); | 12538 | bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start); |
11614 | bf_set(lpfc_post_sgl_pages_xricnt, sgl, els_xri_cnt); | 12539 | bf_set(lpfc_post_sgl_pages_xricnt, sgl, els_xri_cnt); |
11615 | /* Perform endian conversion if necessary */ | ||
11616 | sgl->word0 = cpu_to_le32(sgl->word0); | 12540 | sgl->word0 = cpu_to_le32(sgl->word0); |
11617 | |||
11618 | if (!phba->sli4_hba.intr_enable) | 12541 | if (!phba->sli4_hba.intr_enable) |
11619 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | 12542 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); |
11620 | else { | 12543 | else { |
@@ -11633,6 +12556,181 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba) | |||
11633 | shdr_status, shdr_add_status, rc); | 12556 | shdr_status, shdr_add_status, rc); |
11634 | rc = -ENXIO; | 12557 | rc = -ENXIO; |
11635 | } | 12558 | } |
12559 | |||
12560 | if (rc == 0) | ||
12561 | bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, | ||
12562 | LPFC_XRI_RSRC_RDY); | ||
12563 | return rc; | ||
12564 | } | ||
12565 | |||
12566 | /** | ||
12567 | * lpfc_sli4_post_els_sgl_list_ext - post a block of ELS sgls to the port. | ||
12568 | * @phba: pointer to lpfc hba data structure. | ||
12569 | * | ||
12570 | * This routine is invoked to post a block of driver's sgl pages to the | ||
12571 | * HBA using non-embedded mailbox command. No Lock is held. This routine | ||
12572 | * is only called when the driver is loading and after all IO has been | ||
12573 | * stopped. | ||
12574 | **/ | ||
12575 | int | ||
12576 | lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba) | ||
12577 | { | ||
12578 | struct lpfc_sglq *sglq_entry; | ||
12579 | struct lpfc_mbx_post_uembed_sgl_page1 *sgl; | ||
12580 | struct sgl_page_pairs *sgl_pg_pairs; | ||
12581 | void *viraddr; | ||
12582 | LPFC_MBOXQ_t *mbox; | ||
12583 | uint32_t reqlen, alloclen, index; | ||
12584 | uint32_t mbox_tmo; | ||
12585 | uint16_t rsrc_start, rsrc_size, els_xri_cnt; | ||
12586 | uint16_t xritag_start = 0, lxri = 0; | ||
12587 | struct lpfc_rsrc_blks *rsrc_blk; | ||
12588 | int cnt, ttl_cnt, rc = 0; | ||
12589 | int loop_cnt; | ||
12590 | uint32_t shdr_status, shdr_add_status; | ||
12591 | union lpfc_sli4_cfg_shdr *shdr; | ||
12592 | |||
12593 | /* The number of sgls to be posted */ | ||
12594 | els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); | ||
12595 | |||
12596 | reqlen = els_xri_cnt * sizeof(struct sgl_page_pairs) + | ||
12597 | sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); | ||
12598 | if (reqlen > SLI4_PAGE_SIZE) { | ||
12599 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
12600 | "2989 Block sgl registration required DMA " | ||
12601 | "size (%d) great than a page\n", reqlen); | ||
12602 | return -ENOMEM; | ||
12603 | } | ||
12604 | |||
12605 | cnt = 0; | ||
12606 | ttl_cnt = 0; | ||
12607 | list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list, | ||
12608 | list) { | ||
12609 | rsrc_start = rsrc_blk->rsrc_start; | ||
12610 | rsrc_size = rsrc_blk->rsrc_size; | ||
12611 | |||
12612 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
12613 | "3014 Working ELS Extent start %d, cnt %d\n", | ||
12614 | rsrc_start, rsrc_size); | ||
12615 | |||
12616 | loop_cnt = min(els_xri_cnt, rsrc_size); | ||
12617 | if (ttl_cnt + loop_cnt >= els_xri_cnt) { | ||
12618 | loop_cnt = els_xri_cnt - ttl_cnt; | ||
12619 | ttl_cnt = els_xri_cnt; | ||
12620 | } | ||
12621 | |||
12622 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
12623 | if (!mbox) | ||
12624 | return -ENOMEM; | ||
12625 | /* | ||
12626 | * Allocate DMA memory and set up the non-embedded mailbox | ||
12627 | * command. | ||
12628 | */ | ||
12629 | alloclen = lpfc_sli4_config(phba, mbox, | ||
12630 | LPFC_MBOX_SUBSYSTEM_FCOE, | ||
12631 | LPFC_MBOX_OPCODE_FCOE_POST_SGL_PAGES, | ||
12632 | reqlen, LPFC_SLI4_MBX_NEMBED); | ||
12633 | if (alloclen < reqlen) { | ||
12634 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
12635 | "2987 Allocated DMA memory size (%d) " | ||
12636 | "is less than the requested DMA memory " | ||
12637 | "size (%d)\n", alloclen, reqlen); | ||
12638 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
12639 | return -ENOMEM; | ||
12640 | } | ||
12641 | |||
12642 | /* Set up the SGL pages in the non-embedded DMA pages */ | ||
12643 | viraddr = mbox->sge_array->addr[0]; | ||
12644 | sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; | ||
12645 | sgl_pg_pairs = &sgl->sgl_pg_pairs; | ||
12646 | |||
12647 | /* | ||
12648 | * The starting resource may not begin at zero. Control | ||
12649 | * the loop variants via the block resource parameters, | ||
12650 | * but handle the sge pointers with a zero-based index | ||
12651 | * that doesn't get reset per loop pass. | ||
12652 | */ | ||
12653 | for (index = rsrc_start; | ||
12654 | index < rsrc_start + loop_cnt; | ||
12655 | index++) { | ||
12656 | sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[cnt]; | ||
12657 | |||
12658 | /* | ||
12659 | * Assign the sglq a physical xri only if the driver | ||
12660 | * has not initialized those resources. A port reset | ||
12661 | * only needs the sglq's posted. | ||
12662 | */ | ||
12663 | if (bf_get(lpfc_xri_rsrc_rdy, | ||
12664 | &phba->sli4_hba.sli4_flags) != | ||
12665 | LPFC_XRI_RSRC_RDY) { | ||
12666 | lxri = lpfc_sli4_next_xritag(phba); | ||
12667 | if (lxri == NO_XRI) { | ||
12668 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
12669 | rc = -ENOMEM; | ||
12670 | goto err_exit; | ||
12671 | } | ||
12672 | sglq_entry->sli4_lxritag = lxri; | ||
12673 | sglq_entry->sli4_xritag = | ||
12674 | phba->sli4_hba.xri_ids[lxri]; | ||
12675 | } | ||
12676 | |||
12677 | /* Set up the sge entry */ | ||
12678 | sgl_pg_pairs->sgl_pg0_addr_lo = | ||
12679 | cpu_to_le32(putPaddrLow(sglq_entry->phys)); | ||
12680 | sgl_pg_pairs->sgl_pg0_addr_hi = | ||
12681 | cpu_to_le32(putPaddrHigh(sglq_entry->phys)); | ||
12682 | sgl_pg_pairs->sgl_pg1_addr_lo = | ||
12683 | cpu_to_le32(putPaddrLow(0)); | ||
12684 | sgl_pg_pairs->sgl_pg1_addr_hi = | ||
12685 | cpu_to_le32(putPaddrHigh(0)); | ||
12686 | |||
12687 | /* Track the starting physical XRI for the mailbox. */ | ||
12688 | if (index == rsrc_start) | ||
12689 | xritag_start = sglq_entry->sli4_xritag; | ||
12690 | sgl_pg_pairs++; | ||
12691 | cnt++; | ||
12692 | } | ||
12693 | |||
12694 | /* Complete initialization and perform endian conversion. */ | ||
12695 | rsrc_blk->rsrc_used += loop_cnt; | ||
12696 | bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start); | ||
12697 | bf_set(lpfc_post_sgl_pages_xricnt, sgl, loop_cnt); | ||
12698 | sgl->word0 = cpu_to_le32(sgl->word0); | ||
12699 | |||
12700 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
12701 | "3015 Post ELS Extent SGL, start %d, " | ||
12702 | "cnt %d, used %d\n", | ||
12703 | xritag_start, loop_cnt, rsrc_blk->rsrc_used); | ||
12704 | if (!phba->sli4_hba.intr_enable) | ||
12705 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
12706 | else { | ||
12707 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
12708 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
12709 | } | ||
12710 | shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; | ||
12711 | shdr_status = bf_get(lpfc_mbox_hdr_status, | ||
12712 | &shdr->response); | ||
12713 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
12714 | &shdr->response); | ||
12715 | if (rc != MBX_TIMEOUT) | ||
12716 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
12717 | if (shdr_status || shdr_add_status || rc) { | ||
12718 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
12719 | "2988 POST_SGL_BLOCK mailbox " | ||
12720 | "command failed status x%x " | ||
12721 | "add_status x%x mbx status x%x\n", | ||
12722 | shdr_status, shdr_add_status, rc); | ||
12723 | rc = -ENXIO; | ||
12724 | goto err_exit; | ||
12725 | } | ||
12726 | if (ttl_cnt >= els_xri_cnt) | ||
12727 | break; | ||
12728 | } | ||
12729 | |||
12730 | err_exit: | ||
12731 | if (rc == 0) | ||
12732 | bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, | ||
12733 | LPFC_XRI_RSRC_RDY); | ||
11636 | return rc; | 12734 | return rc; |
11637 | } | 12735 | } |
11638 | 12736 | ||
@@ -11693,6 +12791,7 @@ lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, struct list_head *sblist, | |||
11693 | lpfc_sli4_mbox_cmd_free(phba, mbox); | 12791 | lpfc_sli4_mbox_cmd_free(phba, mbox); |
11694 | return -ENOMEM; | 12792 | return -ENOMEM; |
11695 | } | 12793 | } |
12794 | |||
11696 | /* Get the first SGE entry from the non-embedded DMA memory */ | 12795 | /* Get the first SGE entry from the non-embedded DMA memory */ |
11697 | viraddr = mbox->sge_array->addr[0]; | 12796 | viraddr = mbox->sge_array->addr[0]; |
11698 | 12797 | ||
@@ -11748,6 +12847,169 @@ lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *phba, struct list_head *sblist, | |||
11748 | } | 12847 | } |
11749 | 12848 | ||
11750 | /** | 12849 | /** |
12850 | * lpfc_sli4_post_scsi_sgl_blk_ext - post a block of scsi sgls to the port. | ||
12851 | * @phba: pointer to lpfc hba data structure. | ||
12852 | * @sblist: pointer to scsi buffer list. | ||
12853 | * @count: number of scsi buffers on the list. | ||
12854 | * | ||
12855 | * This routine is invoked to post a block of @count scsi sgl pages from a | ||
12856 | * SCSI buffer list @sblist to the HBA using non-embedded mailbox command. | ||
12857 | * No Lock is held. | ||
12858 | * | ||
12859 | **/ | ||
12860 | int | ||
12861 | lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *phba, struct list_head *sblist, | ||
12862 | int cnt) | ||
12863 | { | ||
12864 | struct lpfc_scsi_buf *psb = NULL; | ||
12865 | struct lpfc_mbx_post_uembed_sgl_page1 *sgl; | ||
12866 | struct sgl_page_pairs *sgl_pg_pairs; | ||
12867 | void *viraddr; | ||
12868 | LPFC_MBOXQ_t *mbox; | ||
12869 | uint32_t reqlen, alloclen, pg_pairs; | ||
12870 | uint32_t mbox_tmo; | ||
12871 | uint16_t xri_start = 0, scsi_xri_start; | ||
12872 | uint16_t rsrc_range; | ||
12873 | int rc = 0, avail_cnt; | ||
12874 | uint32_t shdr_status, shdr_add_status; | ||
12875 | dma_addr_t pdma_phys_bpl1; | ||
12876 | union lpfc_sli4_cfg_shdr *shdr; | ||
12877 | struct lpfc_rsrc_blks *rsrc_blk; | ||
12878 | uint32_t xri_cnt = 0; | ||
12879 | |||
12880 | /* Calculate the total requested length of the dma memory */ | ||
12881 | reqlen = cnt * sizeof(struct sgl_page_pairs) + | ||
12882 | sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); | ||
12883 | if (reqlen > SLI4_PAGE_SIZE) { | ||
12884 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
12885 | "2932 Block sgl registration required DMA " | ||
12886 | "size (%d) great than a page\n", reqlen); | ||
12887 | return -ENOMEM; | ||
12888 | } | ||
12889 | |||
12890 | /* | ||
12891 | * The use of extents requires the driver to post the sgl headers | ||
12892 | * in multiple postings to meet the contiguous resource assignment. | ||
12893 | */ | ||
12894 | psb = list_prepare_entry(psb, sblist, list); | ||
12895 | scsi_xri_start = phba->sli4_hba.scsi_xri_start; | ||
12896 | list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list, | ||
12897 | list) { | ||
12898 | rsrc_range = rsrc_blk->rsrc_start + rsrc_blk->rsrc_size; | ||
12899 | if (rsrc_range < scsi_xri_start) | ||
12900 | continue; | ||
12901 | else if (rsrc_blk->rsrc_used >= rsrc_blk->rsrc_size) | ||
12902 | continue; | ||
12903 | else | ||
12904 | avail_cnt = rsrc_blk->rsrc_size - rsrc_blk->rsrc_used; | ||
12905 | |||
12906 | reqlen = (avail_cnt * sizeof(struct sgl_page_pairs)) + | ||
12907 | sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t); | ||
12908 | /* | ||
12909 | * Allocate DMA memory and set up the non-embedded mailbox | ||
12910 | * command. The mbox is used to post an SGL page per loop | ||
12911 | * but the DMA memory has a use-once semantic so the mailbox | ||
12912 | * is used and freed per loop pass. | ||
12913 | */ | ||
12914 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
12915 | if (!mbox) { | ||
12916 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
12917 | "2933 Failed to allocate mbox cmd " | ||
12918 | "memory\n"); | ||
12919 | return -ENOMEM; | ||
12920 | } | ||
12921 | alloclen = lpfc_sli4_config(phba, mbox, | ||
12922 | LPFC_MBOX_SUBSYSTEM_FCOE, | ||
12923 | LPFC_MBOX_OPCODE_FCOE_POST_SGL_PAGES, | ||
12924 | reqlen, | ||
12925 | LPFC_SLI4_MBX_NEMBED); | ||
12926 | if (alloclen < reqlen) { | ||
12927 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
12928 | "2934 Allocated DMA memory size (%d) " | ||
12929 | "is less than the requested DMA memory " | ||
12930 | "size (%d)\n", alloclen, reqlen); | ||
12931 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
12932 | return -ENOMEM; | ||
12933 | } | ||
12934 | |||
12935 | /* Get the first SGE entry from the non-embedded DMA memory */ | ||
12936 | viraddr = mbox->sge_array->addr[0]; | ||
12937 | |||
12938 | /* Set up the SGL pages in the non-embedded DMA pages */ | ||
12939 | sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr; | ||
12940 | sgl_pg_pairs = &sgl->sgl_pg_pairs; | ||
12941 | |||
12942 | /* pg_pairs tracks posted SGEs per loop iteration. */ | ||
12943 | pg_pairs = 0; | ||
12944 | list_for_each_entry_continue(psb, sblist, list) { | ||
12945 | /* Set up the sge entry */ | ||
12946 | sgl_pg_pairs->sgl_pg0_addr_lo = | ||
12947 | cpu_to_le32(putPaddrLow(psb->dma_phys_bpl)); | ||
12948 | sgl_pg_pairs->sgl_pg0_addr_hi = | ||
12949 | cpu_to_le32(putPaddrHigh(psb->dma_phys_bpl)); | ||
12950 | if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) | ||
12951 | pdma_phys_bpl1 = psb->dma_phys_bpl + | ||
12952 | SGL_PAGE_SIZE; | ||
12953 | else | ||
12954 | pdma_phys_bpl1 = 0; | ||
12955 | sgl_pg_pairs->sgl_pg1_addr_lo = | ||
12956 | cpu_to_le32(putPaddrLow(pdma_phys_bpl1)); | ||
12957 | sgl_pg_pairs->sgl_pg1_addr_hi = | ||
12958 | cpu_to_le32(putPaddrHigh(pdma_phys_bpl1)); | ||
12959 | /* Keep the first xri for this extent. */ | ||
12960 | if (pg_pairs == 0) | ||
12961 | xri_start = psb->cur_iocbq.sli4_xritag; | ||
12962 | sgl_pg_pairs++; | ||
12963 | pg_pairs++; | ||
12964 | xri_cnt++; | ||
12965 | |||
12966 | /* | ||
12967 | * Track two exit conditions - the loop has constructed | ||
12968 | * all of the caller's SGE pairs or all available | ||
12969 | * resource IDs in this extent are consumed. | ||
12970 | */ | ||
12971 | if ((xri_cnt == cnt) || (pg_pairs >= avail_cnt)) | ||
12972 | break; | ||
12973 | } | ||
12974 | rsrc_blk->rsrc_used += pg_pairs; | ||
12975 | bf_set(lpfc_post_sgl_pages_xri, sgl, xri_start); | ||
12976 | bf_set(lpfc_post_sgl_pages_xricnt, sgl, pg_pairs); | ||
12977 | |||
12978 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
12979 | "3016 Post SCSI Extent SGL, start %d, cnt %d " | ||
12980 | "blk use %d\n", | ||
12981 | xri_start, pg_pairs, rsrc_blk->rsrc_used); | ||
12982 | /* Perform endian conversion if necessary */ | ||
12983 | sgl->word0 = cpu_to_le32(sgl->word0); | ||
12984 | if (!phba->sli4_hba.intr_enable) | ||
12985 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
12986 | else { | ||
12987 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
12988 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
12989 | } | ||
12990 | shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; | ||
12991 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
12992 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
12993 | &shdr->response); | ||
12994 | if (rc != MBX_TIMEOUT) | ||
12995 | lpfc_sli4_mbox_cmd_free(phba, mbox); | ||
12996 | if (shdr_status || shdr_add_status || rc) { | ||
12997 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
12998 | "2935 POST_SGL_BLOCK mailbox command " | ||
12999 | "failed status x%x add_status x%x " | ||
13000 | "mbx status x%x\n", | ||
13001 | shdr_status, shdr_add_status, rc); | ||
13002 | return -ENXIO; | ||
13003 | } | ||
13004 | |||
13005 | /* Post only what is requested. */ | ||
13006 | if (xri_cnt >= cnt) | ||
13007 | break; | ||
13008 | } | ||
13009 | return rc; | ||
13010 | } | ||
13011 | |||
13012 | /** | ||
11751 | * lpfc_fc_frame_check - Check that this frame is a valid frame to handle | 13013 | * lpfc_fc_frame_check - Check that this frame is a valid frame to handle |
11752 | * @phba: pointer to lpfc_hba struct that the frame was received on | 13014 | * @phba: pointer to lpfc_hba struct that the frame was received on |
11753 | * @fc_hdr: A pointer to the FC Header data (In Big Endian Format) | 13015 | * @fc_hdr: A pointer to the FC Header data (In Big Endian Format) |
@@ -12137,6 +13399,28 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba, | |||
12137 | } | 13399 | } |
12138 | 13400 | ||
12139 | /** | 13401 | /** |
13402 | * lpfc_sli4_xri_inrange - check xri is in range of xris owned by driver. | ||
13403 | * @phba: Pointer to HBA context object. | ||
13404 | * @xri: xri id in transaction. | ||
13405 | * | ||
13406 | * This function validates the xri maps to the known range of XRIs allocated an | ||
13407 | * used by the driver. | ||
13408 | **/ | ||
13409 | static uint16_t | ||
13410 | lpfc_sli4_xri_inrange(struct lpfc_hba *phba, | ||
13411 | uint16_t xri) | ||
13412 | { | ||
13413 | int i; | ||
13414 | |||
13415 | for (i = 0; i < phba->sli4_hba.max_cfg_param.max_xri; i++) { | ||
13416 | if (xri == phba->sli4_hba.xri_ids[i]) | ||
13417 | return i; | ||
13418 | } | ||
13419 | return NO_XRI; | ||
13420 | } | ||
13421 | |||
13422 | |||
13423 | /** | ||
12140 | * lpfc_sli4_seq_abort_rsp - bls rsp to sequence abort | 13424 | * lpfc_sli4_seq_abort_rsp - bls rsp to sequence abort |
12141 | * @phba: Pointer to HBA context object. | 13425 | * @phba: Pointer to HBA context object. |
12142 | * @fc_hdr: pointer to a FC frame header. | 13426 | * @fc_hdr: pointer to a FC frame header. |
@@ -12169,9 +13453,7 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_hba *phba, | |||
12169 | "SID:x%x\n", oxid, sid); | 13453 | "SID:x%x\n", oxid, sid); |
12170 | return; | 13454 | return; |
12171 | } | 13455 | } |
12172 | if (rxid >= phba->sli4_hba.max_cfg_param.xri_base | 13456 | if (lpfc_sli4_xri_inrange(phba, rxid)) |
12173 | && rxid <= (phba->sli4_hba.max_cfg_param.max_xri | ||
12174 | + phba->sli4_hba.max_cfg_param.xri_base)) | ||
12175 | lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0); | 13457 | lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0); |
12176 | 13458 | ||
12177 | /* Allocate buffer for rsp iocb */ | 13459 | /* Allocate buffer for rsp iocb */ |
@@ -12194,12 +13476,13 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_hba *phba, | |||
12194 | icmd->ulpBdeCount = 0; | 13476 | icmd->ulpBdeCount = 0; |
12195 | icmd->ulpLe = 1; | 13477 | icmd->ulpLe = 1; |
12196 | icmd->ulpClass = CLASS3; | 13478 | icmd->ulpClass = CLASS3; |
12197 | icmd->ulpContext = ndlp->nlp_rpi; | 13479 | icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; |
12198 | ctiocb->context1 = ndlp; | 13480 | ctiocb->context1 = ndlp; |
12199 | 13481 | ||
12200 | ctiocb->iocb_cmpl = NULL; | 13482 | ctiocb->iocb_cmpl = NULL; |
12201 | ctiocb->vport = phba->pport; | 13483 | ctiocb->vport = phba->pport; |
12202 | ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_rsp_cmpl; | 13484 | ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_rsp_cmpl; |
13485 | ctiocb->sli4_lxritag = NO_XRI; | ||
12203 | ctiocb->sli4_xritag = NO_XRI; | 13486 | ctiocb->sli4_xritag = NO_XRI; |
12204 | 13487 | ||
12205 | /* If the oxid maps to the FCP XRI range or if it is out of range, | 13488 | /* If the oxid maps to the FCP XRI range or if it is out of range, |
@@ -12380,8 +13663,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
12380 | first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; | 13663 | first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; |
12381 | first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; | 13664 | first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; |
12382 | first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); | 13665 | first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); |
12383 | first_iocbq->iocb.unsli3.rcvsli3.vpi = | 13666 | /* iocbq is prepped for internal consumption. Logical vpi. */ |
12384 | vport->vpi + vport->phba->vpi_base; | 13667 | first_iocbq->iocb.unsli3.rcvsli3.vpi = vport->vpi; |
12385 | /* put the first buffer into the first IOCBq */ | 13668 | /* put the first buffer into the first IOCBq */ |
12386 | first_iocbq->context2 = &seq_dmabuf->dbuf; | 13669 | first_iocbq->context2 = &seq_dmabuf->dbuf; |
12387 | first_iocbq->context3 = NULL; | 13670 | first_iocbq->context3 = NULL; |
@@ -12461,7 +13744,7 @@ lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport, | |||
12461 | &phba->sli.ring[LPFC_ELS_RING], | 13744 | &phba->sli.ring[LPFC_ELS_RING], |
12462 | iocbq, fc_hdr->fh_r_ctl, | 13745 | iocbq, fc_hdr->fh_r_ctl, |
12463 | fc_hdr->fh_type)) | 13746 | fc_hdr->fh_type)) |
12464 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | 13747 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
12465 | "2540 Ring %d handler: unexpected Rctl " | 13748 | "2540 Ring %d handler: unexpected Rctl " |
12466 | "x%x Type x%x received\n", | 13749 | "x%x Type x%x received\n", |
12467 | LPFC_ELS_RING, | 13750 | LPFC_ELS_RING, |
@@ -12558,9 +13841,24 @@ lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *phba) | |||
12558 | { | 13841 | { |
12559 | struct lpfc_rpi_hdr *rpi_page; | 13842 | struct lpfc_rpi_hdr *rpi_page; |
12560 | uint32_t rc = 0; | 13843 | uint32_t rc = 0; |
13844 | uint16_t lrpi = 0; | ||
13845 | |||
13846 | /* SLI4 ports that support extents do not require RPI headers. */ | ||
13847 | if (!phba->sli4_hba.rpi_hdrs_in_use) | ||
13848 | goto exit; | ||
13849 | if (phba->sli4_hba.extents_in_use) | ||
13850 | return -EIO; | ||
12561 | 13851 | ||
12562 | /* Post all rpi memory regions to the port. */ | ||
12563 | list_for_each_entry(rpi_page, &phba->sli4_hba.lpfc_rpi_hdr_list, list) { | 13852 | list_for_each_entry(rpi_page, &phba->sli4_hba.lpfc_rpi_hdr_list, list) { |
13853 | /* | ||
13854 | * Assign the rpi headers a physical rpi only if the driver | ||
13855 | * has not initialized those resources. A port reset only | ||
13856 | * needs the headers posted. | ||
13857 | */ | ||
13858 | if (bf_get(lpfc_rpi_rsrc_rdy, &phba->sli4_hba.sli4_flags) != | ||
13859 | LPFC_RPI_RSRC_RDY) | ||
13860 | rpi_page->start_rpi = phba->sli4_hba.rpi_ids[lrpi]; | ||
13861 | |||
12564 | rc = lpfc_sli4_post_rpi_hdr(phba, rpi_page); | 13862 | rc = lpfc_sli4_post_rpi_hdr(phba, rpi_page); |
12565 | if (rc != MBX_SUCCESS) { | 13863 | if (rc != MBX_SUCCESS) { |
12566 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 13864 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
@@ -12571,6 +13869,9 @@ lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *phba) | |||
12571 | } | 13869 | } |
12572 | } | 13870 | } |
12573 | 13871 | ||
13872 | exit: | ||
13873 | bf_set(lpfc_rpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, | ||
13874 | LPFC_RPI_RSRC_RDY); | ||
12574 | return rc; | 13875 | return rc; |
12575 | } | 13876 | } |
12576 | 13877 | ||
@@ -12594,10 +13895,15 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) | |||
12594 | LPFC_MBOXQ_t *mboxq; | 13895 | LPFC_MBOXQ_t *mboxq; |
12595 | struct lpfc_mbx_post_hdr_tmpl *hdr_tmpl; | 13896 | struct lpfc_mbx_post_hdr_tmpl *hdr_tmpl; |
12596 | uint32_t rc = 0; | 13897 | uint32_t rc = 0; |
12597 | uint32_t mbox_tmo; | ||
12598 | uint32_t shdr_status, shdr_add_status; | 13898 | uint32_t shdr_status, shdr_add_status; |
12599 | union lpfc_sli4_cfg_shdr *shdr; | 13899 | union lpfc_sli4_cfg_shdr *shdr; |
12600 | 13900 | ||
13901 | /* SLI4 ports that support extents do not require RPI headers. */ | ||
13902 | if (!phba->sli4_hba.rpi_hdrs_in_use) | ||
13903 | return rc; | ||
13904 | if (phba->sli4_hba.extents_in_use) | ||
13905 | return -EIO; | ||
13906 | |||
12601 | /* The port is notified of the header region via a mailbox command. */ | 13907 | /* The port is notified of the header region via a mailbox command. */ |
12602 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 13908 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
12603 | if (!mboxq) { | 13909 | if (!mboxq) { |
@@ -12609,16 +13915,19 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) | |||
12609 | 13915 | ||
12610 | /* Post all rpi memory regions to the port. */ | 13916 | /* Post all rpi memory regions to the port. */ |
12611 | hdr_tmpl = &mboxq->u.mqe.un.hdr_tmpl; | 13917 | hdr_tmpl = &mboxq->u.mqe.un.hdr_tmpl; |
12612 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
12613 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | 13918 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, |
12614 | LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE, | 13919 | LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE, |
12615 | sizeof(struct lpfc_mbx_post_hdr_tmpl) - | 13920 | sizeof(struct lpfc_mbx_post_hdr_tmpl) - |
12616 | sizeof(struct lpfc_sli4_cfg_mhdr), | 13921 | sizeof(struct lpfc_sli4_cfg_mhdr), |
12617 | LPFC_SLI4_MBX_EMBED); | 13922 | LPFC_SLI4_MBX_EMBED); |
12618 | bf_set(lpfc_mbx_post_hdr_tmpl_page_cnt, | 13923 | |
12619 | hdr_tmpl, rpi_page->page_count); | 13924 | |
13925 | /* Post the physical rpi to the port for this rpi header. */ | ||
12620 | bf_set(lpfc_mbx_post_hdr_tmpl_rpi_offset, hdr_tmpl, | 13926 | bf_set(lpfc_mbx_post_hdr_tmpl_rpi_offset, hdr_tmpl, |
12621 | rpi_page->start_rpi); | 13927 | rpi_page->start_rpi); |
13928 | bf_set(lpfc_mbx_post_hdr_tmpl_page_cnt, | ||
13929 | hdr_tmpl, rpi_page->page_count); | ||
13930 | |||
12622 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); | 13931 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); |
12623 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); | 13932 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); |
12624 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | 13933 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
@@ -12653,22 +13962,21 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) | |||
12653 | int | 13962 | int |
12654 | lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) | 13963 | lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) |
12655 | { | 13964 | { |
12656 | int rpi; | 13965 | unsigned long rpi; |
12657 | uint16_t max_rpi, rpi_base, rpi_limit; | 13966 | uint16_t max_rpi, rpi_limit; |
12658 | uint16_t rpi_remaining; | 13967 | uint16_t rpi_remaining, lrpi = 0; |
12659 | struct lpfc_rpi_hdr *rpi_hdr; | 13968 | struct lpfc_rpi_hdr *rpi_hdr; |
12660 | 13969 | ||
12661 | max_rpi = phba->sli4_hba.max_cfg_param.max_rpi; | 13970 | max_rpi = phba->sli4_hba.max_cfg_param.max_rpi; |
12662 | rpi_base = phba->sli4_hba.max_cfg_param.rpi_base; | ||
12663 | rpi_limit = phba->sli4_hba.next_rpi; | 13971 | rpi_limit = phba->sli4_hba.next_rpi; |
12664 | 13972 | ||
12665 | /* | 13973 | /* |
12666 | * The valid rpi range is not guaranteed to be zero-based. Start | 13974 | * Fetch the next logical rpi. Because this index is logical, |
12667 | * the search at the rpi_base as reported by the port. | 13975 | * the driver starts at 0 each time. |
12668 | */ | 13976 | */ |
12669 | spin_lock_irq(&phba->hbalock); | 13977 | spin_lock_irq(&phba->hbalock); |
12670 | rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, rpi_base); | 13978 | rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, 0); |
12671 | if (rpi >= rpi_limit || rpi < rpi_base) | 13979 | if (rpi >= rpi_limit) |
12672 | rpi = LPFC_RPI_ALLOC_ERROR; | 13980 | rpi = LPFC_RPI_ALLOC_ERROR; |
12673 | else { | 13981 | else { |
12674 | set_bit(rpi, phba->sli4_hba.rpi_bmask); | 13982 | set_bit(rpi, phba->sli4_hba.rpi_bmask); |
@@ -12678,7 +13986,7 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) | |||
12678 | 13986 | ||
12679 | /* | 13987 | /* |
12680 | * Don't try to allocate more rpi header regions if the device limit | 13988 | * Don't try to allocate more rpi header regions if the device limit |
12681 | * on available rpis max has been exhausted. | 13989 | * has been exhausted. |
12682 | */ | 13990 | */ |
12683 | if ((rpi == LPFC_RPI_ALLOC_ERROR) && | 13991 | if ((rpi == LPFC_RPI_ALLOC_ERROR) && |
12684 | (phba->sli4_hba.rpi_count >= max_rpi)) { | 13992 | (phba->sli4_hba.rpi_count >= max_rpi)) { |
@@ -12687,13 +13995,21 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) | |||
12687 | } | 13995 | } |
12688 | 13996 | ||
12689 | /* | 13997 | /* |
13998 | * RPI header postings are not required for SLI4 ports capable of | ||
13999 | * extents. | ||
14000 | */ | ||
14001 | if (!phba->sli4_hba.rpi_hdrs_in_use) { | ||
14002 | spin_unlock_irq(&phba->hbalock); | ||
14003 | return rpi; | ||
14004 | } | ||
14005 | |||
14006 | /* | ||
12690 | * If the driver is running low on rpi resources, allocate another | 14007 | * If the driver is running low on rpi resources, allocate another |
12691 | * page now. Note that the next_rpi value is used because | 14008 | * page now. Note that the next_rpi value is used because |
12692 | * it represents how many are actually in use whereas max_rpi notes | 14009 | * it represents how many are actually in use whereas max_rpi notes |
12693 | * how many are supported max by the device. | 14010 | * how many are supported max by the device. |
12694 | */ | 14011 | */ |
12695 | rpi_remaining = phba->sli4_hba.next_rpi - rpi_base - | 14012 | rpi_remaining = phba->sli4_hba.next_rpi - phba->sli4_hba.rpi_count; |
12696 | phba->sli4_hba.rpi_count; | ||
12697 | spin_unlock_irq(&phba->hbalock); | 14013 | spin_unlock_irq(&phba->hbalock); |
12698 | if (rpi_remaining < LPFC_RPI_LOW_WATER_MARK) { | 14014 | if (rpi_remaining < LPFC_RPI_LOW_WATER_MARK) { |
12699 | rpi_hdr = lpfc_sli4_create_rpi_hdr(phba); | 14015 | rpi_hdr = lpfc_sli4_create_rpi_hdr(phba); |
@@ -12702,6 +14018,8 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) | |||
12702 | "2002 Error Could not grow rpi " | 14018 | "2002 Error Could not grow rpi " |
12703 | "count\n"); | 14019 | "count\n"); |
12704 | } else { | 14020 | } else { |
14021 | lrpi = rpi_hdr->start_rpi; | ||
14022 | rpi_hdr->start_rpi = phba->sli4_hba.rpi_ids[lrpi]; | ||
12705 | lpfc_sli4_post_rpi_hdr(phba, rpi_hdr); | 14023 | lpfc_sli4_post_rpi_hdr(phba, rpi_hdr); |
12706 | } | 14024 | } |
12707 | } | 14025 | } |
@@ -12751,6 +14069,8 @@ void | |||
12751 | lpfc_sli4_remove_rpis(struct lpfc_hba *phba) | 14069 | lpfc_sli4_remove_rpis(struct lpfc_hba *phba) |
12752 | { | 14070 | { |
12753 | kfree(phba->sli4_hba.rpi_bmask); | 14071 | kfree(phba->sli4_hba.rpi_bmask); |
14072 | kfree(phba->sli4_hba.rpi_ids); | ||
14073 | bf_set(lpfc_rpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); | ||
12754 | } | 14074 | } |
12755 | 14075 | ||
12756 | /** | 14076 | /** |
@@ -13490,6 +14810,96 @@ out: | |||
13490 | } | 14810 | } |
13491 | 14811 | ||
13492 | /** | 14812 | /** |
14813 | * lpfc_wr_object - write an object to the firmware | ||
14814 | * @phba: HBA structure that indicates port to create a queue on. | ||
14815 | * @dmabuf_list: list of dmabufs to write to the port. | ||
14816 | * @size: the total byte value of the objects to write to the port. | ||
14817 | * @offset: the current offset to be used to start the transfer. | ||
14818 | * | ||
14819 | * This routine will create a wr_object mailbox command to send to the port. | ||
14820 | * the mailbox command will be constructed using the dma buffers described in | ||
14821 | * @dmabuf_list to create a list of BDEs. This routine will fill in as many | ||
14822 | * BDEs that the imbedded mailbox can support. The @offset variable will be | ||
14823 | * used to indicate the starting offset of the transfer and will also return | ||
14824 | * the offset after the write object mailbox has completed. @size is used to | ||
14825 | * determine the end of the object and whether the eof bit should be set. | ||
14826 | * | ||
14827 | * Return 0 is successful and offset will contain the the new offset to use | ||
14828 | * for the next write. | ||
14829 | * Return negative value for error cases. | ||
14830 | **/ | ||
14831 | int | ||
14832 | lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, | ||
14833 | uint32_t size, uint32_t *offset) | ||
14834 | { | ||
14835 | struct lpfc_mbx_wr_object *wr_object; | ||
14836 | LPFC_MBOXQ_t *mbox; | ||
14837 | int rc = 0, i = 0; | ||
14838 | uint32_t shdr_status, shdr_add_status; | ||
14839 | uint32_t mbox_tmo; | ||
14840 | union lpfc_sli4_cfg_shdr *shdr; | ||
14841 | struct lpfc_dmabuf *dmabuf; | ||
14842 | uint32_t written = 0; | ||
14843 | |||
14844 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
14845 | if (!mbox) | ||
14846 | return -ENOMEM; | ||
14847 | |||
14848 | lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
14849 | LPFC_MBOX_OPCODE_WRITE_OBJECT, | ||
14850 | sizeof(struct lpfc_mbx_wr_object) - | ||
14851 | sizeof(struct lpfc_sli4_cfg_mhdr), LPFC_SLI4_MBX_EMBED); | ||
14852 | |||
14853 | wr_object = (struct lpfc_mbx_wr_object *)&mbox->u.mqe.un.wr_object; | ||
14854 | wr_object->u.request.write_offset = *offset; | ||
14855 | sprintf((uint8_t *)wr_object->u.request.object_name, "/"); | ||
14856 | wr_object->u.request.object_name[0] = | ||
14857 | cpu_to_le32(wr_object->u.request.object_name[0]); | ||
14858 | bf_set(lpfc_wr_object_eof, &wr_object->u.request, 0); | ||
14859 | list_for_each_entry(dmabuf, dmabuf_list, list) { | ||
14860 | if (i >= LPFC_MBX_WR_CONFIG_MAX_BDE || written >= size) | ||
14861 | break; | ||
14862 | wr_object->u.request.bde[i].addrLow = putPaddrLow(dmabuf->phys); | ||
14863 | wr_object->u.request.bde[i].addrHigh = | ||
14864 | putPaddrHigh(dmabuf->phys); | ||
14865 | if (written + SLI4_PAGE_SIZE >= size) { | ||
14866 | wr_object->u.request.bde[i].tus.f.bdeSize = | ||
14867 | (size - written); | ||
14868 | written += (size - written); | ||
14869 | bf_set(lpfc_wr_object_eof, &wr_object->u.request, 1); | ||
14870 | } else { | ||
14871 | wr_object->u.request.bde[i].tus.f.bdeSize = | ||
14872 | SLI4_PAGE_SIZE; | ||
14873 | written += SLI4_PAGE_SIZE; | ||
14874 | } | ||
14875 | i++; | ||
14876 | } | ||
14877 | wr_object->u.request.bde_count = i; | ||
14878 | bf_set(lpfc_wr_object_write_length, &wr_object->u.request, written); | ||
14879 | if (!phba->sli4_hba.intr_enable) | ||
14880 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | ||
14881 | else { | ||
14882 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
14883 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo); | ||
14884 | } | ||
14885 | /* The IOCTL status is embedded in the mailbox subheader. */ | ||
14886 | shdr = (union lpfc_sli4_cfg_shdr *) &wr_object->header.cfg_shdr; | ||
14887 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
14888 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
14889 | if (rc != MBX_TIMEOUT) | ||
14890 | mempool_free(mbox, phba->mbox_mem_pool); | ||
14891 | if (shdr_status || shdr_add_status || rc) { | ||
14892 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
14893 | "3025 Write Object mailbox failed with " | ||
14894 | "status x%x add_status x%x, mbx status x%x\n", | ||
14895 | shdr_status, shdr_add_status, rc); | ||
14896 | rc = -ENXIO; | ||
14897 | } else | ||
14898 | *offset += wr_object->u.response.actual_write_length; | ||
14899 | return rc; | ||
14900 | } | ||
14901 | |||
14902 | /** | ||
13493 | * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands. | 14903 | * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands. |
13494 | * @vport: pointer to vport data structure. | 14904 | * @vport: pointer to vport data structure. |
13495 | * | 14905 | * |
@@ -13644,7 +15054,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) | |||
13644 | * never happen | 15054 | * never happen |
13645 | */ | 15055 | */ |
13646 | sglq = __lpfc_clear_active_sglq(phba, | 15056 | sglq = __lpfc_clear_active_sglq(phba, |
13647 | sglq->sli4_xritag); | 15057 | sglq->sli4_lxritag); |
13648 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 15058 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
13649 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 15059 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
13650 | "2823 txq empty and txq_cnt is %d\n ", | 15060 | "2823 txq empty and txq_cnt is %d\n ", |
@@ -13656,6 +15066,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) | |||
13656 | /* The xri and iocb resources secured, | 15066 | /* The xri and iocb resources secured, |
13657 | * attempt to issue request | 15067 | * attempt to issue request |
13658 | */ | 15068 | */ |
15069 | piocbq->sli4_lxritag = sglq->sli4_lxritag; | ||
13659 | piocbq->sli4_xritag = sglq->sli4_xritag; | 15070 | piocbq->sli4_xritag = sglq->sli4_xritag; |
13660 | if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocbq, sglq)) | 15071 | if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocbq, sglq)) |
13661 | fail_msg = "to convert bpl to sgl"; | 15072 | fail_msg = "to convert bpl to sgl"; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 453577c21c14..a0075b0af142 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -52,6 +52,7 @@ struct lpfc_iocbq { | |||
52 | struct list_head clist; | 52 | struct list_head clist; |
53 | struct list_head dlist; | 53 | struct list_head dlist; |
54 | uint16_t iotag; /* pre-assigned IO tag */ | 54 | uint16_t iotag; /* pre-assigned IO tag */ |
55 | uint16_t sli4_lxritag; /* logical pre-assigned XRI. */ | ||
55 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ | 56 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ |
56 | struct lpfc_cq_event cq_event; | 57 | struct lpfc_cq_event cq_event; |
57 | 58 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 1a3cbf88f2ce..4b1703554a26 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -310,7 +310,6 @@ struct lpfc_max_cfg_param { | |||
310 | uint16_t vfi_base; | 310 | uint16_t vfi_base; |
311 | uint16_t vfi_used; | 311 | uint16_t vfi_used; |
312 | uint16_t max_fcfi; | 312 | uint16_t max_fcfi; |
313 | uint16_t fcfi_base; | ||
314 | uint16_t fcfi_used; | 313 | uint16_t fcfi_used; |
315 | uint16_t max_eq; | 314 | uint16_t max_eq; |
316 | uint16_t max_rq; | 315 | uint16_t max_rq; |
@@ -365,6 +364,11 @@ struct lpfc_pc_sli4_params { | |||
365 | uint8_t rqv; | 364 | uint8_t rqv; |
366 | }; | 365 | }; |
367 | 366 | ||
367 | struct lpfc_iov { | ||
368 | uint32_t pf_number; | ||
369 | uint32_t vf_number; | ||
370 | }; | ||
371 | |||
368 | /* SLI4 HBA data structure entries */ | 372 | /* SLI4 HBA data structure entries */ |
369 | struct lpfc_sli4_hba { | 373 | struct lpfc_sli4_hba { |
370 | void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for | 374 | void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for |
@@ -444,10 +448,13 @@ struct lpfc_sli4_hba { | |||
444 | uint32_t intr_enable; | 448 | uint32_t intr_enable; |
445 | struct lpfc_bmbx bmbx; | 449 | struct lpfc_bmbx bmbx; |
446 | struct lpfc_max_cfg_param max_cfg_param; | 450 | struct lpfc_max_cfg_param max_cfg_param; |
451 | uint16_t extents_in_use; /* must allocate resource extents. */ | ||
452 | uint16_t rpi_hdrs_in_use; /* must post rpi hdrs if set. */ | ||
447 | uint16_t next_xri; /* last_xri - max_cfg_param.xri_base = used */ | 453 | uint16_t next_xri; /* last_xri - max_cfg_param.xri_base = used */ |
448 | uint16_t next_rpi; | 454 | uint16_t next_rpi; |
449 | uint16_t scsi_xri_max; | 455 | uint16_t scsi_xri_max; |
450 | uint16_t scsi_xri_cnt; | 456 | uint16_t scsi_xri_cnt; |
457 | uint16_t scsi_xri_start; | ||
451 | struct list_head lpfc_free_sgl_list; | 458 | struct list_head lpfc_free_sgl_list; |
452 | struct list_head lpfc_sgl_list; | 459 | struct list_head lpfc_sgl_list; |
453 | struct lpfc_sglq **lpfc_els_sgl_array; | 460 | struct lpfc_sglq **lpfc_els_sgl_array; |
@@ -458,7 +465,17 @@ struct lpfc_sli4_hba { | |||
458 | struct lpfc_sglq **lpfc_sglq_active_list; | 465 | struct lpfc_sglq **lpfc_sglq_active_list; |
459 | struct list_head lpfc_rpi_hdr_list; | 466 | struct list_head lpfc_rpi_hdr_list; |
460 | unsigned long *rpi_bmask; | 467 | unsigned long *rpi_bmask; |
468 | uint16_t *rpi_ids; | ||
461 | uint16_t rpi_count; | 469 | uint16_t rpi_count; |
470 | struct list_head lpfc_rpi_blk_list; | ||
471 | unsigned long *xri_bmask; | ||
472 | uint16_t *xri_ids; | ||
473 | uint16_t xri_count; | ||
474 | struct list_head lpfc_xri_blk_list; | ||
475 | unsigned long *vfi_bmask; | ||
476 | uint16_t *vfi_ids; | ||
477 | uint16_t vfi_count; | ||
478 | struct list_head lpfc_vfi_blk_list; | ||
462 | struct lpfc_sli4_flags sli4_flags; | 479 | struct lpfc_sli4_flags sli4_flags; |
463 | struct list_head sp_queue_event; | 480 | struct list_head sp_queue_event; |
464 | struct list_head sp_cqe_event_pool; | 481 | struct list_head sp_cqe_event_pool; |
@@ -467,6 +484,7 @@ struct lpfc_sli4_hba { | |||
467 | struct list_head sp_els_xri_aborted_work_queue; | 484 | struct list_head sp_els_xri_aborted_work_queue; |
468 | struct list_head sp_unsol_work_queue; | 485 | struct list_head sp_unsol_work_queue; |
469 | struct lpfc_sli4_link link_state; | 486 | struct lpfc_sli4_link link_state; |
487 | struct lpfc_iov iov; | ||
470 | spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ | 488 | spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ |
471 | spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */ | 489 | spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */ |
472 | }; | 490 | }; |
@@ -490,6 +508,7 @@ struct lpfc_sglq { | |||
490 | enum lpfc_sgl_state state; | 508 | enum lpfc_sgl_state state; |
491 | struct lpfc_nodelist *ndlp; /* ndlp associated with IO */ | 509 | struct lpfc_nodelist *ndlp; /* ndlp associated with IO */ |
492 | uint16_t iotag; /* pre-assigned IO tag */ | 510 | uint16_t iotag; /* pre-assigned IO tag */ |
511 | uint16_t sli4_lxritag; /* logical pre-assigned xri. */ | ||
493 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ | 512 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ |
494 | struct sli4_sge *sgl; /* pre-assigned SGL */ | 513 | struct sli4_sge *sgl; /* pre-assigned SGL */ |
495 | void *virt; /* virtual address. */ | 514 | void *virt; /* virtual address. */ |
@@ -504,6 +523,13 @@ struct lpfc_rpi_hdr { | |||
504 | uint32_t start_rpi; | 523 | uint32_t start_rpi; |
505 | }; | 524 | }; |
506 | 525 | ||
526 | struct lpfc_rsrc_blks { | ||
527 | struct list_head list; | ||
528 | uint16_t rsrc_start; | ||
529 | uint16_t rsrc_size; | ||
530 | uint16_t rsrc_used; | ||
531 | }; | ||
532 | |||
507 | /* | 533 | /* |
508 | * SLI4 specific function prototypes | 534 | * SLI4 specific function prototypes |
509 | */ | 535 | */ |
@@ -543,8 +569,11 @@ int lpfc_sli4_post_sgl(struct lpfc_hba *, dma_addr_t, dma_addr_t, uint16_t); | |||
543 | int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *); | 569 | int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *); |
544 | uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *); | 570 | uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *); |
545 | int lpfc_sli4_post_async_mbox(struct lpfc_hba *); | 571 | int lpfc_sli4_post_async_mbox(struct lpfc_hba *); |
546 | int lpfc_sli4_post_sgl_list(struct lpfc_hba *phba); | 572 | int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba); |
573 | int lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba); | ||
547 | int lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *, struct list_head *, int); | 574 | int lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *, struct list_head *, int); |
575 | int lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *, struct list_head *, | ||
576 | int); | ||
548 | struct lpfc_cq_event *__lpfc_sli4_cq_event_alloc(struct lpfc_hba *); | 577 | struct lpfc_cq_event *__lpfc_sli4_cq_event_alloc(struct lpfc_hba *); |
549 | struct lpfc_cq_event *lpfc_sli4_cq_event_alloc(struct lpfc_hba *); | 578 | struct lpfc_cq_event *lpfc_sli4_cq_event_alloc(struct lpfc_hba *); |
550 | void __lpfc_sli4_cq_event_release(struct lpfc_hba *, struct lpfc_cq_event *); | 579 | void __lpfc_sli4_cq_event_release(struct lpfc_hba *, struct lpfc_cq_event *); |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 30ba5440c67a..1feb551a57bc 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -83,7 +83,7 @@ inline void lpfc_vport_set_state(struct lpfc_vport *vport, | |||
83 | static int | 83 | static int |
84 | lpfc_alloc_vpi(struct lpfc_hba *phba) | 84 | lpfc_alloc_vpi(struct lpfc_hba *phba) |
85 | { | 85 | { |
86 | int vpi; | 86 | unsigned long vpi; |
87 | 87 | ||
88 | spin_lock_irq(&phba->hbalock); | 88 | spin_lock_irq(&phba->hbalock); |
89 | /* Start at bit 1 because vpi zero is reserved for the physical port */ | 89 | /* Start at bit 1 because vpi zero is reserved for the physical port */ |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 046dcc672ec1..7370c084b178 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -33,9 +33,9 @@ | |||
33 | /* | 33 | /* |
34 | * MegaRAID SAS Driver meta data | 34 | * MegaRAID SAS Driver meta data |
35 | */ | 35 | */ |
36 | #define MEGASAS_VERSION "00.00.05.34-rc1" | 36 | #define MEGASAS_VERSION "00.00.05.38-rc1" |
37 | #define MEGASAS_RELDATE "Feb. 24, 2011" | 37 | #define MEGASAS_RELDATE "May. 11, 2011" |
38 | #define MEGASAS_EXT_VERSION "Thu. Feb. 24 17:00:00 PDT 2011" | 38 | #define MEGASAS_EXT_VERSION "Wed. May. 11 17:00:00 PDT 2011" |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Device IDs | 41 | * Device IDs |
@@ -76,8 +76,8 @@ | |||
76 | #define MFI_STATE_READY 0xB0000000 | 76 | #define MFI_STATE_READY 0xB0000000 |
77 | #define MFI_STATE_OPERATIONAL 0xC0000000 | 77 | #define MFI_STATE_OPERATIONAL 0xC0000000 |
78 | #define MFI_STATE_FAULT 0xF0000000 | 78 | #define MFI_STATE_FAULT 0xF0000000 |
79 | #define MFI_RESET_REQUIRED 0x00000001 | 79 | #define MFI_RESET_REQUIRED 0x00000001 |
80 | 80 | #define MFI_RESET_ADAPTER 0x00000002 | |
81 | #define MEGAMFI_FRAME_SIZE 64 | 81 | #define MEGAMFI_FRAME_SIZE 64 |
82 | 82 | ||
83 | /* | 83 | /* |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 89c623ebadbc..2d8cdce7b2f5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * | 19 | * |
20 | * FILE: megaraid_sas_base.c | 20 | * FILE: megaraid_sas_base.c |
21 | * Version : v00.00.05.34-rc1 | 21 | * Version : v00.00.05.38-rc1 |
22 | * | 22 | * |
23 | * Authors: LSI Corporation | 23 | * Authors: LSI Corporation |
24 | * Sreenivas Bagalkote | 24 | * Sreenivas Bagalkote |
@@ -437,15 +437,18 @@ megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) | |||
437 | static int | 437 | static int |
438 | megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) | 438 | megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) |
439 | { | 439 | { |
440 | u32 status; | 440 | u32 status, mfiStatus = 0; |
441 | |||
441 | /* | 442 | /* |
442 | * Check if it is our interrupt | 443 | * Check if it is our interrupt |
443 | */ | 444 | */ |
444 | status = readl(®s->outbound_intr_status); | 445 | status = readl(®s->outbound_intr_status); |
445 | 446 | ||
446 | if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) { | 447 | if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT) |
447 | return 0; | 448 | mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; |
448 | } | 449 | |
450 | if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) | ||
451 | mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; | ||
449 | 452 | ||
450 | /* | 453 | /* |
451 | * Clear the interrupt by writing back the same value | 454 | * Clear the interrupt by writing back the same value |
@@ -455,8 +458,9 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) | |||
455 | /* Dummy readl to force pci flush */ | 458 | /* Dummy readl to force pci flush */ |
456 | readl(®s->outbound_doorbell_clear); | 459 | readl(®s->outbound_doorbell_clear); |
457 | 460 | ||
458 | return 1; | 461 | return mfiStatus; |
459 | } | 462 | } |
463 | |||
460 | /** | 464 | /** |
461 | * megasas_fire_cmd_ppc - Sends command to the FW | 465 | * megasas_fire_cmd_ppc - Sends command to the FW |
462 | * @frame_phys_addr : Physical address of cmd | 466 | * @frame_phys_addr : Physical address of cmd |
@@ -477,17 +481,6 @@ megasas_fire_cmd_ppc(struct megasas_instance *instance, | |||
477 | } | 481 | } |
478 | 482 | ||
479 | /** | 483 | /** |
480 | * megasas_adp_reset_ppc - For controller reset | ||
481 | * @regs: MFI register set | ||
482 | */ | ||
483 | static int | ||
484 | megasas_adp_reset_ppc(struct megasas_instance *instance, | ||
485 | struct megasas_register_set __iomem *regs) | ||
486 | { | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | /** | ||
491 | * megasas_check_reset_ppc - For controller reset check | 484 | * megasas_check_reset_ppc - For controller reset check |
492 | * @regs: MFI register set | 485 | * @regs: MFI register set |
493 | */ | 486 | */ |
@@ -495,8 +488,12 @@ static int | |||
495 | megasas_check_reset_ppc(struct megasas_instance *instance, | 488 | megasas_check_reset_ppc(struct megasas_instance *instance, |
496 | struct megasas_register_set __iomem *regs) | 489 | struct megasas_register_set __iomem *regs) |
497 | { | 490 | { |
491 | if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) | ||
492 | return 1; | ||
493 | |||
498 | return 0; | 494 | return 0; |
499 | } | 495 | } |
496 | |||
500 | static struct megasas_instance_template megasas_instance_template_ppc = { | 497 | static struct megasas_instance_template megasas_instance_template_ppc = { |
501 | 498 | ||
502 | .fire_cmd = megasas_fire_cmd_ppc, | 499 | .fire_cmd = megasas_fire_cmd_ppc, |
@@ -504,7 +501,7 @@ static struct megasas_instance_template megasas_instance_template_ppc = { | |||
504 | .disable_intr = megasas_disable_intr_ppc, | 501 | .disable_intr = megasas_disable_intr_ppc, |
505 | .clear_intr = megasas_clear_intr_ppc, | 502 | .clear_intr = megasas_clear_intr_ppc, |
506 | .read_fw_status_reg = megasas_read_fw_status_reg_ppc, | 503 | .read_fw_status_reg = megasas_read_fw_status_reg_ppc, |
507 | .adp_reset = megasas_adp_reset_ppc, | 504 | .adp_reset = megasas_adp_reset_xscale, |
508 | .check_reset = megasas_check_reset_ppc, | 505 | .check_reset = megasas_check_reset_ppc, |
509 | .service_isr = megasas_isr, | 506 | .service_isr = megasas_isr, |
510 | .tasklet = megasas_complete_cmd_dpc, | 507 | .tasklet = megasas_complete_cmd_dpc, |
@@ -620,6 +617,9 @@ static int | |||
620 | megasas_check_reset_skinny(struct megasas_instance *instance, | 617 | megasas_check_reset_skinny(struct megasas_instance *instance, |
621 | struct megasas_register_set __iomem *regs) | 618 | struct megasas_register_set __iomem *regs) |
622 | { | 619 | { |
620 | if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) | ||
621 | return 1; | ||
622 | |||
623 | return 0; | 623 | return 0; |
624 | } | 624 | } |
625 | 625 | ||
@@ -3454,7 +3454,7 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
3454 | { | 3454 | { |
3455 | u32 max_sectors_1; | 3455 | u32 max_sectors_1; |
3456 | u32 max_sectors_2; | 3456 | u32 max_sectors_2; |
3457 | u32 tmp_sectors; | 3457 | u32 tmp_sectors, msix_enable; |
3458 | struct megasas_register_set __iomem *reg_set; | 3458 | struct megasas_register_set __iomem *reg_set; |
3459 | struct megasas_ctrl_info *ctrl_info; | 3459 | struct megasas_ctrl_info *ctrl_info; |
3460 | unsigned long bar_list; | 3460 | unsigned long bar_list; |
@@ -3507,6 +3507,13 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
3507 | if (megasas_transition_to_ready(instance)) | 3507 | if (megasas_transition_to_ready(instance)) |
3508 | goto fail_ready_state; | 3508 | goto fail_ready_state; |
3509 | 3509 | ||
3510 | /* Check if MSI-X is supported while in ready state */ | ||
3511 | msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & | ||
3512 | 0x4000000) >> 0x1a; | ||
3513 | if (msix_enable && !msix_disable && | ||
3514 | !pci_enable_msix(instance->pdev, &instance->msixentry, 1)) | ||
3515 | instance->msi_flag = 1; | ||
3516 | |||
3510 | /* Get operational params, sge flags, send init cmd to controller */ | 3517 | /* Get operational params, sge flags, send init cmd to controller */ |
3511 | if (instance->instancet->init_adapter(instance)) | 3518 | if (instance->instancet->init_adapter(instance)) |
3512 | goto fail_init_adapter; | 3519 | goto fail_init_adapter; |
@@ -4076,14 +4083,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4076 | else | 4083 | else |
4077 | INIT_WORK(&instance->work_init, process_fw_state_change_wq); | 4084 | INIT_WORK(&instance->work_init, process_fw_state_change_wq); |
4078 | 4085 | ||
4079 | /* Try to enable MSI-X */ | ||
4080 | if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) && | ||
4081 | (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) && | ||
4082 | (instance->pdev->device != PCI_DEVICE_ID_LSI_VERDE_ZCR) && | ||
4083 | !msix_disable && !pci_enable_msix(instance->pdev, | ||
4084 | &instance->msixentry, 1)) | ||
4085 | instance->msi_flag = 1; | ||
4086 | |||
4087 | /* | 4086 | /* |
4088 | * Initialize MFI Firmware | 4087 | * Initialize MFI Firmware |
4089 | */ | 4088 | */ |
@@ -4116,6 +4115,14 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4116 | megasas_mgmt_info.max_index++; | 4115 | megasas_mgmt_info.max_index++; |
4117 | 4116 | ||
4118 | /* | 4117 | /* |
4118 | * Register with SCSI mid-layer | ||
4119 | */ | ||
4120 | if (megasas_io_attach(instance)) | ||
4121 | goto fail_io_attach; | ||
4122 | |||
4123 | instance->unload = 0; | ||
4124 | |||
4125 | /* | ||
4119 | * Initiate AEN (Asynchronous Event Notification) | 4126 | * Initiate AEN (Asynchronous Event Notification) |
4120 | */ | 4127 | */ |
4121 | if (megasas_start_aen(instance)) { | 4128 | if (megasas_start_aen(instance)) { |
@@ -4123,13 +4130,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4123 | goto fail_start_aen; | 4130 | goto fail_start_aen; |
4124 | } | 4131 | } |
4125 | 4132 | ||
4126 | /* | ||
4127 | * Register with SCSI mid-layer | ||
4128 | */ | ||
4129 | if (megasas_io_attach(instance)) | ||
4130 | goto fail_io_attach; | ||
4131 | |||
4132 | instance->unload = 0; | ||
4133 | return 0; | 4133 | return 0; |
4134 | 4134 | ||
4135 | fail_start_aen: | 4135 | fail_start_aen: |
@@ -4332,10 +4332,6 @@ megasas_resume(struct pci_dev *pdev) | |||
4332 | if (megasas_set_dma_mask(pdev)) | 4332 | if (megasas_set_dma_mask(pdev)) |
4333 | goto fail_set_dma_mask; | 4333 | goto fail_set_dma_mask; |
4334 | 4334 | ||
4335 | /* Now re-enable MSI-X */ | ||
4336 | if (instance->msi_flag) | ||
4337 | pci_enable_msix(instance->pdev, &instance->msixentry, 1); | ||
4338 | |||
4339 | /* | 4335 | /* |
4340 | * Initialize MFI Firmware | 4336 | * Initialize MFI Firmware |
4341 | */ | 4337 | */ |
@@ -4348,6 +4344,10 @@ megasas_resume(struct pci_dev *pdev) | |||
4348 | if (megasas_transition_to_ready(instance)) | 4344 | if (megasas_transition_to_ready(instance)) |
4349 | goto fail_ready_state; | 4345 | goto fail_ready_state; |
4350 | 4346 | ||
4347 | /* Now re-enable MSI-X */ | ||
4348 | if (instance->msi_flag) | ||
4349 | pci_enable_msix(instance->pdev, &instance->msixentry, 1); | ||
4350 | |||
4351 | switch (instance->pdev->device) { | 4351 | switch (instance->pdev->device) { |
4352 | case PCI_DEVICE_ID_LSI_FUSION: | 4352 | case PCI_DEVICE_ID_LSI_FUSION: |
4353 | { | 4353 | { |
@@ -4384,12 +4384,6 @@ megasas_resume(struct pci_dev *pdev) | |||
4384 | 4384 | ||
4385 | instance->instancet->enable_intr(instance->reg_set); | 4385 | instance->instancet->enable_intr(instance->reg_set); |
4386 | 4386 | ||
4387 | /* | ||
4388 | * Initiate AEN (Asynchronous Event Notification) | ||
4389 | */ | ||
4390 | if (megasas_start_aen(instance)) | ||
4391 | printk(KERN_ERR "megasas: Start AEN failed\n"); | ||
4392 | |||
4393 | /* Initialize the cmd completion timer */ | 4387 | /* Initialize the cmd completion timer */ |
4394 | if (poll_mode_io) | 4388 | if (poll_mode_io) |
4395 | megasas_start_timer(instance, &instance->io_completion_timer, | 4389 | megasas_start_timer(instance, &instance->io_completion_timer, |
@@ -4397,6 +4391,12 @@ megasas_resume(struct pci_dev *pdev) | |||
4397 | MEGASAS_COMPLETION_TIMER_INTERVAL); | 4391 | MEGASAS_COMPLETION_TIMER_INTERVAL); |
4398 | instance->unload = 0; | 4392 | instance->unload = 0; |
4399 | 4393 | ||
4394 | /* | ||
4395 | * Initiate AEN (Asynchronous Event Notification) | ||
4396 | */ | ||
4397 | if (megasas_start_aen(instance)) | ||
4398 | printk(KERN_ERR "megasas: Start AEN failed\n"); | ||
4399 | |||
4400 | return 0; | 4400 | return 0; |
4401 | 4401 | ||
4402 | fail_irq: | 4402 | fail_irq: |
@@ -4527,6 +4527,11 @@ static void megasas_shutdown(struct pci_dev *pdev) | |||
4527 | instance->unload = 1; | 4527 | instance->unload = 1; |
4528 | megasas_flush_cache(instance); | 4528 | megasas_flush_cache(instance); |
4529 | megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); | 4529 | megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); |
4530 | instance->instancet->disable_intr(instance->reg_set); | ||
4531 | free_irq(instance->msi_flag ? instance->msixentry.vector : | ||
4532 | instance->pdev->irq, instance); | ||
4533 | if (instance->msi_flag) | ||
4534 | pci_disable_msix(instance->pdev); | ||
4530 | } | 4535 | } |
4531 | 4536 | ||
4532 | /** | 4537 | /** |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 145a8cffb1fa..f13e7abd345a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -696,22 +696,6 @@ fail_get_cmd: | |||
696 | } | 696 | } |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * megasas_return_cmd_for_smid - Returns a cmd_fusion for a SMID | ||
700 | * @instance: Adapter soft state | ||
701 | * | ||
702 | */ | ||
703 | void | ||
704 | megasas_return_cmd_for_smid(struct megasas_instance *instance, u16 smid) | ||
705 | { | ||
706 | struct fusion_context *fusion; | ||
707 | struct megasas_cmd_fusion *cmd; | ||
708 | |||
709 | fusion = instance->ctrl_context; | ||
710 | cmd = fusion->cmd_list[smid - 1]; | ||
711 | megasas_return_cmd_fusion(instance, cmd); | ||
712 | } | ||
713 | |||
714 | /* | ||
715 | * megasas_get_ld_map_info - Returns FW's ld_map structure | 699 | * megasas_get_ld_map_info - Returns FW's ld_map structure |
716 | * @instance: Adapter soft state | 700 | * @instance: Adapter soft state |
717 | * @pend: Pend the command or not | 701 | * @pend: Pend the command or not |
@@ -1153,7 +1137,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, | |||
1153 | u64 start_blk = io_info->pdBlock; | 1137 | u64 start_blk = io_info->pdBlock; |
1154 | u8 *cdb = io_request->CDB.CDB32; | 1138 | u8 *cdb = io_request->CDB.CDB32; |
1155 | u32 num_blocks = io_info->numBlocks; | 1139 | u32 num_blocks = io_info->numBlocks; |
1156 | u8 opcode, flagvals, groupnum, control; | 1140 | u8 opcode = 0, flagvals = 0, groupnum = 0, control = 0; |
1157 | 1141 | ||
1158 | /* Check if T10 PI (DIF) is enabled for this LD */ | 1142 | /* Check if T10 PI (DIF) is enabled for this LD */ |
1159 | ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr); | 1143 | ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr); |
@@ -1235,7 +1219,46 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, | |||
1235 | cdb[8] = (u8)(num_blocks & 0xff); | 1219 | cdb[8] = (u8)(num_blocks & 0xff); |
1236 | cdb[7] = (u8)((num_blocks >> 8) & 0xff); | 1220 | cdb[7] = (u8)((num_blocks >> 8) & 0xff); |
1237 | 1221 | ||
1222 | io_request->IoFlags = 10; /* Specify 10-byte cdb */ | ||
1238 | cdb_len = 10; | 1223 | cdb_len = 10; |
1224 | } else if ((cdb_len < 16) && (start_blk > 0xffffffff)) { | ||
1225 | /* Convert to 16 byte CDB for large LBA's */ | ||
1226 | switch (cdb_len) { | ||
1227 | case 6: | ||
1228 | opcode = cdb[0] == READ_6 ? READ_16 : WRITE_16; | ||
1229 | control = cdb[5]; | ||
1230 | break; | ||
1231 | case 10: | ||
1232 | opcode = | ||
1233 | cdb[0] == READ_10 ? READ_16 : WRITE_16; | ||
1234 | flagvals = cdb[1]; | ||
1235 | groupnum = cdb[6]; | ||
1236 | control = cdb[9]; | ||
1237 | break; | ||
1238 | case 12: | ||
1239 | opcode = | ||
1240 | cdb[0] == READ_12 ? READ_16 : WRITE_16; | ||
1241 | flagvals = cdb[1]; | ||
1242 | groupnum = cdb[10]; | ||
1243 | control = cdb[11]; | ||
1244 | break; | ||
1245 | } | ||
1246 | |||
1247 | memset(cdb, 0, sizeof(io_request->CDB.CDB32)); | ||
1248 | |||
1249 | cdb[0] = opcode; | ||
1250 | cdb[1] = flagvals; | ||
1251 | cdb[14] = groupnum; | ||
1252 | cdb[15] = control; | ||
1253 | |||
1254 | /* Transfer length */ | ||
1255 | cdb[13] = (u8)(num_blocks & 0xff); | ||
1256 | cdb[12] = (u8)((num_blocks >> 8) & 0xff); | ||
1257 | cdb[11] = (u8)((num_blocks >> 16) & 0xff); | ||
1258 | cdb[10] = (u8)((num_blocks >> 24) & 0xff); | ||
1259 | |||
1260 | io_request->IoFlags = 16; /* Specify 16-byte cdb */ | ||
1261 | cdb_len = 16; | ||
1239 | } | 1262 | } |
1240 | 1263 | ||
1241 | /* Normal case, just load LBA here */ | 1264 | /* Normal case, just load LBA here */ |
@@ -2026,17 +2049,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2026 | struct fusion_context *fusion; | 2049 | struct fusion_context *fusion; |
2027 | struct megasas_cmd *cmd_mfi; | 2050 | struct megasas_cmd *cmd_mfi; |
2028 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; | 2051 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; |
2029 | u32 host_diag, abs_state; | 2052 | u32 host_diag, abs_state, status_reg, reset_adapter; |
2030 | 2053 | ||
2031 | instance = (struct megasas_instance *)shost->hostdata; | 2054 | instance = (struct megasas_instance *)shost->hostdata; |
2032 | fusion = instance->ctrl_context; | 2055 | fusion = instance->ctrl_context; |
2033 | 2056 | ||
2034 | mutex_lock(&instance->reset_mutex); | ||
2035 | set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); | ||
2036 | instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; | ||
2037 | instance->instancet->disable_intr(instance->reg_set); | ||
2038 | msleep(1000); | ||
2039 | |||
2040 | if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { | 2057 | if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) { |
2041 | printk(KERN_WARNING "megaraid_sas: Hardware critical error, " | 2058 | printk(KERN_WARNING "megaraid_sas: Hardware critical error, " |
2042 | "returning FAILED.\n"); | 2059 | "returning FAILED.\n"); |
@@ -2044,6 +2061,12 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2044 | goto out; | 2061 | goto out; |
2045 | } | 2062 | } |
2046 | 2063 | ||
2064 | mutex_lock(&instance->reset_mutex); | ||
2065 | set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); | ||
2066 | instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; | ||
2067 | instance->instancet->disable_intr(instance->reg_set); | ||
2068 | msleep(1000); | ||
2069 | |||
2047 | /* First try waiting for commands to complete */ | 2070 | /* First try waiting for commands to complete */ |
2048 | if (megasas_wait_for_outstanding_fusion(instance)) { | 2071 | if (megasas_wait_for_outstanding_fusion(instance)) { |
2049 | printk(KERN_WARNING "megaraid_sas: resetting fusion " | 2072 | printk(KERN_WARNING "megaraid_sas: resetting fusion " |
@@ -2060,7 +2083,12 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2060 | } | 2083 | } |
2061 | } | 2084 | } |
2062 | 2085 | ||
2063 | if (instance->disableOnlineCtrlReset == 1) { | 2086 | status_reg = instance->instancet->read_fw_status_reg( |
2087 | instance->reg_set); | ||
2088 | abs_state = status_reg & MFI_STATE_MASK; | ||
2089 | reset_adapter = status_reg & MFI_RESET_ADAPTER; | ||
2090 | if (instance->disableOnlineCtrlReset || | ||
2091 | (abs_state == MFI_STATE_FAULT && !reset_adapter)) { | ||
2064 | /* Reset not supported, kill adapter */ | 2092 | /* Reset not supported, kill adapter */ |
2065 | printk(KERN_WARNING "megaraid_sas: Reset not supported" | 2093 | printk(KERN_WARNING "megaraid_sas: Reset not supported" |
2066 | ", killing adapter.\n"); | 2094 | ", killing adapter.\n"); |
@@ -2089,6 +2117,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2089 | 2117 | ||
2090 | /* Check that the diag write enable (DRWE) bit is on */ | 2118 | /* Check that the diag write enable (DRWE) bit is on */ |
2091 | host_diag = readl(&instance->reg_set->fusion_host_diag); | 2119 | host_diag = readl(&instance->reg_set->fusion_host_diag); |
2120 | retry = 0; | ||
2092 | while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) { | 2121 | while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) { |
2093 | msleep(100); | 2122 | msleep(100); |
2094 | host_diag = | 2123 | host_diag = |
@@ -2126,7 +2155,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2126 | 2155 | ||
2127 | abs_state = | 2156 | abs_state = |
2128 | instance->instancet->read_fw_status_reg( | 2157 | instance->instancet->read_fw_status_reg( |
2129 | instance->reg_set); | 2158 | instance->reg_set) & MFI_STATE_MASK; |
2130 | retry = 0; | 2159 | retry = 0; |
2131 | 2160 | ||
2132 | while ((abs_state <= MFI_STATE_FW_INIT) && | 2161 | while ((abs_state <= MFI_STATE_FW_INIT) && |
@@ -2134,7 +2163,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost) | |||
2134 | msleep(100); | 2163 | msleep(100); |
2135 | abs_state = | 2164 | abs_state = |
2136 | instance->instancet->read_fw_status_reg( | 2165 | instance->instancet->read_fw_status_reg( |
2137 | instance->reg_set); | 2166 | instance->reg_set) & MFI_STATE_MASK; |
2138 | } | 2167 | } |
2139 | if (abs_state <= MFI_STATE_FW_INIT) { | 2168 | if (abs_state <= MFI_STATE_FW_INIT) { |
2140 | printk(KERN_WARNING "megaraid_sas: firmware " | 2169 | printk(KERN_WARNING "megaraid_sas: firmware " |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 2a3c05f6db8b..dcc289c25459 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -69,11 +69,11 @@ | |||
69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" | 69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" |
70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" | 70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" |
71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" | 71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" |
72 | #define MPT2SAS_DRIVER_VERSION "08.100.00.01" | 72 | #define MPT2SAS_DRIVER_VERSION "08.100.00.02" |
73 | #define MPT2SAS_MAJOR_VERSION 08 | 73 | #define MPT2SAS_MAJOR_VERSION 08 |
74 | #define MPT2SAS_MINOR_VERSION 100 | 74 | #define MPT2SAS_MINOR_VERSION 100 |
75 | #define MPT2SAS_BUILD_VERSION 00 | 75 | #define MPT2SAS_BUILD_VERSION 00 |
76 | #define MPT2SAS_RELEASE_VERSION 01 | 76 | #define MPT2SAS_RELEASE_VERSION 02 |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Set MPT2SAS_SG_DEPTH value based on user input. | 79 | * Set MPT2SAS_SG_DEPTH value based on user input. |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index f12e02358d6d..a7dbc6825f5f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -113,6 +113,7 @@ struct sense_info { | |||
113 | }; | 113 | }; |
114 | 114 | ||
115 | 115 | ||
116 | #define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) | ||
116 | #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) | 117 | #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) |
117 | 118 | ||
118 | /** | 119 | /** |
@@ -121,6 +122,7 @@ struct sense_info { | |||
121 | * @work: work object (ioc->fault_reset_work_q) | 122 | * @work: work object (ioc->fault_reset_work_q) |
122 | * @cancel_pending_work: flag set during reset handling | 123 | * @cancel_pending_work: flag set during reset handling |
123 | * @ioc: per adapter object | 124 | * @ioc: per adapter object |
125 | * @device_handle: device handle | ||
124 | * @VF_ID: virtual function id | 126 | * @VF_ID: virtual function id |
125 | * @VP_ID: virtual port id | 127 | * @VP_ID: virtual port id |
126 | * @ignore: flag meaning this event has been marked to ignore | 128 | * @ignore: flag meaning this event has been marked to ignore |
@@ -134,6 +136,7 @@ struct fw_event_work { | |||
134 | u8 cancel_pending_work; | 136 | u8 cancel_pending_work; |
135 | struct delayed_work delayed_work; | 137 | struct delayed_work delayed_work; |
136 | struct MPT2SAS_ADAPTER *ioc; | 138 | struct MPT2SAS_ADAPTER *ioc; |
139 | u16 device_handle; | ||
137 | u8 VF_ID; | 140 | u8 VF_ID; |
138 | u8 VP_ID; | 141 | u8 VP_ID; |
139 | u8 ignore; | 142 | u8 ignore; |
@@ -3499,6 +3502,7 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
3499 | 3502 | ||
3500 | switch (prot_type) { | 3503 | switch (prot_type) { |
3501 | case SCSI_PROT_DIF_TYPE1: | 3504 | case SCSI_PROT_DIF_TYPE1: |
3505 | case SCSI_PROT_DIF_TYPE2: | ||
3502 | 3506 | ||
3503 | /* | 3507 | /* |
3504 | * enable ref/guard checking | 3508 | * enable ref/guard checking |
@@ -3511,13 +3515,6 @@ _scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request) | |||
3511 | cpu_to_be32(scsi_get_lba(scmd)); | 3515 | cpu_to_be32(scsi_get_lba(scmd)); |
3512 | break; | 3516 | break; |
3513 | 3517 | ||
3514 | case SCSI_PROT_DIF_TYPE2: | ||
3515 | |||
3516 | eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | | ||
3517 | MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | | ||
3518 | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; | ||
3519 | break; | ||
3520 | |||
3521 | case SCSI_PROT_DIF_TYPE3: | 3518 | case SCSI_PROT_DIF_TYPE3: |
3522 | 3519 | ||
3523 | /* | 3520 | /* |
@@ -4047,17 +4044,75 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
4047 | #endif | 4044 | #endif |
4048 | 4045 | ||
4049 | /** | 4046 | /** |
4050 | * _scsih_smart_predicted_fault - illuminate Fault LED | 4047 | * _scsih_turn_on_fault_led - illuminate Fault LED |
4051 | * @ioc: per adapter object | 4048 | * @ioc: per adapter object |
4052 | * @handle: device handle | 4049 | * @handle: device handle |
4050 | * Context: process | ||
4053 | * | 4051 | * |
4054 | * Return nothing. | 4052 | * Return nothing. |
4055 | */ | 4053 | */ |
4056 | static void | 4054 | static void |
4057 | _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 4055 | _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) |
4058 | { | 4056 | { |
4059 | Mpi2SepReply_t mpi_reply; | 4057 | Mpi2SepReply_t mpi_reply; |
4060 | Mpi2SepRequest_t mpi_request; | 4058 | Mpi2SepRequest_t mpi_request; |
4059 | |||
4060 | memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); | ||
4061 | mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | ||
4062 | mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; | ||
4063 | mpi_request.SlotStatus = | ||
4064 | cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); | ||
4065 | mpi_request.DevHandle = cpu_to_le16(handle); | ||
4066 | mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; | ||
4067 | if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, | ||
4068 | &mpi_request)) != 0) { | ||
4069 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, | ||
4070 | __FILE__, __LINE__, __func__); | ||
4071 | return; | ||
4072 | } | ||
4073 | |||
4074 | if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { | ||
4075 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: " | ||
4076 | "ioc_status (0x%04x), loginfo(0x%08x)\n", ioc->name, | ||
4077 | le16_to_cpu(mpi_reply.IOCStatus), | ||
4078 | le32_to_cpu(mpi_reply.IOCLogInfo))); | ||
4079 | return; | ||
4080 | } | ||
4081 | } | ||
4082 | |||
4083 | /** | ||
4084 | * _scsih_send_event_to_turn_on_fault_led - fire delayed event | ||
4085 | * @ioc: per adapter object | ||
4086 | * @handle: device handle | ||
4087 | * Context: interrupt. | ||
4088 | * | ||
4089 | * Return nothing. | ||
4090 | */ | ||
4091 | static void | ||
4092 | _scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
4093 | { | ||
4094 | struct fw_event_work *fw_event; | ||
4095 | |||
4096 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | ||
4097 | if (!fw_event) | ||
4098 | return; | ||
4099 | fw_event->event = MPT2SAS_TURN_ON_FAULT_LED; | ||
4100 | fw_event->device_handle = handle; | ||
4101 | fw_event->ioc = ioc; | ||
4102 | _scsih_fw_event_add(ioc, fw_event); | ||
4103 | } | ||
4104 | |||
4105 | /** | ||
4106 | * _scsih_smart_predicted_fault - process smart errors | ||
4107 | * @ioc: per adapter object | ||
4108 | * @handle: device handle | ||
4109 | * Context: interrupt. | ||
4110 | * | ||
4111 | * Return nothing. | ||
4112 | */ | ||
4113 | static void | ||
4114 | _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
4115 | { | ||
4061 | struct scsi_target *starget; | 4116 | struct scsi_target *starget; |
4062 | struct MPT2SAS_TARGET *sas_target_priv_data; | 4117 | struct MPT2SAS_TARGET *sas_target_priv_data; |
4063 | Mpi2EventNotificationReply_t *event_reply; | 4118 | Mpi2EventNotificationReply_t *event_reply; |
@@ -4084,30 +4139,8 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4084 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); | 4139 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); |
4085 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4140 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4086 | 4141 | ||
4087 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) { | 4142 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) |
4088 | memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); | 4143 | _scsih_send_event_to_turn_on_fault_led(ioc, handle); |
4089 | mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | ||
4090 | mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; | ||
4091 | mpi_request.SlotStatus = | ||
4092 | cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); | ||
4093 | mpi_request.DevHandle = cpu_to_le16(handle); | ||
4094 | mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; | ||
4095 | if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, | ||
4096 | &mpi_request)) != 0) { | ||
4097 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
4098 | ioc->name, __FILE__, __LINE__, __func__); | ||
4099 | return; | ||
4100 | } | ||
4101 | |||
4102 | if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { | ||
4103 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
4104 | "enclosure_processor: ioc_status (0x%04x), " | ||
4105 | "loginfo(0x%08x)\n", ioc->name, | ||
4106 | le16_to_cpu(mpi_reply.IOCStatus), | ||
4107 | le32_to_cpu(mpi_reply.IOCLogInfo))); | ||
4108 | return; | ||
4109 | } | ||
4110 | } | ||
4111 | 4144 | ||
4112 | /* insert into event log */ | 4145 | /* insert into event log */ |
4113 | sz = offsetof(Mpi2EventNotificationReply_t, EventData) + | 4146 | sz = offsetof(Mpi2EventNotificationReply_t, EventData) + |
@@ -6753,6 +6786,9 @@ _firmware_event_work(struct work_struct *work) | |||
6753 | } | 6786 | } |
6754 | 6787 | ||
6755 | switch (fw_event->event) { | 6788 | switch (fw_event->event) { |
6789 | case MPT2SAS_TURN_ON_FAULT_LED: | ||
6790 | _scsih_turn_on_fault_led(ioc, fw_event->device_handle); | ||
6791 | break; | ||
6756 | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: | 6792 | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: |
6757 | _scsih_sas_topology_change_event(ioc, fw_event); | 6793 | _scsih_sas_topology_change_event(ioc, fw_event); |
6758 | break; | 6794 | break; |
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 58f5be4740e9..de0b1a704fb5 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c | |||
@@ -4698,12 +4698,14 @@ static int __os_scsi_tape_open(struct inode * inode, struct file * filp) | |||
4698 | break; | 4698 | break; |
4699 | 4699 | ||
4700 | if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { | 4700 | if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { |
4701 | int j; | ||
4702 | |||
4701 | STp->pos_unknown = 0; | 4703 | STp->pos_unknown = 0; |
4702 | STp->partition = STp->new_partition = 0; | 4704 | STp->partition = STp->new_partition = 0; |
4703 | if (STp->can_partitions) | 4705 | if (STp->can_partitions) |
4704 | STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ | 4706 | STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ |
4705 | for (i=0; i < ST_NBR_PARTITIONS; i++) { | 4707 | for (j = 0; j < ST_NBR_PARTITIONS; j++) { |
4706 | STps = &(STp->ps[i]); | 4708 | STps = &(STp->ps[j]); |
4707 | STps->rw = ST_IDLE; | 4709 | STps->rw = ST_IDLE; |
4708 | STps->eof = ST_NOEOF; | 4710 | STps->eof = ST_NOEOF; |
4709 | STps->at_sm = 0; | 4711 | STps->at_sm = 0; |
diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile index 0339ff03a535..252523d7847e 100644 --- a/drivers/scsi/qla4xxx/Makefile +++ b/drivers/scsi/qla4xxx/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ | 1 | qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ |
2 | ql4_nx.o ql4_nvram.o ql4_dbg.o | 2 | ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o |
3 | 3 | ||
4 | obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o | 4 | obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o |
5 | 5 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c new file mode 100644 index 000000000000..864d018631c0 --- /dev/null +++ b/drivers/scsi/qla4xxx/ql4_attr.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * QLogic iSCSI HBA Driver | ||
3 | * Copyright (c) 2003-2011 QLogic Corporation | ||
4 | * | ||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | ||
6 | */ | ||
7 | |||
8 | #include "ql4_def.h" | ||
9 | #include "ql4_glbl.h" | ||
10 | #include "ql4_dbg.h" | ||
11 | |||
12 | /* Scsi_Host attributes. */ | ||
13 | static ssize_t | ||
14 | qla4xxx_fw_version_show(struct device *dev, | ||
15 | struct device_attribute *attr, char *buf) | ||
16 | { | ||
17 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
18 | |||
19 | if (is_qla8022(ha)) | ||
20 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", | ||
21 | ha->firmware_version[0], | ||
22 | ha->firmware_version[1], | ||
23 | ha->patch_number, ha->build_number); | ||
24 | else | ||
25 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d.%02d\n", | ||
26 | ha->firmware_version[0], | ||
27 | ha->firmware_version[1], | ||
28 | ha->patch_number, ha->build_number); | ||
29 | } | ||
30 | |||
31 | static ssize_t | ||
32 | qla4xxx_serial_num_show(struct device *dev, struct device_attribute *attr, | ||
33 | char *buf) | ||
34 | { | ||
35 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
36 | return snprintf(buf, PAGE_SIZE, "%s\n", ha->serial_number); | ||
37 | } | ||
38 | |||
39 | static ssize_t | ||
40 | qla4xxx_iscsi_version_show(struct device *dev, struct device_attribute *attr, | ||
41 | char *buf) | ||
42 | { | ||
43 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
44 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->iscsi_major, | ||
45 | ha->iscsi_minor); | ||
46 | } | ||
47 | |||
48 | static ssize_t | ||
49 | qla4xxx_optrom_version_show(struct device *dev, struct device_attribute *attr, | ||
50 | char *buf) | ||
51 | { | ||
52 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
53 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d.%02d\n", | ||
54 | ha->bootload_major, ha->bootload_minor, | ||
55 | ha->bootload_patch, ha->bootload_build); | ||
56 | } | ||
57 | |||
58 | static DEVICE_ATTR(fw_version, S_IRUGO, qla4xxx_fw_version_show, NULL); | ||
59 | static DEVICE_ATTR(serial_num, S_IRUGO, qla4xxx_serial_num_show, NULL); | ||
60 | static DEVICE_ATTR(iscsi_version, S_IRUGO, qla4xxx_iscsi_version_show, NULL); | ||
61 | static DEVICE_ATTR(optrom_version, S_IRUGO, qla4xxx_optrom_version_show, NULL); | ||
62 | |||
63 | struct device_attribute *qla4xxx_host_attrs[] = { | ||
64 | &dev_attr_fw_version, | ||
65 | &dev_attr_serial_num, | ||
66 | &dev_attr_iscsi_version, | ||
67 | &dev_attr_optrom_version, | ||
68 | NULL, | ||
69 | }; | ||
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 4757878d59dd..473c5c872b39 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -115,7 +115,7 @@ | |||
115 | #define INVALID_ENTRY 0xFFFF | 115 | #define INVALID_ENTRY 0xFFFF |
116 | #define MAX_CMDS_TO_RISC 1024 | 116 | #define MAX_CMDS_TO_RISC 1024 |
117 | #define MAX_SRBS MAX_CMDS_TO_RISC | 117 | #define MAX_SRBS MAX_CMDS_TO_RISC |
118 | #define MBOX_AEN_REG_COUNT 5 | 118 | #define MBOX_AEN_REG_COUNT 8 |
119 | #define MAX_INIT_RETRIES 5 | 119 | #define MAX_INIT_RETRIES 5 |
120 | 120 | ||
121 | /* | 121 | /* |
@@ -368,7 +368,6 @@ struct scsi_qla_host { | |||
368 | #define AF_INIT_DONE 1 /* 0x00000002 */ | 368 | #define AF_INIT_DONE 1 /* 0x00000002 */ |
369 | #define AF_MBOX_COMMAND 2 /* 0x00000004 */ | 369 | #define AF_MBOX_COMMAND 2 /* 0x00000004 */ |
370 | #define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */ | 370 | #define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */ |
371 | #define AF_DPC_SCHEDULED 5 /* 0x00000020 */ | ||
372 | #define AF_INTERRUPTS_ON 6 /* 0x00000040 */ | 371 | #define AF_INTERRUPTS_ON 6 /* 0x00000040 */ |
373 | #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ | 372 | #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ |
374 | #define AF_LINK_UP 8 /* 0x00000100 */ | 373 | #define AF_LINK_UP 8 /* 0x00000100 */ |
@@ -584,6 +583,14 @@ struct scsi_qla_host { | |||
584 | uint32_t nx_reset_timeout; | 583 | uint32_t nx_reset_timeout; |
585 | 584 | ||
586 | struct completion mbx_intr_comp; | 585 | struct completion mbx_intr_comp; |
586 | |||
587 | /* --- From About Firmware --- */ | ||
588 | uint16_t iscsi_major; | ||
589 | uint16_t iscsi_minor; | ||
590 | uint16_t bootload_major; | ||
591 | uint16_t bootload_minor; | ||
592 | uint16_t bootload_patch; | ||
593 | uint16_t bootload_build; | ||
587 | }; | 594 | }; |
588 | 595 | ||
589 | static inline int is_ipv4_enabled(struct scsi_qla_host *ha) | 596 | static inline int is_ipv4_enabled(struct scsi_qla_host *ha) |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 31e2bf97198c..01082aa77098 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -690,6 +690,29 @@ struct mbx_sys_info { | |||
690 | uint8_t reserved[12]; /* 34-3f */ | 690 | uint8_t reserved[12]; /* 34-3f */ |
691 | }; | 691 | }; |
692 | 692 | ||
693 | struct about_fw_info { | ||
694 | uint16_t fw_major; /* 00 - 01 */ | ||
695 | uint16_t fw_minor; /* 02 - 03 */ | ||
696 | uint16_t fw_patch; /* 04 - 05 */ | ||
697 | uint16_t fw_build; /* 06 - 07 */ | ||
698 | uint8_t fw_build_date[16]; /* 08 - 17 ASCII String */ | ||
699 | uint8_t fw_build_time[16]; /* 18 - 27 ASCII String */ | ||
700 | uint8_t fw_build_user[16]; /* 28 - 37 ASCII String */ | ||
701 | uint16_t fw_load_source; /* 38 - 39 */ | ||
702 | /* 1 = Flash Primary, | ||
703 | 2 = Flash Secondary, | ||
704 | 3 = Host Download | ||
705 | */ | ||
706 | uint8_t reserved1[6]; /* 3A - 3F */ | ||
707 | uint16_t iscsi_major; /* 40 - 41 */ | ||
708 | uint16_t iscsi_minor; /* 42 - 43 */ | ||
709 | uint16_t bootload_major; /* 44 - 45 */ | ||
710 | uint16_t bootload_minor; /* 46 - 47 */ | ||
711 | uint16_t bootload_patch; /* 48 - 49 */ | ||
712 | uint16_t bootload_build; /* 4A - 4B */ | ||
713 | uint8_t reserved2[180]; /* 4C - FF */ | ||
714 | }; | ||
715 | |||
693 | struct crash_record { | 716 | struct crash_record { |
694 | uint16_t fw_major_version; /* 00 - 01 */ | 717 | uint16_t fw_major_version; /* 00 - 01 */ |
695 | uint16_t fw_minor_version; /* 02 - 03 */ | 718 | uint16_t fw_minor_version; /* 02 - 03 */ |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index cc53e3fbd78c..a53a256c1f8d 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -61,7 +61,7 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha); | |||
61 | int qla4xxx_add_sess(struct ddb_entry *); | 61 | int qla4xxx_add_sess(struct ddb_entry *); |
62 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); | 62 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); |
63 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); | 63 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); |
64 | int qla4xxx_get_fw_version(struct scsi_qla_host * ha); | 64 | int qla4xxx_about_firmware(struct scsi_qla_host *ha); |
65 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, | 65 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, |
66 | uint32_t intr_status); | 66 | uint32_t intr_status); |
67 | int qla4xxx_init_rings(struct scsi_qla_host *ha); | 67 | int qla4xxx_init_rings(struct scsi_qla_host *ha); |
@@ -139,4 +139,5 @@ extern int ql4xextended_error_logging; | |||
139 | extern int ql4xdontresethba; | 139 | extern int ql4xdontresethba; |
140 | extern int ql4xenablemsix; | 140 | extern int ql4xenablemsix; |
141 | 141 | ||
142 | extern struct device_attribute *qla4xxx_host_attrs[]; | ||
142 | #endif /* _QLA4x_GBL_H */ | 143 | #endif /* _QLA4x_GBL_H */ |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 48e2241ddaf4..42ed5db2d530 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -1275,7 +1275,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1275 | if (ha->isp_ops->start_firmware(ha) == QLA_ERROR) | 1275 | if (ha->isp_ops->start_firmware(ha) == QLA_ERROR) |
1276 | goto exit_init_hba; | 1276 | goto exit_init_hba; |
1277 | 1277 | ||
1278 | if (qla4xxx_get_fw_version(ha) == QLA_ERROR) | 1278 | if (qla4xxx_about_firmware(ha) == QLA_ERROR) |
1279 | goto exit_init_hba; | 1279 | goto exit_init_hba; |
1280 | 1280 | ||
1281 | if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR) | 1281 | if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR) |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 2f40ac761cd4..0e72921c752d 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
@@ -25,9 +25,14 @@ static void qla4xxx_copy_sense(struct scsi_qla_host *ha, | |||
25 | 25 | ||
26 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 26 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
27 | sense_len = le16_to_cpu(sts_entry->senseDataByteCnt); | 27 | sense_len = le16_to_cpu(sts_entry->senseDataByteCnt); |
28 | if (sense_len == 0) | 28 | if (sense_len == 0) { |
29 | DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d:%d: %s:" | ||
30 | " sense len 0\n", ha->host_no, | ||
31 | cmd->device->channel, cmd->device->id, | ||
32 | cmd->device->lun, __func__)); | ||
33 | ha->status_srb = NULL; | ||
29 | return; | 34 | return; |
30 | 35 | } | |
31 | /* Save total available sense length, | 36 | /* Save total available sense length, |
32 | * not to exceed cmd's sense buffer size */ | 37 | * not to exceed cmd's sense buffer size */ |
33 | sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE); | 38 | sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE); |
@@ -541,6 +546,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, | |||
541 | case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED: /* Connection mode */ | 546 | case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED: /* Connection mode */ |
542 | case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR: | 547 | case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR: |
543 | case MBOX_ASTS_SUBNET_STATE_CHANGE: | 548 | case MBOX_ASTS_SUBNET_STATE_CHANGE: |
549 | case MBOX_ASTS_DUPLICATE_IP: | ||
544 | /* No action */ | 550 | /* No action */ |
545 | DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no, | 551 | DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no, |
546 | mbox_status)); | 552 | mbox_status)); |
@@ -593,11 +599,13 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, | |||
593 | mbox_sts[i]; | 599 | mbox_sts[i]; |
594 | 600 | ||
595 | /* print debug message */ | 601 | /* print debug message */ |
596 | DEBUG2(printk("scsi%ld: AEN[%d] %04x queued" | 602 | DEBUG2(printk("scsi%ld: AEN[%d] %04x queued " |
597 | " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n", | 603 | "mb1:0x%x mb2:0x%x mb3:0x%x " |
598 | ha->host_no, ha->aen_in, mbox_sts[0], | 604 | "mb4:0x%x mb5:0x%x\n", |
599 | mbox_sts[1], mbox_sts[2], mbox_sts[3], | 605 | ha->host_no, ha->aen_in, |
600 | mbox_sts[4])); | 606 | mbox_sts[0], mbox_sts[1], |
607 | mbox_sts[2], mbox_sts[3], | ||
608 | mbox_sts[4], mbox_sts[5])); | ||
601 | 609 | ||
602 | /* advance pointer */ | 610 | /* advance pointer */ |
603 | ha->aen_in++; | 611 | ha->aen_in++; |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index d78b58dc5011..fce8289e9752 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -86,22 +86,8 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
86 | msleep(10); | 86 | msleep(10); |
87 | } | 87 | } |
88 | 88 | ||
89 | /* To prevent overwriting mailbox registers for a command that has | ||
90 | * not yet been serviced, check to see if an active command | ||
91 | * (AEN, IOCB, etc.) is interrupting, then service it. | ||
92 | * ----------------------------------------------------------------- | ||
93 | */ | ||
94 | spin_lock_irqsave(&ha->hardware_lock, flags); | 89 | spin_lock_irqsave(&ha->hardware_lock, flags); |
95 | 90 | ||
96 | if (!is_qla8022(ha)) { | ||
97 | intr_status = readl(&ha->reg->ctrl_status); | ||
98 | if (intr_status & CSR_SCSI_PROCESSOR_INTR) { | ||
99 | /* Service existing interrupt */ | ||
100 | ha->isp_ops->interrupt_service_routine(ha, intr_status); | ||
101 | clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | ha->mbox_status_count = outCount; | 91 | ha->mbox_status_count = outCount; |
106 | for (i = 0; i < outCount; i++) | 92 | for (i = 0; i < outCount; i++) |
107 | ha->mbox_status[i] = 0; | 93 | ha->mbox_status[i] = 0; |
@@ -1057,38 +1043,65 @@ int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | |||
1057 | } | 1043 | } |
1058 | 1044 | ||
1059 | /** | 1045 | /** |
1060 | * qla4xxx_get_fw_version - gets firmware version | 1046 | * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version |
1061 | * @ha: Pointer to host adapter structure. | 1047 | * @ha: Pointer to host adapter structure. |
1062 | * | 1048 | * |
1063 | * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may | 1049 | * Retrieves the FW version, iSCSI draft version & bootloader version of HBA. |
1064 | * hold an address for data. Make sure that we write 0 to those mailboxes, | 1050 | * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to |
1065 | * if unused. | 1051 | * those mailboxes, if unused. |
1066 | **/ | 1052 | **/ |
1067 | int qla4xxx_get_fw_version(struct scsi_qla_host * ha) | 1053 | int qla4xxx_about_firmware(struct scsi_qla_host *ha) |
1068 | { | 1054 | { |
1055 | struct about_fw_info *about_fw = NULL; | ||
1056 | dma_addr_t about_fw_dma; | ||
1069 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | 1057 | uint32_t mbox_cmd[MBOX_REG_COUNT]; |
1070 | uint32_t mbox_sts[MBOX_REG_COUNT]; | 1058 | uint32_t mbox_sts[MBOX_REG_COUNT]; |
1059 | int status = QLA_ERROR; | ||
1060 | |||
1061 | about_fw = dma_alloc_coherent(&ha->pdev->dev, | ||
1062 | sizeof(struct about_fw_info), | ||
1063 | &about_fw_dma, GFP_KERNEL); | ||
1064 | if (!about_fw) { | ||
1065 | DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory " | ||
1066 | "for about_fw\n", __func__)); | ||
1067 | return status; | ||
1068 | } | ||
1071 | 1069 | ||
1072 | /* Get firmware version. */ | 1070 | memset(about_fw, 0, sizeof(struct about_fw_info)); |
1073 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | 1071 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); |
1074 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | 1072 | memset(&mbox_sts, 0, sizeof(mbox_sts)); |
1075 | 1073 | ||
1076 | mbox_cmd[0] = MBOX_CMD_ABOUT_FW; | 1074 | mbox_cmd[0] = MBOX_CMD_ABOUT_FW; |
1077 | 1075 | mbox_cmd[2] = LSDW(about_fw_dma); | |
1078 | if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != | 1076 | mbox_cmd[3] = MSDW(about_fw_dma); |
1079 | QLA_SUCCESS) { | 1077 | mbox_cmd[4] = sizeof(struct about_fw_info); |
1080 | DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ " | 1078 | |
1081 | "status %04X\n", ha->host_no, __func__, mbox_sts[0])); | 1079 | status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT, |
1082 | return QLA_ERROR; | 1080 | &mbox_cmd[0], &mbox_sts[0]); |
1081 | if (status != QLA_SUCCESS) { | ||
1082 | DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW " | ||
1083 | "failed w/ status %04X\n", __func__, | ||
1084 | mbox_sts[0])); | ||
1085 | goto exit_about_fw; | ||
1083 | } | 1086 | } |
1084 | 1087 | ||
1085 | /* Save firmware version information. */ | 1088 | /* Save version information. */ |
1086 | ha->firmware_version[0] = mbox_sts[1]; | 1089 | ha->firmware_version[0] = le16_to_cpu(about_fw->fw_major); |
1087 | ha->firmware_version[1] = mbox_sts[2]; | 1090 | ha->firmware_version[1] = le16_to_cpu(about_fw->fw_minor); |
1088 | ha->patch_number = mbox_sts[3]; | 1091 | ha->patch_number = le16_to_cpu(about_fw->fw_patch); |
1089 | ha->build_number = mbox_sts[4]; | 1092 | ha->build_number = le16_to_cpu(about_fw->fw_build); |
1093 | ha->iscsi_major = le16_to_cpu(about_fw->iscsi_major); | ||
1094 | ha->iscsi_minor = le16_to_cpu(about_fw->iscsi_minor); | ||
1095 | ha->bootload_major = le16_to_cpu(about_fw->bootload_major); | ||
1096 | ha->bootload_minor = le16_to_cpu(about_fw->bootload_minor); | ||
1097 | ha->bootload_patch = le16_to_cpu(about_fw->bootload_patch); | ||
1098 | ha->bootload_build = le16_to_cpu(about_fw->bootload_build); | ||
1099 | status = QLA_SUCCESS; | ||
1090 | 1100 | ||
1091 | return QLA_SUCCESS; | 1101 | exit_about_fw: |
1102 | dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info), | ||
1103 | about_fw, about_fw_dma); | ||
1104 | return status; | ||
1092 | } | 1105 | } |
1093 | 1106 | ||
1094 | static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, | 1107 | static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, |
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 03e522b2fe0b..fdfe27b38698 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c | |||
@@ -964,12 +964,26 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose) | |||
964 | /* Halt all the indiviual PEGs and other blocks of the ISP */ | 964 | /* Halt all the indiviual PEGs and other blocks of the ISP */ |
965 | qla4_8xxx_rom_lock(ha); | 965 | qla4_8xxx_rom_lock(ha); |
966 | 966 | ||
967 | /* mask all niu interrupts */ | 967 | /* disable all I2Q */ |
968 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0); | ||
969 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0); | ||
970 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0); | ||
971 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0); | ||
972 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0); | ||
973 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0); | ||
974 | |||
975 | /* disable all niu interrupts */ | ||
968 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff); | 976 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff); |
969 | /* disable xge rx/tx */ | 977 | /* disable xge rx/tx */ |
970 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00); | 978 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00); |
971 | /* disable xg1 rx/tx */ | 979 | /* disable xg1 rx/tx */ |
972 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00); | 980 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00); |
981 | /* disable sideband mac */ | ||
982 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00); | ||
983 | /* disable ap0 mac */ | ||
984 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00); | ||
985 | /* disable ap1 mac */ | ||
986 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00); | ||
973 | 987 | ||
974 | /* halt sre */ | 988 | /* halt sre */ |
975 | val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000); | 989 | val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000); |
@@ -984,6 +998,7 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose) | |||
984 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0); | 998 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0); |
985 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0); | 999 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0); |
986 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0); | 1000 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0); |
1001 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0); | ||
987 | 1002 | ||
988 | /* halt pegs */ | 1003 | /* halt pegs */ |
989 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1); | 1004 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1); |
@@ -991,9 +1006,9 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose) | |||
991 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1); | 1006 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1); |
992 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1); | 1007 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1); |
993 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1); | 1008 | qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1); |
1009 | msleep(5); | ||
994 | 1010 | ||
995 | /* big hammer */ | 1011 | /* big hammer */ |
996 | msleep(1000); | ||
997 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) | 1012 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) |
998 | /* don't reset CAM block on reset */ | 1013 | /* don't reset CAM block on reset */ |
999 | qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff); | 1014 | qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff); |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index c22f2a764d9d..f2364ec59f03 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -124,6 +124,7 @@ static struct scsi_host_template qla4xxx_driver_template = { | |||
124 | .sg_tablesize = SG_ALL, | 124 | .sg_tablesize = SG_ALL, |
125 | 125 | ||
126 | .max_sectors = 0xFFFF, | 126 | .max_sectors = 0xFFFF, |
127 | .shost_attrs = qla4xxx_host_attrs, | ||
127 | }; | 128 | }; |
128 | 129 | ||
129 | static struct iscsi_transport qla4xxx_iscsi_transport = { | 130 | static struct iscsi_transport qla4xxx_iscsi_transport = { |
@@ -412,8 +413,7 @@ void qla4xxx_mark_all_devices_missing(struct scsi_qla_host *ha) | |||
412 | 413 | ||
413 | static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, | 414 | static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, |
414 | struct ddb_entry *ddb_entry, | 415 | struct ddb_entry *ddb_entry, |
415 | struct scsi_cmnd *cmd, | 416 | struct scsi_cmnd *cmd) |
416 | void (*done)(struct scsi_cmnd *)) | ||
417 | { | 417 | { |
418 | struct srb *srb; | 418 | struct srb *srb; |
419 | 419 | ||
@@ -427,7 +427,6 @@ static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, | |||
427 | srb->cmd = cmd; | 427 | srb->cmd = cmd; |
428 | srb->flags = 0; | 428 | srb->flags = 0; |
429 | CMD_SP(cmd) = (void *)srb; | 429 | CMD_SP(cmd) = (void *)srb; |
430 | cmd->scsi_done = done; | ||
431 | 430 | ||
432 | return srb; | 431 | return srb; |
433 | } | 432 | } |
@@ -458,9 +457,8 @@ void qla4xxx_srb_compl(struct kref *ref) | |||
458 | 457 | ||
459 | /** | 458 | /** |
460 | * qla4xxx_queuecommand - scsi layer issues scsi command to driver. | 459 | * qla4xxx_queuecommand - scsi layer issues scsi command to driver. |
460 | * @host: scsi host | ||
461 | * @cmd: Pointer to Linux's SCSI command structure | 461 | * @cmd: Pointer to Linux's SCSI command structure |
462 | * @done_fn: Function that the driver calls to notify the SCSI mid-layer | ||
463 | * that the command has been processed. | ||
464 | * | 462 | * |
465 | * Remarks: | 463 | * Remarks: |
466 | * This routine is invoked by Linux to send a SCSI command to the driver. | 464 | * This routine is invoked by Linux to send a SCSI command to the driver. |
@@ -470,10 +468,9 @@ void qla4xxx_srb_compl(struct kref *ref) | |||
470 | * completion handling). Unfortunely, it sometimes calls the scheduler | 468 | * completion handling). Unfortunely, it sometimes calls the scheduler |
471 | * in interrupt context which is a big NO! NO!. | 469 | * in interrupt context which is a big NO! NO!. |
472 | **/ | 470 | **/ |
473 | static int qla4xxx_queuecommand_lck(struct scsi_cmnd *cmd, | 471 | static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
474 | void (*done)(struct scsi_cmnd *)) | ||
475 | { | 472 | { |
476 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | 473 | struct scsi_qla_host *ha = to_qla_host(host); |
477 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | 474 | struct ddb_entry *ddb_entry = cmd->device->hostdata; |
478 | struct iscsi_cls_session *sess = ddb_entry->sess; | 475 | struct iscsi_cls_session *sess = ddb_entry->sess; |
479 | struct srb *srb; | 476 | struct srb *srb; |
@@ -515,37 +512,29 @@ static int qla4xxx_queuecommand_lck(struct scsi_cmnd *cmd, | |||
515 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) | 512 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) |
516 | goto qc_host_busy; | 513 | goto qc_host_busy; |
517 | 514 | ||
518 | spin_unlock_irq(ha->host->host_lock); | 515 | srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd); |
519 | |||
520 | srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done); | ||
521 | if (!srb) | 516 | if (!srb) |
522 | goto qc_host_busy_lock; | 517 | goto qc_host_busy; |
523 | 518 | ||
524 | rval = qla4xxx_send_command_to_isp(ha, srb); | 519 | rval = qla4xxx_send_command_to_isp(ha, srb); |
525 | if (rval != QLA_SUCCESS) | 520 | if (rval != QLA_SUCCESS) |
526 | goto qc_host_busy_free_sp; | 521 | goto qc_host_busy_free_sp; |
527 | 522 | ||
528 | spin_lock_irq(ha->host->host_lock); | ||
529 | return 0; | 523 | return 0; |
530 | 524 | ||
531 | qc_host_busy_free_sp: | 525 | qc_host_busy_free_sp: |
532 | qla4xxx_srb_free_dma(ha, srb); | 526 | qla4xxx_srb_free_dma(ha, srb); |
533 | mempool_free(srb, ha->srb_mempool); | 527 | mempool_free(srb, ha->srb_mempool); |
534 | 528 | ||
535 | qc_host_busy_lock: | ||
536 | spin_lock_irq(ha->host->host_lock); | ||
537 | |||
538 | qc_host_busy: | 529 | qc_host_busy: |
539 | return SCSI_MLQUEUE_HOST_BUSY; | 530 | return SCSI_MLQUEUE_HOST_BUSY; |
540 | 531 | ||
541 | qc_fail_command: | 532 | qc_fail_command: |
542 | done(cmd); | 533 | cmd->scsi_done(cmd); |
543 | 534 | ||
544 | return 0; | 535 | return 0; |
545 | } | 536 | } |
546 | 537 | ||
547 | static DEF_SCSI_QCMD(qla4xxx_queuecommand) | ||
548 | |||
549 | /** | 538 | /** |
550 | * qla4xxx_mem_free - frees memory allocated to adapter | 539 | * qla4xxx_mem_free - frees memory allocated to adapter |
551 | * @ha: Pointer to host adapter structure. | 540 | * @ha: Pointer to host adapter structure. |
@@ -679,7 +668,27 @@ static void qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) | |||
679 | if (ha->seconds_since_last_heartbeat == 2) { | 668 | if (ha->seconds_since_last_heartbeat == 2) { |
680 | ha->seconds_since_last_heartbeat = 0; | 669 | ha->seconds_since_last_heartbeat = 0; |
681 | halt_status = qla4_8xxx_rd_32(ha, | 670 | halt_status = qla4_8xxx_rd_32(ha, |
682 | QLA82XX_PEG_HALT_STATUS1); | 671 | QLA82XX_PEG_HALT_STATUS1); |
672 | |||
673 | ql4_printk(KERN_INFO, ha, | ||
674 | "scsi(%ld): %s, Dumping hw/fw registers:\n " | ||
675 | " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:" | ||
676 | " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:" | ||
677 | " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:" | ||
678 | " 0x%x,\n PEG_NET_4_PC: 0x%x\n", | ||
679 | ha->host_no, __func__, halt_status, | ||
680 | qla4_8xxx_rd_32(ha, | ||
681 | QLA82XX_PEG_HALT_STATUS2), | ||
682 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 + | ||
683 | 0x3c), | ||
684 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 + | ||
685 | 0x3c), | ||
686 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 + | ||
687 | 0x3c), | ||
688 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 + | ||
689 | 0x3c), | ||
690 | qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 + | ||
691 | 0x3c)); | ||
683 | 692 | ||
684 | /* Since we cannot change dev_state in interrupt | 693 | /* Since we cannot change dev_state in interrupt |
685 | * context, set appropriate DPC flag then wakeup | 694 | * context, set appropriate DPC flag then wakeup |
@@ -715,7 +724,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | |||
715 | /* don't poll if reset is going on */ | 724 | /* don't poll if reset is going on */ |
716 | if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || | 725 | if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || |
717 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 726 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
718 | test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags))) { | 727 | test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) { |
719 | if (dev_state == QLA82XX_DEV_NEED_RESET && | 728 | if (dev_state == QLA82XX_DEV_NEED_RESET && |
720 | !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { | 729 | !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { |
721 | if (!ql4xdontresethba) { | 730 | if (!ql4xdontresethba) { |
@@ -839,7 +848,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |||
839 | } | 848 | } |
840 | 849 | ||
841 | /* Wakeup the dpc routine for this adapter, if needed. */ | 850 | /* Wakeup the dpc routine for this adapter, if needed. */ |
842 | if ((start_dpc || | 851 | if (start_dpc || |
843 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 852 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
844 | test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) || | 853 | test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) || |
845 | test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) || | 854 | test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) || |
@@ -849,9 +858,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |||
849 | test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) || | 858 | test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) || |
850 | test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) || | 859 | test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) || |
851 | test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) || | 860 | test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) || |
852 | test_bit(DPC_AEN, &ha->dpc_flags)) && | 861 | test_bit(DPC_AEN, &ha->dpc_flags)) { |
853 | !test_bit(AF_DPC_SCHEDULED, &ha->flags) && | ||
854 | ha->dpc_thread) { | ||
855 | DEBUG2(printk("scsi%ld: %s: scheduling dpc routine" | 862 | DEBUG2(printk("scsi%ld: %s: scheduling dpc routine" |
856 | " - dpc flags = 0x%lx\n", | 863 | " - dpc flags = 0x%lx\n", |
857 | ha->host_no, __func__, ha->dpc_flags)); | 864 | ha->host_no, __func__, ha->dpc_flags)); |
@@ -1241,11 +1248,8 @@ static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) | |||
1241 | 1248 | ||
1242 | void qla4xxx_wake_dpc(struct scsi_qla_host *ha) | 1249 | void qla4xxx_wake_dpc(struct scsi_qla_host *ha) |
1243 | { | 1250 | { |
1244 | if (ha->dpc_thread && | 1251 | if (ha->dpc_thread) |
1245 | !test_bit(AF_DPC_SCHEDULED, &ha->flags)) { | ||
1246 | set_bit(AF_DPC_SCHEDULED, &ha->flags); | ||
1247 | queue_work(ha->dpc_thread, &ha->dpc_work); | 1252 | queue_work(ha->dpc_thread, &ha->dpc_work); |
1248 | } | ||
1249 | } | 1253 | } |
1250 | 1254 | ||
1251 | /** | 1255 | /** |
@@ -1272,12 +1276,12 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
1272 | 1276 | ||
1273 | /* Initialization not yet finished. Don't do anything yet. */ | 1277 | /* Initialization not yet finished. Don't do anything yet. */ |
1274 | if (!test_bit(AF_INIT_DONE, &ha->flags)) | 1278 | if (!test_bit(AF_INIT_DONE, &ha->flags)) |
1275 | goto do_dpc_exit; | 1279 | return; |
1276 | 1280 | ||
1277 | if (test_bit(AF_EEH_BUSY, &ha->flags)) { | 1281 | if (test_bit(AF_EEH_BUSY, &ha->flags)) { |
1278 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: flags = %lx\n", | 1282 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: flags = %lx\n", |
1279 | ha->host_no, __func__, ha->flags)); | 1283 | ha->host_no, __func__, ha->flags)); |
1280 | goto do_dpc_exit; | 1284 | return; |
1281 | } | 1285 | } |
1282 | 1286 | ||
1283 | if (is_qla8022(ha)) { | 1287 | if (is_qla8022(ha)) { |
@@ -1384,8 +1388,6 @@ dpc_post_reset_ha: | |||
1384 | } | 1388 | } |
1385 | } | 1389 | } |
1386 | 1390 | ||
1387 | do_dpc_exit: | ||
1388 | clear_bit(AF_DPC_SCHEDULED, &ha->flags); | ||
1389 | } | 1391 | } |
1390 | 1392 | ||
1391 | /** | 1393 | /** |
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index 603155769407..610492877253 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h | |||
@@ -5,4 +5,4 @@ | |||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define QLA4XXX_DRIVER_VERSION "5.02.00-k6" | 8 | #define QLA4XXX_DRIVER_VERSION "5.02.00-k7" |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index abea2cf05c2e..a4b9cdbaaa0b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -50,6 +50,8 @@ | |||
50 | #define BUS_RESET_SETTLE_TIME (10) | 50 | #define BUS_RESET_SETTLE_TIME (10) |
51 | #define HOST_RESET_SETTLE_TIME (10) | 51 | #define HOST_RESET_SETTLE_TIME (10) |
52 | 52 | ||
53 | static int scsi_eh_try_stu(struct scsi_cmnd *scmd); | ||
54 | |||
53 | /* called with shost->host_lock held */ | 55 | /* called with shost->host_lock held */ |
54 | void scsi_eh_wakeup(struct Scsi_Host *shost) | 56 | void scsi_eh_wakeup(struct Scsi_Host *shost) |
55 | { | 57 | { |
@@ -947,6 +949,48 @@ retry_tur: | |||
947 | } | 949 | } |
948 | 950 | ||
949 | /** | 951 | /** |
952 | * scsi_eh_test_devices - check if devices are responding from error recovery. | ||
953 | * @cmd_list: scsi commands in error recovery. | ||
954 | * @work_q: queue for commands which still need more error recovery | ||
955 | * @done_q: queue for commands which are finished | ||
956 | * @try_stu: boolean on if a STU command should be tried in addition to TUR. | ||
957 | * | ||
958 | * Decription: | ||
959 | * Tests if devices are in a working state. Commands to devices now in | ||
960 | * a working state are sent to the done_q while commands to devices which | ||
961 | * are still failing to respond are returned to the work_q for more | ||
962 | * processing. | ||
963 | **/ | ||
964 | static int scsi_eh_test_devices(struct list_head *cmd_list, | ||
965 | struct list_head *work_q, | ||
966 | struct list_head *done_q, int try_stu) | ||
967 | { | ||
968 | struct scsi_cmnd *scmd, *next; | ||
969 | struct scsi_device *sdev; | ||
970 | int finish_cmds; | ||
971 | |||
972 | while (!list_empty(cmd_list)) { | ||
973 | scmd = list_entry(cmd_list->next, struct scsi_cmnd, eh_entry); | ||
974 | sdev = scmd->device; | ||
975 | |||
976 | finish_cmds = !scsi_device_online(scmd->device) || | ||
977 | (try_stu && !scsi_eh_try_stu(scmd) && | ||
978 | !scsi_eh_tur(scmd)) || | ||
979 | !scsi_eh_tur(scmd); | ||
980 | |||
981 | list_for_each_entry_safe(scmd, next, cmd_list, eh_entry) | ||
982 | if (scmd->device == sdev) { | ||
983 | if (finish_cmds) | ||
984 | scsi_eh_finish_cmd(scmd, done_q); | ||
985 | else | ||
986 | list_move_tail(&scmd->eh_entry, work_q); | ||
987 | } | ||
988 | } | ||
989 | return list_empty(work_q); | ||
990 | } | ||
991 | |||
992 | |||
993 | /** | ||
950 | * scsi_eh_abort_cmds - abort pending commands. | 994 | * scsi_eh_abort_cmds - abort pending commands. |
951 | * @work_q: &list_head for pending commands. | 995 | * @work_q: &list_head for pending commands. |
952 | * @done_q: &list_head for processed commands. | 996 | * @done_q: &list_head for processed commands. |
@@ -962,6 +1006,7 @@ static int scsi_eh_abort_cmds(struct list_head *work_q, | |||
962 | struct list_head *done_q) | 1006 | struct list_head *done_q) |
963 | { | 1007 | { |
964 | struct scsi_cmnd *scmd, *next; | 1008 | struct scsi_cmnd *scmd, *next; |
1009 | LIST_HEAD(check_list); | ||
965 | int rtn; | 1010 | int rtn; |
966 | 1011 | ||
967 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | 1012 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { |
@@ -973,11 +1018,10 @@ static int scsi_eh_abort_cmds(struct list_head *work_q, | |||
973 | rtn = scsi_try_to_abort_cmd(scmd->device->host->hostt, scmd); | 1018 | rtn = scsi_try_to_abort_cmd(scmd->device->host->hostt, scmd); |
974 | if (rtn == SUCCESS || rtn == FAST_IO_FAIL) { | 1019 | if (rtn == SUCCESS || rtn == FAST_IO_FAIL) { |
975 | scmd->eh_eflags &= ~SCSI_EH_CANCEL_CMD; | 1020 | scmd->eh_eflags &= ~SCSI_EH_CANCEL_CMD; |
976 | if (!scsi_device_online(scmd->device) || | 1021 | if (rtn == FAST_IO_FAIL) |
977 | rtn == FAST_IO_FAIL || | ||
978 | !scsi_eh_tur(scmd)) { | ||
979 | scsi_eh_finish_cmd(scmd, done_q); | 1022 | scsi_eh_finish_cmd(scmd, done_q); |
980 | } | 1023 | else |
1024 | list_move_tail(&scmd->eh_entry, &check_list); | ||
981 | } else | 1025 | } else |
982 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: aborting" | 1026 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: aborting" |
983 | " cmd failed:" | 1027 | " cmd failed:" |
@@ -986,7 +1030,7 @@ static int scsi_eh_abort_cmds(struct list_head *work_q, | |||
986 | scmd)); | 1030 | scmd)); |
987 | } | 1031 | } |
988 | 1032 | ||
989 | return list_empty(work_q); | 1033 | return scsi_eh_test_devices(&check_list, work_q, done_q, 0); |
990 | } | 1034 | } |
991 | 1035 | ||
992 | /** | 1036 | /** |
@@ -1137,6 +1181,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, | |||
1137 | struct list_head *done_q) | 1181 | struct list_head *done_q) |
1138 | { | 1182 | { |
1139 | LIST_HEAD(tmp_list); | 1183 | LIST_HEAD(tmp_list); |
1184 | LIST_HEAD(check_list); | ||
1140 | 1185 | ||
1141 | list_splice_init(work_q, &tmp_list); | 1186 | list_splice_init(work_q, &tmp_list); |
1142 | 1187 | ||
@@ -1161,9 +1206,9 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, | |||
1161 | if (scmd_id(scmd) != id) | 1206 | if (scmd_id(scmd) != id) |
1162 | continue; | 1207 | continue; |
1163 | 1208 | ||
1164 | if ((rtn == SUCCESS || rtn == FAST_IO_FAIL) | 1209 | if (rtn == SUCCESS) |
1165 | && (!scsi_device_online(scmd->device) || | 1210 | list_move_tail(&scmd->eh_entry, &check_list); |
1166 | rtn == FAST_IO_FAIL || !scsi_eh_tur(scmd))) | 1211 | else if (rtn == FAST_IO_FAIL) |
1167 | scsi_eh_finish_cmd(scmd, done_q); | 1212 | scsi_eh_finish_cmd(scmd, done_q); |
1168 | else | 1213 | else |
1169 | /* push back on work queue for further processing */ | 1214 | /* push back on work queue for further processing */ |
@@ -1171,7 +1216,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, | |||
1171 | } | 1216 | } |
1172 | } | 1217 | } |
1173 | 1218 | ||
1174 | return list_empty(work_q); | 1219 | return scsi_eh_test_devices(&check_list, work_q, done_q, 0); |
1175 | } | 1220 | } |
1176 | 1221 | ||
1177 | /** | 1222 | /** |
@@ -1185,6 +1230,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost, | |||
1185 | struct list_head *done_q) | 1230 | struct list_head *done_q) |
1186 | { | 1231 | { |
1187 | struct scsi_cmnd *scmd, *chan_scmd, *next; | 1232 | struct scsi_cmnd *scmd, *chan_scmd, *next; |
1233 | LIST_HEAD(check_list); | ||
1188 | unsigned int channel; | 1234 | unsigned int channel; |
1189 | int rtn; | 1235 | int rtn; |
1190 | 1236 | ||
@@ -1216,12 +1262,14 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost, | |||
1216 | rtn = scsi_try_bus_reset(chan_scmd); | 1262 | rtn = scsi_try_bus_reset(chan_scmd); |
1217 | if (rtn == SUCCESS || rtn == FAST_IO_FAIL) { | 1263 | if (rtn == SUCCESS || rtn == FAST_IO_FAIL) { |
1218 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | 1264 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { |
1219 | if (channel == scmd_channel(scmd)) | 1265 | if (channel == scmd_channel(scmd)) { |
1220 | if (!scsi_device_online(scmd->device) || | 1266 | if (rtn == FAST_IO_FAIL) |
1221 | rtn == FAST_IO_FAIL || | ||
1222 | !scsi_eh_tur(scmd)) | ||
1223 | scsi_eh_finish_cmd(scmd, | 1267 | scsi_eh_finish_cmd(scmd, |
1224 | done_q); | 1268 | done_q); |
1269 | else | ||
1270 | list_move_tail(&scmd->eh_entry, | ||
1271 | &check_list); | ||
1272 | } | ||
1225 | } | 1273 | } |
1226 | } else { | 1274 | } else { |
1227 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: BRST" | 1275 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: BRST" |
@@ -1230,7 +1278,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost, | |||
1230 | channel)); | 1278 | channel)); |
1231 | } | 1279 | } |
1232 | } | 1280 | } |
1233 | return list_empty(work_q); | 1281 | return scsi_eh_test_devices(&check_list, work_q, done_q, 0); |
1234 | } | 1282 | } |
1235 | 1283 | ||
1236 | /** | 1284 | /** |
@@ -1242,6 +1290,7 @@ static int scsi_eh_host_reset(struct list_head *work_q, | |||
1242 | struct list_head *done_q) | 1290 | struct list_head *done_q) |
1243 | { | 1291 | { |
1244 | struct scsi_cmnd *scmd, *next; | 1292 | struct scsi_cmnd *scmd, *next; |
1293 | LIST_HEAD(check_list); | ||
1245 | int rtn; | 1294 | int rtn; |
1246 | 1295 | ||
1247 | if (!list_empty(work_q)) { | 1296 | if (!list_empty(work_q)) { |
@@ -1252,12 +1301,10 @@ static int scsi_eh_host_reset(struct list_head *work_q, | |||
1252 | , current->comm)); | 1301 | , current->comm)); |
1253 | 1302 | ||
1254 | rtn = scsi_try_host_reset(scmd); | 1303 | rtn = scsi_try_host_reset(scmd); |
1255 | if (rtn == SUCCESS || rtn == FAST_IO_FAIL) { | 1304 | if (rtn == SUCCESS) { |
1305 | list_splice_init(work_q, &check_list); | ||
1306 | } else if (rtn == FAST_IO_FAIL) { | ||
1256 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | 1307 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { |
1257 | if (!scsi_device_online(scmd->device) || | ||
1258 | rtn == FAST_IO_FAIL || | ||
1259 | (!scsi_eh_try_stu(scmd) && !scsi_eh_tur(scmd)) || | ||
1260 | !scsi_eh_tur(scmd)) | ||
1261 | scsi_eh_finish_cmd(scmd, done_q); | 1308 | scsi_eh_finish_cmd(scmd, done_q); |
1262 | } | 1309 | } |
1263 | } else { | 1310 | } else { |
@@ -1266,7 +1313,7 @@ static int scsi_eh_host_reset(struct list_head *work_q, | |||
1266 | current->comm)); | 1313 | current->comm)); |
1267 | } | 1314 | } |
1268 | } | 1315 | } |
1269 | return list_empty(work_q); | 1316 | return scsi_eh_test_devices(&check_list, work_q, done_q, 1); |
1270 | } | 1317 | } |
1271 | 1318 | ||
1272 | /** | 1319 | /** |
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index f46855cd853d..ad747dc337da 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c | |||
@@ -381,11 +381,6 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, | |||
381 | return err; | 381 | return err; |
382 | } | 382 | } |
383 | 383 | ||
384 | /** | ||
385 | * proc_scsi_show - show contents of /proc/scsi/scsi (attached devices) | ||
386 | * @s: output goes here | ||
387 | * @p: not used | ||
388 | */ | ||
389 | static int always_match(struct device *dev, void *data) | 384 | static int always_match(struct device *dev, void *data) |
390 | { | 385 | { |
391 | return 1; | 386 | return 1; |
diff --git a/drivers/scsi/scsi_trace.c b/drivers/scsi/scsi_trace.c index b587289cfacb..2bea4f0b684a 100644 --- a/drivers/scsi/scsi_trace.c +++ b/drivers/scsi/scsi_trace.c | |||
@@ -59,6 +59,10 @@ scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) | |||
59 | trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", | 59 | trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", |
60 | (unsigned long long)lba, (unsigned long long)txlen, | 60 | (unsigned long long)lba, (unsigned long long)txlen, |
61 | cdb[1] >> 5); | 61 | cdb[1] >> 5); |
62 | |||
63 | if (cdb[0] == WRITE_SAME) | ||
64 | trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); | ||
65 | |||
62 | trace_seq_putc(p, 0); | 66 | trace_seq_putc(p, 0); |
63 | 67 | ||
64 | return ret; | 68 | return ret; |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bd0806e64e85..953773cb26d9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -490,7 +490,8 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
490 | unsigned int max_blocks = 0; | 490 | unsigned int max_blocks = 0; |
491 | 491 | ||
492 | q->limits.discard_zeroes_data = sdkp->lbprz; | 492 | q->limits.discard_zeroes_data = sdkp->lbprz; |
493 | q->limits.discard_alignment = sdkp->unmap_alignment; | 493 | q->limits.discard_alignment = sdkp->unmap_alignment * |
494 | logical_block_size; | ||
494 | q->limits.discard_granularity = | 495 | q->limits.discard_granularity = |
495 | max(sdkp->physical_block_size, | 496 | max(sdkp->physical_block_size, |
496 | sdkp->unmap_granularity * logical_block_size); | 497 | sdkp->unmap_granularity * logical_block_size); |
@@ -2021,16 +2022,26 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2021 | 2022 | ||
2022 | int dbd; | 2023 | int dbd; |
2023 | int modepage; | 2024 | int modepage; |
2025 | int first_len; | ||
2024 | struct scsi_mode_data data; | 2026 | struct scsi_mode_data data; |
2025 | struct scsi_sense_hdr sshdr; | 2027 | struct scsi_sense_hdr sshdr; |
2026 | int old_wce = sdkp->WCE; | 2028 | int old_wce = sdkp->WCE; |
2027 | int old_rcd = sdkp->RCD; | 2029 | int old_rcd = sdkp->RCD; |
2028 | int old_dpofua = sdkp->DPOFUA; | 2030 | int old_dpofua = sdkp->DPOFUA; |
2029 | 2031 | ||
2030 | if (sdp->skip_ms_page_8) | 2032 | first_len = 4; |
2031 | goto defaults; | 2033 | if (sdp->skip_ms_page_8) { |
2032 | 2034 | if (sdp->type == TYPE_RBC) | |
2033 | if (sdp->type == TYPE_RBC) { | 2035 | goto defaults; |
2036 | else { | ||
2037 | if (sdp->skip_ms_page_3f) | ||
2038 | goto defaults; | ||
2039 | modepage = 0x3F; | ||
2040 | if (sdp->use_192_bytes_for_3f) | ||
2041 | first_len = 192; | ||
2042 | dbd = 0; | ||
2043 | } | ||
2044 | } else if (sdp->type == TYPE_RBC) { | ||
2034 | modepage = 6; | 2045 | modepage = 6; |
2035 | dbd = 8; | 2046 | dbd = 8; |
2036 | } else { | 2047 | } else { |
@@ -2039,13 +2050,15 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2039 | } | 2050 | } |
2040 | 2051 | ||
2041 | /* cautiously ask */ | 2052 | /* cautiously ask */ |
2042 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, 4, &data, &sshdr); | 2053 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, first_len, |
2054 | &data, &sshdr); | ||
2043 | 2055 | ||
2044 | if (!scsi_status_is_good(res)) | 2056 | if (!scsi_status_is_good(res)) |
2045 | goto bad_sense; | 2057 | goto bad_sense; |
2046 | 2058 | ||
2047 | if (!data.header_length) { | 2059 | if (!data.header_length) { |
2048 | modepage = 6; | 2060 | modepage = 6; |
2061 | first_len = 0; | ||
2049 | sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n"); | 2062 | sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n"); |
2050 | } | 2063 | } |
2051 | 2064 | ||
@@ -2058,30 +2071,61 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2058 | */ | 2071 | */ |
2059 | if (len < 3) | 2072 | if (len < 3) |
2060 | goto bad_sense; | 2073 | goto bad_sense; |
2061 | if (len > 20) | 2074 | else if (len > SD_BUF_SIZE) { |
2062 | len = 20; | 2075 | sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter " |
2063 | 2076 | "data from %d to %d bytes\n", len, SD_BUF_SIZE); | |
2064 | /* Take headers and block descriptors into account */ | 2077 | len = SD_BUF_SIZE; |
2065 | len += data.header_length + data.block_descriptor_length; | 2078 | } |
2066 | if (len > SD_BUF_SIZE) | 2079 | if (modepage == 0x3F && sdp->use_192_bytes_for_3f) |
2067 | goto bad_sense; | 2080 | len = 192; |
2068 | 2081 | ||
2069 | /* Get the data */ | 2082 | /* Get the data */ |
2070 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); | 2083 | if (len > first_len) |
2084 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, | ||
2085 | &data, &sshdr); | ||
2071 | 2086 | ||
2072 | if (scsi_status_is_good(res)) { | 2087 | if (scsi_status_is_good(res)) { |
2073 | int offset = data.header_length + data.block_descriptor_length; | 2088 | int offset = data.header_length + data.block_descriptor_length; |
2074 | 2089 | ||
2075 | if (offset >= SD_BUF_SIZE - 2) { | 2090 | while (offset < len) { |
2076 | sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n"); | 2091 | u8 page_code = buffer[offset] & 0x3F; |
2077 | goto defaults; | 2092 | u8 spf = buffer[offset] & 0x40; |
2093 | |||
2094 | if (page_code == 8 || page_code == 6) { | ||
2095 | /* We're interested only in the first 3 bytes. | ||
2096 | */ | ||
2097 | if (len - offset <= 2) { | ||
2098 | sd_printk(KERN_ERR, sdkp, "Incomplete " | ||
2099 | "mode parameter data\n"); | ||
2100 | goto defaults; | ||
2101 | } else { | ||
2102 | modepage = page_code; | ||
2103 | goto Page_found; | ||
2104 | } | ||
2105 | } else { | ||
2106 | /* Go to the next page */ | ||
2107 | if (spf && len - offset > 3) | ||
2108 | offset += 4 + (buffer[offset+2] << 8) + | ||
2109 | buffer[offset+3]; | ||
2110 | else if (!spf && len - offset > 1) | ||
2111 | offset += 2 + buffer[offset+1]; | ||
2112 | else { | ||
2113 | sd_printk(KERN_ERR, sdkp, "Incomplete " | ||
2114 | "mode parameter data\n"); | ||
2115 | goto defaults; | ||
2116 | } | ||
2117 | } | ||
2078 | } | 2118 | } |
2079 | 2119 | ||
2080 | if ((buffer[offset] & 0x3f) != modepage) { | 2120 | if (modepage == 0x3F) { |
2121 | sd_printk(KERN_ERR, sdkp, "No Caching mode page " | ||
2122 | "present\n"); | ||
2123 | goto defaults; | ||
2124 | } else if ((buffer[offset] & 0x3f) != modepage) { | ||
2081 | sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); | 2125 | sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); |
2082 | goto defaults; | 2126 | goto defaults; |
2083 | } | 2127 | } |
2084 | 2128 | Page_found: | |
2085 | if (modepage == 8) { | 2129 | if (modepage == 8) { |
2086 | sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); | 2130 | sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); |
2087 | sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0); | 2131 | sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0); |
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index 9f4b58b7daad..7e22b737dfd8 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c | |||
@@ -307,7 +307,7 @@ static inline int find_and_clear_bit_16(unsigned long *field) | |||
307 | "0: bsfw %1,%w0\n\t" | 307 | "0: bsfw %1,%w0\n\t" |
308 | "btr %0,%1\n\t" | 308 | "btr %0,%1\n\t" |
309 | "jnc 0b" | 309 | "jnc 0b" |
310 | : "=&r" (rv), "=m" (*field) :); | 310 | : "=&r" (rv), "+m" (*field) :); |
311 | 311 | ||
312 | return rv; | 312 | return rv; |
313 | } | 313 | } |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index fbd96b29530d..de35c3ad8a69 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -80,6 +80,15 @@ config SPI_BFIN | |||
80 | help | 80 | help |
81 | This is the SPI controller master driver for Blackfin 5xx processor. | 81 | This is the SPI controller master driver for Blackfin 5xx processor. |
82 | 82 | ||
83 | config SPI_BFIN_SPORT | ||
84 | tristate "SPI bus via Blackfin SPORT" | ||
85 | depends on BLACKFIN | ||
86 | help | ||
87 | Enable support for a SPI bus via the Blackfin SPORT peripheral. | ||
88 | |||
89 | This driver can also be built as a module. If so, the module | ||
90 | will be called spi_bfin_sport. | ||
91 | |||
83 | config SPI_AU1550 | 92 | config SPI_AU1550 |
84 | tristate "Au1550/Au12x0 SPI Controller" | 93 | tristate "Au1550/Au12x0 SPI Controller" |
85 | depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL | 94 | depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fd2fc5f6505f..0f8c69b6b19e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_SPI_ALTERA) += spi_altera.o | |||
13 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o | 13 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o |
14 | obj-$(CONFIG_SPI_ATH79) += ath79_spi.o | 14 | obj-$(CONFIG_SPI_ATH79) += ath79_spi.o |
15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o | 15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o |
16 | obj-$(CONFIG_SPI_BFIN_SPORT) += spi_bfin_sport.o | ||
16 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o | 17 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o |
17 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o | 18 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o |
18 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o | 19 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o |
diff --git a/drivers/spi/spi_bfin_sport.c b/drivers/spi/spi_bfin_sport.c new file mode 100644 index 000000000000..e557ff617b11 --- /dev/null +++ b/drivers/spi/spi_bfin_sport.c | |||
@@ -0,0 +1,952 @@ | |||
1 | /* | ||
2 | * SPI bus via the Blackfin SPORT peripheral | ||
3 | * | ||
4 | * Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright 2009-2011 Analog Devices Inc. | ||
7 | * | ||
8 | * Licensed under the GPL-2 or later. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/ioport.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/spi/spi.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | |||
25 | #include <asm/portmux.h> | ||
26 | #include <asm/bfin5xx_spi.h> | ||
27 | #include <asm/blackfin.h> | ||
28 | #include <asm/bfin_sport.h> | ||
29 | #include <asm/cacheflush.h> | ||
30 | |||
31 | #define DRV_NAME "bfin-sport-spi" | ||
32 | #define DRV_DESC "SPI bus via the Blackfin SPORT" | ||
33 | |||
34 | MODULE_AUTHOR("Cliff Cai"); | ||
35 | MODULE_DESCRIPTION(DRV_DESC); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | MODULE_ALIAS("platform:bfin-sport-spi"); | ||
38 | |||
39 | enum bfin_sport_spi_state { | ||
40 | START_STATE, | ||
41 | RUNNING_STATE, | ||
42 | DONE_STATE, | ||
43 | ERROR_STATE, | ||
44 | }; | ||
45 | |||
46 | struct bfin_sport_spi_master_data; | ||
47 | |||
48 | struct bfin_sport_transfer_ops { | ||
49 | void (*write) (struct bfin_sport_spi_master_data *); | ||
50 | void (*read) (struct bfin_sport_spi_master_data *); | ||
51 | void (*duplex) (struct bfin_sport_spi_master_data *); | ||
52 | }; | ||
53 | |||
54 | struct bfin_sport_spi_master_data { | ||
55 | /* Driver model hookup */ | ||
56 | struct device *dev; | ||
57 | |||
58 | /* SPI framework hookup */ | ||
59 | struct spi_master *master; | ||
60 | |||
61 | /* Regs base of SPI controller */ | ||
62 | struct sport_register __iomem *regs; | ||
63 | int err_irq; | ||
64 | |||
65 | /* Pin request list */ | ||
66 | u16 *pin_req; | ||
67 | |||
68 | /* Driver message queue */ | ||
69 | struct workqueue_struct *workqueue; | ||
70 | struct work_struct pump_messages; | ||
71 | spinlock_t lock; | ||
72 | struct list_head queue; | ||
73 | int busy; | ||
74 | bool run; | ||
75 | |||
76 | /* Message Transfer pump */ | ||
77 | struct tasklet_struct pump_transfers; | ||
78 | |||
79 | /* Current message transfer state info */ | ||
80 | enum bfin_sport_spi_state state; | ||
81 | struct spi_message *cur_msg; | ||
82 | struct spi_transfer *cur_transfer; | ||
83 | struct bfin_sport_spi_slave_data *cur_chip; | ||
84 | union { | ||
85 | void *tx; | ||
86 | u8 *tx8; | ||
87 | u16 *tx16; | ||
88 | }; | ||
89 | void *tx_end; | ||
90 | union { | ||
91 | void *rx; | ||
92 | u8 *rx8; | ||
93 | u16 *rx16; | ||
94 | }; | ||
95 | void *rx_end; | ||
96 | |||
97 | int cs_change; | ||
98 | struct bfin_sport_transfer_ops *ops; | ||
99 | }; | ||
100 | |||
101 | struct bfin_sport_spi_slave_data { | ||
102 | u16 ctl_reg; | ||
103 | u16 baud; | ||
104 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ | ||
105 | u32 cs_gpio; | ||
106 | u16 idle_tx_val; | ||
107 | struct bfin_sport_transfer_ops *ops; | ||
108 | }; | ||
109 | |||
110 | static void | ||
111 | bfin_sport_spi_enable(struct bfin_sport_spi_master_data *drv_data) | ||
112 | { | ||
113 | bfin_write_or(&drv_data->regs->tcr1, TSPEN); | ||
114 | bfin_write_or(&drv_data->regs->rcr1, TSPEN); | ||
115 | SSYNC(); | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | bfin_sport_spi_disable(struct bfin_sport_spi_master_data *drv_data) | ||
120 | { | ||
121 | bfin_write_and(&drv_data->regs->tcr1, ~TSPEN); | ||
122 | bfin_write_and(&drv_data->regs->rcr1, ~TSPEN); | ||
123 | SSYNC(); | ||
124 | } | ||
125 | |||
126 | /* Caculate the SPI_BAUD register value based on input HZ */ | ||
127 | static u16 | ||
128 | bfin_sport_hz_to_spi_baud(u32 speed_hz) | ||
129 | { | ||
130 | u_long clk, sclk = get_sclk(); | ||
131 | int div = (sclk / (2 * speed_hz)) - 1; | ||
132 | |||
133 | if (div < 0) | ||
134 | div = 0; | ||
135 | |||
136 | clk = sclk / (2 * (div + 1)); | ||
137 | |||
138 | if (clk > speed_hz) | ||
139 | div++; | ||
140 | |||
141 | return div; | ||
142 | } | ||
143 | |||
144 | /* Chip select operation functions for cs_change flag */ | ||
145 | static void | ||
146 | bfin_sport_spi_cs_active(struct bfin_sport_spi_slave_data *chip) | ||
147 | { | ||
148 | gpio_direction_output(chip->cs_gpio, 0); | ||
149 | } | ||
150 | |||
151 | static void | ||
152 | bfin_sport_spi_cs_deactive(struct bfin_sport_spi_slave_data *chip) | ||
153 | { | ||
154 | gpio_direction_output(chip->cs_gpio, 1); | ||
155 | /* Move delay here for consistency */ | ||
156 | if (chip->cs_chg_udelay) | ||
157 | udelay(chip->cs_chg_udelay); | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | bfin_sport_spi_stat_poll_complete(struct bfin_sport_spi_master_data *drv_data) | ||
162 | { | ||
163 | unsigned long timeout = jiffies + HZ; | ||
164 | while (!(bfin_read(&drv_data->regs->stat) & RXNE)) { | ||
165 | if (!time_before(jiffies, timeout)) | ||
166 | break; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | bfin_sport_spi_u8_writer(struct bfin_sport_spi_master_data *drv_data) | ||
172 | { | ||
173 | u16 dummy; | ||
174 | |||
175 | while (drv_data->tx < drv_data->tx_end) { | ||
176 | bfin_write(&drv_data->regs->tx16, *drv_data->tx8++); | ||
177 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
178 | dummy = bfin_read(&drv_data->regs->rx16); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void | ||
183 | bfin_sport_spi_u8_reader(struct bfin_sport_spi_master_data *drv_data) | ||
184 | { | ||
185 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
186 | |||
187 | while (drv_data->rx < drv_data->rx_end) { | ||
188 | bfin_write(&drv_data->regs->tx16, tx_val); | ||
189 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
190 | *drv_data->rx8++ = bfin_read(&drv_data->regs->rx16); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static void | ||
195 | bfin_sport_spi_u8_duplex(struct bfin_sport_spi_master_data *drv_data) | ||
196 | { | ||
197 | while (drv_data->rx < drv_data->rx_end) { | ||
198 | bfin_write(&drv_data->regs->tx16, *drv_data->tx8++); | ||
199 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
200 | *drv_data->rx8++ = bfin_read(&drv_data->regs->rx16); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u8 = { | ||
205 | .write = bfin_sport_spi_u8_writer, | ||
206 | .read = bfin_sport_spi_u8_reader, | ||
207 | .duplex = bfin_sport_spi_u8_duplex, | ||
208 | }; | ||
209 | |||
210 | static void | ||
211 | bfin_sport_spi_u16_writer(struct bfin_sport_spi_master_data *drv_data) | ||
212 | { | ||
213 | u16 dummy; | ||
214 | |||
215 | while (drv_data->tx < drv_data->tx_end) { | ||
216 | bfin_write(&drv_data->regs->tx16, *drv_data->tx16++); | ||
217 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
218 | dummy = bfin_read(&drv_data->regs->rx16); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | static void | ||
223 | bfin_sport_spi_u16_reader(struct bfin_sport_spi_master_data *drv_data) | ||
224 | { | ||
225 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
226 | |||
227 | while (drv_data->rx < drv_data->rx_end) { | ||
228 | bfin_write(&drv_data->regs->tx16, tx_val); | ||
229 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
230 | *drv_data->rx16++ = bfin_read(&drv_data->regs->rx16); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | static void | ||
235 | bfin_sport_spi_u16_duplex(struct bfin_sport_spi_master_data *drv_data) | ||
236 | { | ||
237 | while (drv_data->rx < drv_data->rx_end) { | ||
238 | bfin_write(&drv_data->regs->tx16, *drv_data->tx16++); | ||
239 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
240 | *drv_data->rx16++ = bfin_read(&drv_data->regs->rx16); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u16 = { | ||
245 | .write = bfin_sport_spi_u16_writer, | ||
246 | .read = bfin_sport_spi_u16_reader, | ||
247 | .duplex = bfin_sport_spi_u16_duplex, | ||
248 | }; | ||
249 | |||
250 | /* stop controller and re-config current chip */ | ||
251 | static void | ||
252 | bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data) | ||
253 | { | ||
254 | struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; | ||
255 | unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15); | ||
256 | |||
257 | bfin_sport_spi_disable(drv_data); | ||
258 | dev_dbg(drv_data->dev, "restoring spi ctl state\n"); | ||
259 | |||
260 | bfin_write(&drv_data->regs->tcr1, chip->ctl_reg); | ||
261 | bfin_write(&drv_data->regs->tcr2, bits); | ||
262 | bfin_write(&drv_data->regs->tclkdiv, chip->baud); | ||
263 | bfin_write(&drv_data->regs->tfsdiv, bits); | ||
264 | SSYNC(); | ||
265 | |||
266 | bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS)); | ||
267 | bfin_write(&drv_data->regs->rcr2, bits); | ||
268 | SSYNC(); | ||
269 | |||
270 | bfin_sport_spi_cs_active(chip); | ||
271 | } | ||
272 | |||
273 | /* test if there is more transfer to be done */ | ||
274 | static enum bfin_sport_spi_state | ||
275 | bfin_sport_spi_next_transfer(struct bfin_sport_spi_master_data *drv_data) | ||
276 | { | ||
277 | struct spi_message *msg = drv_data->cur_msg; | ||
278 | struct spi_transfer *trans = drv_data->cur_transfer; | ||
279 | |||
280 | /* Move to next transfer */ | ||
281 | if (trans->transfer_list.next != &msg->transfers) { | ||
282 | drv_data->cur_transfer = | ||
283 | list_entry(trans->transfer_list.next, | ||
284 | struct spi_transfer, transfer_list); | ||
285 | return RUNNING_STATE; | ||
286 | } | ||
287 | |||
288 | return DONE_STATE; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * caller already set message->status; | ||
293 | * dma and pio irqs are blocked give finished message back | ||
294 | */ | ||
295 | static void | ||
296 | bfin_sport_spi_giveback(struct bfin_sport_spi_master_data *drv_data) | ||
297 | { | ||
298 | struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; | ||
299 | unsigned long flags; | ||
300 | struct spi_message *msg; | ||
301 | |||
302 | spin_lock_irqsave(&drv_data->lock, flags); | ||
303 | msg = drv_data->cur_msg; | ||
304 | drv_data->state = START_STATE; | ||
305 | drv_data->cur_msg = NULL; | ||
306 | drv_data->cur_transfer = NULL; | ||
307 | drv_data->cur_chip = NULL; | ||
308 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | ||
309 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
310 | |||
311 | if (!drv_data->cs_change) | ||
312 | bfin_sport_spi_cs_deactive(chip); | ||
313 | |||
314 | if (msg->complete) | ||
315 | msg->complete(msg->context); | ||
316 | } | ||
317 | |||
318 | static irqreturn_t | ||
319 | sport_err_handler(int irq, void *dev_id) | ||
320 | { | ||
321 | struct bfin_sport_spi_master_data *drv_data = dev_id; | ||
322 | u16 status; | ||
323 | |||
324 | dev_dbg(drv_data->dev, "%s enter\n", __func__); | ||
325 | status = bfin_read(&drv_data->regs->stat) & (TOVF | TUVF | ROVF | RUVF); | ||
326 | |||
327 | if (status) { | ||
328 | bfin_write(&drv_data->regs->stat, status); | ||
329 | SSYNC(); | ||
330 | |||
331 | bfin_sport_spi_disable(drv_data); | ||
332 | dev_err(drv_data->dev, "status error:%s%s%s%s\n", | ||
333 | status & TOVF ? " TOVF" : "", | ||
334 | status & TUVF ? " TUVF" : "", | ||
335 | status & ROVF ? " ROVF" : "", | ||
336 | status & RUVF ? " RUVF" : ""); | ||
337 | } | ||
338 | |||
339 | return IRQ_HANDLED; | ||
340 | } | ||
341 | |||
342 | static void | ||
343 | bfin_sport_spi_pump_transfers(unsigned long data) | ||
344 | { | ||
345 | struct bfin_sport_spi_master_data *drv_data = (void *)data; | ||
346 | struct spi_message *message = NULL; | ||
347 | struct spi_transfer *transfer = NULL; | ||
348 | struct spi_transfer *previous = NULL; | ||
349 | struct bfin_sport_spi_slave_data *chip = NULL; | ||
350 | unsigned int bits_per_word; | ||
351 | u32 tranf_success = 1; | ||
352 | u32 transfer_speed; | ||
353 | u8 full_duplex = 0; | ||
354 | |||
355 | /* Get current state information */ | ||
356 | message = drv_data->cur_msg; | ||
357 | transfer = drv_data->cur_transfer; | ||
358 | chip = drv_data->cur_chip; | ||
359 | |||
360 | if (transfer->speed_hz) | ||
361 | transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); | ||
362 | else | ||
363 | transfer_speed = chip->baud; | ||
364 | bfin_write(&drv_data->regs->tclkdiv, transfer_speed); | ||
365 | SSYNC(); | ||
366 | |||
367 | /* | ||
368 | * if msg is error or done, report it back using complete() callback | ||
369 | */ | ||
370 | |||
371 | /* Handle for abort */ | ||
372 | if (drv_data->state == ERROR_STATE) { | ||
373 | dev_dbg(drv_data->dev, "transfer: we've hit an error\n"); | ||
374 | message->status = -EIO; | ||
375 | bfin_sport_spi_giveback(drv_data); | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | /* Handle end of message */ | ||
380 | if (drv_data->state == DONE_STATE) { | ||
381 | dev_dbg(drv_data->dev, "transfer: all done!\n"); | ||
382 | message->status = 0; | ||
383 | bfin_sport_spi_giveback(drv_data); | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | /* Delay if requested at end of transfer */ | ||
388 | if (drv_data->state == RUNNING_STATE) { | ||
389 | dev_dbg(drv_data->dev, "transfer: still running ...\n"); | ||
390 | previous = list_entry(transfer->transfer_list.prev, | ||
391 | struct spi_transfer, transfer_list); | ||
392 | if (previous->delay_usecs) | ||
393 | udelay(previous->delay_usecs); | ||
394 | } | ||
395 | |||
396 | if (transfer->len == 0) { | ||
397 | /* Move to next transfer of this msg */ | ||
398 | drv_data->state = bfin_sport_spi_next_transfer(drv_data); | ||
399 | /* Schedule next transfer tasklet */ | ||
400 | tasklet_schedule(&drv_data->pump_transfers); | ||
401 | } | ||
402 | |||
403 | if (transfer->tx_buf != NULL) { | ||
404 | drv_data->tx = (void *)transfer->tx_buf; | ||
405 | drv_data->tx_end = drv_data->tx + transfer->len; | ||
406 | dev_dbg(drv_data->dev, "tx_buf is %p, tx_end is %p\n", | ||
407 | transfer->tx_buf, drv_data->tx_end); | ||
408 | } else | ||
409 | drv_data->tx = NULL; | ||
410 | |||
411 | if (transfer->rx_buf != NULL) { | ||
412 | full_duplex = transfer->tx_buf != NULL; | ||
413 | drv_data->rx = transfer->rx_buf; | ||
414 | drv_data->rx_end = drv_data->rx + transfer->len; | ||
415 | dev_dbg(drv_data->dev, "rx_buf is %p, rx_end is %p\n", | ||
416 | transfer->rx_buf, drv_data->rx_end); | ||
417 | } else | ||
418 | drv_data->rx = NULL; | ||
419 | |||
420 | drv_data->cs_change = transfer->cs_change; | ||
421 | |||
422 | /* Bits per word setup */ | ||
423 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; | ||
424 | if (bits_per_word == 8) | ||
425 | drv_data->ops = &bfin_sport_transfer_ops_u8; | ||
426 | else | ||
427 | drv_data->ops = &bfin_sport_transfer_ops_u16; | ||
428 | |||
429 | drv_data->state = RUNNING_STATE; | ||
430 | |||
431 | if (drv_data->cs_change) | ||
432 | bfin_sport_spi_cs_active(chip); | ||
433 | |||
434 | dev_dbg(drv_data->dev, | ||
435 | "now pumping a transfer: width is %d, len is %d\n", | ||
436 | bits_per_word, transfer->len); | ||
437 | |||
438 | /* PIO mode write then read */ | ||
439 | dev_dbg(drv_data->dev, "doing IO transfer\n"); | ||
440 | |||
441 | bfin_sport_spi_enable(drv_data); | ||
442 | if (full_duplex) { | ||
443 | /* full duplex mode */ | ||
444 | BUG_ON((drv_data->tx_end - drv_data->tx) != | ||
445 | (drv_data->rx_end - drv_data->rx)); | ||
446 | drv_data->ops->duplex(drv_data); | ||
447 | |||
448 | if (drv_data->tx != drv_data->tx_end) | ||
449 | tranf_success = 0; | ||
450 | } else if (drv_data->tx != NULL) { | ||
451 | /* write only half duplex */ | ||
452 | |||
453 | drv_data->ops->write(drv_data); | ||
454 | |||
455 | if (drv_data->tx != drv_data->tx_end) | ||
456 | tranf_success = 0; | ||
457 | } else if (drv_data->rx != NULL) { | ||
458 | /* read only half duplex */ | ||
459 | |||
460 | drv_data->ops->read(drv_data); | ||
461 | if (drv_data->rx != drv_data->rx_end) | ||
462 | tranf_success = 0; | ||
463 | } | ||
464 | bfin_sport_spi_disable(drv_data); | ||
465 | |||
466 | if (!tranf_success) { | ||
467 | dev_dbg(drv_data->dev, "IO write error!\n"); | ||
468 | drv_data->state = ERROR_STATE; | ||
469 | } else { | ||
470 | /* Update total byte transfered */ | ||
471 | message->actual_length += transfer->len; | ||
472 | /* Move to next transfer of this msg */ | ||
473 | drv_data->state = bfin_sport_spi_next_transfer(drv_data); | ||
474 | if (drv_data->cs_change) | ||
475 | bfin_sport_spi_cs_deactive(chip); | ||
476 | } | ||
477 | |||
478 | /* Schedule next transfer tasklet */ | ||
479 | tasklet_schedule(&drv_data->pump_transfers); | ||
480 | } | ||
481 | |||
482 | /* pop a msg from queue and kick off real transfer */ | ||
483 | static void | ||
484 | bfin_sport_spi_pump_messages(struct work_struct *work) | ||
485 | { | ||
486 | struct bfin_sport_spi_master_data *drv_data; | ||
487 | unsigned long flags; | ||
488 | struct spi_message *next_msg; | ||
489 | |||
490 | drv_data = container_of(work, struct bfin_sport_spi_master_data, pump_messages); | ||
491 | |||
492 | /* Lock queue and check for queue work */ | ||
493 | spin_lock_irqsave(&drv_data->lock, flags); | ||
494 | if (list_empty(&drv_data->queue) || !drv_data->run) { | ||
495 | /* pumper kicked off but no work to do */ | ||
496 | drv_data->busy = 0; | ||
497 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | /* Make sure we are not already running a message */ | ||
502 | if (drv_data->cur_msg) { | ||
503 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
504 | return; | ||
505 | } | ||
506 | |||
507 | /* Extract head of queue */ | ||
508 | next_msg = list_entry(drv_data->queue.next, | ||
509 | struct spi_message, queue); | ||
510 | |||
511 | drv_data->cur_msg = next_msg; | ||
512 | |||
513 | /* Setup the SSP using the per chip configuration */ | ||
514 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); | ||
515 | |||
516 | list_del_init(&drv_data->cur_msg->queue); | ||
517 | |||
518 | /* Initialize message state */ | ||
519 | drv_data->cur_msg->state = START_STATE; | ||
520 | drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, | ||
521 | struct spi_transfer, transfer_list); | ||
522 | bfin_sport_spi_restore_state(drv_data); | ||
523 | dev_dbg(drv_data->dev, "got a message to pump, " | ||
524 | "state is set to: baud %d, cs_gpio %i, ctl 0x%x\n", | ||
525 | drv_data->cur_chip->baud, drv_data->cur_chip->cs_gpio, | ||
526 | drv_data->cur_chip->ctl_reg); | ||
527 | |||
528 | dev_dbg(drv_data->dev, | ||
529 | "the first transfer len is %d\n", | ||
530 | drv_data->cur_transfer->len); | ||
531 | |||
532 | /* Mark as busy and launch transfers */ | ||
533 | tasklet_schedule(&drv_data->pump_transfers); | ||
534 | |||
535 | drv_data->busy = 1; | ||
536 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * got a msg to transfer, queue it in drv_data->queue. | ||
541 | * And kick off message pumper | ||
542 | */ | ||
543 | static int | ||
544 | bfin_sport_spi_transfer(struct spi_device *spi, struct spi_message *msg) | ||
545 | { | ||
546 | struct bfin_sport_spi_master_data *drv_data = spi_master_get_devdata(spi->master); | ||
547 | unsigned long flags; | ||
548 | |||
549 | spin_lock_irqsave(&drv_data->lock, flags); | ||
550 | |||
551 | if (!drv_data->run) { | ||
552 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
553 | return -ESHUTDOWN; | ||
554 | } | ||
555 | |||
556 | msg->actual_length = 0; | ||
557 | msg->status = -EINPROGRESS; | ||
558 | msg->state = START_STATE; | ||
559 | |||
560 | dev_dbg(&spi->dev, "adding an msg in transfer()\n"); | ||
561 | list_add_tail(&msg->queue, &drv_data->queue); | ||
562 | |||
563 | if (drv_data->run && !drv_data->busy) | ||
564 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | ||
565 | |||
566 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | /* Called every time common spi devices change state */ | ||
572 | static int | ||
573 | bfin_sport_spi_setup(struct spi_device *spi) | ||
574 | { | ||
575 | struct bfin_sport_spi_slave_data *chip, *first = NULL; | ||
576 | int ret; | ||
577 | |||
578 | /* Only alloc (or use chip_info) on first setup */ | ||
579 | chip = spi_get_ctldata(spi); | ||
580 | if (chip == NULL) { | ||
581 | struct bfin5xx_spi_chip *chip_info; | ||
582 | |||
583 | chip = first = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
584 | if (!chip) | ||
585 | return -ENOMEM; | ||
586 | |||
587 | /* platform chip_info isn't required */ | ||
588 | chip_info = spi->controller_data; | ||
589 | if (chip_info) { | ||
590 | /* | ||
591 | * DITFS and TDTYPE are only thing we don't set, but | ||
592 | * they probably shouldn't be changed by people. | ||
593 | */ | ||
594 | if (chip_info->ctl_reg || chip_info->enable_dma) { | ||
595 | ret = -EINVAL; | ||
596 | dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields"); | ||
597 | goto error; | ||
598 | } | ||
599 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; | ||
600 | chip->idle_tx_val = chip_info->idle_tx_val; | ||
601 | spi->bits_per_word = chip_info->bits_per_word; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { | ||
606 | ret = -EINVAL; | ||
607 | goto error; | ||
608 | } | ||
609 | |||
610 | /* translate common spi framework into our register | ||
611 | * following configure contents are same for tx and rx. | ||
612 | */ | ||
613 | |||
614 | if (spi->mode & SPI_CPHA) | ||
615 | chip->ctl_reg &= ~TCKFE; | ||
616 | else | ||
617 | chip->ctl_reg |= TCKFE; | ||
618 | |||
619 | if (spi->mode & SPI_LSB_FIRST) | ||
620 | chip->ctl_reg |= TLSBIT; | ||
621 | else | ||
622 | chip->ctl_reg &= ~TLSBIT; | ||
623 | |||
624 | /* Sport in master mode */ | ||
625 | chip->ctl_reg |= ITCLK | ITFS | TFSR | LATFS | LTFS; | ||
626 | |||
627 | chip->baud = bfin_sport_hz_to_spi_baud(spi->max_speed_hz); | ||
628 | |||
629 | chip->cs_gpio = spi->chip_select; | ||
630 | ret = gpio_request(chip->cs_gpio, spi->modalias); | ||
631 | if (ret) | ||
632 | goto error; | ||
633 | |||
634 | dev_dbg(&spi->dev, "setup spi chip %s, width is %d\n", | ||
635 | spi->modalias, spi->bits_per_word); | ||
636 | dev_dbg(&spi->dev, "ctl_reg is 0x%x, GPIO is %i\n", | ||
637 | chip->ctl_reg, spi->chip_select); | ||
638 | |||
639 | spi_set_ctldata(spi, chip); | ||
640 | |||
641 | bfin_sport_spi_cs_deactive(chip); | ||
642 | |||
643 | return ret; | ||
644 | |||
645 | error: | ||
646 | kfree(first); | ||
647 | return ret; | ||
648 | } | ||
649 | |||
650 | /* | ||
651 | * callback for spi framework. | ||
652 | * clean driver specific data | ||
653 | */ | ||
654 | static void | ||
655 | bfin_sport_spi_cleanup(struct spi_device *spi) | ||
656 | { | ||
657 | struct bfin_sport_spi_slave_data *chip = spi_get_ctldata(spi); | ||
658 | |||
659 | if (!chip) | ||
660 | return; | ||
661 | |||
662 | gpio_free(chip->cs_gpio); | ||
663 | |||
664 | kfree(chip); | ||
665 | } | ||
666 | |||
667 | static int | ||
668 | bfin_sport_spi_init_queue(struct bfin_sport_spi_master_data *drv_data) | ||
669 | { | ||
670 | INIT_LIST_HEAD(&drv_data->queue); | ||
671 | spin_lock_init(&drv_data->lock); | ||
672 | |||
673 | drv_data->run = false; | ||
674 | drv_data->busy = 0; | ||
675 | |||
676 | /* init transfer tasklet */ | ||
677 | tasklet_init(&drv_data->pump_transfers, | ||
678 | bfin_sport_spi_pump_transfers, (unsigned long)drv_data); | ||
679 | |||
680 | /* init messages workqueue */ | ||
681 | INIT_WORK(&drv_data->pump_messages, bfin_sport_spi_pump_messages); | ||
682 | drv_data->workqueue = | ||
683 | create_singlethread_workqueue(dev_name(drv_data->master->dev.parent)); | ||
684 | if (drv_data->workqueue == NULL) | ||
685 | return -EBUSY; | ||
686 | |||
687 | return 0; | ||
688 | } | ||
689 | |||
690 | static int | ||
691 | bfin_sport_spi_start_queue(struct bfin_sport_spi_master_data *drv_data) | ||
692 | { | ||
693 | unsigned long flags; | ||
694 | |||
695 | spin_lock_irqsave(&drv_data->lock, flags); | ||
696 | |||
697 | if (drv_data->run || drv_data->busy) { | ||
698 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
699 | return -EBUSY; | ||
700 | } | ||
701 | |||
702 | drv_data->run = true; | ||
703 | drv_data->cur_msg = NULL; | ||
704 | drv_data->cur_transfer = NULL; | ||
705 | drv_data->cur_chip = NULL; | ||
706 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
707 | |||
708 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static inline int | ||
714 | bfin_sport_spi_stop_queue(struct bfin_sport_spi_master_data *drv_data) | ||
715 | { | ||
716 | unsigned long flags; | ||
717 | unsigned limit = 500; | ||
718 | int status = 0; | ||
719 | |||
720 | spin_lock_irqsave(&drv_data->lock, flags); | ||
721 | |||
722 | /* | ||
723 | * This is a bit lame, but is optimized for the common execution path. | ||
724 | * A wait_queue on the drv_data->busy could be used, but then the common | ||
725 | * execution path (pump_messages) would be required to call wake_up or | ||
726 | * friends on every SPI message. Do this instead | ||
727 | */ | ||
728 | drv_data->run = false; | ||
729 | while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { | ||
730 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
731 | msleep(10); | ||
732 | spin_lock_irqsave(&drv_data->lock, flags); | ||
733 | } | ||
734 | |||
735 | if (!list_empty(&drv_data->queue) || drv_data->busy) | ||
736 | status = -EBUSY; | ||
737 | |||
738 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
739 | |||
740 | return status; | ||
741 | } | ||
742 | |||
743 | static inline int | ||
744 | bfin_sport_spi_destroy_queue(struct bfin_sport_spi_master_data *drv_data) | ||
745 | { | ||
746 | int status; | ||
747 | |||
748 | status = bfin_sport_spi_stop_queue(drv_data); | ||
749 | if (status) | ||
750 | return status; | ||
751 | |||
752 | destroy_workqueue(drv_data->workqueue); | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | static int __devinit | ||
758 | bfin_sport_spi_probe(struct platform_device *pdev) | ||
759 | { | ||
760 | struct device *dev = &pdev->dev; | ||
761 | struct bfin5xx_spi_master *platform_info; | ||
762 | struct spi_master *master; | ||
763 | struct resource *res, *ires; | ||
764 | struct bfin_sport_spi_master_data *drv_data; | ||
765 | int status; | ||
766 | |||
767 | platform_info = dev->platform_data; | ||
768 | |||
769 | /* Allocate master with space for drv_data */ | ||
770 | master = spi_alloc_master(dev, sizeof(*master) + 16); | ||
771 | if (!master) { | ||
772 | dev_err(dev, "cannot alloc spi_master\n"); | ||
773 | return -ENOMEM; | ||
774 | } | ||
775 | |||
776 | drv_data = spi_master_get_devdata(master); | ||
777 | drv_data->master = master; | ||
778 | drv_data->dev = dev; | ||
779 | drv_data->pin_req = platform_info->pin_req; | ||
780 | |||
781 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; | ||
782 | master->bus_num = pdev->id; | ||
783 | master->num_chipselect = platform_info->num_chipselect; | ||
784 | master->cleanup = bfin_sport_spi_cleanup; | ||
785 | master->setup = bfin_sport_spi_setup; | ||
786 | master->transfer = bfin_sport_spi_transfer; | ||
787 | |||
788 | /* Find and map our resources */ | ||
789 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
790 | if (res == NULL) { | ||
791 | dev_err(dev, "cannot get IORESOURCE_MEM\n"); | ||
792 | status = -ENOENT; | ||
793 | goto out_error_get_res; | ||
794 | } | ||
795 | |||
796 | drv_data->regs = ioremap(res->start, resource_size(res)); | ||
797 | if (drv_data->regs == NULL) { | ||
798 | dev_err(dev, "cannot map registers\n"); | ||
799 | status = -ENXIO; | ||
800 | goto out_error_ioremap; | ||
801 | } | ||
802 | |||
803 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
804 | if (!ires) { | ||
805 | dev_err(dev, "cannot get IORESOURCE_IRQ\n"); | ||
806 | status = -ENODEV; | ||
807 | goto out_error_get_ires; | ||
808 | } | ||
809 | drv_data->err_irq = ires->start; | ||
810 | |||
811 | /* Initial and start queue */ | ||
812 | status = bfin_sport_spi_init_queue(drv_data); | ||
813 | if (status) { | ||
814 | dev_err(dev, "problem initializing queue\n"); | ||
815 | goto out_error_queue_alloc; | ||
816 | } | ||
817 | |||
818 | status = bfin_sport_spi_start_queue(drv_data); | ||
819 | if (status) { | ||
820 | dev_err(dev, "problem starting queue\n"); | ||
821 | goto out_error_queue_alloc; | ||
822 | } | ||
823 | |||
824 | status = request_irq(drv_data->err_irq, sport_err_handler, | ||
825 | 0, "sport_spi_err", drv_data); | ||
826 | if (status) { | ||
827 | dev_err(dev, "unable to request sport err irq\n"); | ||
828 | goto out_error_irq; | ||
829 | } | ||
830 | |||
831 | status = peripheral_request_list(drv_data->pin_req, DRV_NAME); | ||
832 | if (status) { | ||
833 | dev_err(dev, "requesting peripherals failed\n"); | ||
834 | goto out_error_peripheral; | ||
835 | } | ||
836 | |||
837 | /* Register with the SPI framework */ | ||
838 | platform_set_drvdata(pdev, drv_data); | ||
839 | status = spi_register_master(master); | ||
840 | if (status) { | ||
841 | dev_err(dev, "problem registering spi master\n"); | ||
842 | goto out_error_master; | ||
843 | } | ||
844 | |||
845 | dev_info(dev, "%s, regs_base@%p\n", DRV_DESC, drv_data->regs); | ||
846 | return 0; | ||
847 | |||
848 | out_error_master: | ||
849 | peripheral_free_list(drv_data->pin_req); | ||
850 | out_error_peripheral: | ||
851 | free_irq(drv_data->err_irq, drv_data); | ||
852 | out_error_irq: | ||
853 | out_error_queue_alloc: | ||
854 | bfin_sport_spi_destroy_queue(drv_data); | ||
855 | out_error_get_ires: | ||
856 | iounmap(drv_data->regs); | ||
857 | out_error_ioremap: | ||
858 | out_error_get_res: | ||
859 | spi_master_put(master); | ||
860 | |||
861 | return status; | ||
862 | } | ||
863 | |||
864 | /* stop hardware and remove the driver */ | ||
865 | static int __devexit | ||
866 | bfin_sport_spi_remove(struct platform_device *pdev) | ||
867 | { | ||
868 | struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); | ||
869 | int status = 0; | ||
870 | |||
871 | if (!drv_data) | ||
872 | return 0; | ||
873 | |||
874 | /* Remove the queue */ | ||
875 | status = bfin_sport_spi_destroy_queue(drv_data); | ||
876 | if (status) | ||
877 | return status; | ||
878 | |||
879 | /* Disable the SSP at the peripheral and SOC level */ | ||
880 | bfin_sport_spi_disable(drv_data); | ||
881 | |||
882 | /* Disconnect from the SPI framework */ | ||
883 | spi_unregister_master(drv_data->master); | ||
884 | |||
885 | peripheral_free_list(drv_data->pin_req); | ||
886 | |||
887 | /* Prevent double remove */ | ||
888 | platform_set_drvdata(pdev, NULL); | ||
889 | |||
890 | return 0; | ||
891 | } | ||
892 | |||
893 | #ifdef CONFIG_PM | ||
894 | static int | ||
895 | bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state) | ||
896 | { | ||
897 | struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); | ||
898 | int status; | ||
899 | |||
900 | status = bfin_sport_spi_stop_queue(drv_data); | ||
901 | if (status) | ||
902 | return status; | ||
903 | |||
904 | /* stop hardware */ | ||
905 | bfin_sport_spi_disable(drv_data); | ||
906 | |||
907 | return status; | ||
908 | } | ||
909 | |||
910 | static int | ||
911 | bfin_sport_spi_resume(struct platform_device *pdev) | ||
912 | { | ||
913 | struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); | ||
914 | int status; | ||
915 | |||
916 | /* Enable the SPI interface */ | ||
917 | bfin_sport_spi_enable(drv_data); | ||
918 | |||
919 | /* Start the queue running */ | ||
920 | status = bfin_sport_spi_start_queue(drv_data); | ||
921 | if (status) | ||
922 | dev_err(drv_data->dev, "problem resuming queue\n"); | ||
923 | |||
924 | return status; | ||
925 | } | ||
926 | #else | ||
927 | # define bfin_sport_spi_suspend NULL | ||
928 | # define bfin_sport_spi_resume NULL | ||
929 | #endif | ||
930 | |||
931 | static struct platform_driver bfin_sport_spi_driver = { | ||
932 | .driver = { | ||
933 | .name = DRV_NAME, | ||
934 | .owner = THIS_MODULE, | ||
935 | }, | ||
936 | .probe = bfin_sport_spi_probe, | ||
937 | .remove = __devexit_p(bfin_sport_spi_remove), | ||
938 | .suspend = bfin_sport_spi_suspend, | ||
939 | .resume = bfin_sport_spi_resume, | ||
940 | }; | ||
941 | |||
942 | static int __init bfin_sport_spi_init(void) | ||
943 | { | ||
944 | return platform_driver_register(&bfin_sport_spi_driver); | ||
945 | } | ||
946 | module_init(bfin_sport_spi_init); | ||
947 | |||
948 | static void __exit bfin_sport_spi_exit(void) | ||
949 | { | ||
950 | platform_driver_unregister(&bfin_sport_spi_driver); | ||
951 | } | ||
952 | module_exit(bfin_sport_spi_exit); | ||
diff --git a/drivers/spi/tle62x0.c b/drivers/spi/tle62x0.c index a3938958147c..32a40876532f 100644 --- a/drivers/spi/tle62x0.c +++ b/drivers/spi/tle62x0.c | |||
@@ -283,7 +283,7 @@ static int __devinit tle62x0_probe(struct spi_device *spi) | |||
283 | return 0; | 283 | return 0; |
284 | 284 | ||
285 | err_gpios: | 285 | err_gpios: |
286 | for (; ptr > 0; ptr--) | 286 | while (--ptr >= 0) |
287 | device_remove_file(&spi->dev, gpio_attrs[ptr]); | 287 | device_remove_file(&spi->dev, gpio_attrs[ptr]); |
288 | 288 | ||
289 | device_remove_file(&spi->dev, &dev_attr_status_show); | 289 | device_remove_file(&spi->dev, &dev_attr_status_show); |
@@ -301,6 +301,7 @@ static int __devexit tle62x0_remove(struct spi_device *spi) | |||
301 | for (ptr = 0; ptr < st->nr_gpio; ptr++) | 301 | for (ptr = 0; ptr < st->nr_gpio; ptr++) |
302 | device_remove_file(&spi->dev, gpio_attrs[ptr]); | 302 | device_remove_file(&spi->dev, gpio_attrs[ptr]); |
303 | 303 | ||
304 | device_remove_file(&spi->dev, &dev_attr_status_show); | ||
304 | kfree(st); | 305 | kfree(st); |
305 | return 0; | 306 | return 0; |
306 | } | 307 | } |
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index aed4e464d31c..dee2a2c909f5 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <scsi/scsi_host.h> | 31 | #include <scsi/scsi_host.h> |
32 | #include <scsi/scsi_device.h> | 32 | #include <scsi/scsi_device.h> |
33 | #include <scsi/scsi_cmnd.h> | 33 | #include <scsi/scsi_cmnd.h> |
34 | #include <scsi/libsas.h> /* For TASK_ATTR_* */ | 34 | #include <scsi/scsi_tcq.h> |
35 | 35 | ||
36 | #include <target/target_core_base.h> | 36 | #include <target/target_core_base.h> |
37 | #include <target/target_core_transport.h> | 37 | #include <target/target_core_transport.h> |
@@ -95,17 +95,17 @@ static struct se_cmd *tcm_loop_allocate_core_cmd( | |||
95 | if (sc->device->tagged_supported) { | 95 | if (sc->device->tagged_supported) { |
96 | switch (sc->tag) { | 96 | switch (sc->tag) { |
97 | case HEAD_OF_QUEUE_TAG: | 97 | case HEAD_OF_QUEUE_TAG: |
98 | sam_task_attr = TASK_ATTR_HOQ; | 98 | sam_task_attr = MSG_HEAD_TAG; |
99 | break; | 99 | break; |
100 | case ORDERED_QUEUE_TAG: | 100 | case ORDERED_QUEUE_TAG: |
101 | sam_task_attr = TASK_ATTR_ORDERED; | 101 | sam_task_attr = MSG_ORDERED_TAG; |
102 | break; | 102 | break; |
103 | default: | 103 | default: |
104 | sam_task_attr = TASK_ATTR_SIMPLE; | 104 | sam_task_attr = MSG_SIMPLE_TAG; |
105 | break; | 105 | break; |
106 | } | 106 | } |
107 | } else | 107 | } else |
108 | sam_task_attr = TASK_ATTR_SIMPLE; | 108 | sam_task_attr = MSG_SIMPLE_TAG; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure | 111 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure |
@@ -379,7 +379,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) | |||
379 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure | 379 | * Initialize struct se_cmd descriptor from target_core_mod infrastructure |
380 | */ | 380 | */ |
381 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0, | 381 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0, |
382 | DMA_NONE, TASK_ATTR_SIMPLE, | 382 | DMA_NONE, MSG_SIMPLE_TAG, |
383 | &tl_cmd->tl_sense_buf[0]); | 383 | &tl_cmd->tl_sense_buf[0]); |
384 | /* | 384 | /* |
385 | * Allocate the LUN_RESET TMR | 385 | * Allocate the LUN_RESET TMR |
@@ -939,18 +939,6 @@ static u16 tcm_loop_get_fabric_sense_len(void) | |||
939 | return 0; | 939 | return 0; |
940 | } | 940 | } |
941 | 941 | ||
942 | static u64 tcm_loop_pack_lun(unsigned int lun) | ||
943 | { | ||
944 | u64 result; | ||
945 | |||
946 | /* LSB of lun into byte 1 big-endian */ | ||
947 | result = ((lun & 0xff) << 8); | ||
948 | /* use flat space addressing method */ | ||
949 | result |= 0x40 | ((lun >> 8) & 0x3f); | ||
950 | |||
951 | return cpu_to_le64(result); | ||
952 | } | ||
953 | |||
954 | static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) | 942 | static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) |
955 | { | 943 | { |
956 | switch (tl_hba->tl_proto_id) { | 944 | switch (tl_hba->tl_proto_id) { |
@@ -1481,7 +1469,6 @@ static int tcm_loop_register_configfs(void) | |||
1481 | fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len; | 1469 | fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len; |
1482 | fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len; | 1470 | fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len; |
1483 | fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove; | 1471 | fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove; |
1484 | fabric->tf_ops.pack_lun = &tcm_loop_pack_lun; | ||
1485 | 1472 | ||
1486 | tf_cg = &fabric->tf_group; | 1473 | tf_cg = &fabric->tf_group; |
1487 | /* | 1474 | /* |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index a5f44a6e6e1d..ee6fad979b50 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -497,10 +497,6 @@ static int target_fabric_tf_ops_check( | |||
497 | printk(KERN_ERR "Missing tfo->is_state_remove()\n"); | 497 | printk(KERN_ERR "Missing tfo->is_state_remove()\n"); |
498 | return -EINVAL; | 498 | return -EINVAL; |
499 | } | 499 | } |
500 | if (!(tfo->pack_lun)) { | ||
501 | printk(KERN_ERR "Missing tfo->pack_lun()\n"); | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | /* | 500 | /* |
505 | * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() | 501 | * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() |
506 | * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in | 502 | * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index d25e20829012..8407f9ca2b31 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <net/sock.h> | 38 | #include <net/sock.h> |
39 | #include <net/tcp.h> | 39 | #include <net/tcp.h> |
40 | #include <scsi/scsi.h> | 40 | #include <scsi/scsi.h> |
41 | #include <scsi/scsi_device.h> | ||
41 | 42 | ||
42 | #include <target/target_core_base.h> | 43 | #include <target/target_core_base.h> |
43 | #include <target/target_core_device.h> | 44 | #include <target/target_core_device.h> |
@@ -150,13 +151,13 @@ out: | |||
150 | 151 | ||
151 | { | 152 | { |
152 | struct se_device *dev = se_lun->lun_se_dev; | 153 | struct se_device *dev = se_lun->lun_se_dev; |
153 | spin_lock(&dev->stats_lock); | 154 | spin_lock_irq(&dev->stats_lock); |
154 | dev->num_cmds++; | 155 | dev->num_cmds++; |
155 | if (se_cmd->data_direction == DMA_TO_DEVICE) | 156 | if (se_cmd->data_direction == DMA_TO_DEVICE) |
156 | dev->write_bytes += se_cmd->data_length; | 157 | dev->write_bytes += se_cmd->data_length; |
157 | else if (se_cmd->data_direction == DMA_FROM_DEVICE) | 158 | else if (se_cmd->data_direction == DMA_FROM_DEVICE) |
158 | dev->read_bytes += se_cmd->data_length; | 159 | dev->read_bytes += se_cmd->data_length; |
159 | spin_unlock(&dev->stats_lock); | 160 | spin_unlock_irq(&dev->stats_lock); |
160 | } | 161 | } |
161 | 162 | ||
162 | /* | 163 | /* |
@@ -658,8 +659,7 @@ int transport_core_report_lun_response(struct se_cmd *se_cmd) | |||
658 | struct se_session *se_sess = SE_SESS(se_cmd); | 659 | struct se_session *se_sess = SE_SESS(se_cmd); |
659 | struct se_task *se_task; | 660 | struct se_task *se_task; |
660 | unsigned char *buf = (unsigned char *)T_TASK(se_cmd)->t_task_buf; | 661 | unsigned char *buf = (unsigned char *)T_TASK(se_cmd)->t_task_buf; |
661 | u32 cdb_offset = 0, lun_count = 0, offset = 8; | 662 | u32 cdb_offset = 0, lun_count = 0, offset = 8, i; |
662 | u64 i, lun; | ||
663 | 663 | ||
664 | list_for_each_entry(se_task, &T_TASK(se_cmd)->t_task_list, t_list) | 664 | list_for_each_entry(se_task, &T_TASK(se_cmd)->t_task_list, t_list) |
665 | break; | 665 | break; |
@@ -675,15 +675,7 @@ int transport_core_report_lun_response(struct se_cmd *se_cmd) | |||
675 | * a $FABRIC_MOD. In that case, report LUN=0 only. | 675 | * a $FABRIC_MOD. In that case, report LUN=0 only. |
676 | */ | 676 | */ |
677 | if (!(se_sess)) { | 677 | if (!(se_sess)) { |
678 | lun = 0; | 678 | int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); |
679 | buf[offset++] = ((lun >> 56) & 0xff); | ||
680 | buf[offset++] = ((lun >> 48) & 0xff); | ||
681 | buf[offset++] = ((lun >> 40) & 0xff); | ||
682 | buf[offset++] = ((lun >> 32) & 0xff); | ||
683 | buf[offset++] = ((lun >> 24) & 0xff); | ||
684 | buf[offset++] = ((lun >> 16) & 0xff); | ||
685 | buf[offset++] = ((lun >> 8) & 0xff); | ||
686 | buf[offset++] = (lun & 0xff); | ||
687 | lun_count = 1; | 679 | lun_count = 1; |
688 | goto done; | 680 | goto done; |
689 | } | 681 | } |
@@ -703,15 +695,8 @@ int transport_core_report_lun_response(struct se_cmd *se_cmd) | |||
703 | if ((cdb_offset + 8) >= se_cmd->data_length) | 695 | if ((cdb_offset + 8) >= se_cmd->data_length) |
704 | continue; | 696 | continue; |
705 | 697 | ||
706 | lun = cpu_to_be64(CMD_TFO(se_cmd)->pack_lun(deve->mapped_lun)); | 698 | int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); |
707 | buf[offset++] = ((lun >> 56) & 0xff); | 699 | offset += 8; |
708 | buf[offset++] = ((lun >> 48) & 0xff); | ||
709 | buf[offset++] = ((lun >> 40) & 0xff); | ||
710 | buf[offset++] = ((lun >> 32) & 0xff); | ||
711 | buf[offset++] = ((lun >> 24) & 0xff); | ||
712 | buf[offset++] = ((lun >> 16) & 0xff); | ||
713 | buf[offset++] = ((lun >> 8) & 0xff); | ||
714 | buf[offset++] = (lun & 0xff); | ||
715 | cdb_offset += 8; | 700 | cdb_offset += 8; |
716 | } | 701 | } |
717 | spin_unlock_irq(&SE_NODE_ACL(se_sess)->device_list_lock); | 702 | spin_unlock_irq(&SE_NODE_ACL(se_sess)->device_list_lock); |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 7ff6a35f26ac..331d423fd0e0 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <scsi/scsi_device.h> | 41 | #include <scsi/scsi_device.h> |
42 | #include <scsi/scsi_cmnd.h> | 42 | #include <scsi/scsi_cmnd.h> |
43 | #include <scsi/scsi_host.h> | 43 | #include <scsi/scsi_host.h> |
44 | #include <scsi/libsas.h> /* For TASK_ATTR_* */ | 44 | #include <scsi/scsi_tcq.h> |
45 | 45 | ||
46 | #include <target/target_core_base.h> | 46 | #include <target/target_core_base.h> |
47 | #include <target/target_core_device.h> | 47 | #include <target/target_core_device.h> |
@@ -911,7 +911,7 @@ static int pscsi_do_task(struct se_task *task) | |||
911 | * descriptor | 911 | * descriptor |
912 | */ | 912 | */ |
913 | blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, pt->pscsi_req, | 913 | blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, pt->pscsi_req, |
914 | (task->task_se_cmd->sam_task_attr == TASK_ATTR_HOQ), | 914 | (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), |
915 | pscsi_req_done); | 915 | pscsi_req_done); |
916 | 916 | ||
917 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 917 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 4a109835e420..59b8b9c5ad72 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -55,7 +55,8 @@ struct se_tmr_req *core_tmr_alloc_req( | |||
55 | { | 55 | { |
56 | struct se_tmr_req *tmr; | 56 | struct se_tmr_req *tmr; |
57 | 57 | ||
58 | tmr = kmem_cache_zalloc(se_tmr_req_cache, GFP_KERNEL); | 58 | tmr = kmem_cache_zalloc(se_tmr_req_cache, (in_interrupt()) ? |
59 | GFP_ATOMIC : GFP_KERNEL); | ||
59 | if (!(tmr)) { | 60 | if (!(tmr)) { |
60 | printk(KERN_ERR "Unable to allocate struct se_tmr_req\n"); | 61 | printk(KERN_ERR "Unable to allocate struct se_tmr_req\n"); |
61 | return ERR_PTR(-ENOMEM); | 62 | return ERR_PTR(-ENOMEM); |
@@ -398,9 +399,9 @@ int core_tmr_lun_reset( | |||
398 | printk(KERN_INFO "LUN_RESET: SCSI-2 Released reservation\n"); | 399 | printk(KERN_INFO "LUN_RESET: SCSI-2 Released reservation\n"); |
399 | } | 400 | } |
400 | 401 | ||
401 | spin_lock(&dev->stats_lock); | 402 | spin_lock_irq(&dev->stats_lock); |
402 | dev->num_resets++; | 403 | dev->num_resets++; |
403 | spin_unlock(&dev->stats_lock); | 404 | spin_unlock_irq(&dev->stats_lock); |
404 | 405 | ||
405 | DEBUG_LR("LUN_RESET: %s for [%s] Complete\n", | 406 | DEBUG_LR("LUN_RESET: %s for [%s] Complete\n", |
406 | (preempt_and_abort_list) ? "Preempt" : "TMR", | 407 | (preempt_and_abort_list) ? "Preempt" : "TMR", |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index b9d3501bdd91..4dafeb8b5638 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <net/tcp.h> | 42 | #include <net/tcp.h> |
43 | #include <scsi/scsi.h> | 43 | #include <scsi/scsi.h> |
44 | #include <scsi/scsi_cmnd.h> | 44 | #include <scsi/scsi_cmnd.h> |
45 | #include <scsi/libsas.h> /* For TASK_ATTR_* */ | 45 | #include <scsi/scsi_tcq.h> |
46 | 46 | ||
47 | #include <target/target_core_base.h> | 47 | #include <target/target_core_base.h> |
48 | #include <target/target_core_device.h> | 48 | #include <target/target_core_device.h> |
@@ -762,7 +762,6 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) | |||
762 | transport_all_task_dev_remove_state(cmd); | 762 | transport_all_task_dev_remove_state(cmd); |
763 | spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags); | 763 | spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags); |
764 | 764 | ||
765 | transport_free_dev_tasks(cmd); | ||
766 | 765 | ||
767 | check_lun: | 766 | check_lun: |
768 | spin_lock_irqsave(&lun->lun_cmd_lock, flags); | 767 | spin_lock_irqsave(&lun->lun_cmd_lock, flags); |
@@ -1075,7 +1074,7 @@ static inline int transport_add_task_check_sam_attr( | |||
1075 | * head of the struct se_device->execute_task_list, and task_prev | 1074 | * head of the struct se_device->execute_task_list, and task_prev |
1076 | * after that for each subsequent task | 1075 | * after that for each subsequent task |
1077 | */ | 1076 | */ |
1078 | if (task->task_se_cmd->sam_task_attr == TASK_ATTR_HOQ) { | 1077 | if (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG) { |
1079 | list_add(&task->t_execute_list, | 1078 | list_add(&task->t_execute_list, |
1080 | (task_prev != NULL) ? | 1079 | (task_prev != NULL) ? |
1081 | &task_prev->t_execute_list : | 1080 | &task_prev->t_execute_list : |
@@ -1195,6 +1194,7 @@ transport_get_task_from_execute_queue(struct se_device *dev) | |||
1195 | break; | 1194 | break; |
1196 | 1195 | ||
1197 | list_del(&task->t_execute_list); | 1196 | list_del(&task->t_execute_list); |
1197 | atomic_set(&task->task_execute_queue, 0); | ||
1198 | atomic_dec(&dev->execute_tasks); | 1198 | atomic_dec(&dev->execute_tasks); |
1199 | 1199 | ||
1200 | return task; | 1200 | return task; |
@@ -1210,8 +1210,14 @@ void transport_remove_task_from_execute_queue( | |||
1210 | { | 1210 | { |
1211 | unsigned long flags; | 1211 | unsigned long flags; |
1212 | 1212 | ||
1213 | if (atomic_read(&task->task_execute_queue) == 0) { | ||
1214 | dump_stack(); | ||
1215 | return; | ||
1216 | } | ||
1217 | |||
1213 | spin_lock_irqsave(&dev->execute_task_lock, flags); | 1218 | spin_lock_irqsave(&dev->execute_task_lock, flags); |
1214 | list_del(&task->t_execute_list); | 1219 | list_del(&task->t_execute_list); |
1220 | atomic_set(&task->task_execute_queue, 0); | ||
1215 | atomic_dec(&dev->execute_tasks); | 1221 | atomic_dec(&dev->execute_tasks); |
1216 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | 1222 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); |
1217 | } | 1223 | } |
@@ -1867,7 +1873,7 @@ static int transport_check_alloc_task_attr(struct se_cmd *cmd) | |||
1867 | if (SE_DEV(cmd)->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) | 1873 | if (SE_DEV(cmd)->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) |
1868 | return 0; | 1874 | return 0; |
1869 | 1875 | ||
1870 | if (cmd->sam_task_attr == TASK_ATTR_ACA) { | 1876 | if (cmd->sam_task_attr == MSG_ACA_TAG) { |
1871 | DEBUG_STA("SAM Task Attribute ACA" | 1877 | DEBUG_STA("SAM Task Attribute ACA" |
1872 | " emulation is not supported\n"); | 1878 | " emulation is not supported\n"); |
1873 | return -1; | 1879 | return -1; |
@@ -2058,6 +2064,13 @@ int transport_generic_handle_tmr( | |||
2058 | } | 2064 | } |
2059 | EXPORT_SYMBOL(transport_generic_handle_tmr); | 2065 | EXPORT_SYMBOL(transport_generic_handle_tmr); |
2060 | 2066 | ||
2067 | void transport_generic_free_cmd_intr( | ||
2068 | struct se_cmd *cmd) | ||
2069 | { | ||
2070 | transport_add_cmd_to_queue(cmd, TRANSPORT_FREE_CMD_INTR); | ||
2071 | } | ||
2072 | EXPORT_SYMBOL(transport_generic_free_cmd_intr); | ||
2073 | |||
2061 | static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) | 2074 | static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) |
2062 | { | 2075 | { |
2063 | struct se_task *task, *task_tmp; | 2076 | struct se_task *task, *task_tmp; |
@@ -2504,7 +2517,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) | |||
2504 | * Check for the existence of HEAD_OF_QUEUE, and if true return 1 | 2517 | * Check for the existence of HEAD_OF_QUEUE, and if true return 1 |
2505 | * to allow the passed struct se_cmd list of tasks to the front of the list. | 2518 | * to allow the passed struct se_cmd list of tasks to the front of the list. |
2506 | */ | 2519 | */ |
2507 | if (cmd->sam_task_attr == TASK_ATTR_HOQ) { | 2520 | if (cmd->sam_task_attr == MSG_HEAD_TAG) { |
2508 | atomic_inc(&SE_DEV(cmd)->dev_hoq_count); | 2521 | atomic_inc(&SE_DEV(cmd)->dev_hoq_count); |
2509 | smp_mb__after_atomic_inc(); | 2522 | smp_mb__after_atomic_inc(); |
2510 | DEBUG_STA("Added HEAD_OF_QUEUE for CDB:" | 2523 | DEBUG_STA("Added HEAD_OF_QUEUE for CDB:" |
@@ -2512,7 +2525,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) | |||
2512 | T_TASK(cmd)->t_task_cdb[0], | 2525 | T_TASK(cmd)->t_task_cdb[0], |
2513 | cmd->se_ordered_id); | 2526 | cmd->se_ordered_id); |
2514 | return 1; | 2527 | return 1; |
2515 | } else if (cmd->sam_task_attr == TASK_ATTR_ORDERED) { | 2528 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { |
2516 | spin_lock(&SE_DEV(cmd)->ordered_cmd_lock); | 2529 | spin_lock(&SE_DEV(cmd)->ordered_cmd_lock); |
2517 | list_add_tail(&cmd->se_ordered_list, | 2530 | list_add_tail(&cmd->se_ordered_list, |
2518 | &SE_DEV(cmd)->ordered_cmd_list); | 2531 | &SE_DEV(cmd)->ordered_cmd_list); |
@@ -3411,7 +3424,7 @@ static int transport_generic_cmd_sequencer( | |||
3411 | * See spc4r17 section 5.3 | 3424 | * See spc4r17 section 5.3 |
3412 | */ | 3425 | */ |
3413 | if (SE_DEV(cmd)->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 3426 | if (SE_DEV(cmd)->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) |
3414 | cmd->sam_task_attr = TASK_ATTR_HOQ; | 3427 | cmd->sam_task_attr = MSG_HEAD_TAG; |
3415 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB; | 3428 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB; |
3416 | break; | 3429 | break; |
3417 | case READ_BUFFER: | 3430 | case READ_BUFFER: |
@@ -3619,7 +3632,7 @@ static int transport_generic_cmd_sequencer( | |||
3619 | * See spc4r17 section 5.3 | 3632 | * See spc4r17 section 5.3 |
3620 | */ | 3633 | */ |
3621 | if (SE_DEV(cmd)->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 3634 | if (SE_DEV(cmd)->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) |
3622 | cmd->sam_task_attr = TASK_ATTR_HOQ; | 3635 | cmd->sam_task_attr = MSG_HEAD_TAG; |
3623 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB; | 3636 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB; |
3624 | break; | 3637 | break; |
3625 | default: | 3638 | default: |
@@ -3777,21 +3790,21 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
3777 | struct se_cmd *cmd_p, *cmd_tmp; | 3790 | struct se_cmd *cmd_p, *cmd_tmp; |
3778 | int new_active_tasks = 0; | 3791 | int new_active_tasks = 0; |
3779 | 3792 | ||
3780 | if (cmd->sam_task_attr == TASK_ATTR_SIMPLE) { | 3793 | if (cmd->sam_task_attr == MSG_SIMPLE_TAG) { |
3781 | atomic_dec(&dev->simple_cmds); | 3794 | atomic_dec(&dev->simple_cmds); |
3782 | smp_mb__after_atomic_dec(); | 3795 | smp_mb__after_atomic_dec(); |
3783 | dev->dev_cur_ordered_id++; | 3796 | dev->dev_cur_ordered_id++; |
3784 | DEBUG_STA("Incremented dev->dev_cur_ordered_id: %u for" | 3797 | DEBUG_STA("Incremented dev->dev_cur_ordered_id: %u for" |
3785 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, | 3798 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, |
3786 | cmd->se_ordered_id); | 3799 | cmd->se_ordered_id); |
3787 | } else if (cmd->sam_task_attr == TASK_ATTR_HOQ) { | 3800 | } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { |
3788 | atomic_dec(&dev->dev_hoq_count); | 3801 | atomic_dec(&dev->dev_hoq_count); |
3789 | smp_mb__after_atomic_dec(); | 3802 | smp_mb__after_atomic_dec(); |
3790 | dev->dev_cur_ordered_id++; | 3803 | dev->dev_cur_ordered_id++; |
3791 | DEBUG_STA("Incremented dev_cur_ordered_id: %u for" | 3804 | DEBUG_STA("Incremented dev_cur_ordered_id: %u for" |
3792 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, | 3805 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, |
3793 | cmd->se_ordered_id); | 3806 | cmd->se_ordered_id); |
3794 | } else if (cmd->sam_task_attr == TASK_ATTR_ORDERED) { | 3807 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { |
3795 | spin_lock(&dev->ordered_cmd_lock); | 3808 | spin_lock(&dev->ordered_cmd_lock); |
3796 | list_del(&cmd->se_ordered_list); | 3809 | list_del(&cmd->se_ordered_list); |
3797 | atomic_dec(&dev->dev_ordered_sync); | 3810 | atomic_dec(&dev->dev_ordered_sync); |
@@ -3824,7 +3837,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
3824 | new_active_tasks++; | 3837 | new_active_tasks++; |
3825 | 3838 | ||
3826 | spin_lock(&dev->delayed_cmd_lock); | 3839 | spin_lock(&dev->delayed_cmd_lock); |
3827 | if (cmd_p->sam_task_attr == TASK_ATTR_ORDERED) | 3840 | if (cmd_p->sam_task_attr == MSG_ORDERED_TAG) |
3828 | break; | 3841 | break; |
3829 | } | 3842 | } |
3830 | spin_unlock(&dev->delayed_cmd_lock); | 3843 | spin_unlock(&dev->delayed_cmd_lock); |
@@ -4776,18 +4789,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) | |||
4776 | sg_end_cur->page_link &= ~0x02; | 4789 | sg_end_cur->page_link &= ~0x02; |
4777 | 4790 | ||
4778 | sg_chain(sg_head, task_sg_num, sg_head_cur); | 4791 | sg_chain(sg_head, task_sg_num, sg_head_cur); |
4779 | sg_count += (task->task_sg_num + 1); | ||
4780 | } else | ||
4781 | sg_count += task->task_sg_num; | 4792 | sg_count += task->task_sg_num; |
4793 | task_sg_num = (task->task_sg_num + 1); | ||
4794 | } else { | ||
4795 | sg_chain(sg_head, task_sg_num, sg_head_cur); | ||
4796 | sg_count += task->task_sg_num; | ||
4797 | task_sg_num = task->task_sg_num; | ||
4798 | } | ||
4782 | 4799 | ||
4783 | sg_head = sg_head_cur; | 4800 | sg_head = sg_head_cur; |
4784 | sg_link = sg_link_cur; | 4801 | sg_link = sg_link_cur; |
4785 | task_sg_num = task->task_sg_num; | ||
4786 | continue; | 4802 | continue; |
4787 | } | 4803 | } |
4788 | sg_head = sg_first = &task->task_sg[0]; | 4804 | sg_head = sg_first = &task->task_sg[0]; |
4789 | sg_link = &task->task_sg[task->task_sg_num]; | 4805 | sg_link = &task->task_sg[task->task_sg_num]; |
4790 | task_sg_num = task->task_sg_num; | ||
4791 | /* | 4806 | /* |
4792 | * Check for single task.. | 4807 | * Check for single task.. |
4793 | */ | 4808 | */ |
@@ -4798,9 +4813,12 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) | |||
4798 | */ | 4813 | */ |
4799 | sg_end = &task->task_sg[task->task_sg_num - 1]; | 4814 | sg_end = &task->task_sg[task->task_sg_num - 1]; |
4800 | sg_end->page_link &= ~0x02; | 4815 | sg_end->page_link &= ~0x02; |
4801 | sg_count += (task->task_sg_num + 1); | ||
4802 | } else | ||
4803 | sg_count += task->task_sg_num; | 4816 | sg_count += task->task_sg_num; |
4817 | task_sg_num = (task->task_sg_num + 1); | ||
4818 | } else { | ||
4819 | sg_count += task->task_sg_num; | ||
4820 | task_sg_num = task->task_sg_num; | ||
4821 | } | ||
4804 | } | 4822 | } |
4805 | /* | 4823 | /* |
4806 | * Setup the starting pointer and total t_tasks_sg_linked_no including | 4824 | * Setup the starting pointer and total t_tasks_sg_linked_no including |
@@ -4809,21 +4827,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) | |||
4809 | T_TASK(cmd)->t_tasks_sg_chained = sg_first; | 4827 | T_TASK(cmd)->t_tasks_sg_chained = sg_first; |
4810 | T_TASK(cmd)->t_tasks_sg_chained_no = sg_count; | 4828 | T_TASK(cmd)->t_tasks_sg_chained_no = sg_count; |
4811 | 4829 | ||
4812 | DEBUG_CMD_M("Setup T_TASK(cmd)->t_tasks_sg_chained: %p and" | 4830 | DEBUG_CMD_M("Setup cmd: %p T_TASK(cmd)->t_tasks_sg_chained: %p and" |
4813 | " t_tasks_sg_chained_no: %u\n", T_TASK(cmd)->t_tasks_sg_chained, | 4831 | " t_tasks_sg_chained_no: %u\n", cmd, T_TASK(cmd)->t_tasks_sg_chained, |
4814 | T_TASK(cmd)->t_tasks_sg_chained_no); | 4832 | T_TASK(cmd)->t_tasks_sg_chained_no); |
4815 | 4833 | ||
4816 | for_each_sg(T_TASK(cmd)->t_tasks_sg_chained, sg, | 4834 | for_each_sg(T_TASK(cmd)->t_tasks_sg_chained, sg, |
4817 | T_TASK(cmd)->t_tasks_sg_chained_no, i) { | 4835 | T_TASK(cmd)->t_tasks_sg_chained_no, i) { |
4818 | 4836 | ||
4819 | DEBUG_CMD_M("SG: %p page: %p length: %d offset: %d\n", | 4837 | DEBUG_CMD_M("SG[%d]: %p page: %p length: %d offset: %d, magic: 0x%08x\n", |
4820 | sg, sg_page(sg), sg->length, sg->offset); | 4838 | i, sg, sg_page(sg), sg->length, sg->offset, sg->sg_magic); |
4821 | if (sg_is_chain(sg)) | 4839 | if (sg_is_chain(sg)) |
4822 | DEBUG_CMD_M("SG: %p sg_is_chain=1\n", sg); | 4840 | DEBUG_CMD_M("SG: %p sg_is_chain=1\n", sg); |
4823 | if (sg_is_last(sg)) | 4841 | if (sg_is_last(sg)) |
4824 | DEBUG_CMD_M("SG: %p sg_is_last=1\n", sg); | 4842 | DEBUG_CMD_M("SG: %p sg_is_last=1\n", sg); |
4825 | } | 4843 | } |
4826 | |||
4827 | } | 4844 | } |
4828 | EXPORT_SYMBOL(transport_do_task_sg_chain); | 4845 | EXPORT_SYMBOL(transport_do_task_sg_chain); |
4829 | 4846 | ||
@@ -5297,6 +5314,8 @@ void transport_generic_free_cmd( | |||
5297 | if (wait_for_tasks && cmd->transport_wait_for_tasks) | 5314 | if (wait_for_tasks && cmd->transport_wait_for_tasks) |
5298 | cmd->transport_wait_for_tasks(cmd, 0, 0); | 5315 | cmd->transport_wait_for_tasks(cmd, 0, 0); |
5299 | 5316 | ||
5317 | transport_free_dev_tasks(cmd); | ||
5318 | |||
5300 | transport_generic_remove(cmd, release_to_pool, | 5319 | transport_generic_remove(cmd, release_to_pool, |
5301 | session_reinstatement); | 5320 | session_reinstatement); |
5302 | } | 5321 | } |
@@ -6132,6 +6151,9 @@ get_cmd: | |||
6132 | case TRANSPORT_REMOVE: | 6151 | case TRANSPORT_REMOVE: |
6133 | transport_generic_remove(cmd, 1, 0); | 6152 | transport_generic_remove(cmd, 1, 0); |
6134 | break; | 6153 | break; |
6154 | case TRANSPORT_FREE_CMD_INTR: | ||
6155 | transport_generic_free_cmd(cmd, 0, 1, 0); | ||
6156 | break; | ||
6135 | case TRANSPORT_PROCESS_TMR: | 6157 | case TRANSPORT_PROCESS_TMR: |
6136 | transport_generic_do_tmr(cmd); | 6158 | transport_generic_do_tmr(cmd); |
6137 | break; | 6159 | break; |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 49e51778f733..c056a1132ae1 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <scsi/scsi_host.h> | 35 | #include <scsi/scsi_host.h> |
36 | #include <scsi/scsi_device.h> | 36 | #include <scsi/scsi_device.h> |
37 | #include <scsi/scsi_cmnd.h> | 37 | #include <scsi/scsi_cmnd.h> |
38 | #include <scsi/scsi_tcq.h> | ||
38 | #include <scsi/libfc.h> | 39 | #include <scsi/libfc.h> |
39 | #include <scsi/fc_encode.h> | 40 | #include <scsi/fc_encode.h> |
40 | 41 | ||
@@ -592,8 +593,25 @@ static void ft_send_cmd(struct ft_cmd *cmd) | |||
592 | case FCP_CFL_WRDATA | FCP_CFL_RDDATA: | 593 | case FCP_CFL_WRDATA | FCP_CFL_RDDATA: |
593 | goto err; /* TBD not supported by tcm_fc yet */ | 594 | goto err; /* TBD not supported by tcm_fc yet */ |
594 | } | 595 | } |
596 | /* | ||
597 | * Locate the SAM Task Attr from fc_pri_ta | ||
598 | */ | ||
599 | switch (fcp->fc_pri_ta & FCP_PTA_MASK) { | ||
600 | case FCP_PTA_HEADQ: | ||
601 | task_attr = MSG_HEAD_TAG; | ||
602 | break; | ||
603 | case FCP_PTA_ORDERED: | ||
604 | task_attr = MSG_ORDERED_TAG; | ||
605 | break; | ||
606 | case FCP_PTA_ACA: | ||
607 | task_attr = MSG_ACA_TAG; | ||
608 | break; | ||
609 | case FCP_PTA_SIMPLE: /* Fallthrough */ | ||
610 | default: | ||
611 | task_attr = MSG_SIMPLE_TAG; | ||
612 | } | ||
613 | |||
595 | 614 | ||
596 | /* FCP_PTA_ maps 1:1 to TASK_ATTR_ */ | ||
597 | task_attr = fcp->fc_pri_ta & FCP_PTA_MASK; | 615 | task_attr = fcp->fc_pri_ta & FCP_PTA_MASK; |
598 | data_len = ntohl(fcp->fc_dl); | 616 | data_len = ntohl(fcp->fc_dl); |
599 | cmd->cdb = fcp->fc_cdb; | 617 | cmd->cdb = fcp->fc_cdb; |
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index fcdbbffe88cc..84e868c255dd 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c | |||
@@ -519,13 +519,6 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg) | |||
519 | return tpg->index; | 519 | return tpg->index; |
520 | } | 520 | } |
521 | 521 | ||
522 | static u64 ft_pack_lun(unsigned int index) | ||
523 | { | ||
524 | WARN_ON(index >= 256); | ||
525 | /* Caller wants this byte-swapped */ | ||
526 | return cpu_to_le64((index & 0xff) << 8); | ||
527 | } | ||
528 | |||
529 | static struct target_core_fabric_ops ft_fabric_ops = { | 522 | static struct target_core_fabric_ops ft_fabric_ops = { |
530 | .get_fabric_name = ft_get_fabric_name, | 523 | .get_fabric_name = ft_get_fabric_name, |
531 | .get_fabric_proto_ident = fc_get_fabric_proto_ident, | 524 | .get_fabric_proto_ident = fc_get_fabric_proto_ident, |
@@ -564,7 +557,6 @@ static struct target_core_fabric_ops ft_fabric_ops = { | |||
564 | .get_fabric_sense_len = ft_get_fabric_sense_len, | 557 | .get_fabric_sense_len = ft_get_fabric_sense_len, |
565 | .set_fabric_sense_len = ft_set_fabric_sense_len, | 558 | .set_fabric_sense_len = ft_set_fabric_sense_len, |
566 | .is_state_remove = ft_is_state_remove, | 559 | .is_state_remove = ft_is_state_remove, |
567 | .pack_lun = ft_pack_lun, | ||
568 | /* | 560 | /* |
569 | * Setup function pointers for generic logic in | 561 | * Setup function pointers for generic logic in |
570 | * target_core_fabric_configfs.c | 562 | * target_core_fabric_configfs.c |
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index fc6f2a5bde01..0b1c82ad6805 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -499,7 +499,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
499 | dev_set_drvdata(hwmon->device, hwmon); | 499 | dev_set_drvdata(hwmon->device, hwmon); |
500 | result = device_create_file(hwmon->device, &dev_attr_name); | 500 | result = device_create_file(hwmon->device, &dev_attr_name); |
501 | if (result) | 501 | if (result) |
502 | goto unregister_hwmon_device; | 502 | goto free_mem; |
503 | 503 | ||
504 | register_sys_interface: | 504 | register_sys_interface: |
505 | tz->hwmon = hwmon; | 505 | tz->hwmon = hwmon; |
@@ -513,7 +513,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
513 | sysfs_attr_init(&tz->temp_input.attr.attr); | 513 | sysfs_attr_init(&tz->temp_input.attr.attr); |
514 | result = device_create_file(hwmon->device, &tz->temp_input.attr); | 514 | result = device_create_file(hwmon->device, &tz->temp_input.attr); |
515 | if (result) | 515 | if (result) |
516 | goto unregister_hwmon_device; | 516 | goto unregister_name; |
517 | 517 | ||
518 | if (tz->ops->get_crit_temp) { | 518 | if (tz->ops->get_crit_temp) { |
519 | unsigned long temperature; | 519 | unsigned long temperature; |
@@ -527,7 +527,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
527 | result = device_create_file(hwmon->device, | 527 | result = device_create_file(hwmon->device, |
528 | &tz->temp_crit.attr); | 528 | &tz->temp_crit.attr); |
529 | if (result) | 529 | if (result) |
530 | goto unregister_hwmon_device; | 530 | goto unregister_input; |
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
@@ -539,9 +539,9 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
539 | 539 | ||
540 | return 0; | 540 | return 0; |
541 | 541 | ||
542 | unregister_hwmon_device: | 542 | unregister_input: |
543 | device_remove_file(hwmon->device, &tz->temp_crit.attr); | ||
544 | device_remove_file(hwmon->device, &tz->temp_input.attr); | 543 | device_remove_file(hwmon->device, &tz->temp_input.attr); |
544 | unregister_name: | ||
545 | if (new_hwmon_device) { | 545 | if (new_hwmon_device) { |
546 | device_remove_file(hwmon->device, &dev_attr_name); | 546 | device_remove_file(hwmon->device, &dev_attr_name); |
547 | hwmon_device_unregister(hwmon->device); | 547 | hwmon_device_unregister(hwmon->device); |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 652bdac8ce8e..6d5d6e679fc7 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -1420,7 +1420,7 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1420 | port->flags = UPF_BOOT_AUTOCONF; | 1420 | port->flags = UPF_BOOT_AUTOCONF; |
1421 | port->ops = &atmel_pops; | 1421 | port->ops = &atmel_pops; |
1422 | port->fifosize = 1; | 1422 | port->fifosize = 1; |
1423 | port->line = pdev->id; | 1423 | port->line = data->num; |
1424 | port->dev = &pdev->dev; | 1424 | port->dev = &pdev->dev; |
1425 | port->mapbase = pdev->resource[0].start; | 1425 | port->mapbase = pdev->resource[0].start; |
1426 | port->irq = pdev->resource[1].start; | 1426 | port->irq = pdev->resource[1].start; |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 660b80a75cac..1102ce65a3a9 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -348,11 +348,50 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
348 | return rc; | 348 | return rc; |
349 | } | 349 | } |
350 | 350 | ||
351 | static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) | ||
352 | { | ||
353 | return pdev->class == PCI_CLASS_SERIAL_USB_EHCI && | ||
354 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
355 | pdev->device == 0x1E26; | ||
356 | } | ||
357 | |||
358 | static void ehci_enable_xhci_companion(void) | ||
359 | { | ||
360 | struct pci_dev *companion = NULL; | ||
361 | |||
362 | /* The xHCI and EHCI controllers are not on the same PCI slot */ | ||
363 | for_each_pci_dev(companion) { | ||
364 | if (!usb_is_intel_switchable_xhci(companion)) | ||
365 | continue; | ||
366 | usb_enable_xhci_ports(companion); | ||
367 | return; | ||
368 | } | ||
369 | } | ||
370 | |||
351 | static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 371 | static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) |
352 | { | 372 | { |
353 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 373 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
354 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 374 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
355 | 375 | ||
376 | /* The BIOS on systems with the Intel Panther Point chipset may or may | ||
377 | * not support xHCI natively. That means that during system resume, it | ||
378 | * may switch the ports back to EHCI so that users can use their | ||
379 | * keyboard to select a kernel from GRUB after resume from hibernate. | ||
380 | * | ||
381 | * The BIOS is supposed to remember whether the OS had xHCI ports | ||
382 | * enabled before resume, and switch the ports back to xHCI when the | ||
383 | * BIOS/OS semaphore is written, but we all know we can't trust BIOS | ||
384 | * writers. | ||
385 | * | ||
386 | * Unconditionally switch the ports back to xHCI after a system resume. | ||
387 | * We can't tell whether the EHCI or xHCI controller will be resumed | ||
388 | * first, so we have to do the port switchover in both drivers. Writing | ||
389 | * a '1' to the port switchover registers should have no effect if the | ||
390 | * port was already switched over. | ||
391 | */ | ||
392 | if (usb_is_intel_switchable_ehci(pdev)) | ||
393 | ehci_enable_xhci_companion(); | ||
394 | |||
356 | // maybe restore FLADJ | 395 | // maybe restore FLADJ |
357 | 396 | ||
358 | if (time_before(jiffies, ehci->next_statechange)) | 397 | if (time_before(jiffies, ehci->next_statechange)) |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index f16c59d5f487..fd930618c28f 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -69,6 +69,9 @@ | |||
69 | #define NB_PIF0_PWRDOWN_0 0x01100012 | 69 | #define NB_PIF0_PWRDOWN_0 0x01100012 |
70 | #define NB_PIF0_PWRDOWN_1 0x01100013 | 70 | #define NB_PIF0_PWRDOWN_1 0x01100013 |
71 | 71 | ||
72 | #define USB_INTEL_XUSB2PR 0xD0 | ||
73 | #define USB_INTEL_USB3_PSSEN 0xD8 | ||
74 | |||
72 | static struct amd_chipset_info { | 75 | static struct amd_chipset_info { |
73 | struct pci_dev *nb_dev; | 76 | struct pci_dev *nb_dev; |
74 | struct pci_dev *smbus_dev; | 77 | struct pci_dev *smbus_dev; |
@@ -673,6 +676,64 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done, | |||
673 | return -ETIMEDOUT; | 676 | return -ETIMEDOUT; |
674 | } | 677 | } |
675 | 678 | ||
679 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev) | ||
680 | { | ||
681 | return pdev->class == PCI_CLASS_SERIAL_USB_XHCI && | ||
682 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
683 | pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI; | ||
684 | } | ||
685 | EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci); | ||
686 | |||
687 | /* | ||
688 | * Intel's Panther Point chipset has two host controllers (EHCI and xHCI) that | ||
689 | * share some number of ports. These ports can be switched between either | ||
690 | * controller. Not all of the ports under the EHCI host controller may be | ||
691 | * switchable. | ||
692 | * | ||
693 | * The ports should be switched over to xHCI before PCI probes for any device | ||
694 | * start. This avoids active devices under EHCI being disconnected during the | ||
695 | * port switchover, which could cause loss of data on USB storage devices, or | ||
696 | * failed boot when the root file system is on a USB mass storage device and is | ||
697 | * enumerated under EHCI first. | ||
698 | * | ||
699 | * We write into the xHC's PCI configuration space in some Intel-specific | ||
700 | * registers to switch the ports over. The USB 3.0 terminations and the USB | ||
701 | * 2.0 data wires are switched separately. We want to enable the SuperSpeed | ||
702 | * terminations before switching the USB 2.0 wires over, so that USB 3.0 | ||
703 | * devices connect at SuperSpeed, rather than at USB 2.0 speeds. | ||
704 | */ | ||
705 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | ||
706 | { | ||
707 | u32 ports_available; | ||
708 | |||
709 | ports_available = 0xffffffff; | ||
710 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable | ||
711 | * Register, to turn on SuperSpeed terminations for all | ||
712 | * available ports. | ||
713 | */ | ||
714 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | ||
715 | cpu_to_le32(ports_available)); | ||
716 | |||
717 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | ||
718 | &ports_available); | ||
719 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | ||
720 | "under xHCI: 0x%x\n", ports_available); | ||
721 | |||
722 | ports_available = 0xffffffff; | ||
723 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to | ||
724 | * switch the USB 2.0 power and data lines over to the xHCI | ||
725 | * host. | ||
726 | */ | ||
727 | pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | ||
728 | cpu_to_le32(ports_available)); | ||
729 | |||
730 | pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | ||
731 | &ports_available); | ||
732 | dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over " | ||
733 | "to xHCI: 0x%x\n", ports_available); | ||
734 | } | ||
735 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); | ||
736 | |||
676 | /** | 737 | /** |
677 | * PCI Quirks for xHCI. | 738 | * PCI Quirks for xHCI. |
678 | * | 739 | * |
@@ -732,6 +793,8 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
732 | writel(XHCI_LEGACY_DISABLE_SMI, | 793 | writel(XHCI_LEGACY_DISABLE_SMI, |
733 | base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | 794 | base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); |
734 | 795 | ||
796 | if (usb_is_intel_switchable_xhci(pdev)) | ||
797 | usb_enable_xhci_ports(pdev); | ||
735 | hc_init: | 798 | hc_init: |
736 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | 799 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); |
737 | 800 | ||
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 6ae9f78e9938..b1002a8ef96f 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -8,6 +8,8 @@ int usb_amd_find_chipset_info(void); | |||
8 | void usb_amd_dev_put(void); | 8 | void usb_amd_dev_put(void); |
9 | void usb_amd_quirk_pll_disable(void); | 9 | void usb_amd_quirk_pll_disable(void); |
10 | void usb_amd_quirk_pll_enable(void); | 10 | void usb_amd_quirk_pll_enable(void); |
11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); | ||
12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); | ||
11 | #else | 13 | #else |
12 | static inline void usb_amd_quirk_pll_disable(void) {} | 14 | static inline void usb_amd_quirk_pll_disable(void) {} |
13 | static inline void usb_amd_quirk_pll_enable(void) {} | 15 | static inline void usb_amd_quirk_pll_enable(void) {} |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index cbc4d491e626..c408e9f6a707 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -118,6 +118,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
118 | /* AMD PLL quirk */ | 118 | /* AMD PLL quirk */ |
119 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | 119 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) |
120 | xhci->quirks |= XHCI_AMD_PLL_FIX; | 120 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
121 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
122 | pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) { | ||
123 | xhci->quirks |= XHCI_SPURIOUS_SUCCESS; | ||
124 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; | ||
125 | xhci->limit_active_eps = 64; | ||
126 | } | ||
121 | 127 | ||
122 | /* Make sure the HC is halted. */ | 128 | /* Make sure the HC is halted. */ |
123 | retval = xhci_halt(xhci); | 129 | retval = xhci_halt(xhci); |
@@ -242,8 +248,28 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
242 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 248 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) |
243 | { | 249 | { |
244 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 250 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
251 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
245 | int retval = 0; | 252 | int retval = 0; |
246 | 253 | ||
254 | /* The BIOS on systems with the Intel Panther Point chipset may or may | ||
255 | * not support xHCI natively. That means that during system resume, it | ||
256 | * may switch the ports back to EHCI so that users can use their | ||
257 | * keyboard to select a kernel from GRUB after resume from hibernate. | ||
258 | * | ||
259 | * The BIOS is supposed to remember whether the OS had xHCI ports | ||
260 | * enabled before resume, and switch the ports back to xHCI when the | ||
261 | * BIOS/OS semaphore is written, but we all know we can't trust BIOS | ||
262 | * writers. | ||
263 | * | ||
264 | * Unconditionally switch the ports back to xHCI after a system resume. | ||
265 | * We can't tell whether the EHCI or xHCI controller will be resumed | ||
266 | * first, so we have to do the port switchover in both drivers. Writing | ||
267 | * a '1' to the port switchover registers should have no effect if the | ||
268 | * port was already switched over. | ||
269 | */ | ||
270 | if (usb_is_intel_switchable_xhci(pdev)) | ||
271 | usb_enable_xhci_ports(pdev); | ||
272 | |||
247 | retval = xhci_resume(xhci, hibernated); | 273 | retval = xhci_resume(xhci, hibernated); |
248 | return retval; | 274 | return retval; |
249 | } | 275 | } |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 237a765f8d18..cc1485bfed38 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -167,12 +167,6 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
167 | next = ring->dequeue; | 167 | next = ring->dequeue; |
168 | } | 168 | } |
169 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | 169 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
170 | if (ring == xhci->event_ring) | ||
171 | xhci_dbg(xhci, "Event ring deq = 0x%llx (DMA)\n", addr); | ||
172 | else if (ring == xhci->cmd_ring) | ||
173 | xhci_dbg(xhci, "Command ring deq = 0x%llx (DMA)\n", addr); | ||
174 | else | ||
175 | xhci_dbg(xhci, "Ring deq = 0x%llx (DMA)\n", addr); | ||
176 | } | 170 | } |
177 | 171 | ||
178 | /* | 172 | /* |
@@ -248,12 +242,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
248 | next = ring->enqueue; | 242 | next = ring->enqueue; |
249 | } | 243 | } |
250 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); | 244 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); |
251 | if (ring == xhci->event_ring) | ||
252 | xhci_dbg(xhci, "Event ring enq = 0x%llx (DMA)\n", addr); | ||
253 | else if (ring == xhci->cmd_ring) | ||
254 | xhci_dbg(xhci, "Command ring enq = 0x%llx (DMA)\n", addr); | ||
255 | else | ||
256 | xhci_dbg(xhci, "Ring enq = 0x%llx (DMA)\n", addr); | ||
257 | } | 245 | } |
258 | 246 | ||
259 | /* | 247 | /* |
@@ -636,13 +624,11 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
636 | } | 624 | } |
637 | } | 625 | } |
638 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 626 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
639 | xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); | ||
640 | 627 | ||
641 | spin_unlock(&xhci->lock); | 628 | spin_unlock(&xhci->lock); |
642 | usb_hcd_giveback_urb(hcd, urb, status); | 629 | usb_hcd_giveback_urb(hcd, urb, status); |
643 | xhci_urb_free_priv(xhci, urb_priv); | 630 | xhci_urb_free_priv(xhci, urb_priv); |
644 | spin_lock(&xhci->lock); | 631 | spin_lock(&xhci->lock); |
645 | xhci_dbg(xhci, "%s URB given back\n", adjective); | ||
646 | } | 632 | } |
647 | } | 633 | } |
648 | 634 | ||
@@ -692,6 +678,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
692 | 678 | ||
693 | if (list_empty(&ep->cancelled_td_list)) { | 679 | if (list_empty(&ep->cancelled_td_list)) { |
694 | xhci_stop_watchdog_timer_in_irq(xhci, ep); | 680 | xhci_stop_watchdog_timer_in_irq(xhci, ep); |
681 | ep->stopped_td = NULL; | ||
682 | ep->stopped_trb = NULL; | ||
695 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); | 683 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); |
696 | return; | 684 | return; |
697 | } | 685 | } |
@@ -1093,8 +1081,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
1093 | complete(&xhci->addr_dev); | 1081 | complete(&xhci->addr_dev); |
1094 | break; | 1082 | break; |
1095 | case TRB_TYPE(TRB_DISABLE_SLOT): | 1083 | case TRB_TYPE(TRB_DISABLE_SLOT): |
1096 | if (xhci->devs[slot_id]) | 1084 | if (xhci->devs[slot_id]) { |
1085 | if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) | ||
1086 | /* Delete default control endpoint resources */ | ||
1087 | xhci_free_device_endpoint_resources(xhci, | ||
1088 | xhci->devs[slot_id], true); | ||
1097 | xhci_free_virt_device(xhci, slot_id); | 1089 | xhci_free_virt_device(xhci, slot_id); |
1090 | } | ||
1098 | break; | 1091 | break; |
1099 | case TRB_TYPE(TRB_CONFIG_EP): | 1092 | case TRB_TYPE(TRB_CONFIG_EP): |
1100 | virt_dev = xhci->devs[slot_id]; | 1093 | virt_dev = xhci->devs[slot_id]; |
@@ -1630,7 +1623,6 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1630 | "without IOC set??\n"); | 1623 | "without IOC set??\n"); |
1631 | *status = -ESHUTDOWN; | 1624 | *status = -ESHUTDOWN; |
1632 | } else { | 1625 | } else { |
1633 | xhci_dbg(xhci, "Successful control transfer!\n"); | ||
1634 | *status = 0; | 1626 | *status = 0; |
1635 | } | 1627 | } |
1636 | break; | 1628 | break; |
@@ -1727,7 +1719,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1727 | switch (trb_comp_code) { | 1719 | switch (trb_comp_code) { |
1728 | case COMP_SUCCESS: | 1720 | case COMP_SUCCESS: |
1729 | frame->status = 0; | 1721 | frame->status = 0; |
1730 | xhci_dbg(xhci, "Successful isoc transfer!\n"); | ||
1731 | break; | 1722 | break; |
1732 | case COMP_SHORT_TX: | 1723 | case COMP_SHORT_TX: |
1733 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? | 1724 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? |
@@ -1837,12 +1828,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1837 | else | 1828 | else |
1838 | *status = 0; | 1829 | *status = 0; |
1839 | } else { | 1830 | } else { |
1840 | if (usb_endpoint_xfer_bulk(&td->urb->ep->desc)) | ||
1841 | xhci_dbg(xhci, "Successful bulk " | ||
1842 | "transfer!\n"); | ||
1843 | else | ||
1844 | xhci_dbg(xhci, "Successful interrupt " | ||
1845 | "transfer!\n"); | ||
1846 | *status = 0; | 1831 | *status = 0; |
1847 | } | 1832 | } |
1848 | break; | 1833 | break; |
@@ -1856,11 +1841,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1856 | /* Others already handled above */ | 1841 | /* Others already handled above */ |
1857 | break; | 1842 | break; |
1858 | } | 1843 | } |
1859 | xhci_dbg(xhci, "ep %#x - asked for %d bytes, " | 1844 | if (trb_comp_code == COMP_SHORT_TX) |
1860 | "%d bytes untransferred\n", | 1845 | xhci_dbg(xhci, "ep %#x - asked for %d bytes, " |
1861 | td->urb->ep->desc.bEndpointAddress, | 1846 | "%d bytes untransferred\n", |
1862 | td->urb->transfer_buffer_length, | 1847 | td->urb->ep->desc.bEndpointAddress, |
1863 | TRB_LEN(le32_to_cpu(event->transfer_len))); | 1848 | td->urb->transfer_buffer_length, |
1849 | TRB_LEN(le32_to_cpu(event->transfer_len))); | ||
1864 | /* Fast path - was this the last TRB in the TD for this URB? */ | 1850 | /* Fast path - was this the last TRB in the TD for this URB? */ |
1865 | if (event_trb == td->last_trb) { | 1851 | if (event_trb == td->last_trb) { |
1866 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | 1852 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
@@ -1954,7 +1940,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1954 | 1940 | ||
1955 | /* Endpoint ID is 1 based, our index is zero based */ | 1941 | /* Endpoint ID is 1 based, our index is zero based */ |
1956 | ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; | 1942 | ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; |
1957 | xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index); | ||
1958 | ep = &xdev->eps[ep_index]; | 1943 | ep = &xdev->eps[ep_index]; |
1959 | ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); | 1944 | ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); |
1960 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); | 1945 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); |
@@ -2081,6 +2066,16 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2081 | if (!event_seg) { | 2066 | if (!event_seg) { |
2082 | if (!ep->skip || | 2067 | if (!ep->skip || |
2083 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { | 2068 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { |
2069 | /* Some host controllers give a spurious | ||
2070 | * successful event after a short transfer. | ||
2071 | * Ignore it. | ||
2072 | */ | ||
2073 | if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && | ||
2074 | ep_ring->last_td_was_short) { | ||
2075 | ep_ring->last_td_was_short = false; | ||
2076 | ret = 0; | ||
2077 | goto cleanup; | ||
2078 | } | ||
2084 | /* HC is busted, give up! */ | 2079 | /* HC is busted, give up! */ |
2085 | xhci_err(xhci, | 2080 | xhci_err(xhci, |
2086 | "ERROR Transfer event TRB DMA ptr not " | 2081 | "ERROR Transfer event TRB DMA ptr not " |
@@ -2091,6 +2086,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2091 | ret = skip_isoc_td(xhci, td, event, ep, &status); | 2086 | ret = skip_isoc_td(xhci, td, event, ep, &status); |
2092 | goto cleanup; | 2087 | goto cleanup; |
2093 | } | 2088 | } |
2089 | if (trb_comp_code == COMP_SHORT_TX) | ||
2090 | ep_ring->last_td_was_short = true; | ||
2091 | else | ||
2092 | ep_ring->last_td_was_short = false; | ||
2094 | 2093 | ||
2095 | if (ep->skip) { | 2094 | if (ep->skip) { |
2096 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); | 2095 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); |
@@ -2149,9 +2148,15 @@ cleanup: | |||
2149 | xhci_urb_free_priv(xhci, urb_priv); | 2148 | xhci_urb_free_priv(xhci, urb_priv); |
2150 | 2149 | ||
2151 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); | 2150 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
2152 | xhci_dbg(xhci, "Giveback URB %p, len = %d, " | 2151 | if ((urb->actual_length != urb->transfer_buffer_length && |
2153 | "status = %d\n", | 2152 | (urb->transfer_flags & |
2154 | urb, urb->actual_length, status); | 2153 | URB_SHORT_NOT_OK)) || |
2154 | status != 0) | ||
2155 | xhci_dbg(xhci, "Giveback URB %p, len = %d, " | ||
2156 | "expected = %x, status = %d\n", | ||
2157 | urb, urb->actual_length, | ||
2158 | urb->transfer_buffer_length, | ||
2159 | status); | ||
2155 | spin_unlock(&xhci->lock); | 2160 | spin_unlock(&xhci->lock); |
2156 | usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); | 2161 | usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); |
2157 | spin_lock(&xhci->lock); | 2162 | spin_lock(&xhci->lock); |
@@ -2180,7 +2185,6 @@ static int xhci_handle_event(struct xhci_hcd *xhci) | |||
2180 | int update_ptrs = 1; | 2185 | int update_ptrs = 1; |
2181 | int ret; | 2186 | int ret; |
2182 | 2187 | ||
2183 | xhci_dbg(xhci, "In %s\n", __func__); | ||
2184 | if (!xhci->event_ring || !xhci->event_ring->dequeue) { | 2188 | if (!xhci->event_ring || !xhci->event_ring->dequeue) { |
2185 | xhci->error_bitmask |= 1 << 1; | 2189 | xhci->error_bitmask |= 1 << 1; |
2186 | return 0; | 2190 | return 0; |
@@ -2193,7 +2197,6 @@ static int xhci_handle_event(struct xhci_hcd *xhci) | |||
2193 | xhci->error_bitmask |= 1 << 2; | 2197 | xhci->error_bitmask |= 1 << 2; |
2194 | return 0; | 2198 | return 0; |
2195 | } | 2199 | } |
2196 | xhci_dbg(xhci, "%s - OS owns TRB\n", __func__); | ||
2197 | 2200 | ||
2198 | /* | 2201 | /* |
2199 | * Barrier between reading the TRB_CYCLE (valid) flag above and any | 2202 | * Barrier between reading the TRB_CYCLE (valid) flag above and any |
@@ -2203,20 +2206,14 @@ static int xhci_handle_event(struct xhci_hcd *xhci) | |||
2203 | /* FIXME: Handle more event types. */ | 2206 | /* FIXME: Handle more event types. */ |
2204 | switch ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK)) { | 2207 | switch ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK)) { |
2205 | case TRB_TYPE(TRB_COMPLETION): | 2208 | case TRB_TYPE(TRB_COMPLETION): |
2206 | xhci_dbg(xhci, "%s - calling handle_cmd_completion\n", __func__); | ||
2207 | handle_cmd_completion(xhci, &event->event_cmd); | 2209 | handle_cmd_completion(xhci, &event->event_cmd); |
2208 | xhci_dbg(xhci, "%s - returned from handle_cmd_completion\n", __func__); | ||
2209 | break; | 2210 | break; |
2210 | case TRB_TYPE(TRB_PORT_STATUS): | 2211 | case TRB_TYPE(TRB_PORT_STATUS): |
2211 | xhci_dbg(xhci, "%s - calling handle_port_status\n", __func__); | ||
2212 | handle_port_status(xhci, event); | 2212 | handle_port_status(xhci, event); |
2213 | xhci_dbg(xhci, "%s - returned from handle_port_status\n", __func__); | ||
2214 | update_ptrs = 0; | 2213 | update_ptrs = 0; |
2215 | break; | 2214 | break; |
2216 | case TRB_TYPE(TRB_TRANSFER): | 2215 | case TRB_TYPE(TRB_TRANSFER): |
2217 | xhci_dbg(xhci, "%s - calling handle_tx_event\n", __func__); | ||
2218 | ret = handle_tx_event(xhci, &event->trans_event); | 2216 | ret = handle_tx_event(xhci, &event->trans_event); |
2219 | xhci_dbg(xhci, "%s - returned from handle_tx_event\n", __func__); | ||
2220 | if (ret < 0) | 2217 | if (ret < 0) |
2221 | xhci->error_bitmask |= 1 << 9; | 2218 | xhci->error_bitmask |= 1 << 9; |
2222 | else | 2219 | else |
@@ -2273,16 +2270,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) | |||
2273 | spin_unlock(&xhci->lock); | 2270 | spin_unlock(&xhci->lock); |
2274 | return IRQ_NONE; | 2271 | return IRQ_NONE; |
2275 | } | 2272 | } |
2276 | xhci_dbg(xhci, "op reg status = %08x\n", status); | ||
2277 | xhci_dbg(xhci, "Event ring dequeue ptr:\n"); | ||
2278 | xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", | ||
2279 | (unsigned long long) | ||
2280 | xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), | ||
2281 | lower_32_bits(le64_to_cpu(trb->link.segment_ptr)), | ||
2282 | upper_32_bits(le64_to_cpu(trb->link.segment_ptr)), | ||
2283 | (unsigned int) le32_to_cpu(trb->link.intr_target), | ||
2284 | (unsigned int) le32_to_cpu(trb->link.control)); | ||
2285 | |||
2286 | if (status & STS_FATAL) { | 2273 | if (status & STS_FATAL) { |
2287 | xhci_warn(xhci, "WARNING: Host System Error\n"); | 2274 | xhci_warn(xhci, "WARNING: Host System Error\n"); |
2288 | xhci_halt(xhci); | 2275 | xhci_halt(xhci); |
@@ -2397,7 +2384,6 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
2397 | u32 ep_state, unsigned int num_trbs, gfp_t mem_flags) | 2384 | u32 ep_state, unsigned int num_trbs, gfp_t mem_flags) |
2398 | { | 2385 | { |
2399 | /* Make sure the endpoint has been added to xHC schedule */ | 2386 | /* Make sure the endpoint has been added to xHC schedule */ |
2400 | xhci_dbg(xhci, "Endpoint state = 0x%x\n", ep_state); | ||
2401 | switch (ep_state) { | 2387 | switch (ep_state) { |
2402 | case EP_STATE_DISABLED: | 2388 | case EP_STATE_DISABLED: |
2403 | /* | 2389 | /* |
@@ -2434,7 +2420,6 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
2434 | struct xhci_ring *ring = ep_ring; | 2420 | struct xhci_ring *ring = ep_ring; |
2435 | union xhci_trb *next; | 2421 | union xhci_trb *next; |
2436 | 2422 | ||
2437 | xhci_dbg(xhci, "prepare_ring: pointing to link trb\n"); | ||
2438 | next = ring->enqueue; | 2423 | next = ring->enqueue; |
2439 | 2424 | ||
2440 | while (last_trb(xhci, ring, ring->enq_seg, next)) { | 2425 | while (last_trb(xhci, ring, ring->enq_seg, next)) { |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8f2a56ece44f..d9660eb97eb9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1314,8 +1314,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1314 | if (ret <= 0) | 1314 | if (ret <= 0) |
1315 | return ret; | 1315 | return ret; |
1316 | xhci = hcd_to_xhci(hcd); | 1316 | xhci = hcd_to_xhci(hcd); |
1317 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1317 | if (xhci->xhc_state & XHCI_STATE_DYING) |
1318 | return -ENODEV; | ||
1318 | 1319 | ||
1320 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | ||
1319 | drop_flag = xhci_get_endpoint_flag(&ep->desc); | 1321 | drop_flag = xhci_get_endpoint_flag(&ep->desc); |
1320 | if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { | 1322 | if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { |
1321 | xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", | 1323 | xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", |
@@ -1401,6 +1403,8 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1401 | return ret; | 1403 | return ret; |
1402 | } | 1404 | } |
1403 | xhci = hcd_to_xhci(hcd); | 1405 | xhci = hcd_to_xhci(hcd); |
1406 | if (xhci->xhc_state & XHCI_STATE_DYING) | ||
1407 | return -ENODEV; | ||
1404 | 1408 | ||
1405 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); | 1409 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); |
1406 | last_ctx = xhci_last_valid_endpoint(added_ctxs); | 1410 | last_ctx = xhci_last_valid_endpoint(added_ctxs); |
@@ -1578,6 +1582,113 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
1578 | return ret; | 1582 | return ret; |
1579 | } | 1583 | } |
1580 | 1584 | ||
1585 | static u32 xhci_count_num_new_endpoints(struct xhci_hcd *xhci, | ||
1586 | struct xhci_container_ctx *in_ctx) | ||
1587 | { | ||
1588 | struct xhci_input_control_ctx *ctrl_ctx; | ||
1589 | u32 valid_add_flags; | ||
1590 | u32 valid_drop_flags; | ||
1591 | |||
1592 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
1593 | /* Ignore the slot flag (bit 0), and the default control endpoint flag | ||
1594 | * (bit 1). The default control endpoint is added during the Address | ||
1595 | * Device command and is never removed until the slot is disabled. | ||
1596 | */ | ||
1597 | valid_add_flags = ctrl_ctx->add_flags >> 2; | ||
1598 | valid_drop_flags = ctrl_ctx->drop_flags >> 2; | ||
1599 | |||
1600 | /* Use hweight32 to count the number of ones in the add flags, or | ||
1601 | * number of endpoints added. Don't count endpoints that are changed | ||
1602 | * (both added and dropped). | ||
1603 | */ | ||
1604 | return hweight32(valid_add_flags) - | ||
1605 | hweight32(valid_add_flags & valid_drop_flags); | ||
1606 | } | ||
1607 | |||
1608 | static unsigned int xhci_count_num_dropped_endpoints(struct xhci_hcd *xhci, | ||
1609 | struct xhci_container_ctx *in_ctx) | ||
1610 | { | ||
1611 | struct xhci_input_control_ctx *ctrl_ctx; | ||
1612 | u32 valid_add_flags; | ||
1613 | u32 valid_drop_flags; | ||
1614 | |||
1615 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
1616 | valid_add_flags = ctrl_ctx->add_flags >> 2; | ||
1617 | valid_drop_flags = ctrl_ctx->drop_flags >> 2; | ||
1618 | |||
1619 | return hweight32(valid_drop_flags) - | ||
1620 | hweight32(valid_add_flags & valid_drop_flags); | ||
1621 | } | ||
1622 | |||
1623 | /* | ||
1624 | * We need to reserve the new number of endpoints before the configure endpoint | ||
1625 | * command completes. We can't subtract the dropped endpoints from the number | ||
1626 | * of active endpoints until the command completes because we can oversubscribe | ||
1627 | * the host in this case: | ||
1628 | * | ||
1629 | * - the first configure endpoint command drops more endpoints than it adds | ||
1630 | * - a second configure endpoint command that adds more endpoints is queued | ||
1631 | * - the first configure endpoint command fails, so the config is unchanged | ||
1632 | * - the second command may succeed, even though there isn't enough resources | ||
1633 | * | ||
1634 | * Must be called with xhci->lock held. | ||
1635 | */ | ||
1636 | static int xhci_reserve_host_resources(struct xhci_hcd *xhci, | ||
1637 | struct xhci_container_ctx *in_ctx) | ||
1638 | { | ||
1639 | u32 added_eps; | ||
1640 | |||
1641 | added_eps = xhci_count_num_new_endpoints(xhci, in_ctx); | ||
1642 | if (xhci->num_active_eps + added_eps > xhci->limit_active_eps) { | ||
1643 | xhci_dbg(xhci, "Not enough ep ctxs: " | ||
1644 | "%u active, need to add %u, limit is %u.\n", | ||
1645 | xhci->num_active_eps, added_eps, | ||
1646 | xhci->limit_active_eps); | ||
1647 | return -ENOMEM; | ||
1648 | } | ||
1649 | xhci->num_active_eps += added_eps; | ||
1650 | xhci_dbg(xhci, "Adding %u ep ctxs, %u now active.\n", added_eps, | ||
1651 | xhci->num_active_eps); | ||
1652 | return 0; | ||
1653 | } | ||
1654 | |||
1655 | /* | ||
1656 | * The configure endpoint was failed by the xHC for some other reason, so we | ||
1657 | * need to revert the resources that failed configuration would have used. | ||
1658 | * | ||
1659 | * Must be called with xhci->lock held. | ||
1660 | */ | ||
1661 | static void xhci_free_host_resources(struct xhci_hcd *xhci, | ||
1662 | struct xhci_container_ctx *in_ctx) | ||
1663 | { | ||
1664 | u32 num_failed_eps; | ||
1665 | |||
1666 | num_failed_eps = xhci_count_num_new_endpoints(xhci, in_ctx); | ||
1667 | xhci->num_active_eps -= num_failed_eps; | ||
1668 | xhci_dbg(xhci, "Removing %u failed ep ctxs, %u now active.\n", | ||
1669 | num_failed_eps, | ||
1670 | xhci->num_active_eps); | ||
1671 | } | ||
1672 | |||
1673 | /* | ||
1674 | * Now that the command has completed, clean up the active endpoint count by | ||
1675 | * subtracting out the endpoints that were dropped (but not changed). | ||
1676 | * | ||
1677 | * Must be called with xhci->lock held. | ||
1678 | */ | ||
1679 | static void xhci_finish_resource_reservation(struct xhci_hcd *xhci, | ||
1680 | struct xhci_container_ctx *in_ctx) | ||
1681 | { | ||
1682 | u32 num_dropped_eps; | ||
1683 | |||
1684 | num_dropped_eps = xhci_count_num_dropped_endpoints(xhci, in_ctx); | ||
1685 | xhci->num_active_eps -= num_dropped_eps; | ||
1686 | if (num_dropped_eps) | ||
1687 | xhci_dbg(xhci, "Removing %u dropped ep ctxs, %u now active.\n", | ||
1688 | num_dropped_eps, | ||
1689 | xhci->num_active_eps); | ||
1690 | } | ||
1691 | |||
1581 | /* Issue a configure endpoint command or evaluate context command | 1692 | /* Issue a configure endpoint command or evaluate context command |
1582 | * and wait for it to finish. | 1693 | * and wait for it to finish. |
1583 | */ | 1694 | */ |
@@ -1598,6 +1709,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1598 | virt_dev = xhci->devs[udev->slot_id]; | 1709 | virt_dev = xhci->devs[udev->slot_id]; |
1599 | if (command) { | 1710 | if (command) { |
1600 | in_ctx = command->in_ctx; | 1711 | in_ctx = command->in_ctx; |
1712 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK) && | ||
1713 | xhci_reserve_host_resources(xhci, in_ctx)) { | ||
1714 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1715 | xhci_warn(xhci, "Not enough host resources, " | ||
1716 | "active endpoint contexts = %u\n", | ||
1717 | xhci->num_active_eps); | ||
1718 | return -ENOMEM; | ||
1719 | } | ||
1720 | |||
1601 | cmd_completion = command->completion; | 1721 | cmd_completion = command->completion; |
1602 | cmd_status = &command->status; | 1722 | cmd_status = &command->status; |
1603 | command->command_trb = xhci->cmd_ring->enqueue; | 1723 | command->command_trb = xhci->cmd_ring->enqueue; |
@@ -1613,6 +1733,14 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1613 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); | 1733 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); |
1614 | } else { | 1734 | } else { |
1615 | in_ctx = virt_dev->in_ctx; | 1735 | in_ctx = virt_dev->in_ctx; |
1736 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK) && | ||
1737 | xhci_reserve_host_resources(xhci, in_ctx)) { | ||
1738 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1739 | xhci_warn(xhci, "Not enough host resources, " | ||
1740 | "active endpoint contexts = %u\n", | ||
1741 | xhci->num_active_eps); | ||
1742 | return -ENOMEM; | ||
1743 | } | ||
1616 | cmd_completion = &virt_dev->cmd_completion; | 1744 | cmd_completion = &virt_dev->cmd_completion; |
1617 | cmd_status = &virt_dev->cmd_status; | 1745 | cmd_status = &virt_dev->cmd_status; |
1618 | } | 1746 | } |
@@ -1627,6 +1755,8 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1627 | if (ret < 0) { | 1755 | if (ret < 0) { |
1628 | if (command) | 1756 | if (command) |
1629 | list_del(&command->cmd_list); | 1757 | list_del(&command->cmd_list); |
1758 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) | ||
1759 | xhci_free_host_resources(xhci, in_ctx); | ||
1630 | spin_unlock_irqrestore(&xhci->lock, flags); | 1760 | spin_unlock_irqrestore(&xhci->lock, flags); |
1631 | xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); | 1761 | xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); |
1632 | return -ENOMEM; | 1762 | return -ENOMEM; |
@@ -1649,8 +1779,22 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1649 | } | 1779 | } |
1650 | 1780 | ||
1651 | if (!ctx_change) | 1781 | if (!ctx_change) |
1652 | return xhci_configure_endpoint_result(xhci, udev, cmd_status); | 1782 | ret = xhci_configure_endpoint_result(xhci, udev, cmd_status); |
1653 | return xhci_evaluate_context_result(xhci, udev, cmd_status); | 1783 | else |
1784 | ret = xhci_evaluate_context_result(xhci, udev, cmd_status); | ||
1785 | |||
1786 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { | ||
1787 | spin_lock_irqsave(&xhci->lock, flags); | ||
1788 | /* If the command failed, remove the reserved resources. | ||
1789 | * Otherwise, clean up the estimate to include dropped eps. | ||
1790 | */ | ||
1791 | if (ret) | ||
1792 | xhci_free_host_resources(xhci, in_ctx); | ||
1793 | else | ||
1794 | xhci_finish_resource_reservation(xhci, in_ctx); | ||
1795 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1796 | } | ||
1797 | return ret; | ||
1654 | } | 1798 | } |
1655 | 1799 | ||
1656 | /* Called after one or more calls to xhci_add_endpoint() or | 1800 | /* Called after one or more calls to xhci_add_endpoint() or |
@@ -1676,6 +1820,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1676 | if (ret <= 0) | 1820 | if (ret <= 0) |
1677 | return ret; | 1821 | return ret; |
1678 | xhci = hcd_to_xhci(hcd); | 1822 | xhci = hcd_to_xhci(hcd); |
1823 | if (xhci->xhc_state & XHCI_STATE_DYING) | ||
1824 | return -ENODEV; | ||
1679 | 1825 | ||
1680 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1826 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); |
1681 | virt_dev = xhci->devs[udev->slot_id]; | 1827 | virt_dev = xhci->devs[udev->slot_id]; |
@@ -2266,6 +2412,34 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
2266 | } | 2412 | } |
2267 | 2413 | ||
2268 | /* | 2414 | /* |
2415 | * Deletes endpoint resources for endpoints that were active before a Reset | ||
2416 | * Device command, or a Disable Slot command. The Reset Device command leaves | ||
2417 | * the control endpoint intact, whereas the Disable Slot command deletes it. | ||
2418 | * | ||
2419 | * Must be called with xhci->lock held. | ||
2420 | */ | ||
2421 | void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, | ||
2422 | struct xhci_virt_device *virt_dev, bool drop_control_ep) | ||
2423 | { | ||
2424 | int i; | ||
2425 | unsigned int num_dropped_eps = 0; | ||
2426 | unsigned int drop_flags = 0; | ||
2427 | |||
2428 | for (i = (drop_control_ep ? 0 : 1); i < 31; i++) { | ||
2429 | if (virt_dev->eps[i].ring) { | ||
2430 | drop_flags |= 1 << i; | ||
2431 | num_dropped_eps++; | ||
2432 | } | ||
2433 | } | ||
2434 | xhci->num_active_eps -= num_dropped_eps; | ||
2435 | if (num_dropped_eps) | ||
2436 | xhci_dbg(xhci, "Dropped %u ep ctxs, flags = 0x%x, " | ||
2437 | "%u now active.\n", | ||
2438 | num_dropped_eps, drop_flags, | ||
2439 | xhci->num_active_eps); | ||
2440 | } | ||
2441 | |||
2442 | /* | ||
2269 | * This submits a Reset Device Command, which will set the device state to 0, | 2443 | * This submits a Reset Device Command, which will set the device state to 0, |
2270 | * set the device address to 0, and disable all the endpoints except the default | 2444 | * set the device address to 0, and disable all the endpoints except the default |
2271 | * control endpoint. The USB core should come back and call | 2445 | * control endpoint. The USB core should come back and call |
@@ -2406,6 +2580,14 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2406 | goto command_cleanup; | 2580 | goto command_cleanup; |
2407 | } | 2581 | } |
2408 | 2582 | ||
2583 | /* Free up host controller endpoint resources */ | ||
2584 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { | ||
2585 | spin_lock_irqsave(&xhci->lock, flags); | ||
2586 | /* Don't delete the default control endpoint resources */ | ||
2587 | xhci_free_device_endpoint_resources(xhci, virt_dev, false); | ||
2588 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2589 | } | ||
2590 | |||
2409 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ | 2591 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ |
2410 | last_freed_endpoint = 1; | 2592 | last_freed_endpoint = 1; |
2411 | for (i = 1; i < 31; ++i) { | 2593 | for (i = 1; i < 31; ++i) { |
@@ -2479,6 +2661,27 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2479 | } | 2661 | } |
2480 | 2662 | ||
2481 | /* | 2663 | /* |
2664 | * Checks if we have enough host controller resources for the default control | ||
2665 | * endpoint. | ||
2666 | * | ||
2667 | * Must be called with xhci->lock held. | ||
2668 | */ | ||
2669 | static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci) | ||
2670 | { | ||
2671 | if (xhci->num_active_eps + 1 > xhci->limit_active_eps) { | ||
2672 | xhci_dbg(xhci, "Not enough ep ctxs: " | ||
2673 | "%u active, need to add 1, limit is %u.\n", | ||
2674 | xhci->num_active_eps, xhci->limit_active_eps); | ||
2675 | return -ENOMEM; | ||
2676 | } | ||
2677 | xhci->num_active_eps += 1; | ||
2678 | xhci_dbg(xhci, "Adding 1 ep ctx, %u now active.\n", | ||
2679 | xhci->num_active_eps); | ||
2680 | return 0; | ||
2681 | } | ||
2682 | |||
2683 | |||
2684 | /* | ||
2482 | * Returns 0 if the xHC ran out of device slots, the Enable Slot command | 2685 | * Returns 0 if the xHC ran out of device slots, the Enable Slot command |
2483 | * timed out, or allocating memory failed. Returns 1 on success. | 2686 | * timed out, or allocating memory failed. Returns 1 on success. |
2484 | */ | 2687 | */ |
@@ -2513,24 +2716,39 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2513 | xhci_err(xhci, "Error while assigning device slot ID\n"); | 2716 | xhci_err(xhci, "Error while assigning device slot ID\n"); |
2514 | return 0; | 2717 | return 0; |
2515 | } | 2718 | } |
2516 | /* xhci_alloc_virt_device() does not touch rings; no need to lock. | 2719 | |
2517 | * Use GFP_NOIO, since this function can be called from | 2720 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { |
2721 | spin_lock_irqsave(&xhci->lock, flags); | ||
2722 | ret = xhci_reserve_host_control_ep_resources(xhci); | ||
2723 | if (ret) { | ||
2724 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2725 | xhci_warn(xhci, "Not enough host resources, " | ||
2726 | "active endpoint contexts = %u\n", | ||
2727 | xhci->num_active_eps); | ||
2728 | goto disable_slot; | ||
2729 | } | ||
2730 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2731 | } | ||
2732 | /* Use GFP_NOIO, since this function can be called from | ||
2518 | * xhci_discover_or_reset_device(), which may be called as part of | 2733 | * xhci_discover_or_reset_device(), which may be called as part of |
2519 | * mass storage driver error handling. | 2734 | * mass storage driver error handling. |
2520 | */ | 2735 | */ |
2521 | if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { | 2736 | if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { |
2522 | /* Disable slot, if we can do it without mem alloc */ | ||
2523 | xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); | 2737 | xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); |
2524 | spin_lock_irqsave(&xhci->lock, flags); | 2738 | goto disable_slot; |
2525 | if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) | ||
2526 | xhci_ring_cmd_db(xhci); | ||
2527 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2528 | return 0; | ||
2529 | } | 2739 | } |
2530 | udev->slot_id = xhci->slot_id; | 2740 | udev->slot_id = xhci->slot_id; |
2531 | /* Is this a LS or FS device under a HS hub? */ | 2741 | /* Is this a LS or FS device under a HS hub? */ |
2532 | /* Hub or peripherial? */ | 2742 | /* Hub or peripherial? */ |
2533 | return 1; | 2743 | return 1; |
2744 | |||
2745 | disable_slot: | ||
2746 | /* Disable slot, if we can do it without mem alloc */ | ||
2747 | spin_lock_irqsave(&xhci->lock, flags); | ||
2748 | if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) | ||
2749 | xhci_ring_cmd_db(xhci); | ||
2750 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2751 | return 0; | ||
2534 | } | 2752 | } |
2535 | 2753 | ||
2536 | /* | 2754 | /* |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e12db7cfb9bb..ac0196e7fcf1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1123,6 +1123,7 @@ struct xhci_ring { | |||
1123 | */ | 1123 | */ |
1124 | u32 cycle_state; | 1124 | u32 cycle_state; |
1125 | unsigned int stream_id; | 1125 | unsigned int stream_id; |
1126 | bool last_td_was_short; | ||
1126 | }; | 1127 | }; |
1127 | 1128 | ||
1128 | struct xhci_erst_entry { | 1129 | struct xhci_erst_entry { |
@@ -1290,6 +1291,19 @@ struct xhci_hcd { | |||
1290 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1291 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1291 | #define XHCI_NEC_HOST (1 << 2) | 1292 | #define XHCI_NEC_HOST (1 << 2) |
1292 | #define XHCI_AMD_PLL_FIX (1 << 3) | 1293 | #define XHCI_AMD_PLL_FIX (1 << 3) |
1294 | #define XHCI_SPURIOUS_SUCCESS (1 << 4) | ||
1295 | /* | ||
1296 | * Certain Intel host controllers have a limit to the number of endpoint | ||
1297 | * contexts they can handle. Ideally, they would signal that they can't handle | ||
1298 | * anymore endpoint contexts by returning a Resource Error for the Configure | ||
1299 | * Endpoint command, but they don't. Instead they expect software to keep track | ||
1300 | * of the number of active endpoints for them, across configure endpoint | ||
1301 | * commands, reset device commands, disable slot commands, and address device | ||
1302 | * commands. | ||
1303 | */ | ||
1304 | #define XHCI_EP_LIMIT_QUIRK (1 << 5) | ||
1305 | unsigned int num_active_eps; | ||
1306 | unsigned int limit_active_eps; | ||
1293 | /* There are two roothubs to keep track of bus suspend info for */ | 1307 | /* There are two roothubs to keep track of bus suspend info for */ |
1294 | struct xhci_bus_state bus_state[2]; | 1308 | struct xhci_bus_state bus_state[2]; |
1295 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ | 1309 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ |
@@ -1338,9 +1352,6 @@ static inline unsigned int xhci_readl(const struct xhci_hcd *xhci, | |||
1338 | static inline void xhci_writel(struct xhci_hcd *xhci, | 1352 | static inline void xhci_writel(struct xhci_hcd *xhci, |
1339 | const unsigned int val, __le32 __iomem *regs) | 1353 | const unsigned int val, __le32 __iomem *regs) |
1340 | { | 1354 | { |
1341 | xhci_dbg(xhci, | ||
1342 | "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n", | ||
1343 | regs, val); | ||
1344 | writel(val, regs); | 1355 | writel(val, regs); |
1345 | } | 1356 | } |
1346 | 1357 | ||
@@ -1368,9 +1379,6 @@ static inline void xhci_write_64(struct xhci_hcd *xhci, | |||
1368 | u32 val_lo = lower_32_bits(val); | 1379 | u32 val_lo = lower_32_bits(val); |
1369 | u32 val_hi = upper_32_bits(val); | 1380 | u32 val_hi = upper_32_bits(val); |
1370 | 1381 | ||
1371 | xhci_dbg(xhci, | ||
1372 | "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n", | ||
1373 | regs, (long unsigned int) val); | ||
1374 | writel(val_lo, ptr); | 1382 | writel(val_lo, ptr); |
1375 | writel(val_hi, ptr + 1); | 1383 | writel(val_hi, ptr + 1); |
1376 | } | 1384 | } |
@@ -1439,6 +1447,8 @@ void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, | |||
1439 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, | 1447 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, |
1440 | struct xhci_ep_ctx *ep_ctx, | 1448 | struct xhci_ep_ctx *ep_ctx, |
1441 | struct xhci_virt_ep *ep); | 1449 | struct xhci_virt_ep *ep); |
1450 | void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, | ||
1451 | struct xhci_virt_device *virt_dev, bool drop_control_ep); | ||
1442 | struct xhci_ring *xhci_dma_to_transfer_ring( | 1452 | struct xhci_ring *xhci_dma_to_transfer_ring( |
1443 | struct xhci_virt_ep *ep, | 1453 | struct xhci_virt_ep *ep, |
1444 | u64 address); | 1454 | u64 address); |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 2f7c76a85e53..e224a92baa16 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -144,7 +144,7 @@ static void handle_tx(struct vhost_net *net) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | mutex_lock(&vq->mutex); | 146 | mutex_lock(&vq->mutex); |
147 | vhost_disable_notify(vq); | 147 | vhost_disable_notify(&net->dev, vq); |
148 | 148 | ||
149 | if (wmem < sock->sk->sk_sndbuf / 2) | 149 | if (wmem < sock->sk->sk_sndbuf / 2) |
150 | tx_poll_stop(net); | 150 | tx_poll_stop(net); |
@@ -166,8 +166,8 @@ static void handle_tx(struct vhost_net *net) | |||
166 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); | 166 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); |
167 | break; | 167 | break; |
168 | } | 168 | } |
169 | if (unlikely(vhost_enable_notify(vq))) { | 169 | if (unlikely(vhost_enable_notify(&net->dev, vq))) { |
170 | vhost_disable_notify(vq); | 170 | vhost_disable_notify(&net->dev, vq); |
171 | continue; | 171 | continue; |
172 | } | 172 | } |
173 | break; | 173 | break; |
@@ -315,7 +315,7 @@ static void handle_rx(struct vhost_net *net) | |||
315 | return; | 315 | return; |
316 | 316 | ||
317 | mutex_lock(&vq->mutex); | 317 | mutex_lock(&vq->mutex); |
318 | vhost_disable_notify(vq); | 318 | vhost_disable_notify(&net->dev, vq); |
319 | vhost_hlen = vq->vhost_hlen; | 319 | vhost_hlen = vq->vhost_hlen; |
320 | sock_hlen = vq->sock_hlen; | 320 | sock_hlen = vq->sock_hlen; |
321 | 321 | ||
@@ -334,10 +334,10 @@ static void handle_rx(struct vhost_net *net) | |||
334 | break; | 334 | break; |
335 | /* OK, now we need to know about added descriptors. */ | 335 | /* OK, now we need to know about added descriptors. */ |
336 | if (!headcount) { | 336 | if (!headcount) { |
337 | if (unlikely(vhost_enable_notify(vq))) { | 337 | if (unlikely(vhost_enable_notify(&net->dev, vq))) { |
338 | /* They have slipped one in as we were | 338 | /* They have slipped one in as we were |
339 | * doing that: check again. */ | 339 | * doing that: check again. */ |
340 | vhost_disable_notify(vq); | 340 | vhost_disable_notify(&net->dev, vq); |
341 | continue; | 341 | continue; |
342 | } | 342 | } |
343 | /* Nothing new? Wait for eventfd to tell us | 343 | /* Nothing new? Wait for eventfd to tell us |
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 099f30230d06..734e1d74ad80 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c | |||
@@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n) | |||
49 | return; | 49 | return; |
50 | 50 | ||
51 | mutex_lock(&vq->mutex); | 51 | mutex_lock(&vq->mutex); |
52 | vhost_disable_notify(vq); | 52 | vhost_disable_notify(&n->dev, vq); |
53 | 53 | ||
54 | for (;;) { | 54 | for (;;) { |
55 | head = vhost_get_vq_desc(&n->dev, vq, vq->iov, | 55 | head = vhost_get_vq_desc(&n->dev, vq, vq->iov, |
@@ -61,8 +61,8 @@ static void handle_vq(struct vhost_test *n) | |||
61 | break; | 61 | break; |
62 | /* Nothing new? Wait for eventfd to tell us they refilled. */ | 62 | /* Nothing new? Wait for eventfd to tell us they refilled. */ |
63 | if (head == vq->num) { | 63 | if (head == vq->num) { |
64 | if (unlikely(vhost_enable_notify(vq))) { | 64 | if (unlikely(vhost_enable_notify(&n->dev, vq))) { |
65 | vhost_disable_notify(vq); | 65 | vhost_disable_notify(&n->dev, vq); |
66 | continue; | 66 | continue; |
67 | } | 67 | } |
68 | break; | 68 | break; |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7aa4eea930f1..ea966b356352 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -37,6 +37,9 @@ enum { | |||
37 | VHOST_MEMORY_F_LOG = 0x1, | 37 | VHOST_MEMORY_F_LOG = 0x1, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #define vhost_used_event(vq) ((u16 __user *)&vq->avail->ring[vq->num]) | ||
41 | #define vhost_avail_event(vq) ((u16 __user *)&vq->used->ring[vq->num]) | ||
42 | |||
40 | static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, | 43 | static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, |
41 | poll_table *pt) | 44 | poll_table *pt) |
42 | { | 45 | { |
@@ -161,6 +164,8 @@ static void vhost_vq_reset(struct vhost_dev *dev, | |||
161 | vq->last_avail_idx = 0; | 164 | vq->last_avail_idx = 0; |
162 | vq->avail_idx = 0; | 165 | vq->avail_idx = 0; |
163 | vq->last_used_idx = 0; | 166 | vq->last_used_idx = 0; |
167 | vq->signalled_used = 0; | ||
168 | vq->signalled_used_valid = false; | ||
164 | vq->used_flags = 0; | 169 | vq->used_flags = 0; |
165 | vq->log_used = false; | 170 | vq->log_used = false; |
166 | vq->log_addr = -1ull; | 171 | vq->log_addr = -1ull; |
@@ -489,16 +494,17 @@ static int memory_access_ok(struct vhost_dev *d, struct vhost_memory *mem, | |||
489 | return 1; | 494 | return 1; |
490 | } | 495 | } |
491 | 496 | ||
492 | static int vq_access_ok(unsigned int num, | 497 | static int vq_access_ok(struct vhost_dev *d, unsigned int num, |
493 | struct vring_desc __user *desc, | 498 | struct vring_desc __user *desc, |
494 | struct vring_avail __user *avail, | 499 | struct vring_avail __user *avail, |
495 | struct vring_used __user *used) | 500 | struct vring_used __user *used) |
496 | { | 501 | { |
502 | size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; | ||
497 | return access_ok(VERIFY_READ, desc, num * sizeof *desc) && | 503 | return access_ok(VERIFY_READ, desc, num * sizeof *desc) && |
498 | access_ok(VERIFY_READ, avail, | 504 | access_ok(VERIFY_READ, avail, |
499 | sizeof *avail + num * sizeof *avail->ring) && | 505 | sizeof *avail + num * sizeof *avail->ring + s) && |
500 | access_ok(VERIFY_WRITE, used, | 506 | access_ok(VERIFY_WRITE, used, |
501 | sizeof *used + num * sizeof *used->ring); | 507 | sizeof *used + num * sizeof *used->ring + s); |
502 | } | 508 | } |
503 | 509 | ||
504 | /* Can we log writes? */ | 510 | /* Can we log writes? */ |
@@ -514,9 +520,11 @@ int vhost_log_access_ok(struct vhost_dev *dev) | |||
514 | 520 | ||
515 | /* Verify access for write logging. */ | 521 | /* Verify access for write logging. */ |
516 | /* Caller should have vq mutex and device mutex */ | 522 | /* Caller should have vq mutex and device mutex */ |
517 | static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base) | 523 | static int vq_log_access_ok(struct vhost_dev *d, struct vhost_virtqueue *vq, |
524 | void __user *log_base) | ||
518 | { | 525 | { |
519 | struct vhost_memory *mp; | 526 | struct vhost_memory *mp; |
527 | size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; | ||
520 | 528 | ||
521 | mp = rcu_dereference_protected(vq->dev->memory, | 529 | mp = rcu_dereference_protected(vq->dev->memory, |
522 | lockdep_is_held(&vq->mutex)); | 530 | lockdep_is_held(&vq->mutex)); |
@@ -524,15 +532,15 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base) | |||
524 | vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) && | 532 | vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) && |
525 | (!vq->log_used || log_access_ok(log_base, vq->log_addr, | 533 | (!vq->log_used || log_access_ok(log_base, vq->log_addr, |
526 | sizeof *vq->used + | 534 | sizeof *vq->used + |
527 | vq->num * sizeof *vq->used->ring)); | 535 | vq->num * sizeof *vq->used->ring + s)); |
528 | } | 536 | } |
529 | 537 | ||
530 | /* Can we start vq? */ | 538 | /* Can we start vq? */ |
531 | /* Caller should have vq mutex and device mutex */ | 539 | /* Caller should have vq mutex and device mutex */ |
532 | int vhost_vq_access_ok(struct vhost_virtqueue *vq) | 540 | int vhost_vq_access_ok(struct vhost_virtqueue *vq) |
533 | { | 541 | { |
534 | return vq_access_ok(vq->num, vq->desc, vq->avail, vq->used) && | 542 | return vq_access_ok(vq->dev, vq->num, vq->desc, vq->avail, vq->used) && |
535 | vq_log_access_ok(vq, vq->log_base); | 543 | vq_log_access_ok(vq->dev, vq, vq->log_base); |
536 | } | 544 | } |
537 | 545 | ||
538 | static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | 546 | static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) |
@@ -577,6 +585,7 @@ static int init_used(struct vhost_virtqueue *vq, | |||
577 | 585 | ||
578 | if (r) | 586 | if (r) |
579 | return r; | 587 | return r; |
588 | vq->signalled_used_valid = false; | ||
580 | return get_user(vq->last_used_idx, &used->idx); | 589 | return get_user(vq->last_used_idx, &used->idx); |
581 | } | 590 | } |
582 | 591 | ||
@@ -674,7 +683,7 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
674 | * If it is not, we don't as size might not have been setup. | 683 | * If it is not, we don't as size might not have been setup. |
675 | * We will verify when backend is configured. */ | 684 | * We will verify when backend is configured. */ |
676 | if (vq->private_data) { | 685 | if (vq->private_data) { |
677 | if (!vq_access_ok(vq->num, | 686 | if (!vq_access_ok(d, vq->num, |
678 | (void __user *)(unsigned long)a.desc_user_addr, | 687 | (void __user *)(unsigned long)a.desc_user_addr, |
679 | (void __user *)(unsigned long)a.avail_user_addr, | 688 | (void __user *)(unsigned long)a.avail_user_addr, |
680 | (void __user *)(unsigned long)a.used_user_addr)) { | 689 | (void __user *)(unsigned long)a.used_user_addr)) { |
@@ -818,7 +827,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg) | |||
818 | vq = d->vqs + i; | 827 | vq = d->vqs + i; |
819 | mutex_lock(&vq->mutex); | 828 | mutex_lock(&vq->mutex); |
820 | /* If ring is inactive, will check when it's enabled. */ | 829 | /* If ring is inactive, will check when it's enabled. */ |
821 | if (vq->private_data && !vq_log_access_ok(vq, base)) | 830 | if (vq->private_data && !vq_log_access_ok(d, vq, base)) |
822 | r = -EFAULT; | 831 | r = -EFAULT; |
823 | else | 832 | else |
824 | vq->log_base = base; | 833 | vq->log_base = base; |
@@ -1219,6 +1228,10 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq, | |||
1219 | 1228 | ||
1220 | /* On success, increment avail index. */ | 1229 | /* On success, increment avail index. */ |
1221 | vq->last_avail_idx++; | 1230 | vq->last_avail_idx++; |
1231 | |||
1232 | /* Assume notifications from guest are disabled at this point, | ||
1233 | * if they aren't we would need to update avail_event index. */ | ||
1234 | BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY)); | ||
1222 | return head; | 1235 | return head; |
1223 | } | 1236 | } |
1224 | 1237 | ||
@@ -1267,6 +1280,12 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len) | |||
1267 | eventfd_signal(vq->log_ctx, 1); | 1280 | eventfd_signal(vq->log_ctx, 1); |
1268 | } | 1281 | } |
1269 | vq->last_used_idx++; | 1282 | vq->last_used_idx++; |
1283 | /* If the driver never bothers to signal in a very long while, | ||
1284 | * used index might wrap around. If that happens, invalidate | ||
1285 | * signalled_used index we stored. TODO: make sure driver | ||
1286 | * signals at least once in 2^16 and remove this. */ | ||
1287 | if (unlikely(vq->last_used_idx == vq->signalled_used)) | ||
1288 | vq->signalled_used_valid = false; | ||
1270 | return 0; | 1289 | return 0; |
1271 | } | 1290 | } |
1272 | 1291 | ||
@@ -1275,6 +1294,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, | |||
1275 | unsigned count) | 1294 | unsigned count) |
1276 | { | 1295 | { |
1277 | struct vring_used_elem __user *used; | 1296 | struct vring_used_elem __user *used; |
1297 | u16 old, new; | ||
1278 | int start; | 1298 | int start; |
1279 | 1299 | ||
1280 | start = vq->last_used_idx % vq->num; | 1300 | start = vq->last_used_idx % vq->num; |
@@ -1292,7 +1312,14 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, | |||
1292 | ((void __user *)used - (void __user *)vq->used), | 1312 | ((void __user *)used - (void __user *)vq->used), |
1293 | count * sizeof *used); | 1313 | count * sizeof *used); |
1294 | } | 1314 | } |
1295 | vq->last_used_idx += count; | 1315 | old = vq->last_used_idx; |
1316 | new = (vq->last_used_idx += count); | ||
1317 | /* If the driver never bothers to signal in a very long while, | ||
1318 | * used index might wrap around. If that happens, invalidate | ||
1319 | * signalled_used index we stored. TODO: make sure driver | ||
1320 | * signals at least once in 2^16 and remove this. */ | ||
1321 | if (unlikely((u16)(new - vq->signalled_used) < (u16)(new - old))) | ||
1322 | vq->signalled_used_valid = false; | ||
1296 | return 0; | 1323 | return 0; |
1297 | } | 1324 | } |
1298 | 1325 | ||
@@ -1331,29 +1358,47 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, | |||
1331 | return r; | 1358 | return r; |
1332 | } | 1359 | } |
1333 | 1360 | ||
1334 | /* This actually signals the guest, using eventfd. */ | 1361 | static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1335 | void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) | ||
1336 | { | 1362 | { |
1337 | __u16 flags; | 1363 | __u16 old, new, event; |
1338 | 1364 | bool v; | |
1339 | /* Flush out used index updates. This is paired | 1365 | /* Flush out used index updates. This is paired |
1340 | * with the barrier that the Guest executes when enabling | 1366 | * with the barrier that the Guest executes when enabling |
1341 | * interrupts. */ | 1367 | * interrupts. */ |
1342 | smp_mb(); | 1368 | smp_mb(); |
1343 | 1369 | ||
1344 | if (__get_user(flags, &vq->avail->flags)) { | 1370 | if (vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY) && |
1345 | vq_err(vq, "Failed to get flags"); | 1371 | unlikely(vq->avail_idx == vq->last_avail_idx)) |
1346 | return; | 1372 | return true; |
1373 | |||
1374 | if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { | ||
1375 | __u16 flags; | ||
1376 | if (__get_user(flags, &vq->avail->flags)) { | ||
1377 | vq_err(vq, "Failed to get flags"); | ||
1378 | return true; | ||
1379 | } | ||
1380 | return !(flags & VRING_AVAIL_F_NO_INTERRUPT); | ||
1347 | } | 1381 | } |
1382 | old = vq->signalled_used; | ||
1383 | v = vq->signalled_used_valid; | ||
1384 | new = vq->signalled_used = vq->last_used_idx; | ||
1385 | vq->signalled_used_valid = true; | ||
1348 | 1386 | ||
1349 | /* If they don't want an interrupt, don't signal, unless empty. */ | 1387 | if (unlikely(!v)) |
1350 | if ((flags & VRING_AVAIL_F_NO_INTERRUPT) && | 1388 | return true; |
1351 | (vq->avail_idx != vq->last_avail_idx || | ||
1352 | !vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY))) | ||
1353 | return; | ||
1354 | 1389 | ||
1390 | if (get_user(event, vhost_used_event(vq))) { | ||
1391 | vq_err(vq, "Failed to get used event idx"); | ||
1392 | return true; | ||
1393 | } | ||
1394 | return vring_need_event(event, new, old); | ||
1395 | } | ||
1396 | |||
1397 | /* This actually signals the guest, using eventfd. */ | ||
1398 | void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) | ||
1399 | { | ||
1355 | /* Signal the Guest tell them we used something up. */ | 1400 | /* Signal the Guest tell them we used something up. */ |
1356 | if (vq->call_ctx) | 1401 | if (vq->call_ctx && vhost_notify(dev, vq)) |
1357 | eventfd_signal(vq->call_ctx, 1); | 1402 | eventfd_signal(vq->call_ctx, 1); |
1358 | } | 1403 | } |
1359 | 1404 | ||
@@ -1376,7 +1421,7 @@ void vhost_add_used_and_signal_n(struct vhost_dev *dev, | |||
1376 | } | 1421 | } |
1377 | 1422 | ||
1378 | /* OK, now we need to know about added descriptors. */ | 1423 | /* OK, now we need to know about added descriptors. */ |
1379 | bool vhost_enable_notify(struct vhost_virtqueue *vq) | 1424 | bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1380 | { | 1425 | { |
1381 | u16 avail_idx; | 1426 | u16 avail_idx; |
1382 | int r; | 1427 | int r; |
@@ -1384,11 +1429,34 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq) | |||
1384 | if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY)) | 1429 | if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY)) |
1385 | return false; | 1430 | return false; |
1386 | vq->used_flags &= ~VRING_USED_F_NO_NOTIFY; | 1431 | vq->used_flags &= ~VRING_USED_F_NO_NOTIFY; |
1387 | r = put_user(vq->used_flags, &vq->used->flags); | 1432 | if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { |
1388 | if (r) { | 1433 | r = put_user(vq->used_flags, &vq->used->flags); |
1389 | vq_err(vq, "Failed to enable notification at %p: %d\n", | 1434 | if (r) { |
1390 | &vq->used->flags, r); | 1435 | vq_err(vq, "Failed to enable notification at %p: %d\n", |
1391 | return false; | 1436 | &vq->used->flags, r); |
1437 | return false; | ||
1438 | } | ||
1439 | } else { | ||
1440 | r = put_user(vq->avail_idx, vhost_avail_event(vq)); | ||
1441 | if (r) { | ||
1442 | vq_err(vq, "Failed to update avail event index at %p: %d\n", | ||
1443 | vhost_avail_event(vq), r); | ||
1444 | return false; | ||
1445 | } | ||
1446 | } | ||
1447 | if (unlikely(vq->log_used)) { | ||
1448 | void __user *used; | ||
1449 | /* Make sure data is seen before log. */ | ||
1450 | smp_wmb(); | ||
1451 | used = vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX) ? | ||
1452 | &vq->used->flags : vhost_avail_event(vq); | ||
1453 | /* Log used flags or event index entry write. Both are 16 bit | ||
1454 | * fields. */ | ||
1455 | log_write(vq->log_base, vq->log_addr + | ||
1456 | (used - (void __user *)vq->used), | ||
1457 | sizeof(u16)); | ||
1458 | if (vq->log_ctx) | ||
1459 | eventfd_signal(vq->log_ctx, 1); | ||
1392 | } | 1460 | } |
1393 | /* They could have slipped one in as we were doing that: make | 1461 | /* They could have slipped one in as we were doing that: make |
1394 | * sure it's written, then check again. */ | 1462 | * sure it's written, then check again. */ |
@@ -1404,15 +1472,17 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq) | |||
1404 | } | 1472 | } |
1405 | 1473 | ||
1406 | /* We don't need to be notified again. */ | 1474 | /* We don't need to be notified again. */ |
1407 | void vhost_disable_notify(struct vhost_virtqueue *vq) | 1475 | void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1408 | { | 1476 | { |
1409 | int r; | 1477 | int r; |
1410 | 1478 | ||
1411 | if (vq->used_flags & VRING_USED_F_NO_NOTIFY) | 1479 | if (vq->used_flags & VRING_USED_F_NO_NOTIFY) |
1412 | return; | 1480 | return; |
1413 | vq->used_flags |= VRING_USED_F_NO_NOTIFY; | 1481 | vq->used_flags |= VRING_USED_F_NO_NOTIFY; |
1414 | r = put_user(vq->used_flags, &vq->used->flags); | 1482 | if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { |
1415 | if (r) | 1483 | r = put_user(vq->used_flags, &vq->used->flags); |
1416 | vq_err(vq, "Failed to enable notification at %p: %d\n", | 1484 | if (r) |
1417 | &vq->used->flags, r); | 1485 | vq_err(vq, "Failed to enable notification at %p: %d\n", |
1486 | &vq->used->flags, r); | ||
1487 | } | ||
1418 | } | 1488 | } |
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index b3363ae38518..8e03379dd30f 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -84,6 +84,12 @@ struct vhost_virtqueue { | |||
84 | /* Used flags */ | 84 | /* Used flags */ |
85 | u16 used_flags; | 85 | u16 used_flags; |
86 | 86 | ||
87 | /* Last used index value we have signalled on */ | ||
88 | u16 signalled_used; | ||
89 | |||
90 | /* Last used index value we have signalled on */ | ||
91 | bool signalled_used_valid; | ||
92 | |||
87 | /* Log writes to used structure. */ | 93 | /* Log writes to used structure. */ |
88 | bool log_used; | 94 | bool log_used; |
89 | u64 log_addr; | 95 | u64 log_addr; |
@@ -149,8 +155,8 @@ void vhost_add_used_and_signal(struct vhost_dev *, struct vhost_virtqueue *, | |||
149 | void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, | 155 | void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, |
150 | struct vring_used_elem *heads, unsigned count); | 156 | struct vring_used_elem *heads, unsigned count); |
151 | void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); | 157 | void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); |
152 | void vhost_disable_notify(struct vhost_virtqueue *); | 158 | void vhost_disable_notify(struct vhost_dev *, struct vhost_virtqueue *); |
153 | bool vhost_enable_notify(struct vhost_virtqueue *); | 159 | bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); |
154 | 160 | ||
155 | int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | 161 | int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, |
156 | unsigned int log_num, u64 len); | 162 | unsigned int log_num, u64 len); |
@@ -162,11 +168,12 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | |||
162 | } while (0) | 168 | } while (0) |
163 | 169 | ||
164 | enum { | 170 | enum { |
165 | VHOST_FEATURES = (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | | 171 | VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | |
166 | (1 << VIRTIO_RING_F_INDIRECT_DESC) | | 172 | (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | |
167 | (1 << VHOST_F_LOG_ALL) | | 173 | (1ULL << VIRTIO_RING_F_EVENT_IDX) | |
168 | (1 << VHOST_NET_F_VIRTIO_NET_HDR) | | 174 | (1ULL << VHOST_F_LOG_ALL) | |
169 | (1 << VIRTIO_NET_F_MRG_RXBUF), | 175 | (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | |
176 | (1ULL << VIRTIO_NET_F_MRG_RXBUF), | ||
170 | }; | 177 | }; |
171 | 178 | ||
172 | static inline int vhost_has_feature(struct vhost_dev *dev, int bit) | 179 | static inline int vhost_has_feature(struct vhost_dev *dev, int bit) |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 0f1da45ba47d..e058ace2a4ad 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -40,9 +40,6 @@ struct virtio_balloon | |||
40 | /* Waiting for host to ack the pages we released. */ | 40 | /* Waiting for host to ack the pages we released. */ |
41 | struct completion acked; | 41 | struct completion acked; |
42 | 42 | ||
43 | /* Do we have to tell Host *before* we reuse pages? */ | ||
44 | bool tell_host_first; | ||
45 | |||
46 | /* The pages we've told the Host we're not using. */ | 43 | /* The pages we've told the Host we're not using. */ |
47 | unsigned int num_pages; | 44 | unsigned int num_pages; |
48 | struct list_head pages; | 45 | struct list_head pages; |
@@ -151,13 +148,14 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) | |||
151 | vb->num_pages--; | 148 | vb->num_pages--; |
152 | } | 149 | } |
153 | 150 | ||
154 | if (vb->tell_host_first) { | 151 | |
155 | tell_host(vb, vb->deflate_vq); | 152 | /* |
156 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | 153 | * Note that if |
157 | } else { | 154 | * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); |
158 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | 155 | * is true, we *have* to do it in this order |
159 | tell_host(vb, vb->deflate_vq); | 156 | */ |
160 | } | 157 | tell_host(vb, vb->deflate_vq); |
158 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | ||
161 | } | 159 | } |
162 | 160 | ||
163 | static inline void update_stat(struct virtio_balloon *vb, int idx, | 161 | static inline void update_stat(struct virtio_balloon *vb, int idx, |
@@ -325,9 +323,6 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
325 | goto out_del_vqs; | 323 | goto out_del_vqs; |
326 | } | 324 | } |
327 | 325 | ||
328 | vb->tell_host_first | ||
329 | = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); | ||
330 | |||
331 | return 0; | 326 | return 0; |
332 | 327 | ||
333 | out_del_vqs: | 328 | out_del_vqs: |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index b0043fb26a4d..68b9136847af 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -82,6 +82,9 @@ struct vring_virtqueue | |||
82 | /* Host supports indirect buffers */ | 82 | /* Host supports indirect buffers */ |
83 | bool indirect; | 83 | bool indirect; |
84 | 84 | ||
85 | /* Host publishes avail event idx */ | ||
86 | bool event; | ||
87 | |||
85 | /* Number of free buffers */ | 88 | /* Number of free buffers */ |
86 | unsigned int num_free; | 89 | unsigned int num_free; |
87 | /* Head of free buffer list. */ | 90 | /* Head of free buffer list. */ |
@@ -237,18 +240,22 @@ EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); | |||
237 | void virtqueue_kick(struct virtqueue *_vq) | 240 | void virtqueue_kick(struct virtqueue *_vq) |
238 | { | 241 | { |
239 | struct vring_virtqueue *vq = to_vvq(_vq); | 242 | struct vring_virtqueue *vq = to_vvq(_vq); |
243 | u16 new, old; | ||
240 | START_USE(vq); | 244 | START_USE(vq); |
241 | /* Descriptors and available array need to be set before we expose the | 245 | /* Descriptors and available array need to be set before we expose the |
242 | * new available array entries. */ | 246 | * new available array entries. */ |
243 | virtio_wmb(); | 247 | virtio_wmb(); |
244 | 248 | ||
245 | vq->vring.avail->idx += vq->num_added; | 249 | old = vq->vring.avail->idx; |
250 | new = vq->vring.avail->idx = old + vq->num_added; | ||
246 | vq->num_added = 0; | 251 | vq->num_added = 0; |
247 | 252 | ||
248 | /* Need to update avail index before checking if we should notify */ | 253 | /* Need to update avail index before checking if we should notify */ |
249 | virtio_mb(); | 254 | virtio_mb(); |
250 | 255 | ||
251 | if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) | 256 | if (vq->event ? |
257 | vring_need_event(vring_avail_event(&vq->vring), new, old) : | ||
258 | !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) | ||
252 | /* Prod other side to tell it about changes. */ | 259 | /* Prod other side to tell it about changes. */ |
253 | vq->notify(&vq->vq); | 260 | vq->notify(&vq->vq); |
254 | 261 | ||
@@ -324,6 +331,14 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) | |||
324 | ret = vq->data[i]; | 331 | ret = vq->data[i]; |
325 | detach_buf(vq, i); | 332 | detach_buf(vq, i); |
326 | vq->last_used_idx++; | 333 | vq->last_used_idx++; |
334 | /* If we expect an interrupt for the next entry, tell host | ||
335 | * by writing event index and flush out the write before | ||
336 | * the read in the next get_buf call. */ | ||
337 | if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) { | ||
338 | vring_used_event(&vq->vring) = vq->last_used_idx; | ||
339 | virtio_mb(); | ||
340 | } | ||
341 | |||
327 | END_USE(vq); | 342 | END_USE(vq); |
328 | return ret; | 343 | return ret; |
329 | } | 344 | } |
@@ -345,7 +360,11 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) | |||
345 | 360 | ||
346 | /* We optimistically turn back on interrupts, then check if there was | 361 | /* We optimistically turn back on interrupts, then check if there was |
347 | * more to do. */ | 362 | * more to do. */ |
363 | /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to | ||
364 | * either clear the flags bit or point the event index at the next | ||
365 | * entry. Always do both to keep code simple. */ | ||
348 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; | 366 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; |
367 | vring_used_event(&vq->vring) = vq->last_used_idx; | ||
349 | virtio_mb(); | 368 | virtio_mb(); |
350 | if (unlikely(more_used(vq))) { | 369 | if (unlikely(more_used(vq))) { |
351 | END_USE(vq); | 370 | END_USE(vq); |
@@ -357,6 +376,33 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) | |||
357 | } | 376 | } |
358 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); | 377 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); |
359 | 378 | ||
379 | bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) | ||
380 | { | ||
381 | struct vring_virtqueue *vq = to_vvq(_vq); | ||
382 | u16 bufs; | ||
383 | |||
384 | START_USE(vq); | ||
385 | |||
386 | /* We optimistically turn back on interrupts, then check if there was | ||
387 | * more to do. */ | ||
388 | /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to | ||
389 | * either clear the flags bit or point the event index at the next | ||
390 | * entry. Always do both to keep code simple. */ | ||
391 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; | ||
392 | /* TODO: tune this threshold */ | ||
393 | bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4; | ||
394 | vring_used_event(&vq->vring) = vq->last_used_idx + bufs; | ||
395 | virtio_mb(); | ||
396 | if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) { | ||
397 | END_USE(vq); | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | END_USE(vq); | ||
402 | return true; | ||
403 | } | ||
404 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed); | ||
405 | |||
360 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) | 406 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) |
361 | { | 407 | { |
362 | struct vring_virtqueue *vq = to_vvq(_vq); | 408 | struct vring_virtqueue *vq = to_vvq(_vq); |
@@ -438,6 +484,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
438 | #endif | 484 | #endif |
439 | 485 | ||
440 | vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC); | 486 | vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC); |
487 | vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); | ||
441 | 488 | ||
442 | /* No callback? Tell other side not to bother us. */ | 489 | /* No callback? Tell other side not to bother us. */ |
443 | if (!callback) | 490 | if (!callback) |
@@ -472,6 +519,8 @@ void vring_transport_features(struct virtio_device *vdev) | |||
472 | switch (i) { | 519 | switch (i) { |
473 | case VIRTIO_RING_F_INDIRECT_DESC: | 520 | case VIRTIO_RING_F_INDIRECT_DESC: |
474 | break; | 521 | break; |
522 | case VIRTIO_RING_F_EVENT_IDX: | ||
523 | break; | ||
475 | default: | 524 | default: |
476 | /* We don't understand this bit. */ | 525 | /* We don't understand this bit. */ |
477 | clear_bit(i, vdev->features); | 526 | clear_bit(i, vdev->features); |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 8d7f3e69ae29..7f6c67703195 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -814,7 +814,6 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d) | |||
814 | 814 | ||
815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
816 | { | 816 | { |
817 | dentry_unhash(d); | ||
818 | return v9fs_remove(i, d, 1); | 817 | return v9fs_remove(i, d, 1); |
819 | } | 818 | } |
820 | 819 | ||
@@ -840,9 +839,6 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
840 | struct p9_fid *newdirfid; | 839 | struct p9_fid *newdirfid; |
841 | struct p9_wstat wstat; | 840 | struct p9_wstat wstat; |
842 | 841 | ||
843 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
844 | dentry_unhash(new_dentry); | ||
845 | |||
846 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 842 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
847 | retval = 0; | 843 | retval = 0; |
848 | old_inode = old_dentry->d_inode; | 844 | old_inode = old_dentry->d_inode; |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 03330e2e390c..e3e9efc1fdd8 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -320,8 +320,6 @@ affs_rmdir(struct inode *dir, struct dentry *dentry) | |||
320 | dentry->d_inode->i_ino, | 320 | dentry->d_inode->i_ino, |
321 | (int)dentry->d_name.len, dentry->d_name.name); | 321 | (int)dentry->d_name.len, dentry->d_name.name); |
322 | 322 | ||
323 | dentry_unhash(dentry); | ||
324 | |||
325 | return affs_remove_header(dentry); | 323 | return affs_remove_header(dentry); |
326 | } | 324 | } |
327 | 325 | ||
@@ -419,9 +417,6 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
419 | struct buffer_head *bh = NULL; | 417 | struct buffer_head *bh = NULL; |
420 | int retval; | 418 | int retval; |
421 | 419 | ||
422 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
423 | dentry_unhash(new_dentry); | ||
424 | |||
425 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", | 420 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", |
426 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, | 421 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, |
427 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); | 422 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 2c4e05160042..20c106f24927 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -845,8 +845,6 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) | |||
845 | _enter("{%x:%u},{%s}", | 845 | _enter("{%x:%u},{%s}", |
846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); | 846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); |
847 | 847 | ||
848 | dentry_unhash(dentry); | ||
849 | |||
850 | ret = -ENAMETOOLONG; | 848 | ret = -ENAMETOOLONG; |
851 | if (dentry->d_name.len >= AFSNAMEMAX) | 849 | if (dentry->d_name.len >= AFSNAMEMAX) |
852 | goto error; | 850 | goto error; |
@@ -1148,9 +1146,6 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1148 | struct key *key; | 1146 | struct key *key; |
1149 | int ret; | 1147 | int ret; |
1150 | 1148 | ||
1151 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
1152 | dentry_unhash(new_dentry); | ||
1153 | |||
1154 | vnode = AFS_FS_I(old_dentry->d_inode); | 1149 | vnode = AFS_FS_I(old_dentry->d_inode); |
1155 | orig_dvnode = AFS_FS_I(old_dir); | 1150 | orig_dvnode = AFS_FS_I(old_dir); |
1156 | new_dvnode = AFS_FS_I(new_dir); | 1151 | new_dvnode = AFS_FS_I(new_dir); |
@@ -175,6 +175,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
175 | return -EPERM; | 175 | return -EPERM; |
176 | } | 176 | } |
177 | 177 | ||
178 | if ((ia_valid & ATTR_MODE)) { | ||
179 | mode_t amode = attr->ia_mode; | ||
180 | /* Flag setting protected by i_mutex */ | ||
181 | if (is_sxid(amode)) | ||
182 | inode->i_flags &= ~S_NOSEC; | ||
183 | } | ||
184 | |||
178 | now = current_fs_time(inode->i_sb); | 185 | now = current_fs_time(inode->i_sb); |
179 | 186 | ||
180 | attr->ia_ctime = now; | 187 | attr->ia_ctime = now; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 87d95a8cddbc..f55ae23b137e 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -583,8 +583,6 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) | 583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) |
584 | return -EACCES; | 584 | return -EACCES; |
585 | 585 | ||
586 | dentry_unhash(dentry); | ||
587 | |||
588 | if (atomic_dec_and_test(&ino->count)) { | 586 | if (atomic_dec_and_test(&ino->count)) { |
589 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 587 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
590 | if (p_ino && dentry->d_parent != dentry) | 588 | if (p_ino && dentry->d_parent != dentry) |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index c7d1d06b0483..b14cebfd9047 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -224,9 +224,6 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
224 | struct bfs_sb_info *info; | 224 | struct bfs_sb_info *info; |
225 | int error = -ENOENT; | 225 | int error = -ENOENT; |
226 | 226 | ||
227 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
228 | dentry_unhash(new_dentry); | ||
229 | |||
230 | old_bh = new_bh = NULL; | 227 | old_bh = new_bh = NULL; |
231 | old_inode = old_dentry->d_inode; | 228 | old_inode = old_dentry->d_inode; |
232 | if (S_ISDIR(old_inode->i_mode)) | 229 | if (S_ISDIR(old_inode->i_mode)) |
@@ -638,10 +638,11 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
638 | * @offset: vec entry offset | 638 | * @offset: vec entry offset |
639 | * | 639 | * |
640 | * Attempt to add a page to the bio_vec maplist. This can fail for a | 640 | * Attempt to add a page to the bio_vec maplist. This can fail for a |
641 | * number of reasons, such as the bio being full or target block | 641 | * number of reasons, such as the bio being full or target block device |
642 | * device limitations. The target block device must allow bio's | 642 | * limitations. The target block device must allow bio's up to PAGE_SIZE, |
643 | * smaller than PAGE_SIZE, so it is always possible to add a single | 643 | * so it is always possible to add a single page to an empty bio. |
644 | * page to an empty bio. This should only be used by REQ_PC bios. | 644 | * |
645 | * This should only be used by REQ_PC bios. | ||
645 | */ | 646 | */ |
646 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, | 647 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, |
647 | unsigned int len, unsigned int offset) | 648 | unsigned int len, unsigned int offset) |
@@ -659,10 +660,9 @@ EXPORT_SYMBOL(bio_add_pc_page); | |||
659 | * @offset: vec entry offset | 660 | * @offset: vec entry offset |
660 | * | 661 | * |
661 | * Attempt to add a page to the bio_vec maplist. This can fail for a | 662 | * Attempt to add a page to the bio_vec maplist. This can fail for a |
662 | * number of reasons, such as the bio being full or target block | 663 | * number of reasons, such as the bio being full or target block device |
663 | * device limitations. The target block device must allow bio's | 664 | * limitations. The target block device must allow bio's up to PAGE_SIZE, |
664 | * smaller than PAGE_SIZE, so it is always possible to add a single | 665 | * so it is always possible to add a single page to an empty bio. |
665 | * page to an empty bio. | ||
666 | */ | 666 | */ |
667 | int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | 667 | int bio_add_page(struct bio *bio, struct page *page, unsigned int len, |
668 | unsigned int offset) | 668 | unsigned int offset) |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 332323e19dd1..6c093fa98f61 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2524,7 +2524,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); | |||
2524 | int btrfs_readpage(struct file *file, struct page *page); | 2524 | int btrfs_readpage(struct file *file, struct page *page); |
2525 | void btrfs_evict_inode(struct inode *inode); | 2525 | void btrfs_evict_inode(struct inode *inode); |
2526 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); | 2526 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2527 | void btrfs_dirty_inode(struct inode *inode); | 2527 | void btrfs_dirty_inode(struct inode *inode, int flags); |
2528 | struct inode *btrfs_alloc_inode(struct super_block *sb); | 2528 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
2529 | void btrfs_destroy_inode(struct inode *inode); | 2529 | void btrfs_destroy_inode(struct inode *inode); |
2530 | int btrfs_drop_inode(struct inode *inode); | 2530 | int btrfs_drop_inode(struct inode *inode); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index bb51bb1fa44f..39a9d5750efd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4294,7 +4294,7 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4294 | * FIXME, needs more benchmarking...there are no reasons other than performance | 4294 | * FIXME, needs more benchmarking...there are no reasons other than performance |
4295 | * to keep or drop this code. | 4295 | * to keep or drop this code. |
4296 | */ | 4296 | */ |
4297 | void btrfs_dirty_inode(struct inode *inode) | 4297 | void btrfs_dirty_inode(struct inode *inode, int flags) |
4298 | { | 4298 | { |
4299 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4299 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4300 | struct btrfs_trans_handle *trans; | 4300 | struct btrfs_trans_handle *trans; |
diff --git a/fs/buffer.c b/fs/buffer.c index 698c6b2cc462..49c9aada0374 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2382,6 +2382,7 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
2382 | ret = -EAGAIN; | 2382 | ret = -EAGAIN; |
2383 | goto out_unlock; | 2383 | goto out_unlock; |
2384 | } | 2384 | } |
2385 | wait_on_page_writeback(page); | ||
2385 | return 0; | 2386 | return 0; |
2386 | out_unlock: | 2387 | out_unlock: |
2387 | unlock_page(page); | 2388 | unlock_page(page); |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 8f1700623b41..21de1d6d5849 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -74,8 +74,9 @@ shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem, | |||
74 | * Run idmap cache shrinker. | 74 | * Run idmap cache shrinker. |
75 | */ | 75 | */ |
76 | static int | 76 | static int |
77 | cifs_idmap_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) | 77 | cifs_idmap_shrinker(struct shrinker *shrink, struct shrink_control *sc) |
78 | { | 78 | { |
79 | int nr_to_scan = sc->nr_to_scan; | ||
79 | int nr_del = 0; | 80 | int nr_del = 0; |
80 | int nr_rem = 0; | 81 | int nr_rem = 0; |
81 | struct rb_root *root; | 82 | struct rb_root *root; |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index a46126fd5735..2b8dae4d121e 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -336,8 +336,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de) | |||
336 | int len = de->d_name.len; | 336 | int len = de->d_name.len; |
337 | int error; | 337 | int error; |
338 | 338 | ||
339 | dentry_unhash(de); | ||
340 | |||
341 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); | 339 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); |
342 | if (!error) { | 340 | if (!error) { |
343 | /* VFS may delete the child */ | 341 | /* VFS may delete the child */ |
@@ -361,9 +359,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
361 | int new_length = new_dentry->d_name.len; | 359 | int new_length = new_dentry->d_name.len; |
362 | int error; | 360 | int error; |
363 | 361 | ||
364 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
365 | dentry_unhash(new_dentry); | ||
366 | |||
367 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), | 362 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
368 | coda_i2f(new_dir), old_length, new_length, | 363 | coda_i2f(new_dir), old_length, new_length, |
369 | (const char *) old_name, (const char *)new_name); | 364 | (const char *) old_name, (const char *)new_name); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 9d17d350abc5..9a37a9b6de3a 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -1359,8 +1359,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; | 1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; |
1360 | int ret; | 1360 | int ret; |
1361 | 1361 | ||
1362 | dentry_unhash(dentry); | ||
1363 | |||
1364 | if (dentry->d_parent == configfs_sb->s_root) | 1362 | if (dentry->d_parent == configfs_sb->s_root) |
1365 | return -EPERM; | 1363 | return -EPERM; |
1366 | 1364 | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index b8d5c8091024..58609bde3b9f 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1024,25 +1024,25 @@ out: | |||
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | /** | 1026 | /** |
1027 | * contains_ecryptfs_marker - check for the ecryptfs marker | 1027 | * ecryptfs_validate_marker - check for the ecryptfs marker |
1028 | * @data: The data block in which to check | 1028 | * @data: The data block in which to check |
1029 | * | 1029 | * |
1030 | * Returns one if marker found; zero if not found | 1030 | * Returns zero if marker found; -EINVAL if not found |
1031 | */ | 1031 | */ |
1032 | static int contains_ecryptfs_marker(char *data) | 1032 | static int ecryptfs_validate_marker(char *data) |
1033 | { | 1033 | { |
1034 | u32 m_1, m_2; | 1034 | u32 m_1, m_2; |
1035 | 1035 | ||
1036 | m_1 = get_unaligned_be32(data); | 1036 | m_1 = get_unaligned_be32(data); |
1037 | m_2 = get_unaligned_be32(data + 4); | 1037 | m_2 = get_unaligned_be32(data + 4); |
1038 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) | 1038 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) |
1039 | return 1; | 1039 | return 0; |
1040 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " | 1040 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " |
1041 | "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2, | 1041 | "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2, |
1042 | MAGIC_ECRYPTFS_MARKER); | 1042 | MAGIC_ECRYPTFS_MARKER); |
1043 | ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = " | 1043 | ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = " |
1044 | "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER)); | 1044 | "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER)); |
1045 | return 0; | 1045 | return -EINVAL; |
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | struct ecryptfs_flag_map_elem { | 1048 | struct ecryptfs_flag_map_elem { |
@@ -1201,27 +1201,19 @@ int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code) | |||
1201 | return rc; | 1201 | return rc; |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | int ecryptfs_read_and_validate_header_region(char *data, | 1204 | int ecryptfs_read_and_validate_header_region(struct inode *inode) |
1205 | struct inode *ecryptfs_inode) | ||
1206 | { | 1205 | { |
1207 | struct ecryptfs_crypt_stat *crypt_stat = | 1206 | u8 file_size[ECRYPTFS_SIZE_AND_MARKER_BYTES]; |
1208 | &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); | 1207 | u8 *marker = file_size + ECRYPTFS_FILE_SIZE_BYTES; |
1209 | int rc; | 1208 | int rc; |
1210 | 1209 | ||
1211 | if (crypt_stat->extent_size == 0) | 1210 | rc = ecryptfs_read_lower(file_size, 0, ECRYPTFS_SIZE_AND_MARKER_BYTES, |
1212 | crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; | 1211 | inode); |
1213 | rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, | 1212 | if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) |
1214 | ecryptfs_inode); | 1213 | return rc >= 0 ? -EINVAL : rc; |
1215 | if (rc < 0) { | 1214 | rc = ecryptfs_validate_marker(marker); |
1216 | printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n", | 1215 | if (!rc) |
1217 | __func__, rc); | 1216 | ecryptfs_i_size_init(file_size, inode); |
1218 | goto out; | ||
1219 | } | ||
1220 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { | ||
1221 | rc = -EINVAL; | ||
1222 | } else | ||
1223 | rc = 0; | ||
1224 | out: | ||
1225 | return rc; | 1217 | return rc; |
1226 | } | 1218 | } |
1227 | 1219 | ||
@@ -1242,8 +1234,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
1242 | (*written) = 6; | 1234 | (*written) = 6; |
1243 | } | 1235 | } |
1244 | 1236 | ||
1245 | struct kmem_cache *ecryptfs_header_cache_1; | 1237 | struct kmem_cache *ecryptfs_header_cache; |
1246 | struct kmem_cache *ecryptfs_header_cache_2; | ||
1247 | 1238 | ||
1248 | /** | 1239 | /** |
1249 | * ecryptfs_write_headers_virt | 1240 | * ecryptfs_write_headers_virt |
@@ -1496,11 +1487,9 @@ static int ecryptfs_read_headers_virt(char *page_virt, | |||
1496 | crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private( | 1487 | crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private( |
1497 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1488 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1498 | offset = ECRYPTFS_FILE_SIZE_BYTES; | 1489 | offset = ECRYPTFS_FILE_SIZE_BYTES; |
1499 | rc = contains_ecryptfs_marker(page_virt + offset); | 1490 | rc = ecryptfs_validate_marker(page_virt + offset); |
1500 | if (rc == 0) { | 1491 | if (rc) |
1501 | rc = -EINVAL; | ||
1502 | goto out; | 1492 | goto out; |
1503 | } | ||
1504 | if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) | 1493 | if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) |
1505 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | 1494 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); |
1506 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | 1495 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
@@ -1567,20 +1556,21 @@ out: | |||
1567 | return rc; | 1556 | return rc; |
1568 | } | 1557 | } |
1569 | 1558 | ||
1570 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 1559 | int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, |
1571 | struct dentry *ecryptfs_dentry) | 1560 | struct inode *inode) |
1572 | { | 1561 | { |
1562 | u8 file_size[ECRYPTFS_SIZE_AND_MARKER_BYTES]; | ||
1563 | u8 *marker = file_size + ECRYPTFS_FILE_SIZE_BYTES; | ||
1573 | int rc; | 1564 | int rc; |
1574 | 1565 | ||
1575 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry->d_inode); | 1566 | rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), |
1576 | if (rc) | 1567 | ECRYPTFS_XATTR_NAME, file_size, |
1577 | goto out; | 1568 | ECRYPTFS_SIZE_AND_MARKER_BYTES); |
1578 | if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) { | 1569 | if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) |
1579 | printk(KERN_WARNING "Valid data found in [%s] xattr, but " | 1570 | return rc >= 0 ? -EINVAL : rc; |
1580 | "the marker is invalid\n", ECRYPTFS_XATTR_NAME); | 1571 | rc = ecryptfs_validate_marker(marker); |
1581 | rc = -EINVAL; | 1572 | if (!rc) |
1582 | } | 1573 | ecryptfs_i_size_init(file_size, inode); |
1583 | out: | ||
1584 | return rc; | 1574 | return rc; |
1585 | } | 1575 | } |
1586 | 1576 | ||
@@ -1610,7 +1600,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1610 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | 1600 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, |
1611 | mount_crypt_stat); | 1601 | mount_crypt_stat); |
1612 | /* Read the first page from the underlying file */ | 1602 | /* Read the first page from the underlying file */ |
1613 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); | 1603 | page_virt = kmem_cache_alloc(ecryptfs_header_cache, GFP_USER); |
1614 | if (!page_virt) { | 1604 | if (!page_virt) { |
1615 | rc = -ENOMEM; | 1605 | rc = -ENOMEM; |
1616 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", | 1606 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", |
@@ -1655,7 +1645,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1655 | out: | 1645 | out: |
1656 | if (page_virt) { | 1646 | if (page_virt) { |
1657 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1647 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
1658 | kmem_cache_free(ecryptfs_header_cache_1, page_virt); | 1648 | kmem_cache_free(ecryptfs_header_cache, page_virt); |
1659 | } | 1649 | } |
1660 | return rc; | 1650 | return rc; |
1661 | } | 1651 | } |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index e70282775e2c..43c7c43b06f5 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -200,6 +200,8 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
200 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 | 200 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 |
201 | #define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */ | 201 | #define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */ |
202 | #define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64)) | 202 | #define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64)) |
203 | #define ECRYPTFS_SIZE_AND_MARKER_BYTES (ECRYPTFS_FILE_SIZE_BYTES \ | ||
204 | + MAGIC_ECRYPTFS_MARKER_SIZE_BYTES) | ||
203 | #define ECRYPTFS_DEFAULT_CIPHER "aes" | 205 | #define ECRYPTFS_DEFAULT_CIPHER "aes" |
204 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 | 206 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 |
205 | #define ECRYPTFS_DEFAULT_HASH "md5" | 207 | #define ECRYPTFS_DEFAULT_HASH "md5" |
@@ -603,8 +605,7 @@ extern struct kmem_cache *ecryptfs_file_info_cache; | |||
603 | extern struct kmem_cache *ecryptfs_dentry_info_cache; | 605 | extern struct kmem_cache *ecryptfs_dentry_info_cache; |
604 | extern struct kmem_cache *ecryptfs_inode_info_cache; | 606 | extern struct kmem_cache *ecryptfs_inode_info_cache; |
605 | extern struct kmem_cache *ecryptfs_sb_info_cache; | 607 | extern struct kmem_cache *ecryptfs_sb_info_cache; |
606 | extern struct kmem_cache *ecryptfs_header_cache_1; | 608 | extern struct kmem_cache *ecryptfs_header_cache; |
607 | extern struct kmem_cache *ecryptfs_header_cache_2; | ||
608 | extern struct kmem_cache *ecryptfs_xattr_cache; | 609 | extern struct kmem_cache *ecryptfs_xattr_cache; |
609 | extern struct kmem_cache *ecryptfs_key_record_cache; | 610 | extern struct kmem_cache *ecryptfs_key_record_cache; |
610 | extern struct kmem_cache *ecryptfs_key_sig_cache; | 611 | extern struct kmem_cache *ecryptfs_key_sig_cache; |
@@ -625,14 +626,9 @@ struct ecryptfs_open_req { | |||
625 | struct list_head kthread_ctl_list; | 626 | struct list_head kthread_ctl_list; |
626 | }; | 627 | }; |
627 | 628 | ||
628 | #define ECRYPTFS_INTERPOSE_FLAG_D_ADD 0x00000001 | 629 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
629 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 630 | struct super_block *sb); |
630 | struct dentry *this_dentry, struct super_block *sb, | ||
631 | u32 flags); | ||
632 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | 631 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); |
633 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | ||
634 | struct dentry *lower_dentry, | ||
635 | struct inode *ecryptfs_dir_inode); | ||
636 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 632 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
637 | size_t *decrypted_name_size, | 633 | size_t *decrypted_name_size, |
638 | struct dentry *ecryptfs_dentry, | 634 | struct dentry *ecryptfs_dentry, |
@@ -664,10 +660,9 @@ int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | |||
664 | void ecryptfs_write_crypt_stat_flags(char *page_virt, | 660 | void ecryptfs_write_crypt_stat_flags(char *page_virt, |
665 | struct ecryptfs_crypt_stat *crypt_stat, | 661 | struct ecryptfs_crypt_stat *crypt_stat, |
666 | size_t *written); | 662 | size_t *written); |
667 | int ecryptfs_read_and_validate_header_region(char *data, | 663 | int ecryptfs_read_and_validate_header_region(struct inode *inode); |
668 | struct inode *ecryptfs_inode); | 664 | int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, |
669 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 665 | struct inode *inode); |
670 | struct dentry *ecryptfs_dentry); | ||
671 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); | 666 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); |
672 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); | 667 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); |
673 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); | 668 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); |
@@ -679,9 +674,6 @@ int | |||
679 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | 674 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, |
680 | unsigned char *src, struct dentry *ecryptfs_dentry); | 675 | unsigned char *src, struct dentry *ecryptfs_dentry); |
681 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); | 676 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); |
682 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | ||
683 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | ||
684 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | ||
685 | ssize_t | 677 | ssize_t |
686 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | 678 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, |
687 | void *value, size_t size); | 679 | void *value, size_t size); |
@@ -761,7 +753,7 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
761 | struct dentry *lower_dentry, | 753 | struct dentry *lower_dentry, |
762 | struct vfsmount *lower_mnt, | 754 | struct vfsmount *lower_mnt, |
763 | const struct cred *cred); | 755 | const struct cred *cred); |
764 | int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry); | 756 | int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode); |
765 | void ecryptfs_put_lower_file(struct inode *inode); | 757 | void ecryptfs_put_lower_file(struct inode *inode); |
766 | int | 758 | int |
767 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | 759 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 566e5472f78c..4ec9eb00a241 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -191,7 +191,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
191 | | ECRYPTFS_ENCRYPTED); | 191 | | ECRYPTFS_ENCRYPTED); |
192 | } | 192 | } |
193 | mutex_unlock(&crypt_stat->cs_mutex); | 193 | mutex_unlock(&crypt_stat->cs_mutex); |
194 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); | 194 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, inode); |
195 | if (rc) { | 195 | if (rc) { |
196 | printk(KERN_ERR "%s: Error attempting to initialize " | 196 | printk(KERN_ERR "%s: Error attempting to initialize " |
197 | "the lower file for the dentry with name " | 197 | "the lower file for the dentry with name " |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index bc116b9ffcf2..7349ade17de6 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -51,6 +51,97 @@ static void unlock_dir(struct dentry *dir) | |||
51 | dput(dir); | 51 | dput(dir); |
52 | } | 52 | } |
53 | 53 | ||
54 | static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) | ||
55 | { | ||
56 | if (ecryptfs_inode_to_lower(inode) == (struct inode *)lower_inode) | ||
57 | return 1; | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int ecryptfs_inode_set(struct inode *inode, void *opaque) | ||
62 | { | ||
63 | struct inode *lower_inode = opaque; | ||
64 | |||
65 | ecryptfs_set_inode_lower(inode, lower_inode); | ||
66 | fsstack_copy_attr_all(inode, lower_inode); | ||
67 | /* i_size will be overwritten for encrypted regular files */ | ||
68 | fsstack_copy_inode_size(inode, lower_inode); | ||
69 | inode->i_ino = lower_inode->i_ino; | ||
70 | inode->i_version++; | ||
71 | inode->i_mapping->a_ops = &ecryptfs_aops; | ||
72 | |||
73 | if (S_ISLNK(inode->i_mode)) | ||
74 | inode->i_op = &ecryptfs_symlink_iops; | ||
75 | else if (S_ISDIR(inode->i_mode)) | ||
76 | inode->i_op = &ecryptfs_dir_iops; | ||
77 | else | ||
78 | inode->i_op = &ecryptfs_main_iops; | ||
79 | |||
80 | if (S_ISDIR(inode->i_mode)) | ||
81 | inode->i_fop = &ecryptfs_dir_fops; | ||
82 | else if (special_file(inode->i_mode)) | ||
83 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
84 | else | ||
85 | inode->i_fop = &ecryptfs_main_fops; | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, | ||
91 | struct super_block *sb) | ||
92 | { | ||
93 | struct inode *inode; | ||
94 | |||
95 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) | ||
96 | return ERR_PTR(-EXDEV); | ||
97 | if (!igrab(lower_inode)) | ||
98 | return ERR_PTR(-ESTALE); | ||
99 | inode = iget5_locked(sb, (unsigned long)lower_inode, | ||
100 | ecryptfs_inode_test, ecryptfs_inode_set, | ||
101 | lower_inode); | ||
102 | if (!inode) { | ||
103 | iput(lower_inode); | ||
104 | return ERR_PTR(-EACCES); | ||
105 | } | ||
106 | if (!(inode->i_state & I_NEW)) | ||
107 | iput(lower_inode); | ||
108 | |||
109 | return inode; | ||
110 | } | ||
111 | |||
112 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, | ||
113 | struct super_block *sb) | ||
114 | { | ||
115 | struct inode *inode = __ecryptfs_get_inode(lower_inode, sb); | ||
116 | |||
117 | if (!IS_ERR(inode) && (inode->i_state & I_NEW)) | ||
118 | unlock_new_inode(inode); | ||
119 | |||
120 | return inode; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * ecryptfs_interpose | ||
125 | * @lower_dentry: Existing dentry in the lower filesystem | ||
126 | * @dentry: ecryptfs' dentry | ||
127 | * @sb: ecryptfs's super_block | ||
128 | * | ||
129 | * Interposes upper and lower dentries. | ||
130 | * | ||
131 | * Returns zero on success; non-zero otherwise | ||
132 | */ | ||
133 | static int ecryptfs_interpose(struct dentry *lower_dentry, | ||
134 | struct dentry *dentry, struct super_block *sb) | ||
135 | { | ||
136 | struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb); | ||
137 | |||
138 | if (IS_ERR(inode)) | ||
139 | return PTR_ERR(inode); | ||
140 | d_instantiate(dentry, inode); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
54 | /** | 145 | /** |
55 | * ecryptfs_create_underlying_file | 146 | * ecryptfs_create_underlying_file |
56 | * @lower_dir_inode: inode of the parent in the lower fs of the new file | 147 | * @lower_dir_inode: inode of the parent in the lower fs of the new file |
@@ -129,7 +220,7 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
129 | goto out_lock; | 220 | goto out_lock; |
130 | } | 221 | } |
131 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | 222 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, |
132 | directory_inode->i_sb, 0); | 223 | directory_inode->i_sb); |
133 | if (rc) { | 224 | if (rc) { |
134 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); | 225 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); |
135 | goto out_lock; | 226 | goto out_lock; |
@@ -168,7 +259,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
168 | "context; rc = [%d]\n", rc); | 259 | "context; rc = [%d]\n", rc); |
169 | goto out; | 260 | goto out; |
170 | } | 261 | } |
171 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); | 262 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, |
263 | ecryptfs_dentry->d_inode); | ||
172 | if (rc) { | 264 | if (rc) { |
173 | printk(KERN_ERR "%s: Error attempting to initialize " | 265 | printk(KERN_ERR "%s: Error attempting to initialize " |
174 | "the lower file for the dentry with name " | 266 | "the lower file for the dentry with name " |
@@ -215,102 +307,90 @@ out: | |||
215 | return rc; | 307 | return rc; |
216 | } | 308 | } |
217 | 309 | ||
310 | static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode) | ||
311 | { | ||
312 | struct ecryptfs_crypt_stat *crypt_stat; | ||
313 | int rc; | ||
314 | |||
315 | rc = ecryptfs_get_lower_file(dentry, inode); | ||
316 | if (rc) { | ||
317 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
318 | "the lower file for the dentry with name " | ||
319 | "[%s]; rc = [%d]\n", __func__, | ||
320 | dentry->d_name.name, rc); | ||
321 | return rc; | ||
322 | } | ||
323 | |||
324 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
325 | /* TODO: lock for crypt_stat comparison */ | ||
326 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
327 | ecryptfs_set_default_sizes(crypt_stat); | ||
328 | |||
329 | rc = ecryptfs_read_and_validate_header_region(inode); | ||
330 | ecryptfs_put_lower_file(inode); | ||
331 | if (rc) { | ||
332 | rc = ecryptfs_read_and_validate_xattr_region(dentry, inode); | ||
333 | if (!rc) | ||
334 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
335 | } | ||
336 | |||
337 | /* Must return 0 to allow non-eCryptfs files to be looked up, too */ | ||
338 | return 0; | ||
339 | } | ||
340 | |||
218 | /** | 341 | /** |
219 | * ecryptfs_lookup_and_interpose_lower - Perform a lookup | 342 | * ecryptfs_lookup_interpose - Dentry interposition for a lookup |
220 | */ | 343 | */ |
221 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | 344 | static int ecryptfs_lookup_interpose(struct dentry *dentry, |
222 | struct dentry *lower_dentry, | 345 | struct dentry *lower_dentry, |
223 | struct inode *ecryptfs_dir_inode) | 346 | struct inode *dir_inode) |
224 | { | 347 | { |
225 | struct dentry *lower_dir_dentry; | 348 | struct inode *inode, *lower_inode = lower_dentry->d_inode; |
349 | struct ecryptfs_dentry_info *dentry_info; | ||
226 | struct vfsmount *lower_mnt; | 350 | struct vfsmount *lower_mnt; |
227 | struct inode *lower_inode; | 351 | int rc = 0; |
228 | struct ecryptfs_crypt_stat *crypt_stat; | 352 | |
229 | char *page_virt = NULL; | 353 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); |
230 | int put_lower = 0, rc = 0; | 354 | fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode); |
231 | |||
232 | lower_dir_dentry = lower_dentry->d_parent; | ||
233 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | ||
234 | ecryptfs_dentry->d_parent)); | ||
235 | lower_inode = lower_dentry->d_inode; | ||
236 | fsstack_copy_attr_atime(ecryptfs_dir_inode, lower_dir_dentry->d_inode); | ||
237 | BUG_ON(!lower_dentry->d_count); | 355 | BUG_ON(!lower_dentry->d_count); |
238 | ecryptfs_set_dentry_private(ecryptfs_dentry, | 356 | |
239 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 357 | dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); |
240 | GFP_KERNEL)); | 358 | ecryptfs_set_dentry_private(dentry, dentry_info); |
241 | if (!ecryptfs_dentry_to_private(ecryptfs_dentry)) { | 359 | if (!dentry_info) { |
242 | rc = -ENOMEM; | ||
243 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 360 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
244 | "to allocate ecryptfs_dentry_info struct\n", | 361 | "to allocate ecryptfs_dentry_info struct\n", |
245 | __func__); | 362 | __func__); |
246 | goto out_put; | 363 | dput(lower_dentry); |
364 | mntput(lower_mnt); | ||
365 | d_drop(dentry); | ||
366 | return -ENOMEM; | ||
247 | } | 367 | } |
248 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); | 368 | ecryptfs_set_dentry_lower(dentry, lower_dentry); |
249 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); | 369 | ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); |
370 | |||
250 | if (!lower_dentry->d_inode) { | 371 | if (!lower_dentry->d_inode) { |
251 | /* We want to add because we couldn't find in lower */ | 372 | /* We want to add because we couldn't find in lower */ |
252 | d_add(ecryptfs_dentry, NULL); | 373 | d_add(dentry, NULL); |
253 | goto out; | 374 | return 0; |
254 | } | ||
255 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | ||
256 | ecryptfs_dir_inode->i_sb, | ||
257 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | ||
258 | if (rc) { | ||
259 | printk(KERN_ERR "%s: Error interposing; rc = [%d]\n", | ||
260 | __func__, rc); | ||
261 | goto out; | ||
262 | } | ||
263 | if (S_ISDIR(lower_inode->i_mode)) | ||
264 | goto out; | ||
265 | if (S_ISLNK(lower_inode->i_mode)) | ||
266 | goto out; | ||
267 | if (special_file(lower_inode->i_mode)) | ||
268 | goto out; | ||
269 | /* Released in this function */ | ||
270 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER); | ||
271 | if (!page_virt) { | ||
272 | printk(KERN_ERR "%s: Cannot kmem_cache_zalloc() a page\n", | ||
273 | __func__); | ||
274 | rc = -ENOMEM; | ||
275 | goto out; | ||
276 | } | 375 | } |
277 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); | 376 | inode = __ecryptfs_get_inode(lower_inode, dir_inode->i_sb); |
278 | if (rc) { | 377 | if (IS_ERR(inode)) { |
279 | printk(KERN_ERR "%s: Error attempting to initialize " | 378 | printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n", |
280 | "the lower file for the dentry with name " | 379 | __func__, PTR_ERR(inode)); |
281 | "[%s]; rc = [%d]\n", __func__, | 380 | return PTR_ERR(inode); |
282 | ecryptfs_dentry->d_name.name, rc); | ||
283 | goto out_free_kmem; | ||
284 | } | 381 | } |
285 | put_lower = 1; | 382 | if (S_ISREG(inode->i_mode)) { |
286 | crypt_stat = &ecryptfs_inode_to_private( | 383 | rc = ecryptfs_i_size_read(dentry, inode); |
287 | ecryptfs_dentry->d_inode)->crypt_stat; | ||
288 | /* TODO: lock for crypt_stat comparison */ | ||
289 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
290 | ecryptfs_set_default_sizes(crypt_stat); | ||
291 | rc = ecryptfs_read_and_validate_header_region(page_virt, | ||
292 | ecryptfs_dentry->d_inode); | ||
293 | if (rc) { | ||
294 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
295 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, | ||
296 | ecryptfs_dentry); | ||
297 | if (rc) { | 384 | if (rc) { |
298 | rc = 0; | 385 | make_bad_inode(inode); |
299 | goto out_free_kmem; | 386 | return rc; |
300 | } | 387 | } |
301 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
302 | } | 388 | } |
303 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | 389 | |
304 | out_free_kmem: | 390 | if (inode->i_state & I_NEW) |
305 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 391 | unlock_new_inode(inode); |
306 | goto out; | 392 | d_add(dentry, inode); |
307 | out_put: | 393 | |
308 | dput(lower_dentry); | ||
309 | mntput(lower_mnt); | ||
310 | d_drop(ecryptfs_dentry); | ||
311 | out: | ||
312 | if (put_lower) | ||
313 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | ||
314 | return rc; | 394 | return rc; |
315 | } | 395 | } |
316 | 396 | ||
@@ -353,12 +433,12 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
353 | goto out_d_drop; | 433 | goto out_d_drop; |
354 | } | 434 | } |
355 | if (lower_dentry->d_inode) | 435 | if (lower_dentry->d_inode) |
356 | goto lookup_and_interpose; | 436 | goto interpose; |
357 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 437 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
358 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 438 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
359 | if (!(mount_crypt_stat | 439 | if (!(mount_crypt_stat |
360 | && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) | 440 | && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) |
361 | goto lookup_and_interpose; | 441 | goto interpose; |
362 | dput(lower_dentry); | 442 | dput(lower_dentry); |
363 | rc = ecryptfs_encrypt_and_encode_filename( | 443 | rc = ecryptfs_encrypt_and_encode_filename( |
364 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, | 444 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, |
@@ -381,9 +461,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
381 | encrypted_and_encoded_name); | 461 | encrypted_and_encoded_name); |
382 | goto out_d_drop; | 462 | goto out_d_drop; |
383 | } | 463 | } |
384 | lookup_and_interpose: | 464 | interpose: |
385 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, | 465 | rc = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry, |
386 | ecryptfs_dir_inode); | 466 | ecryptfs_dir_inode); |
387 | goto out; | 467 | goto out; |
388 | out_d_drop: | 468 | out_d_drop: |
389 | d_drop(ecryptfs_dentry); | 469 | d_drop(ecryptfs_dentry); |
@@ -411,7 +491,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
411 | lower_new_dentry); | 491 | lower_new_dentry); |
412 | if (rc || !lower_new_dentry->d_inode) | 492 | if (rc || !lower_new_dentry->d_inode) |
413 | goto out_lock; | 493 | goto out_lock; |
414 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); | 494 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); |
415 | if (rc) | 495 | if (rc) |
416 | goto out_lock; | 496 | goto out_lock; |
417 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 497 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -478,7 +558,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
478 | kfree(encoded_symname); | 558 | kfree(encoded_symname); |
479 | if (rc || !lower_dentry->d_inode) | 559 | if (rc || !lower_dentry->d_inode) |
480 | goto out_lock; | 560 | goto out_lock; |
481 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 561 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
482 | if (rc) | 562 | if (rc) |
483 | goto out_lock; | 563 | goto out_lock; |
484 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 564 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -502,7 +582,7 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
502 | rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); | 582 | rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); |
503 | if (rc || !lower_dentry->d_inode) | 583 | if (rc || !lower_dentry->d_inode) |
504 | goto out; | 584 | goto out; |
505 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 585 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
506 | if (rc) | 586 | if (rc) |
507 | goto out; | 587 | goto out; |
508 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 588 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -521,8 +601,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
521 | struct dentry *lower_dir_dentry; | 601 | struct dentry *lower_dir_dentry; |
522 | int rc; | 602 | int rc; |
523 | 603 | ||
524 | dentry_unhash(dentry); | ||
525 | |||
526 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 604 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
527 | dget(dentry); | 605 | dget(dentry); |
528 | lower_dir_dentry = lock_parent(lower_dentry); | 606 | lower_dir_dentry = lock_parent(lower_dentry); |
@@ -552,7 +630,7 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
552 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); | 630 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); |
553 | if (rc || !lower_dentry->d_inode) | 631 | if (rc || !lower_dentry->d_inode) |
554 | goto out; | 632 | goto out; |
555 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 633 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
556 | if (rc) | 634 | if (rc) |
557 | goto out; | 635 | goto out; |
558 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 636 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -575,9 +653,6 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
575 | struct dentry *lower_new_dir_dentry; | 653 | struct dentry *lower_new_dir_dentry; |
576 | struct dentry *trap = NULL; | 654 | struct dentry *trap = NULL; |
577 | 655 | ||
578 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
579 | dentry_unhash(new_dentry); | ||
580 | |||
581 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | 656 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
582 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | 657 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
583 | dget(lower_old_dentry); | 658 | dget(lower_old_dentry); |
@@ -755,7 +830,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
755 | lower_ia->ia_valid &= ~ATTR_SIZE; | 830 | lower_ia->ia_valid &= ~ATTR_SIZE; |
756 | return 0; | 831 | return 0; |
757 | } | 832 | } |
758 | rc = ecryptfs_get_lower_file(dentry); | 833 | rc = ecryptfs_get_lower_file(dentry, inode); |
759 | if (rc) | 834 | if (rc) |
760 | return rc; | 835 | return rc; |
761 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 836 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
@@ -911,7 +986,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
911 | 986 | ||
912 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 987 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
913 | dentry->d_sb)->mount_crypt_stat; | 988 | dentry->d_sb)->mount_crypt_stat; |
914 | rc = ecryptfs_get_lower_file(dentry); | 989 | rc = ecryptfs_get_lower_file(dentry, inode); |
915 | if (rc) { | 990 | if (rc) { |
916 | mutex_unlock(&crypt_stat->cs_mutex); | 991 | mutex_unlock(&crypt_stat->cs_mutex); |
917 | goto out; | 992 | goto out; |
@@ -1084,21 +1159,6 @@ out: | |||
1084 | return rc; | 1159 | return rc; |
1085 | } | 1160 | } |
1086 | 1161 | ||
1087 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode) | ||
1088 | { | ||
1089 | if ((ecryptfs_inode_to_lower(inode) | ||
1090 | == (struct inode *)candidate_lower_inode)) | ||
1091 | return 1; | ||
1092 | else | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode) | ||
1097 | { | ||
1098 | ecryptfs_init_inode(inode, (struct inode *)lower_inode); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | const struct inode_operations ecryptfs_symlink_iops = { | 1162 | const struct inode_operations ecryptfs_symlink_iops = { |
1103 | .readlink = ecryptfs_readlink, | 1163 | .readlink = ecryptfs_readlink, |
1104 | .follow_link = ecryptfs_follow_link, | 1164 | .follow_link = ecryptfs_follow_link, |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 89b93389af8e..9f1bb747d77d 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -135,12 +135,12 @@ static int ecryptfs_init_lower_file(struct dentry *dentry, | |||
135 | return rc; | 135 | return rc; |
136 | } | 136 | } |
137 | 137 | ||
138 | int ecryptfs_get_lower_file(struct dentry *dentry) | 138 | int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode) |
139 | { | 139 | { |
140 | struct ecryptfs_inode_info *inode_info = | 140 | struct ecryptfs_inode_info *inode_info; |
141 | ecryptfs_inode_to_private(dentry->d_inode); | ||
142 | int count, rc = 0; | 141 | int count, rc = 0; |
143 | 142 | ||
143 | inode_info = ecryptfs_inode_to_private(inode); | ||
144 | mutex_lock(&inode_info->lower_file_mutex); | 144 | mutex_lock(&inode_info->lower_file_mutex); |
145 | count = atomic_inc_return(&inode_info->lower_file_count); | 145 | count = atomic_inc_return(&inode_info->lower_file_count); |
146 | if (WARN_ON_ONCE(count < 1)) | 146 | if (WARN_ON_ONCE(count < 1)) |
@@ -168,75 +168,6 @@ void ecryptfs_put_lower_file(struct inode *inode) | |||
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct inode *ecryptfs_get_inode(struct inode *lower_inode, | ||
172 | struct super_block *sb) | ||
173 | { | ||
174 | struct inode *inode; | ||
175 | int rc = 0; | ||
176 | |||
177 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) { | ||
178 | rc = -EXDEV; | ||
179 | goto out; | ||
180 | } | ||
181 | if (!igrab(lower_inode)) { | ||
182 | rc = -ESTALE; | ||
183 | goto out; | ||
184 | } | ||
185 | inode = iget5_locked(sb, (unsigned long)lower_inode, | ||
186 | ecryptfs_inode_test, ecryptfs_inode_set, | ||
187 | lower_inode); | ||
188 | if (!inode) { | ||
189 | rc = -EACCES; | ||
190 | iput(lower_inode); | ||
191 | goto out; | ||
192 | } | ||
193 | if (inode->i_state & I_NEW) | ||
194 | unlock_new_inode(inode); | ||
195 | else | ||
196 | iput(lower_inode); | ||
197 | if (S_ISLNK(lower_inode->i_mode)) | ||
198 | inode->i_op = &ecryptfs_symlink_iops; | ||
199 | else if (S_ISDIR(lower_inode->i_mode)) | ||
200 | inode->i_op = &ecryptfs_dir_iops; | ||
201 | if (S_ISDIR(lower_inode->i_mode)) | ||
202 | inode->i_fop = &ecryptfs_dir_fops; | ||
203 | if (special_file(lower_inode->i_mode)) | ||
204 | init_special_inode(inode, lower_inode->i_mode, | ||
205 | lower_inode->i_rdev); | ||
206 | fsstack_copy_attr_all(inode, lower_inode); | ||
207 | /* This size will be overwritten for real files w/ headers and | ||
208 | * other metadata */ | ||
209 | fsstack_copy_inode_size(inode, lower_inode); | ||
210 | return inode; | ||
211 | out: | ||
212 | return ERR_PTR(rc); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * ecryptfs_interpose | ||
217 | * @lower_dentry: Existing dentry in the lower filesystem | ||
218 | * @dentry: ecryptfs' dentry | ||
219 | * @sb: ecryptfs's super_block | ||
220 | * @flags: flags to govern behavior of interpose procedure | ||
221 | * | ||
222 | * Interposes upper and lower dentries. | ||
223 | * | ||
224 | * Returns zero on success; non-zero otherwise | ||
225 | */ | ||
226 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | ||
227 | struct super_block *sb, u32 flags) | ||
228 | { | ||
229 | struct inode *lower_inode = lower_dentry->d_inode; | ||
230 | struct inode *inode = ecryptfs_get_inode(lower_inode, sb); | ||
231 | if (IS_ERR(inode)) | ||
232 | return PTR_ERR(inode); | ||
233 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) | ||
234 | d_add(dentry, inode); | ||
235 | else | ||
236 | d_instantiate(dentry, inode); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, | 171 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
241 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, | 172 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, |
242 | ecryptfs_opt_ecryptfs_key_bytes, | 173 | ecryptfs_opt_ecryptfs_key_bytes, |
@@ -704,13 +635,8 @@ static struct ecryptfs_cache_info { | |||
704 | .size = sizeof(struct ecryptfs_sb_info), | 635 | .size = sizeof(struct ecryptfs_sb_info), |
705 | }, | 636 | }, |
706 | { | 637 | { |
707 | .cache = &ecryptfs_header_cache_1, | 638 | .cache = &ecryptfs_header_cache, |
708 | .name = "ecryptfs_headers_1", | 639 | .name = "ecryptfs_headers", |
709 | .size = PAGE_CACHE_SIZE, | ||
710 | }, | ||
711 | { | ||
712 | .cache = &ecryptfs_header_cache_2, | ||
713 | .name = "ecryptfs_headers_2", | ||
714 | .size = PAGE_CACHE_SIZE, | 640 | .size = PAGE_CACHE_SIZE, |
715 | }, | 641 | }, |
716 | { | 642 | { |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 245b517bf1b6..dbd52d40df4c 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -93,22 +93,6 @@ static void ecryptfs_destroy_inode(struct inode *inode) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * ecryptfs_init_inode | ||
97 | * @inode: The ecryptfs inode | ||
98 | * | ||
99 | * Set up the ecryptfs inode. | ||
100 | */ | ||
101 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) | ||
102 | { | ||
103 | ecryptfs_set_inode_lower(inode, lower_inode); | ||
104 | inode->i_ino = lower_inode->i_ino; | ||
105 | inode->i_version++; | ||
106 | inode->i_op = &ecryptfs_main_iops; | ||
107 | inode->i_fop = &ecryptfs_main_fops; | ||
108 | inode->i_mapping->a_ops = &ecryptfs_aops; | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * ecryptfs_statfs | 96 | * ecryptfs_statfs |
113 | * @sb: The ecryptfs super block | 97 | * @sb: The ecryptfs super block |
114 | * @buf: The struct kstatfs to fill in with stats | 98 | * @buf: The struct kstatfs to fill in with stats |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 68b2e43d7c35..3451d23c3bae 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3392,7 +3392,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
3392 | * so would cause a commit on atime updates, which we don't bother doing. | 3392 | * so would cause a commit on atime updates, which we don't bother doing. |
3393 | * We handle synchronous inodes at the highest possible level. | 3393 | * We handle synchronous inodes at the highest possible level. |
3394 | */ | 3394 | */ |
3395 | void ext3_dirty_inode(struct inode *inode) | 3395 | void ext3_dirty_inode(struct inode *inode, int flags) |
3396 | { | 3396 | { |
3397 | handle_t *current_handle = ext3_journal_current_handle(); | 3397 | handle_t *current_handle = ext3_journal_current_handle(); |
3398 | handle_t *handle; | 3398 | handle_t *handle; |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index a74b89c09f90..1921392cd708 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1813,7 +1813,7 @@ extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1813 | extern void ext4_evict_inode(struct inode *); | 1813 | extern void ext4_evict_inode(struct inode *); |
1814 | extern void ext4_clear_inode(struct inode *); | 1814 | extern void ext4_clear_inode(struct inode *); |
1815 | extern int ext4_sync_inode(handle_t *, struct inode *); | 1815 | extern int ext4_sync_inode(handle_t *, struct inode *); |
1816 | extern void ext4_dirty_inode(struct inode *); | 1816 | extern void ext4_dirty_inode(struct inode *, int); |
1817 | extern int ext4_change_inode_journal_flag(struct inode *, int); | 1817 | extern int ext4_change_inode_journal_flag(struct inode *, int); |
1818 | extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); | 1818 | extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); |
1819 | extern int ext4_can_truncate(struct inode *inode); | 1819 | extern int ext4_can_truncate(struct inode *inode); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 50d0e9c64584..a5763e3505ba 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5733,7 +5733,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
5733 | * so would cause a commit on atime updates, which we don't bother doing. | 5733 | * so would cause a commit on atime updates, which we don't bother doing. |
5734 | * We handle synchronous inodes at the highest possible level. | 5734 | * We handle synchronous inodes at the highest possible level. |
5735 | */ | 5735 | */ |
5736 | void ext4_dirty_inode(struct inode *inode) | 5736 | void ext4_dirty_inode(struct inode *inode, int flags) |
5737 | { | 5737 | { |
5738 | handle_t *handle; | 5738 | handle_t *handle; |
5739 | 5739 | ||
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index be15437c272e..3b222dafd15b 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -326,8 +326,6 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | |||
326 | struct fat_slot_info sinfo; | 326 | struct fat_slot_info sinfo; |
327 | int err; | 327 | int err; |
328 | 328 | ||
329 | dentry_unhash(dentry); | ||
330 | |||
331 | lock_super(sb); | 329 | lock_super(sb); |
332 | /* | 330 | /* |
333 | * Check whether the directory is not in use, then check | 331 | * Check whether the directory is not in use, then check |
@@ -459,9 +457,6 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
459 | old_inode = old_dentry->d_inode; | 457 | old_inode = old_dentry->d_inode; |
460 | new_inode = new_dentry->d_inode; | 458 | new_inode = new_dentry->d_inode; |
461 | 459 | ||
462 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
463 | dentry_unhash(new_dentry); | ||
464 | |||
465 | err = fat_scan(old_dir, old_name, &old_sinfo); | 460 | err = fat_scan(old_dir, old_name, &old_sinfo); |
466 | if (err) { | 461 | if (err) { |
467 | err = -EIO; | 462 | err = -EIO; |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index c61a6789f36c..20b4ea53fdc4 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -824,8 +824,6 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) | |||
824 | struct fat_slot_info sinfo; | 824 | struct fat_slot_info sinfo; |
825 | int err; | 825 | int err; |
826 | 826 | ||
827 | dentry_unhash(dentry); | ||
828 | |||
829 | lock_super(sb); | 827 | lock_super(sb); |
830 | 828 | ||
831 | err = fat_dir_empty(inode); | 829 | err = fat_dir_empty(inode); |
@@ -933,9 +931,6 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
933 | int err, is_dir, update_dotdot, corrupt = 0; | 931 | int err, is_dir, update_dotdot, corrupt = 0; |
934 | struct super_block *sb = old_dir->i_sb; | 932 | struct super_block *sb = old_dir->i_sb; |
935 | 933 | ||
936 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
937 | dentry_unhash(new_dentry); | ||
938 | |||
939 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; | 934 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
940 | old_inode = old_dentry->d_inode; | 935 | old_inode = old_dentry->d_inode; |
941 | new_inode = new_dentry->d_inode; | 936 | new_inode = new_dentry->d_inode; |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 34591ee804b5..0f015a0468de 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -1007,9 +1007,6 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode) | |||
1007 | * In short, make sure you hash any inodes _before_ you start marking | 1007 | * In short, make sure you hash any inodes _before_ you start marking |
1008 | * them dirty. | 1008 | * them dirty. |
1009 | * | 1009 | * |
1010 | * This function *must* be atomic for the I_DIRTY_PAGES case - | ||
1011 | * set_page_dirty() is called under spinlock in several places. | ||
1012 | * | ||
1013 | * Note that for blockdevs, inode->dirtied_when represents the dirtying time of | 1010 | * Note that for blockdevs, inode->dirtied_when represents the dirtying time of |
1014 | * the block-special inode (/dev/hda1) itself. And the ->dirtied_when field of | 1011 | * the block-special inode (/dev/hda1) itself. And the ->dirtied_when field of |
1015 | * the kernel-internal blockdev inode represents the dirtying time of the | 1012 | * the kernel-internal blockdev inode represents the dirtying time of the |
@@ -1028,7 +1025,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) | |||
1028 | */ | 1025 | */ |
1029 | if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { | 1026 | if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { |
1030 | if (sb->s_op->dirty_inode) | 1027 | if (sb->s_op->dirty_inode) |
1031 | sb->s_op->dirty_inode(inode); | 1028 | sb->s_op->dirty_inode(inode, flags); |
1032 | } | 1029 | } |
1033 | 1030 | ||
1034 | /* | 1031 | /* |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 0d0e3faddcfa..d50160714595 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -667,8 +667,6 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
667 | if (IS_ERR(req)) | 667 | if (IS_ERR(req)) |
668 | return PTR_ERR(req); | 668 | return PTR_ERR(req); |
669 | 669 | ||
670 | dentry_unhash(entry); | ||
671 | |||
672 | req->in.h.opcode = FUSE_RMDIR; | 670 | req->in.h.opcode = FUSE_RMDIR; |
673 | req->in.h.nodeid = get_node_id(dir); | 671 | req->in.h.nodeid = get_node_id(dir); |
674 | req->in.numargs = 1; | 672 | req->in.numargs = 1; |
@@ -694,9 +692,6 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
694 | struct fuse_conn *fc = get_fuse_conn(olddir); | 692 | struct fuse_conn *fc = get_fuse_conn(olddir); |
695 | struct fuse_req *req = fuse_get_req(fc); | 693 | struct fuse_req *req = fuse_get_req(fc); |
696 | 694 | ||
697 | if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode)) | ||
698 | dentry_unhash(newent); | ||
699 | |||
700 | if (IS_ERR(req)) | 695 | if (IS_ERR(req)) |
701 | return PTR_ERR(req); | 696 | return PTR_ERR(req); |
702 | 697 | ||
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 1cb70cdba2c1..b4d70b13be92 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -253,9 +253,6 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry) | |||
253 | struct inode *inode = dentry->d_inode; | 253 | struct inode *inode = dentry->d_inode; |
254 | int res; | 254 | int res; |
255 | 255 | ||
256 | if (S_ISDIR(inode->i_mode)) | ||
257 | dentry_unhash(dentry); | ||
258 | |||
259 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) | 256 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) |
260 | return -ENOTEMPTY; | 257 | return -ENOTEMPTY; |
261 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); | 258 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); |
@@ -286,9 +283,6 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
286 | 283 | ||
287 | /* Unlink destination if it already exists */ | 284 | /* Unlink destination if it already exists */ |
288 | if (new_dentry->d_inode) { | 285 | if (new_dentry->d_inode) { |
289 | if (S_ISDIR(new_dentry->d_inode->i_mode)) | ||
290 | dentry_unhash(new_dentry); | ||
291 | |||
292 | res = hfs_remove(new_dir, new_dentry); | 286 | res = hfs_remove(new_dir, new_dentry); |
293 | if (res) | 287 | if (res) |
294 | return res; | 288 | return res; |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index b28835091dd0..4df5059c25da 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -370,8 +370,6 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) | |||
370 | struct inode *inode = dentry->d_inode; | 370 | struct inode *inode = dentry->d_inode; |
371 | int res; | 371 | int res; |
372 | 372 | ||
373 | dentry_unhash(dentry); | ||
374 | |||
375 | if (inode->i_size != 2) | 373 | if (inode->i_size != 2) |
376 | return -ENOTEMPTY; | 374 | return -ENOTEMPTY; |
377 | 375 | ||
@@ -469,12 +467,10 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
469 | 467 | ||
470 | /* Unlink destination if it already exists */ | 468 | /* Unlink destination if it already exists */ |
471 | if (new_dentry->d_inode) { | 469 | if (new_dentry->d_inode) { |
472 | if (S_ISDIR(new_dentry->d_inode->i_mode)) { | 470 | if (S_ISDIR(new_dentry->d_inode->i_mode)) |
473 | dentry_unhash(new_dentry); | ||
474 | res = hfsplus_rmdir(new_dir, new_dentry); | 471 | res = hfsplus_rmdir(new_dir, new_dentry); |
475 | } else { | 472 | else |
476 | res = hfsplus_unlink(new_dir, new_dentry); | 473 | res = hfsplus_unlink(new_dir, new_dentry); |
477 | } | ||
478 | if (res) | 474 | if (res) |
479 | return res; | 475 | return res; |
480 | } | 476 | } |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e6816b9e6903..2638c834ed28 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -683,8 +683,6 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry) | |||
683 | char *file; | 683 | char *file; |
684 | int err; | 684 | int err; |
685 | 685 | ||
686 | dentry_unhash(dentry); | ||
687 | |||
688 | if ((file = dentry_name(dentry)) == NULL) | 686 | if ((file = dentry_name(dentry)) == NULL) |
689 | return -ENOMEM; | 687 | return -ENOMEM; |
690 | err = do_rmdir(file); | 688 | err = do_rmdir(file); |
@@ -738,9 +736,6 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, | |||
738 | char *from_name, *to_name; | 736 | char *from_name, *to_name; |
739 | int err; | 737 | int err; |
740 | 738 | ||
741 | if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) | ||
742 | dentry_unhash(to); | ||
743 | |||
744 | if ((from_name = dentry_name(from)) == NULL) | 739 | if ((from_name = dentry_name(from)) == NULL) |
745 | return -ENOMEM; | 740 | return -ENOMEM; |
746 | if ((to_name = dentry_name(to)) == NULL) { | 741 | if ((to_name = dentry_name(to)) == NULL) { |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index ff0ce21c0867..acf95dab2aac 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -439,8 +439,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
439 | int err; | 439 | int err; |
440 | int r; | 440 | int r; |
441 | 441 | ||
442 | dentry_unhash(dentry); | ||
443 | |||
444 | hpfs_adjust_length(name, &len); | 442 | hpfs_adjust_length(name, &len); |
445 | hpfs_lock(dir->i_sb); | 443 | hpfs_lock(dir->i_sb); |
446 | err = -ENOENT; | 444 | err = -ENOENT; |
@@ -535,9 +533,6 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
535 | struct fnode *fnode; | 533 | struct fnode *fnode; |
536 | int err; | 534 | int err; |
537 | 535 | ||
538 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
539 | dentry_unhash(new_dentry); | ||
540 | |||
541 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; | 536 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
542 | err = 0; | 537 | err = 0; |
543 | hpfs_adjust_length(old_name, &old_len); | 538 | hpfs_adjust_length(old_name, &old_len); |
diff --git a/fs/inode.c b/fs/inode.c index 990d284877a1..0f7e88a7803f 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1,9 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/inode.c | ||
3 | * | ||
4 | * (C) 1997 Linus Torvalds | 2 | * (C) 1997 Linus Torvalds |
3 | * (C) 1999 Andrea Arcangeli <andrea@suse.de> (dynamic inode allocation) | ||
5 | */ | 4 | */ |
6 | |||
7 | #include <linux/fs.h> | 5 | #include <linux/fs.h> |
8 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
9 | #include <linux/dcache.h> | 7 | #include <linux/dcache.h> |
@@ -27,10 +25,11 @@ | |||
27 | #include <linux/prefetch.h> | 25 | #include <linux/prefetch.h> |
28 | #include <linux/ima.h> | 26 | #include <linux/ima.h> |
29 | #include <linux/cred.h> | 27 | #include <linux/cred.h> |
28 | #include <linux/buffer_head.h> /* for inode_has_buffers */ | ||
30 | #include "internal.h" | 29 | #include "internal.h" |
31 | 30 | ||
32 | /* | 31 | /* |
33 | * inode locking rules. | 32 | * Inode locking rules: |
34 | * | 33 | * |
35 | * inode->i_lock protects: | 34 | * inode->i_lock protects: |
36 | * inode->i_state, inode->i_hash, __iget() | 35 | * inode->i_state, inode->i_hash, __iget() |
@@ -60,54 +59,11 @@ | |||
60 | * inode_hash_lock | 59 | * inode_hash_lock |
61 | */ | 60 | */ |
62 | 61 | ||
63 | /* | ||
64 | * This is needed for the following functions: | ||
65 | * - inode_has_buffers | ||
66 | * - invalidate_bdev | ||
67 | * | ||
68 | * FIXME: remove all knowledge of the buffer layer from this file | ||
69 | */ | ||
70 | #include <linux/buffer_head.h> | ||
71 | |||
72 | /* | ||
73 | * New inode.c implementation. | ||
74 | * | ||
75 | * This implementation has the basic premise of trying | ||
76 | * to be extremely low-overhead and SMP-safe, yet be | ||
77 | * simple enough to be "obviously correct". | ||
78 | * | ||
79 | * Famous last words. | ||
80 | */ | ||
81 | |||
82 | /* inode dynamic allocation 1999, Andrea Arcangeli <andrea@suse.de> */ | ||
83 | |||
84 | /* #define INODE_PARANOIA 1 */ | ||
85 | /* #define INODE_DEBUG 1 */ | ||
86 | |||
87 | /* | ||
88 | * Inode lookup is no longer as critical as it used to be: | ||
89 | * most of the lookups are going to be through the dcache. | ||
90 | */ | ||
91 | #define I_HASHBITS i_hash_shift | ||
92 | #define I_HASHMASK i_hash_mask | ||
93 | |||
94 | static unsigned int i_hash_mask __read_mostly; | 62 | static unsigned int i_hash_mask __read_mostly; |
95 | static unsigned int i_hash_shift __read_mostly; | 63 | static unsigned int i_hash_shift __read_mostly; |
96 | static struct hlist_head *inode_hashtable __read_mostly; | 64 | static struct hlist_head *inode_hashtable __read_mostly; |
97 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); | 65 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); |
98 | 66 | ||
99 | /* | ||
100 | * Each inode can be on two separate lists. One is | ||
101 | * the hash list of the inode, used for lookups. The | ||
102 | * other linked list is the "type" list: | ||
103 | * "in_use" - valid inode, i_count > 0, i_nlink > 0 | ||
104 | * "dirty" - as "in_use" but also dirty | ||
105 | * "unused" - valid inode, i_count = 0 | ||
106 | * | ||
107 | * A "dirty" list is maintained for each super block, | ||
108 | * allowing for low-overhead inode sync() operations. | ||
109 | */ | ||
110 | |||
111 | static LIST_HEAD(inode_lru); | 67 | static LIST_HEAD(inode_lru); |
112 | static DEFINE_SPINLOCK(inode_lru_lock); | 68 | static DEFINE_SPINLOCK(inode_lru_lock); |
113 | 69 | ||
@@ -424,8 +380,8 @@ static unsigned long hash(struct super_block *sb, unsigned long hashval) | |||
424 | 380 | ||
425 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / | 381 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / |
426 | L1_CACHE_BYTES; | 382 | L1_CACHE_BYTES; |
427 | tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | 383 | tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> i_hash_shift); |
428 | return tmp & I_HASHMASK; | 384 | return tmp & i_hash_mask; |
429 | } | 385 | } |
430 | 386 | ||
431 | /** | 387 | /** |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 05f73328b28b..4bca6a2e5c07 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -75,7 +75,6 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | |||
75 | struct nameidata *nd) | 75 | struct nameidata *nd) |
76 | { | 76 | { |
77 | struct jffs2_inode_info *dir_f; | 77 | struct jffs2_inode_info *dir_f; |
78 | struct jffs2_sb_info *c; | ||
79 | struct jffs2_full_dirent *fd = NULL, *fd_list; | 78 | struct jffs2_full_dirent *fd = NULL, *fd_list; |
80 | uint32_t ino = 0; | 79 | uint32_t ino = 0; |
81 | struct inode *inode = NULL; | 80 | struct inode *inode = NULL; |
@@ -86,7 +85,6 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | |||
86 | return ERR_PTR(-ENAMETOOLONG); | 85 | return ERR_PTR(-ENAMETOOLONG); |
87 | 86 | ||
88 | dir_f = JFFS2_INODE_INFO(dir_i); | 87 | dir_f = JFFS2_INODE_INFO(dir_i); |
89 | c = JFFS2_SB_INFO(dir_i->i_sb); | ||
90 | 88 | ||
91 | mutex_lock(&dir_f->sem); | 89 | mutex_lock(&dir_f->sem); |
92 | 90 | ||
@@ -119,7 +117,6 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, | |||
119 | static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) | 117 | static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) |
120 | { | 118 | { |
121 | struct jffs2_inode_info *f; | 119 | struct jffs2_inode_info *f; |
122 | struct jffs2_sb_info *c; | ||
123 | struct inode *inode = filp->f_path.dentry->d_inode; | 120 | struct inode *inode = filp->f_path.dentry->d_inode; |
124 | struct jffs2_full_dirent *fd; | 121 | struct jffs2_full_dirent *fd; |
125 | unsigned long offset, curofs; | 122 | unsigned long offset, curofs; |
@@ -127,7 +124,6 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
127 | D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_path.dentry->d_inode->i_ino)); | 124 | D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_path.dentry->d_inode->i_ino)); |
128 | 125 | ||
129 | f = JFFS2_INODE_INFO(inode); | 126 | f = JFFS2_INODE_INFO(inode); |
130 | c = JFFS2_SB_INFO(inode->i_sb); | ||
131 | 127 | ||
132 | offset = filp->f_pos; | 128 | offset = filp->f_pos; |
133 | 129 | ||
@@ -609,8 +605,6 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | |||
609 | int ret; | 605 | int ret; |
610 | uint32_t now = get_seconds(); | 606 | uint32_t now = get_seconds(); |
611 | 607 | ||
612 | dentry_unhash(dentry); | ||
613 | |||
614 | for (fd = f->dents ; fd; fd = fd->next) { | 608 | for (fd = f->dents ; fd; fd = fd->next) { |
615 | if (fd->ino) | 609 | if (fd->ino) |
616 | return -ENOTEMPTY; | 610 | return -ENOTEMPTY; |
@@ -786,9 +780,6 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
786 | uint8_t type; | 780 | uint8_t type; |
787 | uint32_t now; | 781 | uint32_t now; |
788 | 782 | ||
789 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
790 | dentry_unhash(new_dentry); | ||
791 | |||
792 | /* The VFS will check for us and prevent trying to rename a | 783 | /* The VFS will check for us and prevent trying to rename a |
793 | * file over a directory and vice versa, but if it's a directory, | 784 | * file over a directory and vice versa, but if it's a directory, |
794 | * the VFS can't check whether the victim is empty. The filesystem | 785 | * the VFS can't check whether the victim is empty. The filesystem |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index e896e67767eb..46ad619b6124 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -357,7 +357,7 @@ error: | |||
357 | return ERR_PTR(ret); | 357 | return ERR_PTR(ret); |
358 | } | 358 | } |
359 | 359 | ||
360 | void jffs2_dirty_inode(struct inode *inode) | 360 | void jffs2_dirty_inode(struct inode *inode, int flags) |
361 | { | 361 | { |
362 | struct iattr iattr; | 362 | struct iattr iattr; |
363 | 363 | ||
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 00bae7cc2e48..65c6c43ca482 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -172,7 +172,7 @@ int jffs2_setattr (struct dentry *, struct iattr *); | |||
172 | int jffs2_do_setattr (struct inode *, struct iattr *); | 172 | int jffs2_do_setattr (struct inode *, struct iattr *); |
173 | struct inode *jffs2_iget(struct super_block *, unsigned long); | 173 | struct inode *jffs2_iget(struct super_block *, unsigned long); |
174 | void jffs2_evict_inode (struct inode *); | 174 | void jffs2_evict_inode (struct inode *); |
175 | void jffs2_dirty_inode(struct inode *inode); | 175 | void jffs2_dirty_inode(struct inode *inode, int flags); |
176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, | 176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, |
177 | struct jffs2_raw_inode *ri); | 177 | struct jffs2_raw_inode *ri); |
178 | int jffs2_statfs (struct dentry *, struct kstatfs *); | 178 | int jffs2_statfs (struct dentry *, struct kstatfs *); |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index b632dddcb482..8d8cd3419d02 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -94,7 +94,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
94 | uint32_t buf_size = 0; | 94 | uint32_t buf_size = 0; |
95 | struct jffs2_summary *s = NULL; /* summary info collected by the scan process */ | 95 | struct jffs2_summary *s = NULL; /* summary info collected by the scan process */ |
96 | #ifndef __ECOS | 96 | #ifndef __ECOS |
97 | size_t pointlen; | 97 | size_t pointlen, try_size; |
98 | 98 | ||
99 | if (c->mtd->point) { | 99 | if (c->mtd->point) { |
100 | ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen, | 100 | ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen, |
@@ -113,18 +113,21 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
113 | /* For NAND it's quicker to read a whole eraseblock at a time, | 113 | /* For NAND it's quicker to read a whole eraseblock at a time, |
114 | apparently */ | 114 | apparently */ |
115 | if (jffs2_cleanmarker_oob(c)) | 115 | if (jffs2_cleanmarker_oob(c)) |
116 | buf_size = c->sector_size; | 116 | try_size = c->sector_size; |
117 | else | 117 | else |
118 | buf_size = PAGE_SIZE; | 118 | try_size = PAGE_SIZE; |
119 | 119 | ||
120 | /* Respect kmalloc limitations */ | 120 | D1(printk(KERN_DEBUG "Trying to allocate readbuf of %zu " |
121 | if (buf_size > 128*1024) | 121 | "bytes\n", try_size)); |
122 | buf_size = 128*1024; | ||
123 | 122 | ||
124 | D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size)); | 123 | flashbuf = mtd_kmalloc_up_to(c->mtd, &try_size); |
125 | flashbuf = kmalloc(buf_size, GFP_KERNEL); | ||
126 | if (!flashbuf) | 124 | if (!flashbuf) |
127 | return -ENOMEM; | 125 | return -ENOMEM; |
126 | |||
127 | D1(printk(KERN_DEBUG "Allocated readbuf of %zu bytes\n", | ||
128 | try_size)); | ||
129 | |||
130 | buf_size = (uint32_t)try_size; | ||
128 | } | 131 | } |
129 | 132 | ||
130 | if (jffs2_sum_active()) { | 133 | if (jffs2_sum_active()) { |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index eddbb373209e..109655904bbc 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -173,7 +173,7 @@ void jfs_evict_inode(struct inode *inode) | |||
173 | dquot_drop(inode); | 173 | dquot_drop(inode); |
174 | } | 174 | } |
175 | 175 | ||
176 | void jfs_dirty_inode(struct inode *inode) | 176 | void jfs_dirty_inode(struct inode *inode, int flags) |
177 | { | 177 | { |
178 | static int noisy = 5; | 178 | static int noisy = 5; |
179 | 179 | ||
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 155e91eff07d..ec2fb8b945fc 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -28,7 +28,7 @@ extern struct inode *jfs_iget(struct super_block *, unsigned long); | |||
28 | extern int jfs_commit_inode(struct inode *, int); | 28 | extern int jfs_commit_inode(struct inode *, int); |
29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); | 29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); |
30 | extern void jfs_evict_inode(struct inode *); | 30 | extern void jfs_evict_inode(struct inode *); |
31 | extern void jfs_dirty_inode(struct inode *); | 31 | extern void jfs_dirty_inode(struct inode *, int); |
32 | extern void jfs_truncate(struct inode *); | 32 | extern void jfs_truncate(struct inode *); |
33 | extern void jfs_truncate_nolock(struct inode *, loff_t); | 33 | extern void jfs_truncate_nolock(struct inode *, loff_t); |
34 | extern void jfs_free_zero_link(struct inode *); | 34 | extern void jfs_free_zero_link(struct inode *); |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 865df16a6cf3..eaaf2b511e89 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -360,8 +360,6 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) | |||
360 | 360 | ||
361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); | 361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); |
362 | 362 | ||
363 | dentry_unhash(dentry); | ||
364 | |||
365 | /* Init inode for quota operations. */ | 363 | /* Init inode for quota operations. */ |
366 | dquot_initialize(dip); | 364 | dquot_initialize(dip); |
367 | dquot_initialize(ip); | 365 | dquot_initialize(ip); |
@@ -1097,9 +1095,6 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1097 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, | 1095 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, |
1098 | new_dentry->d_name.name); | 1096 | new_dentry->d_name.name); |
1099 | 1097 | ||
1100 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
1101 | dentry_unhash(new_dentry); | ||
1102 | |||
1103 | dquot_initialize(old_dir); | 1098 | dquot_initialize(old_dir); |
1104 | dquot_initialize(new_dir); | 1099 | dquot_initialize(new_dir); |
1105 | 1100 | ||
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index f34c9cde9e94..9ed89d1663f8 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -273,8 +273,6 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
273 | { | 273 | { |
274 | struct inode *inode = dentry->d_inode; | 274 | struct inode *inode = dentry->d_inode; |
275 | 275 | ||
276 | dentry_unhash(dentry); | ||
277 | |||
278 | if (!logfs_empty_dir(inode)) | 276 | if (!logfs_empty_dir(inode)) |
279 | return -ENOTEMPTY; | 277 | return -ENOTEMPTY; |
280 | 278 | ||
@@ -624,9 +622,6 @@ static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry, | |||
624 | loff_t pos; | 622 | loff_t pos; |
625 | int err; | 623 | int err; |
626 | 624 | ||
627 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
628 | dentry_unhash(new_dentry); | ||
629 | |||
630 | /* 1. locate source dd */ | 625 | /* 1. locate source dd */ |
631 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); | 626 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); |
632 | if (err) | 627 | if (err) |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index f60aed8db9c4..6e6777f1b4b2 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -168,8 +168,6 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry) | |||
168 | struct inode * inode = dentry->d_inode; | 168 | struct inode * inode = dentry->d_inode; |
169 | int err = -ENOTEMPTY; | 169 | int err = -ENOTEMPTY; |
170 | 170 | ||
171 | dentry_unhash(dentry); | ||
172 | |||
173 | if (minix_empty_dir(inode)) { | 171 | if (minix_empty_dir(inode)) { |
174 | err = minix_unlink(dir, dentry); | 172 | err = minix_unlink(dir, dentry); |
175 | if (!err) { | 173 | if (!err) { |
@@ -192,9 +190,6 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
192 | struct minix_dir_entry * old_de; | 190 | struct minix_dir_entry * old_de; |
193 | int err = -ENOENT; | 191 | int err = -ENOENT; |
194 | 192 | ||
195 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
196 | dentry_unhash(new_dentry); | ||
197 | |||
198 | old_de = minix_find_entry(old_dentry, &old_page); | 193 | old_de = minix_find_entry(old_dentry, &old_page); |
199 | if (!old_de) | 194 | if (!old_de) |
200 | goto out; | 195 | goto out; |
diff --git a/fs/namei.c b/fs/namei.c index 2358b326b221..e2e4e8d032ee 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -919,12 +919,11 @@ static inline bool managed_dentry_might_block(struct dentry *dentry) | |||
919 | } | 919 | } |
920 | 920 | ||
921 | /* | 921 | /* |
922 | * Skip to top of mountpoint pile in rcuwalk mode. We abort the rcu-walk if we | 922 | * Try to skip to top of mountpoint pile in rcuwalk mode. Fail if |
923 | * meet a managed dentry and we're not walking to "..". True is returned to | 923 | * we meet a managed dentry that would need blocking. |
924 | * continue, false to abort. | ||
925 | */ | 924 | */ |
926 | static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | 925 | static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, |
927 | struct inode **inode, bool reverse_transit) | 926 | struct inode **inode) |
928 | { | 927 | { |
929 | for (;;) { | 928 | for (;;) { |
930 | struct vfsmount *mounted; | 929 | struct vfsmount *mounted; |
@@ -933,8 +932,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
933 | * that wants to block transit. | 932 | * that wants to block transit. |
934 | */ | 933 | */ |
935 | *inode = path->dentry->d_inode; | 934 | *inode = path->dentry->d_inode; |
936 | if (!reverse_transit && | 935 | if (unlikely(managed_dentry_might_block(path->dentry))) |
937 | unlikely(managed_dentry_might_block(path->dentry))) | ||
938 | return false; | 936 | return false; |
939 | 937 | ||
940 | if (!d_mountpoint(path->dentry)) | 938 | if (!d_mountpoint(path->dentry)) |
@@ -947,16 +945,24 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
947 | path->dentry = mounted->mnt_root; | 945 | path->dentry = mounted->mnt_root; |
948 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); | 946 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); |
949 | } | 947 | } |
950 | |||
951 | if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | ||
952 | return reverse_transit; | ||
953 | return true; | 948 | return true; |
954 | } | 949 | } |
955 | 950 | ||
956 | static int follow_dotdot_rcu(struct nameidata *nd) | 951 | static void follow_mount_rcu(struct nameidata *nd) |
957 | { | 952 | { |
958 | struct inode *inode = nd->inode; | 953 | while (d_mountpoint(nd->path.dentry)) { |
954 | struct vfsmount *mounted; | ||
955 | mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1); | ||
956 | if (!mounted) | ||
957 | break; | ||
958 | nd->path.mnt = mounted; | ||
959 | nd->path.dentry = mounted->mnt_root; | ||
960 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); | ||
961 | } | ||
962 | } | ||
959 | 963 | ||
964 | static int follow_dotdot_rcu(struct nameidata *nd) | ||
965 | { | ||
960 | set_root_rcu(nd); | 966 | set_root_rcu(nd); |
961 | 967 | ||
962 | while (1) { | 968 | while (1) { |
@@ -972,7 +978,6 @@ static int follow_dotdot_rcu(struct nameidata *nd) | |||
972 | seq = read_seqcount_begin(&parent->d_seq); | 978 | seq = read_seqcount_begin(&parent->d_seq); |
973 | if (read_seqcount_retry(&old->d_seq, nd->seq)) | 979 | if (read_seqcount_retry(&old->d_seq, nd->seq)) |
974 | goto failed; | 980 | goto failed; |
975 | inode = parent->d_inode; | ||
976 | nd->path.dentry = parent; | 981 | nd->path.dentry = parent; |
977 | nd->seq = seq; | 982 | nd->seq = seq; |
978 | break; | 983 | break; |
@@ -980,10 +985,9 @@ static int follow_dotdot_rcu(struct nameidata *nd) | |||
980 | if (!follow_up_rcu(&nd->path)) | 985 | if (!follow_up_rcu(&nd->path)) |
981 | break; | 986 | break; |
982 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); | 987 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); |
983 | inode = nd->path.dentry->d_inode; | ||
984 | } | 988 | } |
985 | __follow_mount_rcu(nd, &nd->path, &inode, true); | 989 | follow_mount_rcu(nd); |
986 | nd->inode = inode; | 990 | nd->inode = nd->path.dentry->d_inode; |
987 | return 0; | 991 | return 0; |
988 | 992 | ||
989 | failed: | 993 | failed: |
@@ -1157,8 +1161,11 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
1157 | } | 1161 | } |
1158 | path->mnt = mnt; | 1162 | path->mnt = mnt; |
1159 | path->dentry = dentry; | 1163 | path->dentry = dentry; |
1160 | if (likely(__follow_mount_rcu(nd, path, inode, false))) | 1164 | if (unlikely(!__follow_mount_rcu(nd, path, inode))) |
1161 | return 0; | 1165 | goto unlazy; |
1166 | if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | ||
1167 | goto unlazy; | ||
1168 | return 0; | ||
1162 | unlazy: | 1169 | unlazy: |
1163 | if (unlazy_walk(nd, dentry)) | 1170 | if (unlazy_walk(nd, dentry)) |
1164 | return -ECHILD; | 1171 | return -ECHILD; |
@@ -2572,6 +2579,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2572 | if (error) | 2579 | if (error) |
2573 | goto out; | 2580 | goto out; |
2574 | 2581 | ||
2582 | shrink_dcache_parent(dentry); | ||
2575 | error = dir->i_op->rmdir(dir, dentry); | 2583 | error = dir->i_op->rmdir(dir, dentry); |
2576 | if (error) | 2584 | if (error) |
2577 | goto out; | 2585 | goto out; |
@@ -2986,6 +2994,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2986 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) | 2994 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) |
2987 | goto out; | 2995 | goto out; |
2988 | 2996 | ||
2997 | if (target) | ||
2998 | shrink_dcache_parent(new_dentry); | ||
2989 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 2999 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
2990 | if (error) | 3000 | if (error) |
2991 | goto out; | 3001 | goto out; |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index e3e646b06404..9c51f621e901 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -1033,8 +1033,11 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) | |||
1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", | 1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", |
1034 | dentry->d_parent->d_name.name, dentry->d_name.name); | 1034 | dentry->d_parent->d_name.name, dentry->d_name.name); |
1035 | 1035 | ||
1036 | /* | ||
1037 | * fail with EBUSY if there are still references to this | ||
1038 | * directory. | ||
1039 | */ | ||
1036 | dentry_unhash(dentry); | 1040 | dentry_unhash(dentry); |
1037 | |||
1038 | error = -EBUSY; | 1041 | error = -EBUSY; |
1039 | if (!d_unhashed(dentry)) | 1042 | if (!d_unhashed(dentry)) |
1040 | goto out; | 1043 | goto out; |
@@ -1141,8 +1144,16 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1141 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, | 1144 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1142 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); | 1145 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); |
1143 | 1146 | ||
1144 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | 1147 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) { |
1148 | /* | ||
1149 | * fail with EBUSY if there are still references to this | ||
1150 | * directory. | ||
1151 | */ | ||
1145 | dentry_unhash(new_dentry); | 1152 | dentry_unhash(new_dentry); |
1153 | error = -EBUSY; | ||
1154 | if (!d_unhashed(new_dentry)) | ||
1155 | goto out; | ||
1156 | } | ||
1146 | 1157 | ||
1147 | ncp_age_dentry(server, old_dentry); | 1158 | ncp_age_dentry(server, old_dentry); |
1148 | ncp_age_dentry(server, new_dentry); | 1159 | ncp_age_dentry(server, new_dentry); |
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index ba306658a6db..81515545ba75 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig | |||
@@ -87,6 +87,16 @@ config NFS_V4_1 | |||
87 | config PNFS_FILE_LAYOUT | 87 | config PNFS_FILE_LAYOUT |
88 | tristate | 88 | tristate |
89 | 89 | ||
90 | config PNFS_OBJLAYOUT | ||
91 | tristate "Provide support for the pNFS Objects Layout Driver for NFSv4.1 pNFS (EXPERIMENTAL)" | ||
92 | depends on NFS_FS && NFS_V4_1 && SCSI_OSD_ULD | ||
93 | help | ||
94 | Say M here if you want your pNFS client to support the Objects Layout Driver. | ||
95 | Requires the SCSI osd initiator library (SCSI_OSD_INITIATOR) and | ||
96 | upper level driver (SCSI_OSD_ULD). | ||
97 | |||
98 | If unsure, say N. | ||
99 | |||
90 | config ROOT_NFS | 100 | config ROOT_NFS |
91 | bool "Root file system on NFS" | 101 | bool "Root file system on NFS" |
92 | depends on NFS_FS=y && IP_PNP | 102 | depends on NFS_FS=y && IP_PNP |
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile index 4776ff9e3814..6a34f7dd0e6f 100644 --- a/fs/nfs/Makefile +++ b/fs/nfs/Makefile | |||
@@ -15,9 +15,11 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ | |||
15 | delegation.o idmap.o \ | 15 | delegation.o idmap.o \ |
16 | callback.o callback_xdr.o callback_proc.o \ | 16 | callback.o callback_xdr.o callback_proc.o \ |
17 | nfs4namespace.o | 17 | nfs4namespace.o |
18 | nfs-$(CONFIG_NFS_V4_1) += pnfs.o | 18 | nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o |
19 | nfs-$(CONFIG_SYSCTL) += sysctl.o | 19 | nfs-$(CONFIG_SYSCTL) += sysctl.o |
20 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o | 20 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o |
21 | 21 | ||
22 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o | 22 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o |
23 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o | 23 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o |
24 | |||
25 | obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayout/ | ||
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 46d93ce7311b..b257383bb565 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -167,6 +167,23 @@ extern unsigned nfs4_callback_layoutrecall( | |||
167 | 167 | ||
168 | extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); | 168 | extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); |
169 | extern void nfs4_cb_take_slot(struct nfs_client *clp); | 169 | extern void nfs4_cb_take_slot(struct nfs_client *clp); |
170 | |||
171 | struct cb_devicenotifyitem { | ||
172 | uint32_t cbd_notify_type; | ||
173 | uint32_t cbd_layout_type; | ||
174 | struct nfs4_deviceid cbd_dev_id; | ||
175 | uint32_t cbd_immediate; | ||
176 | }; | ||
177 | |||
178 | struct cb_devicenotifyargs { | ||
179 | int ndevs; | ||
180 | struct cb_devicenotifyitem *devs; | ||
181 | }; | ||
182 | |||
183 | extern __be32 nfs4_callback_devicenotify( | ||
184 | struct cb_devicenotifyargs *args, | ||
185 | void *dummy, struct cb_process_state *cps); | ||
186 | |||
170 | #endif /* CONFIG_NFS_V4_1 */ | 187 | #endif /* CONFIG_NFS_V4_1 */ |
171 | extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); | 188 | extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); |
172 | extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, | 189 | extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 2f41dccea18e..d4d1954e9bb9 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -139,7 +139,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, | |||
139 | spin_lock(&ino->i_lock); | 139 | spin_lock(&ino->i_lock); |
140 | if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || | 140 | if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || |
141 | mark_matching_lsegs_invalid(lo, &free_me_list, | 141 | mark_matching_lsegs_invalid(lo, &free_me_list, |
142 | args->cbl_range.iomode)) | 142 | &args->cbl_range)) |
143 | rv = NFS4ERR_DELAY; | 143 | rv = NFS4ERR_DELAY; |
144 | else | 144 | else |
145 | rv = NFS4ERR_NOMATCHING_LAYOUT; | 145 | rv = NFS4ERR_NOMATCHING_LAYOUT; |
@@ -184,7 +184,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, | |||
184 | ino = lo->plh_inode; | 184 | ino = lo->plh_inode; |
185 | spin_lock(&ino->i_lock); | 185 | spin_lock(&ino->i_lock); |
186 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); | 186 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); |
187 | if (mark_matching_lsegs_invalid(lo, &free_me_list, range.iomode)) | 187 | if (mark_matching_lsegs_invalid(lo, &free_me_list, &range)) |
188 | rv = NFS4ERR_DELAY; | 188 | rv = NFS4ERR_DELAY; |
189 | list_del_init(&lo->plh_bulk_recall); | 189 | list_del_init(&lo->plh_bulk_recall); |
190 | spin_unlock(&ino->i_lock); | 190 | spin_unlock(&ino->i_lock); |
@@ -241,6 +241,53 @@ static void pnfs_recall_all_layouts(struct nfs_client *clp) | |||
241 | do_callback_layoutrecall(clp, &args); | 241 | do_callback_layoutrecall(clp, &args); |
242 | } | 242 | } |
243 | 243 | ||
244 | __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args, | ||
245 | void *dummy, struct cb_process_state *cps) | ||
246 | { | ||
247 | int i; | ||
248 | __be32 res = 0; | ||
249 | struct nfs_client *clp = cps->clp; | ||
250 | struct nfs_server *server = NULL; | ||
251 | |||
252 | dprintk("%s: -->\n", __func__); | ||
253 | |||
254 | if (!clp) { | ||
255 | res = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION); | ||
256 | goto out; | ||
257 | } | ||
258 | |||
259 | for (i = 0; i < args->ndevs; i++) { | ||
260 | struct cb_devicenotifyitem *dev = &args->devs[i]; | ||
261 | |||
262 | if (!server || | ||
263 | server->pnfs_curr_ld->id != dev->cbd_layout_type) { | ||
264 | rcu_read_lock(); | ||
265 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) | ||
266 | if (server->pnfs_curr_ld && | ||
267 | server->pnfs_curr_ld->id == dev->cbd_layout_type) { | ||
268 | rcu_read_unlock(); | ||
269 | goto found; | ||
270 | } | ||
271 | rcu_read_unlock(); | ||
272 | dprintk("%s: layout type %u not found\n", | ||
273 | __func__, dev->cbd_layout_type); | ||
274 | continue; | ||
275 | } | ||
276 | |||
277 | found: | ||
278 | if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) | ||
279 | dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, " | ||
280 | "deleting instead\n", __func__); | ||
281 | nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id); | ||
282 | } | ||
283 | |||
284 | out: | ||
285 | kfree(args->devs); | ||
286 | dprintk("%s: exit with status = %u\n", | ||
287 | __func__, be32_to_cpu(res)); | ||
288 | return res; | ||
289 | } | ||
290 | |||
244 | int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid) | 291 | int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid) |
245 | { | 292 | { |
246 | if (delegation == NULL) | 293 | if (delegation == NULL) |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 00ecf62ce7c1..c6c86a77e043 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #if defined(CONFIG_NFS_V4_1) | 26 | #if defined(CONFIG_NFS_V4_1) |
27 | #define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | 27 | #define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) |
28 | #define CB_OP_DEVICENOTIFY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | ||
28 | #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ | 29 | #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ |
29 | 4 + 1 + 3) | 30 | 4 + 1 + 3) |
30 | #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | 31 | #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) |
@@ -284,6 +285,93 @@ out: | |||
284 | return status; | 285 | return status; |
285 | } | 286 | } |
286 | 287 | ||
288 | static | ||
289 | __be32 decode_devicenotify_args(struct svc_rqst *rqstp, | ||
290 | struct xdr_stream *xdr, | ||
291 | struct cb_devicenotifyargs *args) | ||
292 | { | ||
293 | __be32 *p; | ||
294 | __be32 status = 0; | ||
295 | u32 tmp; | ||
296 | int n, i; | ||
297 | args->ndevs = 0; | ||
298 | |||
299 | /* Num of device notifications */ | ||
300 | p = read_buf(xdr, sizeof(uint32_t)); | ||
301 | if (unlikely(p == NULL)) { | ||
302 | status = htonl(NFS4ERR_BADXDR); | ||
303 | goto out; | ||
304 | } | ||
305 | n = ntohl(*p++); | ||
306 | if (n <= 0) | ||
307 | goto out; | ||
308 | |||
309 | args->devs = kmalloc(n * sizeof(*args->devs), GFP_KERNEL); | ||
310 | if (!args->devs) { | ||
311 | status = htonl(NFS4ERR_DELAY); | ||
312 | goto out; | ||
313 | } | ||
314 | |||
315 | /* Decode each dev notification */ | ||
316 | for (i = 0; i < n; i++) { | ||
317 | struct cb_devicenotifyitem *dev = &args->devs[i]; | ||
318 | |||
319 | p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE); | ||
320 | if (unlikely(p == NULL)) { | ||
321 | status = htonl(NFS4ERR_BADXDR); | ||
322 | goto err; | ||
323 | } | ||
324 | |||
325 | tmp = ntohl(*p++); /* bitmap size */ | ||
326 | if (tmp != 1) { | ||
327 | status = htonl(NFS4ERR_INVAL); | ||
328 | goto err; | ||
329 | } | ||
330 | dev->cbd_notify_type = ntohl(*p++); | ||
331 | if (dev->cbd_notify_type != NOTIFY_DEVICEID4_CHANGE && | ||
332 | dev->cbd_notify_type != NOTIFY_DEVICEID4_DELETE) { | ||
333 | status = htonl(NFS4ERR_INVAL); | ||
334 | goto err; | ||
335 | } | ||
336 | |||
337 | tmp = ntohl(*p++); /* opaque size */ | ||
338 | if (((dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) && | ||
339 | (tmp != NFS4_DEVICEID4_SIZE + 8)) || | ||
340 | ((dev->cbd_notify_type == NOTIFY_DEVICEID4_DELETE) && | ||
341 | (tmp != NFS4_DEVICEID4_SIZE + 4))) { | ||
342 | status = htonl(NFS4ERR_INVAL); | ||
343 | goto err; | ||
344 | } | ||
345 | dev->cbd_layout_type = ntohl(*p++); | ||
346 | memcpy(dev->cbd_dev_id.data, p, NFS4_DEVICEID4_SIZE); | ||
347 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); | ||
348 | |||
349 | if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) { | ||
350 | p = read_buf(xdr, sizeof(uint32_t)); | ||
351 | if (unlikely(p == NULL)) { | ||
352 | status = htonl(NFS4ERR_BADXDR); | ||
353 | goto err; | ||
354 | } | ||
355 | dev->cbd_immediate = ntohl(*p++); | ||
356 | } else { | ||
357 | dev->cbd_immediate = 0; | ||
358 | } | ||
359 | |||
360 | args->ndevs++; | ||
361 | |||
362 | dprintk("%s: type %d layout 0x%x immediate %d\n", | ||
363 | __func__, dev->cbd_notify_type, dev->cbd_layout_type, | ||
364 | dev->cbd_immediate); | ||
365 | } | ||
366 | out: | ||
367 | dprintk("%s: status %d ndevs %d\n", | ||
368 | __func__, ntohl(status), args->ndevs); | ||
369 | return status; | ||
370 | err: | ||
371 | kfree(args->devs); | ||
372 | goto out; | ||
373 | } | ||
374 | |||
287 | static __be32 decode_sessionid(struct xdr_stream *xdr, | 375 | static __be32 decode_sessionid(struct xdr_stream *xdr, |
288 | struct nfs4_sessionid *sid) | 376 | struct nfs4_sessionid *sid) |
289 | { | 377 | { |
@@ -639,10 +727,10 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) | |||
639 | case OP_CB_RECALL_ANY: | 727 | case OP_CB_RECALL_ANY: |
640 | case OP_CB_RECALL_SLOT: | 728 | case OP_CB_RECALL_SLOT: |
641 | case OP_CB_LAYOUTRECALL: | 729 | case OP_CB_LAYOUTRECALL: |
730 | case OP_CB_NOTIFY_DEVICEID: | ||
642 | *op = &callback_ops[op_nr]; | 731 | *op = &callback_ops[op_nr]; |
643 | break; | 732 | break; |
644 | 733 | ||
645 | case OP_CB_NOTIFY_DEVICEID: | ||
646 | case OP_CB_NOTIFY: | 734 | case OP_CB_NOTIFY: |
647 | case OP_CB_PUSH_DELEG: | 735 | case OP_CB_PUSH_DELEG: |
648 | case OP_CB_RECALLABLE_OBJ_AVAIL: | 736 | case OP_CB_RECALLABLE_OBJ_AVAIL: |
@@ -849,6 +937,12 @@ static struct callback_op callback_ops[] = { | |||
849 | (callback_decode_arg_t)decode_layoutrecall_args, | 937 | (callback_decode_arg_t)decode_layoutrecall_args, |
850 | .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ, | 938 | .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ, |
851 | }, | 939 | }, |
940 | [OP_CB_NOTIFY_DEVICEID] = { | ||
941 | .process_op = (callback_process_op_t)nfs4_callback_devicenotify, | ||
942 | .decode_args = | ||
943 | (callback_decode_arg_t)decode_devicenotify_args, | ||
944 | .res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ, | ||
945 | }, | ||
852 | [OP_CB_SEQUENCE] = { | 946 | [OP_CB_SEQUENCE] = { |
853 | .process_op = (callback_process_op_t)nfs4_callback_sequence, | 947 | .process_op = (callback_process_op_t)nfs4_callback_sequence, |
854 | .decode_args = (callback_decode_arg_t)decode_cb_sequence_args, | 948 | .decode_args = (callback_decode_arg_t)decode_cb_sequence_args, |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 139be9647d80..b3dc2b88b65b 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -290,6 +290,8 @@ static void nfs_free_client(struct nfs_client *clp) | |||
290 | if (clp->cl_machine_cred != NULL) | 290 | if (clp->cl_machine_cred != NULL) |
291 | put_rpccred(clp->cl_machine_cred); | 291 | put_rpccred(clp->cl_machine_cred); |
292 | 292 | ||
293 | nfs4_deviceid_purge_client(clp); | ||
294 | |||
293 | kfree(clp->cl_hostname); | 295 | kfree(clp->cl_hostname); |
294 | kfree(clp); | 296 | kfree(clp); |
295 | 297 | ||
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index bbbc6bf5cb2e..dd25c2aec375 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -21,25 +21,13 @@ | |||
21 | #include "delegation.h" | 21 | #include "delegation.h" |
22 | #include "internal.h" | 22 | #include "internal.h" |
23 | 23 | ||
24 | static void nfs_do_free_delegation(struct nfs_delegation *delegation) | ||
25 | { | ||
26 | kfree(delegation); | ||
27 | } | ||
28 | |||
29 | static void nfs_free_delegation_callback(struct rcu_head *head) | ||
30 | { | ||
31 | struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu); | ||
32 | |||
33 | nfs_do_free_delegation(delegation); | ||
34 | } | ||
35 | |||
36 | static void nfs_free_delegation(struct nfs_delegation *delegation) | 24 | static void nfs_free_delegation(struct nfs_delegation *delegation) |
37 | { | 25 | { |
38 | if (delegation->cred) { | 26 | if (delegation->cred) { |
39 | put_rpccred(delegation->cred); | 27 | put_rpccred(delegation->cred); |
40 | delegation->cred = NULL; | 28 | delegation->cred = NULL; |
41 | } | 29 | } |
42 | call_rcu(&delegation->rcu, nfs_free_delegation_callback); | 30 | kfree_rcu(delegation, rcu); |
43 | } | 31 | } |
44 | 32 | ||
45 | /** | 33 | /** |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 424e47773a84..ededdbd0db38 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -512,12 +512,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
512 | struct page **xdr_pages, struct page *page, unsigned int buflen) | 512 | struct page **xdr_pages, struct page *page, unsigned int buflen) |
513 | { | 513 | { |
514 | struct xdr_stream stream; | 514 | struct xdr_stream stream; |
515 | struct xdr_buf buf = { | 515 | struct xdr_buf buf; |
516 | .pages = xdr_pages, | ||
517 | .page_len = buflen, | ||
518 | .buflen = buflen, | ||
519 | .len = buflen, | ||
520 | }; | ||
521 | struct page *scratch; | 516 | struct page *scratch; |
522 | struct nfs_cache_array *array; | 517 | struct nfs_cache_array *array; |
523 | unsigned int count = 0; | 518 | unsigned int count = 0; |
@@ -527,7 +522,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
527 | if (scratch == NULL) | 522 | if (scratch == NULL) |
528 | return -ENOMEM; | 523 | return -ENOMEM; |
529 | 524 | ||
530 | xdr_init_decode(&stream, &buf, NULL); | 525 | xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen); |
531 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | 526 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); |
532 | 527 | ||
533 | do { | 528 | do { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 57bb31ad7a5e..144f2a3c7185 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1298,8 +1298,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1298 | i_size_write(inode, new_isize); | 1298 | i_size_write(inode, new_isize); |
1299 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1299 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1300 | } | 1300 | } |
1301 | dprintk("NFS: isize change on server for file %s/%ld\n", | 1301 | dprintk("NFS: isize change on server for file %s/%ld " |
1302 | inode->i_sb->s_id, inode->i_ino); | 1302 | "(%Ld to %Ld)\n", |
1303 | inode->i_sb->s_id, | ||
1304 | inode->i_ino, | ||
1305 | (long long)cur_isize, | ||
1306 | (long long)new_isize); | ||
1303 | } | 1307 | } |
1304 | } else | 1308 | } else |
1305 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | 1309 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR |
@@ -1424,9 +1428,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1424 | */ | 1428 | */ |
1425 | void nfs4_evict_inode(struct inode *inode) | 1429 | void nfs4_evict_inode(struct inode *inode) |
1426 | { | 1430 | { |
1427 | pnfs_destroy_layout(NFS_I(inode)); | ||
1428 | truncate_inode_pages(&inode->i_data, 0); | 1431 | truncate_inode_pages(&inode->i_data, 0); |
1429 | end_writeback(inode); | 1432 | end_writeback(inode); |
1433 | pnfs_return_layout(inode); | ||
1434 | pnfs_destroy_layout(NFS_I(inode)); | ||
1430 | /* If we are holding a delegation, return it! */ | 1435 | /* If we are holding a delegation, return it! */ |
1431 | nfs_inode_return_delegation_noreclaim(inode); | 1436 | nfs_inode_return_delegation_noreclaim(inode); |
1432 | /* First call standard NFS clear_inode() code */ | 1437 | /* First call standard NFS clear_inode() code */ |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 2df6ca7b5898..b9056cbe68d6 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -310,6 +310,7 @@ extern int nfs_migrate_page(struct address_space *, | |||
310 | #endif | 310 | #endif |
311 | 311 | ||
312 | /* nfs4proc.c */ | 312 | /* nfs4proc.c */ |
313 | extern void __nfs4_read_done_cb(struct nfs_read_data *); | ||
313 | extern void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data); | 314 | extern void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data); |
314 | extern int nfs4_init_client(struct nfs_client *clp, | 315 | extern int nfs4_init_client(struct nfs_client *clp, |
315 | const struct rpc_timeout *timeparms, | 316 | const struct rpc_timeout *timeparms, |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index be79dc9f386d..426908809c97 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -421,6 +421,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
421 | struct nfs4_deviceid *id, | 421 | struct nfs4_deviceid *id, |
422 | gfp_t gfp_flags) | 422 | gfp_t gfp_flags) |
423 | { | 423 | { |
424 | struct nfs4_deviceid_node *d; | ||
424 | struct nfs4_file_layout_dsaddr *dsaddr; | 425 | struct nfs4_file_layout_dsaddr *dsaddr; |
425 | int status = -EINVAL; | 426 | int status = -EINVAL; |
426 | struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); | 427 | struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); |
@@ -428,7 +429,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
428 | dprintk("--> %s\n", __func__); | 429 | dprintk("--> %s\n", __func__); |
429 | 430 | ||
430 | if (fl->pattern_offset > lgr->range.offset) { | 431 | if (fl->pattern_offset > lgr->range.offset) { |
431 | dprintk("%s pattern_offset %lld to large\n", | 432 | dprintk("%s pattern_offset %lld too large\n", |
432 | __func__, fl->pattern_offset); | 433 | __func__, fl->pattern_offset); |
433 | goto out; | 434 | goto out; |
434 | } | 435 | } |
@@ -440,12 +441,14 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
440 | } | 441 | } |
441 | 442 | ||
442 | /* find and reference the deviceid */ | 443 | /* find and reference the deviceid */ |
443 | dsaddr = nfs4_fl_find_get_deviceid(id); | 444 | d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld, |
444 | if (dsaddr == NULL) { | 445 | NFS_SERVER(lo->plh_inode)->nfs_client, id); |
446 | if (d == NULL) { | ||
445 | dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); | 447 | dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); |
446 | if (dsaddr == NULL) | 448 | if (dsaddr == NULL) |
447 | goto out; | 449 | goto out; |
448 | } | 450 | } else |
451 | dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); | ||
449 | fl->dsaddr = dsaddr; | 452 | fl->dsaddr = dsaddr; |
450 | 453 | ||
451 | if (fl->first_stripe_index < 0 || | 454 | if (fl->first_stripe_index < 0 || |
@@ -507,12 +510,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
507 | gfp_t gfp_flags) | 510 | gfp_t gfp_flags) |
508 | { | 511 | { |
509 | struct xdr_stream stream; | 512 | struct xdr_stream stream; |
510 | struct xdr_buf buf = { | 513 | struct xdr_buf buf; |
511 | .pages = lgr->layoutp->pages, | ||
512 | .page_len = lgr->layoutp->len, | ||
513 | .buflen = lgr->layoutp->len, | ||
514 | .len = lgr->layoutp->len, | ||
515 | }; | ||
516 | struct page *scratch; | 514 | struct page *scratch; |
517 | __be32 *p; | 515 | __be32 *p; |
518 | uint32_t nfl_util; | 516 | uint32_t nfl_util; |
@@ -524,7 +522,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
524 | if (!scratch) | 522 | if (!scratch) |
525 | return -ENOMEM; | 523 | return -ENOMEM; |
526 | 524 | ||
527 | xdr_init_decode(&stream, &buf, NULL); | 525 | xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len); |
528 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | 526 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); |
529 | 527 | ||
530 | /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8), | 528 | /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8), |
@@ -535,7 +533,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
535 | 533 | ||
536 | memcpy(id, p, sizeof(*id)); | 534 | memcpy(id, p, sizeof(*id)); |
537 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); | 535 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); |
538 | print_deviceid(id); | 536 | nfs4_print_deviceid(id); |
539 | 537 | ||
540 | nfl_util = be32_to_cpup(p++); | 538 | nfl_util = be32_to_cpup(p++); |
541 | if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) | 539 | if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) |
@@ -653,16 +651,19 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, | |||
653 | /* | 651 | /* |
654 | * filelayout_pg_test(). Called by nfs_can_coalesce_requests() | 652 | * filelayout_pg_test(). Called by nfs_can_coalesce_requests() |
655 | * | 653 | * |
656 | * return 1 : coalesce page | 654 | * return true : coalesce page |
657 | * return 0 : don't coalesce page | 655 | * return false : don't coalesce page |
658 | */ | 656 | */ |
659 | int | 657 | bool |
660 | filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | 658 | filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, |
661 | struct nfs_page *req) | 659 | struct nfs_page *req) |
662 | { | 660 | { |
663 | u64 p_stripe, r_stripe; | 661 | u64 p_stripe, r_stripe; |
664 | u32 stripe_unit; | 662 | u32 stripe_unit; |
665 | 663 | ||
664 | if (!pnfs_generic_pg_test(pgio, prev, req)) | ||
665 | return 0; | ||
666 | |||
666 | if (!pgio->pg_lseg) | 667 | if (!pgio->pg_lseg) |
667 | return 1; | 668 | return 1; |
668 | p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; | 669 | p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; |
@@ -860,6 +861,12 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages, | |||
860 | return -ENOMEM; | 861 | return -ENOMEM; |
861 | } | 862 | } |
862 | 863 | ||
864 | static void | ||
865 | filelayout_free_deveiceid_node(struct nfs4_deviceid_node *d) | ||
866 | { | ||
867 | nfs4_fl_free_deviceid(container_of(d, struct nfs4_file_layout_dsaddr, id_node)); | ||
868 | } | ||
869 | |||
863 | static struct pnfs_layoutdriver_type filelayout_type = { | 870 | static struct pnfs_layoutdriver_type filelayout_type = { |
864 | .id = LAYOUT_NFSV4_1_FILES, | 871 | .id = LAYOUT_NFSV4_1_FILES, |
865 | .name = "LAYOUT_NFSV4_1_FILES", | 872 | .name = "LAYOUT_NFSV4_1_FILES", |
@@ -872,6 +879,7 @@ static struct pnfs_layoutdriver_type filelayout_type = { | |||
872 | .commit_pagelist = filelayout_commit_pagelist, | 879 | .commit_pagelist = filelayout_commit_pagelist, |
873 | .read_pagelist = filelayout_read_pagelist, | 880 | .read_pagelist = filelayout_read_pagelist, |
874 | .write_pagelist = filelayout_write_pagelist, | 881 | .write_pagelist = filelayout_write_pagelist, |
882 | .free_deviceid_node = filelayout_free_deveiceid_node, | ||
875 | }; | 883 | }; |
876 | 884 | ||
877 | static int __init nfs4filelayout_init(void) | 885 | static int __init nfs4filelayout_init(void) |
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h index 2b461d77b43a..cebe01e3795e 100644 --- a/fs/nfs/nfs4filelayout.h +++ b/fs/nfs/nfs4filelayout.h | |||
@@ -59,9 +59,7 @@ struct nfs4_pnfs_ds { | |||
59 | #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 | 59 | #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 |
60 | 60 | ||
61 | struct nfs4_file_layout_dsaddr { | 61 | struct nfs4_file_layout_dsaddr { |
62 | struct hlist_node node; | 62 | struct nfs4_deviceid_node id_node; |
63 | struct nfs4_deviceid deviceid; | ||
64 | atomic_t ref; | ||
65 | unsigned long flags; | 63 | unsigned long flags; |
66 | u32 stripe_count; | 64 | u32 stripe_count; |
67 | u8 *stripe_indices; | 65 | u8 *stripe_indices; |
@@ -95,14 +93,12 @@ extern struct nfs_fh * | |||
95 | nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); | 93 | nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); |
96 | 94 | ||
97 | extern void print_ds(struct nfs4_pnfs_ds *ds); | 95 | extern void print_ds(struct nfs4_pnfs_ds *ds); |
98 | extern void print_deviceid(struct nfs4_deviceid *dev_id); | ||
99 | u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); | 96 | u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); |
100 | u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); | 97 | u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); |
101 | struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, | 98 | struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, |
102 | u32 ds_idx); | 99 | u32 ds_idx); |
103 | extern struct nfs4_file_layout_dsaddr * | ||
104 | nfs4_fl_find_get_deviceid(struct nfs4_deviceid *dev_id); | ||
105 | extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); | 100 | extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); |
101 | extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); | ||
106 | struct nfs4_file_layout_dsaddr * | 102 | struct nfs4_file_layout_dsaddr * |
107 | get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); | 103 | get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); |
108 | 104 | ||
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index db07c7af1395..3b7bf1377264 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c | |||
@@ -37,30 +37,6 @@ | |||
37 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | 37 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Device ID RCU cache. A device ID is unique per client ID and layout type. | ||
41 | */ | ||
42 | #define NFS4_FL_DEVICE_ID_HASH_BITS 5 | ||
43 | #define NFS4_FL_DEVICE_ID_HASH_SIZE (1 << NFS4_FL_DEVICE_ID_HASH_BITS) | ||
44 | #define NFS4_FL_DEVICE_ID_HASH_MASK (NFS4_FL_DEVICE_ID_HASH_SIZE - 1) | ||
45 | |||
46 | static inline u32 | ||
47 | nfs4_fl_deviceid_hash(struct nfs4_deviceid *id) | ||
48 | { | ||
49 | unsigned char *cptr = (unsigned char *)id->data; | ||
50 | unsigned int nbytes = NFS4_DEVICEID4_SIZE; | ||
51 | u32 x = 0; | ||
52 | |||
53 | while (nbytes--) { | ||
54 | x *= 37; | ||
55 | x += *cptr++; | ||
56 | } | ||
57 | return x & NFS4_FL_DEVICE_ID_HASH_MASK; | ||
58 | } | ||
59 | |||
60 | static struct hlist_head filelayout_deviceid_cache[NFS4_FL_DEVICE_ID_HASH_SIZE]; | ||
61 | static DEFINE_SPINLOCK(filelayout_deviceid_lock); | ||
62 | |||
63 | /* | ||
64 | * Data server cache | 40 | * Data server cache |
65 | * | 41 | * |
66 | * Data servers can be mapped to different device ids. | 42 | * Data servers can be mapped to different device ids. |
@@ -89,27 +65,6 @@ print_ds(struct nfs4_pnfs_ds *ds) | |||
89 | ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0); | 65 | ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0); |
90 | } | 66 | } |
91 | 67 | ||
92 | void | ||
93 | print_ds_list(struct nfs4_file_layout_dsaddr *dsaddr) | ||
94 | { | ||
95 | int i; | ||
96 | |||
97 | ifdebug(FACILITY) { | ||
98 | printk("%s dsaddr->ds_num %d\n", __func__, | ||
99 | dsaddr->ds_num); | ||
100 | for (i = 0; i < dsaddr->ds_num; i++) | ||
101 | print_ds(dsaddr->ds_list[i]); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void print_deviceid(struct nfs4_deviceid *id) | ||
106 | { | ||
107 | u32 *p = (u32 *)id; | ||
108 | |||
109 | dprintk("%s: device id= [%x%x%x%x]\n", __func__, | ||
110 | p[0], p[1], p[2], p[3]); | ||
111 | } | ||
112 | |||
113 | /* nfs4_ds_cache_lock is held */ | 68 | /* nfs4_ds_cache_lock is held */ |
114 | static struct nfs4_pnfs_ds * | 69 | static struct nfs4_pnfs_ds * |
115 | _data_server_lookup_locked(u32 ip_addr, u32 port) | 70 | _data_server_lookup_locked(u32 ip_addr, u32 port) |
@@ -201,13 +156,13 @@ destroy_ds(struct nfs4_pnfs_ds *ds) | |||
201 | kfree(ds); | 156 | kfree(ds); |
202 | } | 157 | } |
203 | 158 | ||
204 | static void | 159 | void |
205 | nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) | 160 | nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) |
206 | { | 161 | { |
207 | struct nfs4_pnfs_ds *ds; | 162 | struct nfs4_pnfs_ds *ds; |
208 | int i; | 163 | int i; |
209 | 164 | ||
210 | print_deviceid(&dsaddr->deviceid); | 165 | nfs4_print_deviceid(&dsaddr->id_node.deviceid); |
211 | 166 | ||
212 | for (i = 0; i < dsaddr->ds_num; i++) { | 167 | for (i = 0; i < dsaddr->ds_num; i++) { |
213 | ds = dsaddr->ds_list[i]; | 168 | ds = dsaddr->ds_list[i]; |
@@ -353,12 +308,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
353 | u8 max_stripe_index; | 308 | u8 max_stripe_index; |
354 | struct nfs4_file_layout_dsaddr *dsaddr = NULL; | 309 | struct nfs4_file_layout_dsaddr *dsaddr = NULL; |
355 | struct xdr_stream stream; | 310 | struct xdr_stream stream; |
356 | struct xdr_buf buf = { | 311 | struct xdr_buf buf; |
357 | .pages = pdev->pages, | ||
358 | .page_len = pdev->pglen, | ||
359 | .buflen = pdev->pglen, | ||
360 | .len = pdev->pglen, | ||
361 | }; | ||
362 | struct page *scratch; | 312 | struct page *scratch; |
363 | 313 | ||
364 | /* set up xdr stream */ | 314 | /* set up xdr stream */ |
@@ -366,7 +316,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
366 | if (!scratch) | 316 | if (!scratch) |
367 | goto out_err; | 317 | goto out_err; |
368 | 318 | ||
369 | xdr_init_decode(&stream, &buf, NULL); | 319 | xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen); |
370 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | 320 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); |
371 | 321 | ||
372 | /* Get the stripe count (number of stripe index) */ | 322 | /* Get the stripe count (number of stripe index) */ |
@@ -431,8 +381,10 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
431 | dsaddr->stripe_indices = stripe_indices; | 381 | dsaddr->stripe_indices = stripe_indices; |
432 | stripe_indices = NULL; | 382 | stripe_indices = NULL; |
433 | dsaddr->ds_num = num; | 383 | dsaddr->ds_num = num; |
434 | 384 | nfs4_init_deviceid_node(&dsaddr->id_node, | |
435 | memcpy(&dsaddr->deviceid, &pdev->dev_id, sizeof(pdev->dev_id)); | 385 | NFS_SERVER(ino)->pnfs_curr_ld, |
386 | NFS_SERVER(ino)->nfs_client, | ||
387 | &pdev->dev_id); | ||
436 | 388 | ||
437 | for (i = 0; i < dsaddr->ds_num; i++) { | 389 | for (i = 0; i < dsaddr->ds_num; i++) { |
438 | int j; | 390 | int j; |
@@ -505,8 +457,8 @@ out_err: | |||
505 | static struct nfs4_file_layout_dsaddr * | 457 | static struct nfs4_file_layout_dsaddr * |
506 | decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) | 458 | decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) |
507 | { | 459 | { |
508 | struct nfs4_file_layout_dsaddr *d, *new; | 460 | struct nfs4_deviceid_node *d; |
509 | long hash; | 461 | struct nfs4_file_layout_dsaddr *n, *new; |
510 | 462 | ||
511 | new = decode_device(inode, dev, gfp_flags); | 463 | new = decode_device(inode, dev, gfp_flags); |
512 | if (!new) { | 464 | if (!new) { |
@@ -515,20 +467,13 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl | |||
515 | return NULL; | 467 | return NULL; |
516 | } | 468 | } |
517 | 469 | ||
518 | spin_lock(&filelayout_deviceid_lock); | 470 | d = nfs4_insert_deviceid_node(&new->id_node); |
519 | d = nfs4_fl_find_get_deviceid(&new->deviceid); | 471 | n = container_of(d, struct nfs4_file_layout_dsaddr, id_node); |
520 | if (d) { | 472 | if (n != new) { |
521 | spin_unlock(&filelayout_deviceid_lock); | ||
522 | nfs4_fl_free_deviceid(new); | 473 | nfs4_fl_free_deviceid(new); |
523 | return d; | 474 | return n; |
524 | } | 475 | } |
525 | 476 | ||
526 | INIT_HLIST_NODE(&new->node); | ||
527 | atomic_set(&new->ref, 1); | ||
528 | hash = nfs4_fl_deviceid_hash(&new->deviceid); | ||
529 | hlist_add_head_rcu(&new->node, &filelayout_deviceid_cache[hash]); | ||
530 | spin_unlock(&filelayout_deviceid_lock); | ||
531 | |||
532 | return new; | 477 | return new; |
533 | } | 478 | } |
534 | 479 | ||
@@ -600,35 +545,7 @@ out_free: | |||
600 | void | 545 | void |
601 | nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) | 546 | nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) |
602 | { | 547 | { |
603 | if (atomic_dec_and_lock(&dsaddr->ref, &filelayout_deviceid_lock)) { | 548 | nfs4_put_deviceid_node(&dsaddr->id_node); |
604 | hlist_del_rcu(&dsaddr->node); | ||
605 | spin_unlock(&filelayout_deviceid_lock); | ||
606 | |||
607 | synchronize_rcu(); | ||
608 | nfs4_fl_free_deviceid(dsaddr); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | struct nfs4_file_layout_dsaddr * | ||
613 | nfs4_fl_find_get_deviceid(struct nfs4_deviceid *id) | ||
614 | { | ||
615 | struct nfs4_file_layout_dsaddr *d; | ||
616 | struct hlist_node *n; | ||
617 | long hash = nfs4_fl_deviceid_hash(id); | ||
618 | |||
619 | |||
620 | rcu_read_lock(); | ||
621 | hlist_for_each_entry_rcu(d, n, &filelayout_deviceid_cache[hash], node) { | ||
622 | if (!memcmp(&d->deviceid, id, sizeof(*id))) { | ||
623 | if (!atomic_inc_not_zero(&d->ref)) | ||
624 | goto fail; | ||
625 | rcu_read_unlock(); | ||
626 | return d; | ||
627 | } | ||
628 | } | ||
629 | fail: | ||
630 | rcu_read_unlock(); | ||
631 | return NULL; | ||
632 | } | 549 | } |
633 | 550 | ||
634 | /* | 551 | /* |
@@ -676,15 +593,15 @@ static void | |||
676 | filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, | 593 | filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, |
677 | int err, u32 ds_addr) | 594 | int err, u32 ds_addr) |
678 | { | 595 | { |
679 | u32 *p = (u32 *)&dsaddr->deviceid; | 596 | u32 *p = (u32 *)&dsaddr->id_node.deviceid; |
680 | 597 | ||
681 | printk(KERN_ERR "NFS: data server %x connection error %d." | 598 | printk(KERN_ERR "NFS: data server %x connection error %d." |
682 | " Deviceid [%x%x%x%x] marked out of use.\n", | 599 | " Deviceid [%x%x%x%x] marked out of use.\n", |
683 | ds_addr, err, p[0], p[1], p[2], p[3]); | 600 | ds_addr, err, p[0], p[1], p[2], p[3]); |
684 | 601 | ||
685 | spin_lock(&filelayout_deviceid_lock); | 602 | spin_lock(&nfs4_ds_cache_lock); |
686 | dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; | 603 | dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; |
687 | spin_unlock(&filelayout_deviceid_lock); | 604 | spin_unlock(&nfs4_ds_cache_lock); |
688 | } | 605 | } |
689 | 606 | ||
690 | struct nfs4_pnfs_ds * | 607 | struct nfs4_pnfs_ds * |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index cf1b339c3937..d2c4b59c896d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -267,9 +267,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
267 | break; | 267 | break; |
268 | nfs4_schedule_stateid_recovery(server, state); | 268 | nfs4_schedule_stateid_recovery(server, state); |
269 | goto wait_on_recovery; | 269 | goto wait_on_recovery; |
270 | case -NFS4ERR_EXPIRED: | ||
271 | if (state != NULL) | ||
272 | nfs4_schedule_stateid_recovery(server, state); | ||
270 | case -NFS4ERR_STALE_STATEID: | 273 | case -NFS4ERR_STALE_STATEID: |
271 | case -NFS4ERR_STALE_CLIENTID: | 274 | case -NFS4ERR_STALE_CLIENTID: |
272 | case -NFS4ERR_EXPIRED: | ||
273 | nfs4_schedule_lease_recovery(clp); | 275 | nfs4_schedule_lease_recovery(clp); |
274 | goto wait_on_recovery; | 276 | goto wait_on_recovery; |
275 | #if defined(CONFIG_NFS_V4_1) | 277 | #if defined(CONFIG_NFS_V4_1) |
@@ -2361,6 +2363,9 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, | |||
2361 | struct nfs4_state *state = NULL; | 2363 | struct nfs4_state *state = NULL; |
2362 | int status; | 2364 | int status; |
2363 | 2365 | ||
2366 | if (pnfs_ld_layoutret_on_setattr(inode)) | ||
2367 | pnfs_return_layout(inode); | ||
2368 | |||
2364 | nfs_fattr_init(fattr); | 2369 | nfs_fattr_init(fattr); |
2365 | 2370 | ||
2366 | /* Search for an existing open(O_WRITE) file */ | 2371 | /* Search for an existing open(O_WRITE) file */ |
@@ -3175,6 +3180,11 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, | |||
3175 | return err; | 3180 | return err; |
3176 | } | 3181 | } |
3177 | 3182 | ||
3183 | void __nfs4_read_done_cb(struct nfs_read_data *data) | ||
3184 | { | ||
3185 | nfs_invalidate_atime(data->inode); | ||
3186 | } | ||
3187 | |||
3178 | static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) | 3188 | static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) |
3179 | { | 3189 | { |
3180 | struct nfs_server *server = NFS_SERVER(data->inode); | 3190 | struct nfs_server *server = NFS_SERVER(data->inode); |
@@ -3184,7 +3194,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) | |||
3184 | return -EAGAIN; | 3194 | return -EAGAIN; |
3185 | } | 3195 | } |
3186 | 3196 | ||
3187 | nfs_invalidate_atime(data->inode); | 3197 | __nfs4_read_done_cb(data); |
3188 | if (task->tk_status > 0) | 3198 | if (task->tk_status > 0) |
3189 | renew_lease(server, data->timestamp); | 3199 | renew_lease(server, data->timestamp); |
3190 | return 0; | 3200 | return 0; |
@@ -3198,7 +3208,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) | |||
3198 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | 3208 | if (!nfs4_sequence_done(task, &data->res.seq_res)) |
3199 | return -EAGAIN; | 3209 | return -EAGAIN; |
3200 | 3210 | ||
3201 | return data->read_done_cb(task, data); | 3211 | return data->read_done_cb ? data->read_done_cb(task, data) : |
3212 | nfs4_read_done_cb(task, data); | ||
3202 | } | 3213 | } |
3203 | 3214 | ||
3204 | static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) | 3215 | static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) |
@@ -3243,7 +3254,8 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) | |||
3243 | { | 3254 | { |
3244 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | 3255 | if (!nfs4_sequence_done(task, &data->res.seq_res)) |
3245 | return -EAGAIN; | 3256 | return -EAGAIN; |
3246 | return data->write_done_cb(task, data); | 3257 | return data->write_done_cb ? data->write_done_cb(task, data) : |
3258 | nfs4_write_done_cb(task, data); | ||
3247 | } | 3259 | } |
3248 | 3260 | ||
3249 | /* Reset the the nfs_write_data to send the write to the MDS. */ | 3261 | /* Reset the the nfs_write_data to send the write to the MDS. */ |
@@ -3670,9 +3682,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3670 | break; | 3682 | break; |
3671 | nfs4_schedule_stateid_recovery(server, state); | 3683 | nfs4_schedule_stateid_recovery(server, state); |
3672 | goto wait_on_recovery; | 3684 | goto wait_on_recovery; |
3685 | case -NFS4ERR_EXPIRED: | ||
3686 | if (state != NULL) | ||
3687 | nfs4_schedule_stateid_recovery(server, state); | ||
3673 | case -NFS4ERR_STALE_STATEID: | 3688 | case -NFS4ERR_STALE_STATEID: |
3674 | case -NFS4ERR_STALE_CLIENTID: | 3689 | case -NFS4ERR_STALE_CLIENTID: |
3675 | case -NFS4ERR_EXPIRED: | ||
3676 | nfs4_schedule_lease_recovery(clp); | 3690 | nfs4_schedule_lease_recovery(clp); |
3677 | goto wait_on_recovery; | 3691 | goto wait_on_recovery; |
3678 | #if defined(CONFIG_NFS_V4_1) | 3692 | #if defined(CONFIG_NFS_V4_1) |
@@ -4543,6 +4557,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | |||
4543 | case -ESTALE: | 4557 | case -ESTALE: |
4544 | goto out; | 4558 | goto out; |
4545 | case -NFS4ERR_EXPIRED: | 4559 | case -NFS4ERR_EXPIRED: |
4560 | nfs4_schedule_stateid_recovery(server, state); | ||
4546 | case -NFS4ERR_STALE_CLIENTID: | 4561 | case -NFS4ERR_STALE_CLIENTID: |
4547 | case -NFS4ERR_STALE_STATEID: | 4562 | case -NFS4ERR_STALE_STATEID: |
4548 | nfs4_schedule_lease_recovery(server->nfs_client); | 4563 | nfs4_schedule_lease_recovery(server->nfs_client); |
@@ -5666,6 +5681,88 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
5666 | return status; | 5681 | return status; |
5667 | } | 5682 | } |
5668 | 5683 | ||
5684 | static void | ||
5685 | nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata) | ||
5686 | { | ||
5687 | struct nfs4_layoutreturn *lrp = calldata; | ||
5688 | |||
5689 | dprintk("--> %s\n", __func__); | ||
5690 | if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args, | ||
5691 | &lrp->res.seq_res, 0, task)) | ||
5692 | return; | ||
5693 | rpc_call_start(task); | ||
5694 | } | ||
5695 | |||
5696 | static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | ||
5697 | { | ||
5698 | struct nfs4_layoutreturn *lrp = calldata; | ||
5699 | struct nfs_server *server; | ||
5700 | |||
5701 | dprintk("--> %s\n", __func__); | ||
5702 | |||
5703 | if (!nfs4_sequence_done(task, &lrp->res.seq_res)) | ||
5704 | return; | ||
5705 | |||
5706 | server = NFS_SERVER(lrp->args.inode); | ||
5707 | if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { | ||
5708 | nfs_restart_rpc(task, lrp->clp); | ||
5709 | return; | ||
5710 | } | ||
5711 | if (task->tk_status == 0) { | ||
5712 | struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; | ||
5713 | |||
5714 | if (lrp->res.lrs_present) { | ||
5715 | spin_lock(&lo->plh_inode->i_lock); | ||
5716 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | ||
5717 | spin_unlock(&lo->plh_inode->i_lock); | ||
5718 | } else | ||
5719 | BUG_ON(!list_empty(&lo->plh_segs)); | ||
5720 | } | ||
5721 | dprintk("<-- %s\n", __func__); | ||
5722 | } | ||
5723 | |||
5724 | static void nfs4_layoutreturn_release(void *calldata) | ||
5725 | { | ||
5726 | struct nfs4_layoutreturn *lrp = calldata; | ||
5727 | |||
5728 | dprintk("--> %s\n", __func__); | ||
5729 | put_layout_hdr(NFS_I(lrp->args.inode)->layout); | ||
5730 | kfree(calldata); | ||
5731 | dprintk("<-- %s\n", __func__); | ||
5732 | } | ||
5733 | |||
5734 | static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { | ||
5735 | .rpc_call_prepare = nfs4_layoutreturn_prepare, | ||
5736 | .rpc_call_done = nfs4_layoutreturn_done, | ||
5737 | .rpc_release = nfs4_layoutreturn_release, | ||
5738 | }; | ||
5739 | |||
5740 | int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) | ||
5741 | { | ||
5742 | struct rpc_task *task; | ||
5743 | struct rpc_message msg = { | ||
5744 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN], | ||
5745 | .rpc_argp = &lrp->args, | ||
5746 | .rpc_resp = &lrp->res, | ||
5747 | }; | ||
5748 | struct rpc_task_setup task_setup_data = { | ||
5749 | .rpc_client = lrp->clp->cl_rpcclient, | ||
5750 | .rpc_message = &msg, | ||
5751 | .callback_ops = &nfs4_layoutreturn_call_ops, | ||
5752 | .callback_data = lrp, | ||
5753 | }; | ||
5754 | int status; | ||
5755 | |||
5756 | dprintk("--> %s\n", __func__); | ||
5757 | task = rpc_run_task(&task_setup_data); | ||
5758 | if (IS_ERR(task)) | ||
5759 | return PTR_ERR(task); | ||
5760 | status = task->tk_status; | ||
5761 | dprintk("<-- %s status=%d\n", __func__, status); | ||
5762 | rpc_put_task(task); | ||
5763 | return status; | ||
5764 | } | ||
5765 | |||
5669 | static int | 5766 | static int |
5670 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) | 5767 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) |
5671 | { | 5768 | { |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 036f5adc9e1f..e97dd219f84f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1466,7 +1466,10 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) | |||
1466 | #ifdef CONFIG_NFS_V4_1 | 1466 | #ifdef CONFIG_NFS_V4_1 |
1467 | void nfs4_schedule_session_recovery(struct nfs4_session *session) | 1467 | void nfs4_schedule_session_recovery(struct nfs4_session *session) |
1468 | { | 1468 | { |
1469 | nfs4_schedule_lease_recovery(session->clp); | 1469 | struct nfs_client *clp = session->clp; |
1470 | |||
1471 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
1472 | nfs4_schedule_lease_recovery(clp); | ||
1470 | } | 1473 | } |
1471 | EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); | 1474 | EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); |
1472 | 1475 | ||
@@ -1549,6 +1552,7 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
1549 | status = nfs4_recovery_handle_error(clp, status); | 1552 | status = nfs4_recovery_handle_error(clp, status); |
1550 | goto out; | 1553 | goto out; |
1551 | } | 1554 | } |
1555 | clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
1552 | /* create_session negotiated new slot table */ | 1556 | /* create_session negotiated new slot table */ |
1553 | clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); | 1557 | clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); |
1554 | 1558 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c3ccd2c46834..d869a5e5464b 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -338,7 +338,11 @@ static int nfs4_stat_to_errno(int); | |||
338 | 1 /* layoutupdate4 layout type */ + \ | 338 | 1 /* layoutupdate4 layout type */ + \ |
339 | 1 /* NULL filelayout layoutupdate4 payload */) | 339 | 1 /* NULL filelayout layoutupdate4 payload */) |
340 | #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) | 340 | #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) |
341 | 341 | #define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \ | |
342 | encode_stateid_maxsz + \ | ||
343 | 1 /* FIXME: opaque lrf_body always empty at the moment */) | ||
344 | #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ | ||
345 | 1 + decode_stateid_maxsz) | ||
342 | #else /* CONFIG_NFS_V4_1 */ | 346 | #else /* CONFIG_NFS_V4_1 */ |
343 | #define encode_sequence_maxsz 0 | 347 | #define encode_sequence_maxsz 0 |
344 | #define decode_sequence_maxsz 0 | 348 | #define decode_sequence_maxsz 0 |
@@ -760,7 +764,14 @@ static int nfs4_stat_to_errno(int); | |||
760 | decode_putfh_maxsz + \ | 764 | decode_putfh_maxsz + \ |
761 | decode_layoutcommit_maxsz + \ | 765 | decode_layoutcommit_maxsz + \ |
762 | decode_getattr_maxsz) | 766 | decode_getattr_maxsz) |
763 | 767 | #define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \ | |
768 | encode_sequence_maxsz + \ | ||
769 | encode_putfh_maxsz + \ | ||
770 | encode_layoutreturn_maxsz) | ||
771 | #define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \ | ||
772 | decode_sequence_maxsz + \ | ||
773 | decode_putfh_maxsz + \ | ||
774 | decode_layoutreturn_maxsz) | ||
764 | 775 | ||
765 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + | 776 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + |
766 | compound_encode_hdr_maxsz + | 777 | compound_encode_hdr_maxsz + |
@@ -1864,6 +1875,7 @@ encode_layoutget(struct xdr_stream *xdr, | |||
1864 | 1875 | ||
1865 | static int | 1876 | static int |
1866 | encode_layoutcommit(struct xdr_stream *xdr, | 1877 | encode_layoutcommit(struct xdr_stream *xdr, |
1878 | struct inode *inode, | ||
1867 | const struct nfs4_layoutcommit_args *args, | 1879 | const struct nfs4_layoutcommit_args *args, |
1868 | struct compound_hdr *hdr) | 1880 | struct compound_hdr *hdr) |
1869 | { | 1881 | { |
@@ -1872,7 +1884,7 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
1872 | dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, | 1884 | dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, |
1873 | NFS_SERVER(args->inode)->pnfs_curr_ld->id); | 1885 | NFS_SERVER(args->inode)->pnfs_curr_ld->id); |
1874 | 1886 | ||
1875 | p = reserve_space(xdr, 48 + NFS4_STATEID_SIZE); | 1887 | p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE); |
1876 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); | 1888 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); |
1877 | /* Only whole file layouts */ | 1889 | /* Only whole file layouts */ |
1878 | p = xdr_encode_hyper(p, 0); /* offset */ | 1890 | p = xdr_encode_hyper(p, 0); /* offset */ |
@@ -1883,12 +1895,49 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
1883 | p = xdr_encode_hyper(p, args->lastbytewritten); | 1895 | p = xdr_encode_hyper(p, args->lastbytewritten); |
1884 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ | 1896 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ |
1885 | *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ | 1897 | *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ |
1886 | *p++ = cpu_to_be32(0); /* no file layout payload */ | 1898 | |
1899 | if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit) | ||
1900 | NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit( | ||
1901 | NFS_I(inode)->layout, xdr, args); | ||
1902 | else { | ||
1903 | p = reserve_space(xdr, 4); | ||
1904 | *p = cpu_to_be32(0); /* no layout-type payload */ | ||
1905 | } | ||
1887 | 1906 | ||
1888 | hdr->nops++; | 1907 | hdr->nops++; |
1889 | hdr->replen += decode_layoutcommit_maxsz; | 1908 | hdr->replen += decode_layoutcommit_maxsz; |
1890 | return 0; | 1909 | return 0; |
1891 | } | 1910 | } |
1911 | |||
1912 | static void | ||
1913 | encode_layoutreturn(struct xdr_stream *xdr, | ||
1914 | const struct nfs4_layoutreturn_args *args, | ||
1915 | struct compound_hdr *hdr) | ||
1916 | { | ||
1917 | __be32 *p; | ||
1918 | |||
1919 | p = reserve_space(xdr, 20); | ||
1920 | *p++ = cpu_to_be32(OP_LAYOUTRETURN); | ||
1921 | *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */ | ||
1922 | *p++ = cpu_to_be32(args->layout_type); | ||
1923 | *p++ = cpu_to_be32(IOMODE_ANY); | ||
1924 | *p = cpu_to_be32(RETURN_FILE); | ||
1925 | p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE); | ||
1926 | p = xdr_encode_hyper(p, 0); | ||
1927 | p = xdr_encode_hyper(p, NFS4_MAX_UINT64); | ||
1928 | spin_lock(&args->inode->i_lock); | ||
1929 | xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE); | ||
1930 | spin_unlock(&args->inode->i_lock); | ||
1931 | if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) { | ||
1932 | NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn( | ||
1933 | NFS_I(args->inode)->layout, xdr, args); | ||
1934 | } else { | ||
1935 | p = reserve_space(xdr, 4); | ||
1936 | *p = cpu_to_be32(0); | ||
1937 | } | ||
1938 | hdr->nops++; | ||
1939 | hdr->replen += decode_layoutreturn_maxsz; | ||
1940 | } | ||
1892 | #endif /* CONFIG_NFS_V4_1 */ | 1941 | #endif /* CONFIG_NFS_V4_1 */ |
1893 | 1942 | ||
1894 | /* | 1943 | /* |
@@ -2706,10 +2755,12 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, | |||
2706 | /* | 2755 | /* |
2707 | * Encode LAYOUTCOMMIT request | 2756 | * Encode LAYOUTCOMMIT request |
2708 | */ | 2757 | */ |
2709 | static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, | 2758 | static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, |
2710 | struct xdr_stream *xdr, | 2759 | struct xdr_stream *xdr, |
2711 | struct nfs4_layoutcommit_args *args) | 2760 | struct nfs4_layoutcommit_args *args) |
2712 | { | 2761 | { |
2762 | struct nfs4_layoutcommit_data *data = | ||
2763 | container_of(args, struct nfs4_layoutcommit_data, args); | ||
2713 | struct compound_hdr hdr = { | 2764 | struct compound_hdr hdr = { |
2714 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | 2765 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), |
2715 | }; | 2766 | }; |
@@ -2717,10 +2768,27 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, | |||
2717 | encode_compound_hdr(xdr, req, &hdr); | 2768 | encode_compound_hdr(xdr, req, &hdr); |
2718 | encode_sequence(xdr, &args->seq_args, &hdr); | 2769 | encode_sequence(xdr, &args->seq_args, &hdr); |
2719 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); | 2770 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); |
2720 | encode_layoutcommit(xdr, args, &hdr); | 2771 | encode_layoutcommit(xdr, data->args.inode, args, &hdr); |
2721 | encode_getfattr(xdr, args->bitmask, &hdr); | 2772 | encode_getfattr(xdr, args->bitmask, &hdr); |
2722 | encode_nops(&hdr); | 2773 | encode_nops(&hdr); |
2723 | return 0; | 2774 | } |
2775 | |||
2776 | /* | ||
2777 | * Encode LAYOUTRETURN request | ||
2778 | */ | ||
2779 | static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, | ||
2780 | struct xdr_stream *xdr, | ||
2781 | struct nfs4_layoutreturn_args *args) | ||
2782 | { | ||
2783 | struct compound_hdr hdr = { | ||
2784 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2785 | }; | ||
2786 | |||
2787 | encode_compound_hdr(xdr, req, &hdr); | ||
2788 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2789 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); | ||
2790 | encode_layoutreturn(xdr, args, &hdr); | ||
2791 | encode_nops(&hdr); | ||
2724 | } | 2792 | } |
2725 | #endif /* CONFIG_NFS_V4_1 */ | 2793 | #endif /* CONFIG_NFS_V4_1 */ |
2726 | 2794 | ||
@@ -5203,6 +5271,27 @@ out_overflow: | |||
5203 | return -EIO; | 5271 | return -EIO; |
5204 | } | 5272 | } |
5205 | 5273 | ||
5274 | static int decode_layoutreturn(struct xdr_stream *xdr, | ||
5275 | struct nfs4_layoutreturn_res *res) | ||
5276 | { | ||
5277 | __be32 *p; | ||
5278 | int status; | ||
5279 | |||
5280 | status = decode_op_hdr(xdr, OP_LAYOUTRETURN); | ||
5281 | if (status) | ||
5282 | return status; | ||
5283 | p = xdr_inline_decode(xdr, 4); | ||
5284 | if (unlikely(!p)) | ||
5285 | goto out_overflow; | ||
5286 | res->lrs_present = be32_to_cpup(p); | ||
5287 | if (res->lrs_present) | ||
5288 | status = decode_stateid(xdr, &res->stateid); | ||
5289 | return status; | ||
5290 | out_overflow: | ||
5291 | print_overflow_msg(__func__, xdr); | ||
5292 | return -EIO; | ||
5293 | } | ||
5294 | |||
5206 | static int decode_layoutcommit(struct xdr_stream *xdr, | 5295 | static int decode_layoutcommit(struct xdr_stream *xdr, |
5207 | struct rpc_rqst *req, | 5296 | struct rpc_rqst *req, |
5208 | struct nfs4_layoutcommit_res *res) | 5297 | struct nfs4_layoutcommit_res *res) |
@@ -6320,6 +6409,30 @@ out: | |||
6320 | } | 6409 | } |
6321 | 6410 | ||
6322 | /* | 6411 | /* |
6412 | * Decode LAYOUTRETURN response | ||
6413 | */ | ||
6414 | static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp, | ||
6415 | struct xdr_stream *xdr, | ||
6416 | struct nfs4_layoutreturn_res *res) | ||
6417 | { | ||
6418 | struct compound_hdr hdr; | ||
6419 | int status; | ||
6420 | |||
6421 | status = decode_compound_hdr(xdr, &hdr); | ||
6422 | if (status) | ||
6423 | goto out; | ||
6424 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6425 | if (status) | ||
6426 | goto out; | ||
6427 | status = decode_putfh(xdr); | ||
6428 | if (status) | ||
6429 | goto out; | ||
6430 | status = decode_layoutreturn(xdr, res); | ||
6431 | out: | ||
6432 | return status; | ||
6433 | } | ||
6434 | |||
6435 | /* | ||
6323 | * Decode LAYOUTCOMMIT response | 6436 | * Decode LAYOUTCOMMIT response |
6324 | */ | 6437 | */ |
6325 | static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, | 6438 | static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, |
@@ -6547,6 +6660,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6547 | PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), | 6660 | PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), |
6548 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), | 6661 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), |
6549 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), | 6662 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), |
6663 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), | ||
6550 | #endif /* CONFIG_NFS_V4_1 */ | 6664 | #endif /* CONFIG_NFS_V4_1 */ |
6551 | }; | 6665 | }; |
6552 | 6666 | ||
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index c541093a5bf2..c4744e1d513c 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -87,7 +87,7 @@ | |||
87 | #define NFS_ROOT "/tftpboot/%s" | 87 | #define NFS_ROOT "/tftpboot/%s" |
88 | 88 | ||
89 | /* Default NFSROOT mount options. */ | 89 | /* Default NFSROOT mount options. */ |
90 | #define NFS_DEF_OPTIONS "udp" | 90 | #define NFS_DEF_OPTIONS "vers=2,udp,rsize=4096,wsize=4096" |
91 | 91 | ||
92 | /* Parameters passed from the kernel command line */ | 92 | /* Parameters passed from the kernel command line */ |
93 | static char nfs_root_parms[256] __initdata = ""; | 93 | static char nfs_root_parms[256] __initdata = ""; |
diff --git a/fs/nfs/objlayout/Kbuild b/fs/nfs/objlayout/Kbuild new file mode 100644 index 000000000000..ed30ea072bb8 --- /dev/null +++ b/fs/nfs/objlayout/Kbuild | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for the pNFS Objects Layout Driver kernel module | ||
3 | # | ||
4 | objlayoutdriver-y := objio_osd.o pnfs_osd_xdr_cli.o objlayout.o | ||
5 | obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayoutdriver.o | ||
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c new file mode 100644 index 000000000000..9cf208df1f25 --- /dev/null +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -0,0 +1,1057 @@ | |||
1 | /* | ||
2 | * pNFS Objects layout implementation over open-osd initiator library | ||
3 | * | ||
4 | * Copyright (C) 2009 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/module.h> | ||
41 | #include <scsi/osd_initiator.h> | ||
42 | |||
43 | #include "objlayout.h" | ||
44 | |||
45 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
46 | |||
47 | #define _LLU(x) ((unsigned long long)x) | ||
48 | |||
49 | enum { BIO_MAX_PAGES_KMALLOC = | ||
50 | (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec), | ||
51 | }; | ||
52 | |||
53 | struct objio_dev_ent { | ||
54 | struct nfs4_deviceid_node id_node; | ||
55 | struct osd_dev *od; | ||
56 | }; | ||
57 | |||
58 | static void | ||
59 | objio_free_deviceid_node(struct nfs4_deviceid_node *d) | ||
60 | { | ||
61 | struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node); | ||
62 | |||
63 | dprintk("%s: free od=%p\n", __func__, de->od); | ||
64 | osduld_put_device(de->od); | ||
65 | kfree(de); | ||
66 | } | ||
67 | |||
68 | static struct objio_dev_ent *_dev_list_find(const struct nfs_server *nfss, | ||
69 | const struct nfs4_deviceid *d_id) | ||
70 | { | ||
71 | struct nfs4_deviceid_node *d; | ||
72 | struct objio_dev_ent *de; | ||
73 | |||
74 | d = nfs4_find_get_deviceid(nfss->pnfs_curr_ld, nfss->nfs_client, d_id); | ||
75 | if (!d) | ||
76 | return NULL; | ||
77 | |||
78 | de = container_of(d, struct objio_dev_ent, id_node); | ||
79 | return de; | ||
80 | } | ||
81 | |||
82 | static struct objio_dev_ent * | ||
83 | _dev_list_add(const struct nfs_server *nfss, | ||
84 | const struct nfs4_deviceid *d_id, struct osd_dev *od, | ||
85 | gfp_t gfp_flags) | ||
86 | { | ||
87 | struct nfs4_deviceid_node *d; | ||
88 | struct objio_dev_ent *de = kzalloc(sizeof(*de), gfp_flags); | ||
89 | struct objio_dev_ent *n; | ||
90 | |||
91 | if (!de) { | ||
92 | dprintk("%s: -ENOMEM od=%p\n", __func__, od); | ||
93 | return NULL; | ||
94 | } | ||
95 | |||
96 | dprintk("%s: Adding od=%p\n", __func__, od); | ||
97 | nfs4_init_deviceid_node(&de->id_node, | ||
98 | nfss->pnfs_curr_ld, | ||
99 | nfss->nfs_client, | ||
100 | d_id); | ||
101 | de->od = od; | ||
102 | |||
103 | d = nfs4_insert_deviceid_node(&de->id_node); | ||
104 | n = container_of(d, struct objio_dev_ent, id_node); | ||
105 | if (n != de) { | ||
106 | dprintk("%s: Race with other n->od=%p\n", __func__, n->od); | ||
107 | objio_free_deviceid_node(&de->id_node); | ||
108 | de = n; | ||
109 | } | ||
110 | |||
111 | atomic_inc(&de->id_node.ref); | ||
112 | return de; | ||
113 | } | ||
114 | |||
115 | struct caps_buffers { | ||
116 | u8 caps_key[OSD_CRYPTO_KEYID_SIZE]; | ||
117 | u8 creds[OSD_CAP_LEN]; | ||
118 | }; | ||
119 | |||
120 | struct objio_segment { | ||
121 | struct pnfs_layout_segment lseg; | ||
122 | |||
123 | struct pnfs_osd_object_cred *comps; | ||
124 | |||
125 | unsigned mirrors_p1; | ||
126 | unsigned stripe_unit; | ||
127 | unsigned group_width; /* Data stripe_units without integrity comps */ | ||
128 | u64 group_depth; | ||
129 | unsigned group_count; | ||
130 | |||
131 | unsigned max_io_size; | ||
132 | |||
133 | unsigned comps_index; | ||
134 | unsigned num_comps; | ||
135 | /* variable length */ | ||
136 | struct objio_dev_ent *ods[]; | ||
137 | }; | ||
138 | |||
139 | static inline struct objio_segment * | ||
140 | OBJIO_LSEG(struct pnfs_layout_segment *lseg) | ||
141 | { | ||
142 | return container_of(lseg, struct objio_segment, lseg); | ||
143 | } | ||
144 | |||
145 | struct objio_state; | ||
146 | typedef ssize_t (*objio_done_fn)(struct objio_state *ios); | ||
147 | |||
148 | struct objio_state { | ||
149 | /* Generic layer */ | ||
150 | struct objlayout_io_state ol_state; | ||
151 | |||
152 | struct objio_segment *layout; | ||
153 | |||
154 | struct kref kref; | ||
155 | objio_done_fn done; | ||
156 | void *private; | ||
157 | |||
158 | unsigned long length; | ||
159 | unsigned numdevs; /* Actually used devs in this IO */ | ||
160 | /* A per-device variable array of size numdevs */ | ||
161 | struct _objio_per_comp { | ||
162 | struct bio *bio; | ||
163 | struct osd_request *or; | ||
164 | unsigned long length; | ||
165 | u64 offset; | ||
166 | unsigned dev; | ||
167 | } per_dev[]; | ||
168 | }; | ||
169 | |||
170 | /* Send and wait for a get_device_info of devices in the layout, | ||
171 | then look them up with the osd_initiator library */ | ||
172 | static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay, | ||
173 | struct objio_segment *objio_seg, unsigned comp, | ||
174 | gfp_t gfp_flags) | ||
175 | { | ||
176 | struct pnfs_osd_deviceaddr *deviceaddr; | ||
177 | struct nfs4_deviceid *d_id; | ||
178 | struct objio_dev_ent *ode; | ||
179 | struct osd_dev *od; | ||
180 | struct osd_dev_info odi; | ||
181 | int err; | ||
182 | |||
183 | d_id = &objio_seg->comps[comp].oc_object_id.oid_device_id; | ||
184 | |||
185 | ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id); | ||
186 | if (ode) | ||
187 | return ode; | ||
188 | |||
189 | err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags); | ||
190 | if (unlikely(err)) { | ||
191 | dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n", | ||
192 | __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err); | ||
193 | return ERR_PTR(err); | ||
194 | } | ||
195 | |||
196 | odi.systemid_len = deviceaddr->oda_systemid.len; | ||
197 | if (odi.systemid_len > sizeof(odi.systemid)) { | ||
198 | err = -EINVAL; | ||
199 | goto out; | ||
200 | } else if (odi.systemid_len) | ||
201 | memcpy(odi.systemid, deviceaddr->oda_systemid.data, | ||
202 | odi.systemid_len); | ||
203 | odi.osdname_len = deviceaddr->oda_osdname.len; | ||
204 | odi.osdname = (u8 *)deviceaddr->oda_osdname.data; | ||
205 | |||
206 | if (!odi.osdname_len && !odi.systemid_len) { | ||
207 | dprintk("%s: !odi.osdname_len && !odi.systemid_len\n", | ||
208 | __func__); | ||
209 | err = -ENODEV; | ||
210 | goto out; | ||
211 | } | ||
212 | |||
213 | od = osduld_info_lookup(&odi); | ||
214 | if (unlikely(IS_ERR(od))) { | ||
215 | err = PTR_ERR(od); | ||
216 | dprintk("%s: osduld_info_lookup => %d\n", __func__, err); | ||
217 | goto out; | ||
218 | } | ||
219 | |||
220 | ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od, | ||
221 | gfp_flags); | ||
222 | |||
223 | out: | ||
224 | dprintk("%s: return=%d\n", __func__, err); | ||
225 | objlayout_put_deviceinfo(deviceaddr); | ||
226 | return err ? ERR_PTR(err) : ode; | ||
227 | } | ||
228 | |||
229 | static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay, | ||
230 | struct objio_segment *objio_seg, | ||
231 | gfp_t gfp_flags) | ||
232 | { | ||
233 | unsigned i; | ||
234 | int err; | ||
235 | |||
236 | /* lookup all devices */ | ||
237 | for (i = 0; i < objio_seg->num_comps; i++) { | ||
238 | struct objio_dev_ent *ode; | ||
239 | |||
240 | ode = _device_lookup(pnfslay, objio_seg, i, gfp_flags); | ||
241 | if (unlikely(IS_ERR(ode))) { | ||
242 | err = PTR_ERR(ode); | ||
243 | goto out; | ||
244 | } | ||
245 | objio_seg->ods[i] = ode; | ||
246 | } | ||
247 | err = 0; | ||
248 | |||
249 | out: | ||
250 | dprintk("%s: return=%d\n", __func__, err); | ||
251 | return err; | ||
252 | } | ||
253 | |||
254 | static int _verify_data_map(struct pnfs_osd_layout *layout) | ||
255 | { | ||
256 | struct pnfs_osd_data_map *data_map = &layout->olo_map; | ||
257 | u64 stripe_length; | ||
258 | u32 group_width; | ||
259 | |||
260 | /* FIXME: Only raid0 for now. if not go through MDS */ | ||
261 | if (data_map->odm_raid_algorithm != PNFS_OSD_RAID_0) { | ||
262 | printk(KERN_ERR "Only RAID_0 for now\n"); | ||
263 | return -ENOTSUPP; | ||
264 | } | ||
265 | if (0 != (data_map->odm_num_comps % (data_map->odm_mirror_cnt + 1))) { | ||
266 | printk(KERN_ERR "Data Map wrong, num_comps=%u mirrors=%u\n", | ||
267 | data_map->odm_num_comps, data_map->odm_mirror_cnt); | ||
268 | return -EINVAL; | ||
269 | } | ||
270 | |||
271 | if (data_map->odm_group_width) | ||
272 | group_width = data_map->odm_group_width; | ||
273 | else | ||
274 | group_width = data_map->odm_num_comps / | ||
275 | (data_map->odm_mirror_cnt + 1); | ||
276 | |||
277 | stripe_length = (u64)data_map->odm_stripe_unit * group_width; | ||
278 | if (stripe_length >= (1ULL << 32)) { | ||
279 | printk(KERN_ERR "Total Stripe length(0x%llx)" | ||
280 | " >= 32bit is not supported\n", _LLU(stripe_length)); | ||
281 | return -ENOTSUPP; | ||
282 | } | ||
283 | |||
284 | if (0 != (data_map->odm_stripe_unit & ~PAGE_MASK)) { | ||
285 | printk(KERN_ERR "Stripe Unit(0x%llx)" | ||
286 | " must be Multples of PAGE_SIZE(0x%lx)\n", | ||
287 | _LLU(data_map->odm_stripe_unit), PAGE_SIZE); | ||
288 | return -ENOTSUPP; | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static void copy_single_comp(struct pnfs_osd_object_cred *cur_comp, | ||
295 | struct pnfs_osd_object_cred *src_comp, | ||
296 | struct caps_buffers *caps_p) | ||
297 | { | ||
298 | WARN_ON(src_comp->oc_cap_key.cred_len > sizeof(caps_p->caps_key)); | ||
299 | WARN_ON(src_comp->oc_cap.cred_len > sizeof(caps_p->creds)); | ||
300 | |||
301 | *cur_comp = *src_comp; | ||
302 | |||
303 | memcpy(caps_p->caps_key, src_comp->oc_cap_key.cred, | ||
304 | sizeof(caps_p->caps_key)); | ||
305 | cur_comp->oc_cap_key.cred = caps_p->caps_key; | ||
306 | |||
307 | memcpy(caps_p->creds, src_comp->oc_cap.cred, | ||
308 | sizeof(caps_p->creds)); | ||
309 | cur_comp->oc_cap.cred = caps_p->creds; | ||
310 | } | ||
311 | |||
312 | int objio_alloc_lseg(struct pnfs_layout_segment **outp, | ||
313 | struct pnfs_layout_hdr *pnfslay, | ||
314 | struct pnfs_layout_range *range, | ||
315 | struct xdr_stream *xdr, | ||
316 | gfp_t gfp_flags) | ||
317 | { | ||
318 | struct objio_segment *objio_seg; | ||
319 | struct pnfs_osd_xdr_decode_layout_iter iter; | ||
320 | struct pnfs_osd_layout layout; | ||
321 | struct pnfs_osd_object_cred *cur_comp, src_comp; | ||
322 | struct caps_buffers *caps_p; | ||
323 | int err; | ||
324 | |||
325 | err = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); | ||
326 | if (unlikely(err)) | ||
327 | return err; | ||
328 | |||
329 | err = _verify_data_map(&layout); | ||
330 | if (unlikely(err)) | ||
331 | return err; | ||
332 | |||
333 | objio_seg = kzalloc(sizeof(*objio_seg) + | ||
334 | sizeof(objio_seg->ods[0]) * layout.olo_num_comps + | ||
335 | sizeof(*objio_seg->comps) * layout.olo_num_comps + | ||
336 | sizeof(struct caps_buffers) * layout.olo_num_comps, | ||
337 | gfp_flags); | ||
338 | if (!objio_seg) | ||
339 | return -ENOMEM; | ||
340 | |||
341 | objio_seg->comps = (void *)(objio_seg->ods + layout.olo_num_comps); | ||
342 | cur_comp = objio_seg->comps; | ||
343 | caps_p = (void *)(cur_comp + layout.olo_num_comps); | ||
344 | while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) | ||
345 | copy_single_comp(cur_comp++, &src_comp, caps_p++); | ||
346 | if (unlikely(err)) | ||
347 | goto err; | ||
348 | |||
349 | objio_seg->num_comps = layout.olo_num_comps; | ||
350 | objio_seg->comps_index = layout.olo_comps_index; | ||
351 | err = objio_devices_lookup(pnfslay, objio_seg, gfp_flags); | ||
352 | if (err) | ||
353 | goto err; | ||
354 | |||
355 | objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1; | ||
356 | objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit; | ||
357 | if (layout.olo_map.odm_group_width) { | ||
358 | objio_seg->group_width = layout.olo_map.odm_group_width; | ||
359 | objio_seg->group_depth = layout.olo_map.odm_group_depth; | ||
360 | objio_seg->group_count = layout.olo_map.odm_num_comps / | ||
361 | objio_seg->mirrors_p1 / | ||
362 | objio_seg->group_width; | ||
363 | } else { | ||
364 | objio_seg->group_width = layout.olo_map.odm_num_comps / | ||
365 | objio_seg->mirrors_p1; | ||
366 | objio_seg->group_depth = -1; | ||
367 | objio_seg->group_count = 1; | ||
368 | } | ||
369 | |||
370 | /* Cache this calculation it will hit for every page */ | ||
371 | objio_seg->max_io_size = (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - | ||
372 | objio_seg->stripe_unit) * | ||
373 | objio_seg->group_width; | ||
374 | |||
375 | *outp = &objio_seg->lseg; | ||
376 | return 0; | ||
377 | |||
378 | err: | ||
379 | kfree(objio_seg); | ||
380 | dprintk("%s: Error: return %d\n", __func__, err); | ||
381 | *outp = NULL; | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | void objio_free_lseg(struct pnfs_layout_segment *lseg) | ||
386 | { | ||
387 | int i; | ||
388 | struct objio_segment *objio_seg = OBJIO_LSEG(lseg); | ||
389 | |||
390 | for (i = 0; i < objio_seg->num_comps; i++) { | ||
391 | if (!objio_seg->ods[i]) | ||
392 | break; | ||
393 | nfs4_put_deviceid_node(&objio_seg->ods[i]->id_node); | ||
394 | } | ||
395 | kfree(objio_seg); | ||
396 | } | ||
397 | |||
398 | int objio_alloc_io_state(struct pnfs_layout_segment *lseg, | ||
399 | struct objlayout_io_state **outp, | ||
400 | gfp_t gfp_flags) | ||
401 | { | ||
402 | struct objio_segment *objio_seg = OBJIO_LSEG(lseg); | ||
403 | struct objio_state *ios; | ||
404 | const unsigned first_size = sizeof(*ios) + | ||
405 | objio_seg->num_comps * sizeof(ios->per_dev[0]); | ||
406 | const unsigned sec_size = objio_seg->num_comps * | ||
407 | sizeof(ios->ol_state.ioerrs[0]); | ||
408 | |||
409 | ios = kzalloc(first_size + sec_size, gfp_flags); | ||
410 | if (unlikely(!ios)) | ||
411 | return -ENOMEM; | ||
412 | |||
413 | ios->layout = objio_seg; | ||
414 | ios->ol_state.ioerrs = ((void *)ios) + first_size; | ||
415 | ios->ol_state.num_comps = objio_seg->num_comps; | ||
416 | |||
417 | *outp = &ios->ol_state; | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | void objio_free_io_state(struct objlayout_io_state *ol_state) | ||
422 | { | ||
423 | struct objio_state *ios = container_of(ol_state, struct objio_state, | ||
424 | ol_state); | ||
425 | |||
426 | kfree(ios); | ||
427 | } | ||
428 | |||
429 | enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) | ||
430 | { | ||
431 | switch (oep) { | ||
432 | case OSD_ERR_PRI_NO_ERROR: | ||
433 | return (enum pnfs_osd_errno)0; | ||
434 | |||
435 | case OSD_ERR_PRI_CLEAR_PAGES: | ||
436 | BUG_ON(1); | ||
437 | return 0; | ||
438 | |||
439 | case OSD_ERR_PRI_RESOURCE: | ||
440 | return PNFS_OSD_ERR_RESOURCE; | ||
441 | case OSD_ERR_PRI_BAD_CRED: | ||
442 | return PNFS_OSD_ERR_BAD_CRED; | ||
443 | case OSD_ERR_PRI_NO_ACCESS: | ||
444 | return PNFS_OSD_ERR_NO_ACCESS; | ||
445 | case OSD_ERR_PRI_UNREACHABLE: | ||
446 | return PNFS_OSD_ERR_UNREACHABLE; | ||
447 | case OSD_ERR_PRI_NOT_FOUND: | ||
448 | return PNFS_OSD_ERR_NOT_FOUND; | ||
449 | case OSD_ERR_PRI_NO_SPACE: | ||
450 | return PNFS_OSD_ERR_NO_SPACE; | ||
451 | default: | ||
452 | WARN_ON(1); | ||
453 | /* fallthrough */ | ||
454 | case OSD_ERR_PRI_EIO: | ||
455 | return PNFS_OSD_ERR_EIO; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | static void _clear_bio(struct bio *bio) | ||
460 | { | ||
461 | struct bio_vec *bv; | ||
462 | unsigned i; | ||
463 | |||
464 | __bio_for_each_segment(bv, bio, i, 0) { | ||
465 | unsigned this_count = bv->bv_len; | ||
466 | |||
467 | if (likely(PAGE_SIZE == this_count)) | ||
468 | clear_highpage(bv->bv_page); | ||
469 | else | ||
470 | zero_user(bv->bv_page, bv->bv_offset, this_count); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static int _io_check(struct objio_state *ios, bool is_write) | ||
475 | { | ||
476 | enum osd_err_priority oep = OSD_ERR_PRI_NO_ERROR; | ||
477 | int lin_ret = 0; | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < ios->numdevs; i++) { | ||
481 | struct osd_sense_info osi; | ||
482 | struct osd_request *or = ios->per_dev[i].or; | ||
483 | unsigned dev; | ||
484 | int ret; | ||
485 | |||
486 | if (!or) | ||
487 | continue; | ||
488 | |||
489 | ret = osd_req_decode_sense(or, &osi); | ||
490 | if (likely(!ret)) | ||
491 | continue; | ||
492 | |||
493 | if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { | ||
494 | /* start read offset passed endof file */ | ||
495 | BUG_ON(is_write); | ||
496 | _clear_bio(ios->per_dev[i].bio); | ||
497 | dprintk("%s: start read offset passed end of file " | ||
498 | "offset=0x%llx, length=0x%lx\n", __func__, | ||
499 | _LLU(ios->per_dev[i].offset), | ||
500 | ios->per_dev[i].length); | ||
501 | |||
502 | continue; /* we recovered */ | ||
503 | } | ||
504 | dev = ios->per_dev[i].dev; | ||
505 | objlayout_io_set_result(&ios->ol_state, dev, | ||
506 | &ios->layout->comps[dev].oc_object_id, | ||
507 | osd_pri_2_pnfs_err(osi.osd_err_pri), | ||
508 | ios->per_dev[i].offset, | ||
509 | ios->per_dev[i].length, | ||
510 | is_write); | ||
511 | |||
512 | if (osi.osd_err_pri >= oep) { | ||
513 | oep = osi.osd_err_pri; | ||
514 | lin_ret = ret; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | return lin_ret; | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Common IO state helpers. | ||
523 | */ | ||
524 | static void _io_free(struct objio_state *ios) | ||
525 | { | ||
526 | unsigned i; | ||
527 | |||
528 | for (i = 0; i < ios->numdevs; i++) { | ||
529 | struct _objio_per_comp *per_dev = &ios->per_dev[i]; | ||
530 | |||
531 | if (per_dev->or) { | ||
532 | osd_end_request(per_dev->or); | ||
533 | per_dev->or = NULL; | ||
534 | } | ||
535 | |||
536 | if (per_dev->bio) { | ||
537 | bio_put(per_dev->bio); | ||
538 | per_dev->bio = NULL; | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | |||
543 | struct osd_dev *_io_od(struct objio_state *ios, unsigned dev) | ||
544 | { | ||
545 | unsigned min_dev = ios->layout->comps_index; | ||
546 | unsigned max_dev = min_dev + ios->layout->num_comps; | ||
547 | |||
548 | BUG_ON(dev < min_dev || max_dev <= dev); | ||
549 | return ios->layout->ods[dev - min_dev]->od; | ||
550 | } | ||
551 | |||
552 | struct _striping_info { | ||
553 | u64 obj_offset; | ||
554 | u64 group_length; | ||
555 | unsigned dev; | ||
556 | unsigned unit_off; | ||
557 | }; | ||
558 | |||
559 | static void _calc_stripe_info(struct objio_state *ios, u64 file_offset, | ||
560 | struct _striping_info *si) | ||
561 | { | ||
562 | u32 stripe_unit = ios->layout->stripe_unit; | ||
563 | u32 group_width = ios->layout->group_width; | ||
564 | u64 group_depth = ios->layout->group_depth; | ||
565 | u32 U = stripe_unit * group_width; | ||
566 | |||
567 | u64 T = U * group_depth; | ||
568 | u64 S = T * ios->layout->group_count; | ||
569 | u64 M = div64_u64(file_offset, S); | ||
570 | |||
571 | /* | ||
572 | G = (L - (M * S)) / T | ||
573 | H = (L - (M * S)) % T | ||
574 | */ | ||
575 | u64 LmodU = file_offset - M * S; | ||
576 | u32 G = div64_u64(LmodU, T); | ||
577 | u64 H = LmodU - G * T; | ||
578 | |||
579 | u32 N = div_u64(H, U); | ||
580 | |||
581 | div_u64_rem(file_offset, stripe_unit, &si->unit_off); | ||
582 | si->obj_offset = si->unit_off + (N * stripe_unit) + | ||
583 | (M * group_depth * stripe_unit); | ||
584 | |||
585 | /* "H - (N * U)" is just "H % U" so it's bound to u32 */ | ||
586 | si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width; | ||
587 | si->dev *= ios->layout->mirrors_p1; | ||
588 | |||
589 | si->group_length = T - H; | ||
590 | } | ||
591 | |||
592 | static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, | ||
593 | unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len, | ||
594 | gfp_t gfp_flags) | ||
595 | { | ||
596 | unsigned pg = *cur_pg; | ||
597 | struct request_queue *q = | ||
598 | osd_request_queue(_io_od(ios, per_dev->dev)); | ||
599 | |||
600 | per_dev->length += cur_len; | ||
601 | |||
602 | if (per_dev->bio == NULL) { | ||
603 | unsigned stripes = ios->layout->num_comps / | ||
604 | ios->layout->mirrors_p1; | ||
605 | unsigned pages_in_stripe = stripes * | ||
606 | (ios->layout->stripe_unit / PAGE_SIZE); | ||
607 | unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) / | ||
608 | stripes; | ||
609 | |||
610 | if (BIO_MAX_PAGES_KMALLOC < bio_size) | ||
611 | bio_size = BIO_MAX_PAGES_KMALLOC; | ||
612 | |||
613 | per_dev->bio = bio_kmalloc(gfp_flags, bio_size); | ||
614 | if (unlikely(!per_dev->bio)) { | ||
615 | dprintk("Faild to allocate BIO size=%u\n", bio_size); | ||
616 | return -ENOMEM; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | while (cur_len > 0) { | ||
621 | unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len); | ||
622 | unsigned added_len; | ||
623 | |||
624 | BUG_ON(ios->ol_state.nr_pages <= pg); | ||
625 | cur_len -= pglen; | ||
626 | |||
627 | added_len = bio_add_pc_page(q, per_dev->bio, | ||
628 | ios->ol_state.pages[pg], pglen, pgbase); | ||
629 | if (unlikely(pglen != added_len)) | ||
630 | return -ENOMEM; | ||
631 | pgbase = 0; | ||
632 | ++pg; | ||
633 | } | ||
634 | BUG_ON(cur_len); | ||
635 | |||
636 | *cur_pg = pg; | ||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | static int _prepare_one_group(struct objio_state *ios, u64 length, | ||
641 | struct _striping_info *si, unsigned *last_pg, | ||
642 | gfp_t gfp_flags) | ||
643 | { | ||
644 | unsigned stripe_unit = ios->layout->stripe_unit; | ||
645 | unsigned mirrors_p1 = ios->layout->mirrors_p1; | ||
646 | unsigned devs_in_group = ios->layout->group_width * mirrors_p1; | ||
647 | unsigned dev = si->dev; | ||
648 | unsigned first_dev = dev - (dev % devs_in_group); | ||
649 | unsigned max_comp = ios->numdevs ? ios->numdevs - mirrors_p1 : 0; | ||
650 | unsigned cur_pg = *last_pg; | ||
651 | int ret = 0; | ||
652 | |||
653 | while (length) { | ||
654 | struct _objio_per_comp *per_dev = &ios->per_dev[dev]; | ||
655 | unsigned cur_len, page_off = 0; | ||
656 | |||
657 | if (!per_dev->length) { | ||
658 | per_dev->dev = dev; | ||
659 | if (dev < si->dev) { | ||
660 | per_dev->offset = si->obj_offset + stripe_unit - | ||
661 | si->unit_off; | ||
662 | cur_len = stripe_unit; | ||
663 | } else if (dev == si->dev) { | ||
664 | per_dev->offset = si->obj_offset; | ||
665 | cur_len = stripe_unit - si->unit_off; | ||
666 | page_off = si->unit_off & ~PAGE_MASK; | ||
667 | BUG_ON(page_off && | ||
668 | (page_off != ios->ol_state.pgbase)); | ||
669 | } else { /* dev > si->dev */ | ||
670 | per_dev->offset = si->obj_offset - si->unit_off; | ||
671 | cur_len = stripe_unit; | ||
672 | } | ||
673 | |||
674 | if (max_comp < dev) | ||
675 | max_comp = dev; | ||
676 | } else { | ||
677 | cur_len = stripe_unit; | ||
678 | } | ||
679 | if (cur_len >= length) | ||
680 | cur_len = length; | ||
681 | |||
682 | ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev, | ||
683 | cur_len, gfp_flags); | ||
684 | if (unlikely(ret)) | ||
685 | goto out; | ||
686 | |||
687 | dev += mirrors_p1; | ||
688 | dev = (dev % devs_in_group) + first_dev; | ||
689 | |||
690 | length -= cur_len; | ||
691 | ios->length += cur_len; | ||
692 | } | ||
693 | out: | ||
694 | ios->numdevs = max_comp + mirrors_p1; | ||
695 | *last_pg = cur_pg; | ||
696 | return ret; | ||
697 | } | ||
698 | |||
699 | static int _io_rw_pagelist(struct objio_state *ios, gfp_t gfp_flags) | ||
700 | { | ||
701 | u64 length = ios->ol_state.count; | ||
702 | u64 offset = ios->ol_state.offset; | ||
703 | struct _striping_info si; | ||
704 | unsigned last_pg = 0; | ||
705 | int ret = 0; | ||
706 | |||
707 | while (length) { | ||
708 | _calc_stripe_info(ios, offset, &si); | ||
709 | |||
710 | if (length < si.group_length) | ||
711 | si.group_length = length; | ||
712 | |||
713 | ret = _prepare_one_group(ios, si.group_length, &si, &last_pg, gfp_flags); | ||
714 | if (unlikely(ret)) | ||
715 | goto out; | ||
716 | |||
717 | offset += si.group_length; | ||
718 | length -= si.group_length; | ||
719 | } | ||
720 | |||
721 | out: | ||
722 | if (!ios->length) | ||
723 | return ret; | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static ssize_t _sync_done(struct objio_state *ios) | ||
729 | { | ||
730 | struct completion *waiting = ios->private; | ||
731 | |||
732 | complete(waiting); | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static void _last_io(struct kref *kref) | ||
737 | { | ||
738 | struct objio_state *ios = container_of(kref, struct objio_state, kref); | ||
739 | |||
740 | ios->done(ios); | ||
741 | } | ||
742 | |||
743 | static void _done_io(struct osd_request *or, void *p) | ||
744 | { | ||
745 | struct objio_state *ios = p; | ||
746 | |||
747 | kref_put(&ios->kref, _last_io); | ||
748 | } | ||
749 | |||
750 | static ssize_t _io_exec(struct objio_state *ios) | ||
751 | { | ||
752 | DECLARE_COMPLETION_ONSTACK(wait); | ||
753 | ssize_t status = 0; /* sync status */ | ||
754 | unsigned i; | ||
755 | objio_done_fn saved_done_fn = ios->done; | ||
756 | bool sync = ios->ol_state.sync; | ||
757 | |||
758 | if (sync) { | ||
759 | ios->done = _sync_done; | ||
760 | ios->private = &wait; | ||
761 | } | ||
762 | |||
763 | kref_init(&ios->kref); | ||
764 | |||
765 | for (i = 0; i < ios->numdevs; i++) { | ||
766 | struct osd_request *or = ios->per_dev[i].or; | ||
767 | |||
768 | if (!or) | ||
769 | continue; | ||
770 | |||
771 | kref_get(&ios->kref); | ||
772 | osd_execute_request_async(or, _done_io, ios); | ||
773 | } | ||
774 | |||
775 | kref_put(&ios->kref, _last_io); | ||
776 | |||
777 | if (sync) { | ||
778 | wait_for_completion(&wait); | ||
779 | status = saved_done_fn(ios); | ||
780 | } | ||
781 | |||
782 | return status; | ||
783 | } | ||
784 | |||
785 | /* | ||
786 | * read | ||
787 | */ | ||
788 | static ssize_t _read_done(struct objio_state *ios) | ||
789 | { | ||
790 | ssize_t status; | ||
791 | int ret = _io_check(ios, false); | ||
792 | |||
793 | _io_free(ios); | ||
794 | |||
795 | if (likely(!ret)) | ||
796 | status = ios->length; | ||
797 | else | ||
798 | status = ret; | ||
799 | |||
800 | objlayout_read_done(&ios->ol_state, status, ios->ol_state.sync); | ||
801 | return status; | ||
802 | } | ||
803 | |||
804 | static int _read_mirrors(struct objio_state *ios, unsigned cur_comp) | ||
805 | { | ||
806 | struct osd_request *or = NULL; | ||
807 | struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp]; | ||
808 | unsigned dev = per_dev->dev; | ||
809 | struct pnfs_osd_object_cred *cred = | ||
810 | &ios->layout->comps[dev]; | ||
811 | struct osd_obj_id obj = { | ||
812 | .partition = cred->oc_object_id.oid_partition_id, | ||
813 | .id = cred->oc_object_id.oid_object_id, | ||
814 | }; | ||
815 | int ret; | ||
816 | |||
817 | or = osd_start_request(_io_od(ios, dev), GFP_KERNEL); | ||
818 | if (unlikely(!or)) { | ||
819 | ret = -ENOMEM; | ||
820 | goto err; | ||
821 | } | ||
822 | per_dev->or = or; | ||
823 | |||
824 | osd_req_read(or, &obj, per_dev->offset, per_dev->bio, per_dev->length); | ||
825 | |||
826 | ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL); | ||
827 | if (ret) { | ||
828 | dprintk("%s: Faild to osd_finalize_request() => %d\n", | ||
829 | __func__, ret); | ||
830 | goto err; | ||
831 | } | ||
832 | |||
833 | dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n", | ||
834 | __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset), | ||
835 | per_dev->length); | ||
836 | |||
837 | err: | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | static ssize_t _read_exec(struct objio_state *ios) | ||
842 | { | ||
843 | unsigned i; | ||
844 | int ret; | ||
845 | |||
846 | for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { | ||
847 | if (!ios->per_dev[i].length) | ||
848 | continue; | ||
849 | ret = _read_mirrors(ios, i); | ||
850 | if (unlikely(ret)) | ||
851 | goto err; | ||
852 | } | ||
853 | |||
854 | ios->done = _read_done; | ||
855 | return _io_exec(ios); /* In sync mode exec returns the io status */ | ||
856 | |||
857 | err: | ||
858 | _io_free(ios); | ||
859 | return ret; | ||
860 | } | ||
861 | |||
862 | ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state) | ||
863 | { | ||
864 | struct objio_state *ios = container_of(ol_state, struct objio_state, | ||
865 | ol_state); | ||
866 | int ret; | ||
867 | |||
868 | ret = _io_rw_pagelist(ios, GFP_KERNEL); | ||
869 | if (unlikely(ret)) | ||
870 | return ret; | ||
871 | |||
872 | return _read_exec(ios); | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * write | ||
877 | */ | ||
878 | static ssize_t _write_done(struct objio_state *ios) | ||
879 | { | ||
880 | ssize_t status; | ||
881 | int ret = _io_check(ios, true); | ||
882 | |||
883 | _io_free(ios); | ||
884 | |||
885 | if (likely(!ret)) { | ||
886 | /* FIXME: should be based on the OSD's persistence model | ||
887 | * See OSD2r05 Section 4.13 Data persistence model */ | ||
888 | ios->ol_state.committed = NFS_FILE_SYNC; | ||
889 | status = ios->length; | ||
890 | } else { | ||
891 | status = ret; | ||
892 | } | ||
893 | |||
894 | objlayout_write_done(&ios->ol_state, status, ios->ol_state.sync); | ||
895 | return status; | ||
896 | } | ||
897 | |||
898 | static int _write_mirrors(struct objio_state *ios, unsigned cur_comp) | ||
899 | { | ||
900 | struct _objio_per_comp *master_dev = &ios->per_dev[cur_comp]; | ||
901 | unsigned dev = ios->per_dev[cur_comp].dev; | ||
902 | unsigned last_comp = cur_comp + ios->layout->mirrors_p1; | ||
903 | int ret; | ||
904 | |||
905 | for (; cur_comp < last_comp; ++cur_comp, ++dev) { | ||
906 | struct osd_request *or = NULL; | ||
907 | struct pnfs_osd_object_cred *cred = | ||
908 | &ios->layout->comps[dev]; | ||
909 | struct osd_obj_id obj = { | ||
910 | .partition = cred->oc_object_id.oid_partition_id, | ||
911 | .id = cred->oc_object_id.oid_object_id, | ||
912 | }; | ||
913 | struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp]; | ||
914 | struct bio *bio; | ||
915 | |||
916 | or = osd_start_request(_io_od(ios, dev), GFP_NOFS); | ||
917 | if (unlikely(!or)) { | ||
918 | ret = -ENOMEM; | ||
919 | goto err; | ||
920 | } | ||
921 | per_dev->or = or; | ||
922 | |||
923 | if (per_dev != master_dev) { | ||
924 | bio = bio_kmalloc(GFP_NOFS, | ||
925 | master_dev->bio->bi_max_vecs); | ||
926 | if (unlikely(!bio)) { | ||
927 | dprintk("Faild to allocate BIO size=%u\n", | ||
928 | master_dev->bio->bi_max_vecs); | ||
929 | ret = -ENOMEM; | ||
930 | goto err; | ||
931 | } | ||
932 | |||
933 | __bio_clone(bio, master_dev->bio); | ||
934 | bio->bi_bdev = NULL; | ||
935 | bio->bi_next = NULL; | ||
936 | per_dev->bio = bio; | ||
937 | per_dev->dev = dev; | ||
938 | per_dev->length = master_dev->length; | ||
939 | per_dev->offset = master_dev->offset; | ||
940 | } else { | ||
941 | bio = master_dev->bio; | ||
942 | bio->bi_rw |= REQ_WRITE; | ||
943 | } | ||
944 | |||
945 | osd_req_write(or, &obj, per_dev->offset, bio, per_dev->length); | ||
946 | |||
947 | ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL); | ||
948 | if (ret) { | ||
949 | dprintk("%s: Faild to osd_finalize_request() => %d\n", | ||
950 | __func__, ret); | ||
951 | goto err; | ||
952 | } | ||
953 | |||
954 | dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n", | ||
955 | __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset), | ||
956 | per_dev->length); | ||
957 | } | ||
958 | |||
959 | err: | ||
960 | return ret; | ||
961 | } | ||
962 | |||
963 | static ssize_t _write_exec(struct objio_state *ios) | ||
964 | { | ||
965 | unsigned i; | ||
966 | int ret; | ||
967 | |||
968 | for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { | ||
969 | if (!ios->per_dev[i].length) | ||
970 | continue; | ||
971 | ret = _write_mirrors(ios, i); | ||
972 | if (unlikely(ret)) | ||
973 | goto err; | ||
974 | } | ||
975 | |||
976 | ios->done = _write_done; | ||
977 | return _io_exec(ios); /* In sync mode exec returns the io->status */ | ||
978 | |||
979 | err: | ||
980 | _io_free(ios); | ||
981 | return ret; | ||
982 | } | ||
983 | |||
984 | ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, bool stable) | ||
985 | { | ||
986 | struct objio_state *ios = container_of(ol_state, struct objio_state, | ||
987 | ol_state); | ||
988 | int ret; | ||
989 | |||
990 | /* TODO: ios->stable = stable; */ | ||
991 | ret = _io_rw_pagelist(ios, GFP_NOFS); | ||
992 | if (unlikely(ret)) | ||
993 | return ret; | ||
994 | |||
995 | return _write_exec(ios); | ||
996 | } | ||
997 | |||
998 | static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, | ||
999 | struct nfs_page *prev, struct nfs_page *req) | ||
1000 | { | ||
1001 | if (!pnfs_generic_pg_test(pgio, prev, req)) | ||
1002 | return false; | ||
1003 | |||
1004 | return pgio->pg_count + req->wb_bytes <= | ||
1005 | OBJIO_LSEG(pgio->pg_lseg)->max_io_size; | ||
1006 | } | ||
1007 | |||
1008 | static struct pnfs_layoutdriver_type objlayout_type = { | ||
1009 | .id = LAYOUT_OSD2_OBJECTS, | ||
1010 | .name = "LAYOUT_OSD2_OBJECTS", | ||
1011 | .flags = PNFS_LAYOUTRET_ON_SETATTR, | ||
1012 | |||
1013 | .alloc_layout_hdr = objlayout_alloc_layout_hdr, | ||
1014 | .free_layout_hdr = objlayout_free_layout_hdr, | ||
1015 | |||
1016 | .alloc_lseg = objlayout_alloc_lseg, | ||
1017 | .free_lseg = objlayout_free_lseg, | ||
1018 | |||
1019 | .read_pagelist = objlayout_read_pagelist, | ||
1020 | .write_pagelist = objlayout_write_pagelist, | ||
1021 | .pg_test = objio_pg_test, | ||
1022 | |||
1023 | .free_deviceid_node = objio_free_deviceid_node, | ||
1024 | |||
1025 | .encode_layoutcommit = objlayout_encode_layoutcommit, | ||
1026 | .encode_layoutreturn = objlayout_encode_layoutreturn, | ||
1027 | }; | ||
1028 | |||
1029 | MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects"); | ||
1030 | MODULE_AUTHOR("Benny Halevy <bhalevy@panasas.com>"); | ||
1031 | MODULE_LICENSE("GPL"); | ||
1032 | |||
1033 | static int __init | ||
1034 | objlayout_init(void) | ||
1035 | { | ||
1036 | int ret = pnfs_register_layoutdriver(&objlayout_type); | ||
1037 | |||
1038 | if (ret) | ||
1039 | printk(KERN_INFO | ||
1040 | "%s: Registering OSD pNFS Layout Driver failed: error=%d\n", | ||
1041 | __func__, ret); | ||
1042 | else | ||
1043 | printk(KERN_INFO "%s: Registered OSD pNFS Layout Driver\n", | ||
1044 | __func__); | ||
1045 | return ret; | ||
1046 | } | ||
1047 | |||
1048 | static void __exit | ||
1049 | objlayout_exit(void) | ||
1050 | { | ||
1051 | pnfs_unregister_layoutdriver(&objlayout_type); | ||
1052 | printk(KERN_INFO "%s: Unregistered OSD pNFS Layout Driver\n", | ||
1053 | __func__); | ||
1054 | } | ||
1055 | |||
1056 | module_init(objlayout_init); | ||
1057 | module_exit(objlayout_exit); | ||
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c new file mode 100644 index 000000000000..dc3956c0de80 --- /dev/null +++ b/fs/nfs/objlayout/objlayout.c | |||
@@ -0,0 +1,712 @@ | |||
1 | /* | ||
2 | * pNFS Objects layout driver high level definitions | ||
3 | * | ||
4 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <scsi/osd_initiator.h> | ||
41 | #include "objlayout.h" | ||
42 | |||
43 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
44 | /* | ||
45 | * Create a objlayout layout structure for the given inode and return it. | ||
46 | */ | ||
47 | struct pnfs_layout_hdr * | ||
48 | objlayout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags) | ||
49 | { | ||
50 | struct objlayout *objlay; | ||
51 | |||
52 | objlay = kzalloc(sizeof(struct objlayout), gfp_flags); | ||
53 | if (objlay) { | ||
54 | spin_lock_init(&objlay->lock); | ||
55 | INIT_LIST_HEAD(&objlay->err_list); | ||
56 | } | ||
57 | dprintk("%s: Return %p\n", __func__, objlay); | ||
58 | return &objlay->pnfs_layout; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Free an objlayout layout structure | ||
63 | */ | ||
64 | void | ||
65 | objlayout_free_layout_hdr(struct pnfs_layout_hdr *lo) | ||
66 | { | ||
67 | struct objlayout *objlay = OBJLAYOUT(lo); | ||
68 | |||
69 | dprintk("%s: objlay %p\n", __func__, objlay); | ||
70 | |||
71 | WARN_ON(!list_empty(&objlay->err_list)); | ||
72 | kfree(objlay); | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * Unmarshall layout and store it in pnfslay. | ||
77 | */ | ||
78 | struct pnfs_layout_segment * | ||
79 | objlayout_alloc_lseg(struct pnfs_layout_hdr *pnfslay, | ||
80 | struct nfs4_layoutget_res *lgr, | ||
81 | gfp_t gfp_flags) | ||
82 | { | ||
83 | int status = -ENOMEM; | ||
84 | struct xdr_stream stream; | ||
85 | struct xdr_buf buf = { | ||
86 | .pages = lgr->layoutp->pages, | ||
87 | .page_len = lgr->layoutp->len, | ||
88 | .buflen = lgr->layoutp->len, | ||
89 | .len = lgr->layoutp->len, | ||
90 | }; | ||
91 | struct page *scratch; | ||
92 | struct pnfs_layout_segment *lseg; | ||
93 | |||
94 | dprintk("%s: Begin pnfslay %p\n", __func__, pnfslay); | ||
95 | |||
96 | scratch = alloc_page(gfp_flags); | ||
97 | if (!scratch) | ||
98 | goto err_nofree; | ||
99 | |||
100 | xdr_init_decode(&stream, &buf, NULL); | ||
101 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | ||
102 | |||
103 | status = objio_alloc_lseg(&lseg, pnfslay, &lgr->range, &stream, gfp_flags); | ||
104 | if (unlikely(status)) { | ||
105 | dprintk("%s: objio_alloc_lseg Return err %d\n", __func__, | ||
106 | status); | ||
107 | goto err; | ||
108 | } | ||
109 | |||
110 | __free_page(scratch); | ||
111 | |||
112 | dprintk("%s: Return %p\n", __func__, lseg); | ||
113 | return lseg; | ||
114 | |||
115 | err: | ||
116 | __free_page(scratch); | ||
117 | err_nofree: | ||
118 | dprintk("%s: Err Return=>%d\n", __func__, status); | ||
119 | return ERR_PTR(status); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Free a layout segement | ||
124 | */ | ||
125 | void | ||
126 | objlayout_free_lseg(struct pnfs_layout_segment *lseg) | ||
127 | { | ||
128 | dprintk("%s: freeing layout segment %p\n", __func__, lseg); | ||
129 | |||
130 | if (unlikely(!lseg)) | ||
131 | return; | ||
132 | |||
133 | objio_free_lseg(lseg); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * I/O Operations | ||
138 | */ | ||
139 | static inline u64 | ||
140 | end_offset(u64 start, u64 len) | ||
141 | { | ||
142 | u64 end; | ||
143 | |||
144 | end = start + len; | ||
145 | return end >= start ? end : NFS4_MAX_UINT64; | ||
146 | } | ||
147 | |||
148 | /* last octet in a range */ | ||
149 | static inline u64 | ||
150 | last_byte_offset(u64 start, u64 len) | ||
151 | { | ||
152 | u64 end; | ||
153 | |||
154 | BUG_ON(!len); | ||
155 | end = start + len; | ||
156 | return end > start ? end - 1 : NFS4_MAX_UINT64; | ||
157 | } | ||
158 | |||
159 | static struct objlayout_io_state * | ||
160 | objlayout_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type, | ||
161 | struct page **pages, | ||
162 | unsigned pgbase, | ||
163 | loff_t offset, | ||
164 | size_t count, | ||
165 | struct pnfs_layout_segment *lseg, | ||
166 | void *rpcdata, | ||
167 | gfp_t gfp_flags) | ||
168 | { | ||
169 | struct objlayout_io_state *state; | ||
170 | u64 lseg_end_offset; | ||
171 | |||
172 | dprintk("%s: allocating io_state\n", __func__); | ||
173 | if (objio_alloc_io_state(lseg, &state, gfp_flags)) | ||
174 | return NULL; | ||
175 | |||
176 | BUG_ON(offset < lseg->pls_range.offset); | ||
177 | lseg_end_offset = end_offset(lseg->pls_range.offset, | ||
178 | lseg->pls_range.length); | ||
179 | BUG_ON(offset >= lseg_end_offset); | ||
180 | if (offset + count > lseg_end_offset) { | ||
181 | count = lseg->pls_range.length - | ||
182 | (offset - lseg->pls_range.offset); | ||
183 | dprintk("%s: truncated count %Zd\n", __func__, count); | ||
184 | } | ||
185 | |||
186 | if (pgbase > PAGE_SIZE) { | ||
187 | pages += pgbase >> PAGE_SHIFT; | ||
188 | pgbase &= ~PAGE_MASK; | ||
189 | } | ||
190 | |||
191 | INIT_LIST_HEAD(&state->err_list); | ||
192 | state->lseg = lseg; | ||
193 | state->rpcdata = rpcdata; | ||
194 | state->pages = pages; | ||
195 | state->pgbase = pgbase; | ||
196 | state->nr_pages = (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
197 | state->offset = offset; | ||
198 | state->count = count; | ||
199 | state->sync = 0; | ||
200 | |||
201 | return state; | ||
202 | } | ||
203 | |||
204 | static void | ||
205 | objlayout_free_io_state(struct objlayout_io_state *state) | ||
206 | { | ||
207 | dprintk("%s: freeing io_state\n", __func__); | ||
208 | if (unlikely(!state)) | ||
209 | return; | ||
210 | |||
211 | objio_free_io_state(state); | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * I/O done common code | ||
216 | */ | ||
217 | static void | ||
218 | objlayout_iodone(struct objlayout_io_state *state) | ||
219 | { | ||
220 | dprintk("%s: state %p status\n", __func__, state); | ||
221 | |||
222 | if (likely(state->status >= 0)) { | ||
223 | objlayout_free_io_state(state); | ||
224 | } else { | ||
225 | struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout); | ||
226 | |||
227 | spin_lock(&objlay->lock); | ||
228 | objlay->delta_space_valid = OBJ_DSU_INVALID; | ||
229 | list_add(&objlay->err_list, &state->err_list); | ||
230 | spin_unlock(&objlay->lock); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * objlayout_io_set_result - Set an osd_error code on a specific osd comp. | ||
236 | * | ||
237 | * The @index component IO failed (error returned from target). Register | ||
238 | * the error for later reporting at layout-return. | ||
239 | */ | ||
240 | void | ||
241 | objlayout_io_set_result(struct objlayout_io_state *state, unsigned index, | ||
242 | struct pnfs_osd_objid *pooid, int osd_error, | ||
243 | u64 offset, u64 length, bool is_write) | ||
244 | { | ||
245 | struct pnfs_osd_ioerr *ioerr = &state->ioerrs[index]; | ||
246 | |||
247 | BUG_ON(index >= state->num_comps); | ||
248 | if (osd_error) { | ||
249 | ioerr->oer_component = *pooid; | ||
250 | ioerr->oer_comp_offset = offset; | ||
251 | ioerr->oer_comp_length = length; | ||
252 | ioerr->oer_iswrite = is_write; | ||
253 | ioerr->oer_errno = osd_error; | ||
254 | |||
255 | dprintk("%s: err[%d]: errno=%d is_write=%d dev(%llx:%llx) " | ||
256 | "par=0x%llx obj=0x%llx offset=0x%llx length=0x%llx\n", | ||
257 | __func__, index, ioerr->oer_errno, | ||
258 | ioerr->oer_iswrite, | ||
259 | _DEVID_LO(&ioerr->oer_component.oid_device_id), | ||
260 | _DEVID_HI(&ioerr->oer_component.oid_device_id), | ||
261 | ioerr->oer_component.oid_partition_id, | ||
262 | ioerr->oer_component.oid_object_id, | ||
263 | ioerr->oer_comp_offset, | ||
264 | ioerr->oer_comp_length); | ||
265 | } else { | ||
266 | /* User need not call if no error is reported */ | ||
267 | ioerr->oer_errno = 0; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /* Function scheduled on rpc workqueue to call ->nfs_readlist_complete(). | ||
272 | * This is because the osd completion is called with ints-off from | ||
273 | * the block layer | ||
274 | */ | ||
275 | static void _rpc_read_complete(struct work_struct *work) | ||
276 | { | ||
277 | struct rpc_task *task; | ||
278 | struct nfs_read_data *rdata; | ||
279 | |||
280 | dprintk("%s enter\n", __func__); | ||
281 | task = container_of(work, struct rpc_task, u.tk_work); | ||
282 | rdata = container_of(task, struct nfs_read_data, task); | ||
283 | |||
284 | pnfs_ld_read_done(rdata); | ||
285 | } | ||
286 | |||
287 | void | ||
288 | objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync) | ||
289 | { | ||
290 | int eof = state->eof; | ||
291 | struct nfs_read_data *rdata; | ||
292 | |||
293 | state->status = status; | ||
294 | dprintk("%s: Begin status=%ld eof=%d\n", __func__, status, eof); | ||
295 | rdata = state->rpcdata; | ||
296 | rdata->task.tk_status = status; | ||
297 | if (status >= 0) { | ||
298 | rdata->res.count = status; | ||
299 | rdata->res.eof = eof; | ||
300 | } | ||
301 | objlayout_iodone(state); | ||
302 | /* must not use state after this point */ | ||
303 | |||
304 | if (sync) | ||
305 | pnfs_ld_read_done(rdata); | ||
306 | else { | ||
307 | INIT_WORK(&rdata->task.u.tk_work, _rpc_read_complete); | ||
308 | schedule_work(&rdata->task.u.tk_work); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Perform sync or async reads. | ||
314 | */ | ||
315 | enum pnfs_try_status | ||
316 | objlayout_read_pagelist(struct nfs_read_data *rdata) | ||
317 | { | ||
318 | loff_t offset = rdata->args.offset; | ||
319 | size_t count = rdata->args.count; | ||
320 | struct objlayout_io_state *state; | ||
321 | ssize_t status = 0; | ||
322 | loff_t eof; | ||
323 | |||
324 | dprintk("%s: Begin inode %p offset %llu count %d\n", | ||
325 | __func__, rdata->inode, offset, (int)count); | ||
326 | |||
327 | eof = i_size_read(rdata->inode); | ||
328 | if (unlikely(offset + count > eof)) { | ||
329 | if (offset >= eof) { | ||
330 | status = 0; | ||
331 | rdata->res.count = 0; | ||
332 | rdata->res.eof = 1; | ||
333 | goto out; | ||
334 | } | ||
335 | count = eof - offset; | ||
336 | } | ||
337 | |||
338 | state = objlayout_alloc_io_state(NFS_I(rdata->inode)->layout, | ||
339 | rdata->args.pages, rdata->args.pgbase, | ||
340 | offset, count, | ||
341 | rdata->lseg, rdata, | ||
342 | GFP_KERNEL); | ||
343 | if (unlikely(!state)) { | ||
344 | status = -ENOMEM; | ||
345 | goto out; | ||
346 | } | ||
347 | |||
348 | state->eof = state->offset + state->count >= eof; | ||
349 | |||
350 | status = objio_read_pagelist(state); | ||
351 | out: | ||
352 | dprintk("%s: Return status %Zd\n", __func__, status); | ||
353 | rdata->pnfs_error = status; | ||
354 | return PNFS_ATTEMPTED; | ||
355 | } | ||
356 | |||
357 | /* Function scheduled on rpc workqueue to call ->nfs_writelist_complete(). | ||
358 | * This is because the osd completion is called with ints-off from | ||
359 | * the block layer | ||
360 | */ | ||
361 | static void _rpc_write_complete(struct work_struct *work) | ||
362 | { | ||
363 | struct rpc_task *task; | ||
364 | struct nfs_write_data *wdata; | ||
365 | |||
366 | dprintk("%s enter\n", __func__); | ||
367 | task = container_of(work, struct rpc_task, u.tk_work); | ||
368 | wdata = container_of(task, struct nfs_write_data, task); | ||
369 | |||
370 | pnfs_ld_write_done(wdata); | ||
371 | } | ||
372 | |||
373 | void | ||
374 | objlayout_write_done(struct objlayout_io_state *state, ssize_t status, | ||
375 | bool sync) | ||
376 | { | ||
377 | struct nfs_write_data *wdata; | ||
378 | |||
379 | dprintk("%s: Begin\n", __func__); | ||
380 | wdata = state->rpcdata; | ||
381 | state->status = status; | ||
382 | wdata->task.tk_status = status; | ||
383 | if (status >= 0) { | ||
384 | wdata->res.count = status; | ||
385 | wdata->verf.committed = state->committed; | ||
386 | dprintk("%s: Return status %d committed %d\n", | ||
387 | __func__, wdata->task.tk_status, | ||
388 | wdata->verf.committed); | ||
389 | } else | ||
390 | dprintk("%s: Return status %d\n", | ||
391 | __func__, wdata->task.tk_status); | ||
392 | objlayout_iodone(state); | ||
393 | /* must not use state after this point */ | ||
394 | |||
395 | if (sync) | ||
396 | pnfs_ld_write_done(wdata); | ||
397 | else { | ||
398 | INIT_WORK(&wdata->task.u.tk_work, _rpc_write_complete); | ||
399 | schedule_work(&wdata->task.u.tk_work); | ||
400 | } | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Perform sync or async writes. | ||
405 | */ | ||
406 | enum pnfs_try_status | ||
407 | objlayout_write_pagelist(struct nfs_write_data *wdata, | ||
408 | int how) | ||
409 | { | ||
410 | struct objlayout_io_state *state; | ||
411 | ssize_t status; | ||
412 | |||
413 | dprintk("%s: Begin inode %p offset %llu count %u\n", | ||
414 | __func__, wdata->inode, wdata->args.offset, wdata->args.count); | ||
415 | |||
416 | state = objlayout_alloc_io_state(NFS_I(wdata->inode)->layout, | ||
417 | wdata->args.pages, | ||
418 | wdata->args.pgbase, | ||
419 | wdata->args.offset, | ||
420 | wdata->args.count, | ||
421 | wdata->lseg, wdata, | ||
422 | GFP_NOFS); | ||
423 | if (unlikely(!state)) { | ||
424 | status = -ENOMEM; | ||
425 | goto out; | ||
426 | } | ||
427 | |||
428 | state->sync = how & FLUSH_SYNC; | ||
429 | |||
430 | status = objio_write_pagelist(state, how & FLUSH_STABLE); | ||
431 | out: | ||
432 | dprintk("%s: Return status %Zd\n", __func__, status); | ||
433 | wdata->pnfs_error = status; | ||
434 | return PNFS_ATTEMPTED; | ||
435 | } | ||
436 | |||
437 | void | ||
438 | objlayout_encode_layoutcommit(struct pnfs_layout_hdr *pnfslay, | ||
439 | struct xdr_stream *xdr, | ||
440 | const struct nfs4_layoutcommit_args *args) | ||
441 | { | ||
442 | struct objlayout *objlay = OBJLAYOUT(pnfslay); | ||
443 | struct pnfs_osd_layoutupdate lou; | ||
444 | __be32 *start; | ||
445 | |||
446 | dprintk("%s: Begin\n", __func__); | ||
447 | |||
448 | spin_lock(&objlay->lock); | ||
449 | lou.dsu_valid = (objlay->delta_space_valid == OBJ_DSU_VALID); | ||
450 | lou.dsu_delta = objlay->delta_space_used; | ||
451 | objlay->delta_space_used = 0; | ||
452 | objlay->delta_space_valid = OBJ_DSU_INIT; | ||
453 | lou.olu_ioerr_flag = !list_empty(&objlay->err_list); | ||
454 | spin_unlock(&objlay->lock); | ||
455 | |||
456 | start = xdr_reserve_space(xdr, 4); | ||
457 | |||
458 | BUG_ON(pnfs_osd_xdr_encode_layoutupdate(xdr, &lou)); | ||
459 | |||
460 | *start = cpu_to_be32((xdr->p - start - 1) * 4); | ||
461 | |||
462 | dprintk("%s: Return delta_space_used %lld err %d\n", __func__, | ||
463 | lou.dsu_delta, lou.olu_ioerr_flag); | ||
464 | } | ||
465 | |||
466 | static int | ||
467 | err_prio(u32 oer_errno) | ||
468 | { | ||
469 | switch (oer_errno) { | ||
470 | case 0: | ||
471 | return 0; | ||
472 | |||
473 | case PNFS_OSD_ERR_RESOURCE: | ||
474 | return OSD_ERR_PRI_RESOURCE; | ||
475 | case PNFS_OSD_ERR_BAD_CRED: | ||
476 | return OSD_ERR_PRI_BAD_CRED; | ||
477 | case PNFS_OSD_ERR_NO_ACCESS: | ||
478 | return OSD_ERR_PRI_NO_ACCESS; | ||
479 | case PNFS_OSD_ERR_UNREACHABLE: | ||
480 | return OSD_ERR_PRI_UNREACHABLE; | ||
481 | case PNFS_OSD_ERR_NOT_FOUND: | ||
482 | return OSD_ERR_PRI_NOT_FOUND; | ||
483 | case PNFS_OSD_ERR_NO_SPACE: | ||
484 | return OSD_ERR_PRI_NO_SPACE; | ||
485 | default: | ||
486 | WARN_ON(1); | ||
487 | /* fallthrough */ | ||
488 | case PNFS_OSD_ERR_EIO: | ||
489 | return OSD_ERR_PRI_EIO; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | static void | ||
494 | merge_ioerr(struct pnfs_osd_ioerr *dest_err, | ||
495 | const struct pnfs_osd_ioerr *src_err) | ||
496 | { | ||
497 | u64 dest_end, src_end; | ||
498 | |||
499 | if (!dest_err->oer_errno) { | ||
500 | *dest_err = *src_err; | ||
501 | /* accumulated device must be blank */ | ||
502 | memset(&dest_err->oer_component.oid_device_id, 0, | ||
503 | sizeof(dest_err->oer_component.oid_device_id)); | ||
504 | |||
505 | return; | ||
506 | } | ||
507 | |||
508 | if (dest_err->oer_component.oid_partition_id != | ||
509 | src_err->oer_component.oid_partition_id) | ||
510 | dest_err->oer_component.oid_partition_id = 0; | ||
511 | |||
512 | if (dest_err->oer_component.oid_object_id != | ||
513 | src_err->oer_component.oid_object_id) | ||
514 | dest_err->oer_component.oid_object_id = 0; | ||
515 | |||
516 | if (dest_err->oer_comp_offset > src_err->oer_comp_offset) | ||
517 | dest_err->oer_comp_offset = src_err->oer_comp_offset; | ||
518 | |||
519 | dest_end = end_offset(dest_err->oer_comp_offset, | ||
520 | dest_err->oer_comp_length); | ||
521 | src_end = end_offset(src_err->oer_comp_offset, | ||
522 | src_err->oer_comp_length); | ||
523 | if (dest_end < src_end) | ||
524 | dest_end = src_end; | ||
525 | |||
526 | dest_err->oer_comp_length = dest_end - dest_err->oer_comp_offset; | ||
527 | |||
528 | if ((src_err->oer_iswrite == dest_err->oer_iswrite) && | ||
529 | (err_prio(src_err->oer_errno) > err_prio(dest_err->oer_errno))) { | ||
530 | dest_err->oer_errno = src_err->oer_errno; | ||
531 | } else if (src_err->oer_iswrite) { | ||
532 | dest_err->oer_iswrite = true; | ||
533 | dest_err->oer_errno = src_err->oer_errno; | ||
534 | } | ||
535 | } | ||
536 | |||
537 | static void | ||
538 | encode_accumulated_error(struct objlayout *objlay, __be32 *p) | ||
539 | { | ||
540 | struct objlayout_io_state *state, *tmp; | ||
541 | struct pnfs_osd_ioerr accumulated_err = {.oer_errno = 0}; | ||
542 | |||
543 | list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) { | ||
544 | unsigned i; | ||
545 | |||
546 | for (i = 0; i < state->num_comps; i++) { | ||
547 | struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i]; | ||
548 | |||
549 | if (!ioerr->oer_errno) | ||
550 | continue; | ||
551 | |||
552 | printk(KERN_ERR "%s: err[%d]: errno=%d is_write=%d " | ||
553 | "dev(%llx:%llx) par=0x%llx obj=0x%llx " | ||
554 | "offset=0x%llx length=0x%llx\n", | ||
555 | __func__, i, ioerr->oer_errno, | ||
556 | ioerr->oer_iswrite, | ||
557 | _DEVID_LO(&ioerr->oer_component.oid_device_id), | ||
558 | _DEVID_HI(&ioerr->oer_component.oid_device_id), | ||
559 | ioerr->oer_component.oid_partition_id, | ||
560 | ioerr->oer_component.oid_object_id, | ||
561 | ioerr->oer_comp_offset, | ||
562 | ioerr->oer_comp_length); | ||
563 | |||
564 | merge_ioerr(&accumulated_err, ioerr); | ||
565 | } | ||
566 | list_del(&state->err_list); | ||
567 | objlayout_free_io_state(state); | ||
568 | } | ||
569 | |||
570 | pnfs_osd_xdr_encode_ioerr(p, &accumulated_err); | ||
571 | } | ||
572 | |||
573 | void | ||
574 | objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay, | ||
575 | struct xdr_stream *xdr, | ||
576 | const struct nfs4_layoutreturn_args *args) | ||
577 | { | ||
578 | struct objlayout *objlay = OBJLAYOUT(pnfslay); | ||
579 | struct objlayout_io_state *state, *tmp; | ||
580 | __be32 *start; | ||
581 | |||
582 | dprintk("%s: Begin\n", __func__); | ||
583 | start = xdr_reserve_space(xdr, 4); | ||
584 | BUG_ON(!start); | ||
585 | |||
586 | spin_lock(&objlay->lock); | ||
587 | |||
588 | list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) { | ||
589 | __be32 *last_xdr = NULL, *p; | ||
590 | unsigned i; | ||
591 | int res = 0; | ||
592 | |||
593 | for (i = 0; i < state->num_comps; i++) { | ||
594 | struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i]; | ||
595 | |||
596 | if (!ioerr->oer_errno) | ||
597 | continue; | ||
598 | |||
599 | dprintk("%s: err[%d]: errno=%d is_write=%d " | ||
600 | "dev(%llx:%llx) par=0x%llx obj=0x%llx " | ||
601 | "offset=0x%llx length=0x%llx\n", | ||
602 | __func__, i, ioerr->oer_errno, | ||
603 | ioerr->oer_iswrite, | ||
604 | _DEVID_LO(&ioerr->oer_component.oid_device_id), | ||
605 | _DEVID_HI(&ioerr->oer_component.oid_device_id), | ||
606 | ioerr->oer_component.oid_partition_id, | ||
607 | ioerr->oer_component.oid_object_id, | ||
608 | ioerr->oer_comp_offset, | ||
609 | ioerr->oer_comp_length); | ||
610 | |||
611 | p = pnfs_osd_xdr_ioerr_reserve_space(xdr); | ||
612 | if (unlikely(!p)) { | ||
613 | res = -E2BIG; | ||
614 | break; /* accumulated_error */ | ||
615 | } | ||
616 | |||
617 | last_xdr = p; | ||
618 | pnfs_osd_xdr_encode_ioerr(p, &state->ioerrs[i]); | ||
619 | } | ||
620 | |||
621 | /* TODO: use xdr_write_pages */ | ||
622 | if (unlikely(res)) { | ||
623 | /* no space for even one error descriptor */ | ||
624 | BUG_ON(!last_xdr); | ||
625 | |||
626 | /* we've encountered a situation with lots and lots of | ||
627 | * errors and no space to encode them all. Use the last | ||
628 | * available slot to report the union of all the | ||
629 | * remaining errors. | ||
630 | */ | ||
631 | encode_accumulated_error(objlay, last_xdr); | ||
632 | goto loop_done; | ||
633 | } | ||
634 | list_del(&state->err_list); | ||
635 | objlayout_free_io_state(state); | ||
636 | } | ||
637 | loop_done: | ||
638 | spin_unlock(&objlay->lock); | ||
639 | |||
640 | *start = cpu_to_be32((xdr->p - start - 1) * 4); | ||
641 | dprintk("%s: Return\n", __func__); | ||
642 | } | ||
643 | |||
644 | |||
645 | /* | ||
646 | * Get Device Info API for io engines | ||
647 | */ | ||
648 | struct objlayout_deviceinfo { | ||
649 | struct page *page; | ||
650 | struct pnfs_osd_deviceaddr da; /* This must be last */ | ||
651 | }; | ||
652 | |||
653 | /* Initialize and call nfs_getdeviceinfo, then decode and return a | ||
654 | * "struct pnfs_osd_deviceaddr *" Eventually objlayout_put_deviceinfo() | ||
655 | * should be called. | ||
656 | */ | ||
657 | int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, | ||
658 | struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr, | ||
659 | gfp_t gfp_flags) | ||
660 | { | ||
661 | struct objlayout_deviceinfo *odi; | ||
662 | struct pnfs_device pd; | ||
663 | struct super_block *sb; | ||
664 | struct page *page, **pages; | ||
665 | u32 *p; | ||
666 | int err; | ||
667 | |||
668 | page = alloc_page(gfp_flags); | ||
669 | if (!page) | ||
670 | return -ENOMEM; | ||
671 | |||
672 | pages = &page; | ||
673 | pd.pages = pages; | ||
674 | |||
675 | memcpy(&pd.dev_id, d_id, sizeof(*d_id)); | ||
676 | pd.layout_type = LAYOUT_OSD2_OBJECTS; | ||
677 | pd.pages = &page; | ||
678 | pd.pgbase = 0; | ||
679 | pd.pglen = PAGE_SIZE; | ||
680 | pd.mincount = 0; | ||
681 | |||
682 | sb = pnfslay->plh_inode->i_sb; | ||
683 | err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd); | ||
684 | dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err); | ||
685 | if (err) | ||
686 | goto err_out; | ||
687 | |||
688 | p = page_address(page); | ||
689 | odi = kzalloc(sizeof(*odi), gfp_flags); | ||
690 | if (!odi) { | ||
691 | err = -ENOMEM; | ||
692 | goto err_out; | ||
693 | } | ||
694 | pnfs_osd_xdr_decode_deviceaddr(&odi->da, p); | ||
695 | odi->page = page; | ||
696 | *deviceaddr = &odi->da; | ||
697 | return 0; | ||
698 | |||
699 | err_out: | ||
700 | __free_page(page); | ||
701 | return err; | ||
702 | } | ||
703 | |||
704 | void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr) | ||
705 | { | ||
706 | struct objlayout_deviceinfo *odi = container_of(deviceaddr, | ||
707 | struct objlayout_deviceinfo, | ||
708 | da); | ||
709 | |||
710 | __free_page(odi->page); | ||
711 | kfree(odi); | ||
712 | } | ||
diff --git a/fs/nfs/objlayout/objlayout.h b/fs/nfs/objlayout/objlayout.h new file mode 100644 index 000000000000..a8244c8e042d --- /dev/null +++ b/fs/nfs/objlayout/objlayout.h | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Data types and function declerations for interfacing with the | ||
3 | * pNFS standard object layout driver. | ||
4 | * | ||
5 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * Boaz Harrosh <bharrosh@panasas.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 | ||
13 | * See the file COPYING included with this distribution for more details. | ||
14 | * | ||
15 | * Redistribution and use in source and binary forms, with or without | ||
16 | * modification, are permitted provided that the following conditions | ||
17 | * are met: | ||
18 | * | ||
19 | * 1. Redistributions of source code must retain the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer. | ||
21 | * 2. Redistributions in binary form must reproduce the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer in the | ||
23 | * documentation and/or other materials provided with the distribution. | ||
24 | * 3. Neither the name of the Panasas company nor the names of its | ||
25 | * contributors may be used to endorse or promote products derived | ||
26 | * from this software without specific prior written permission. | ||
27 | * | ||
28 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
30 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
31 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
32 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
34 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
35 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
36 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
37 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
38 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
39 | */ | ||
40 | |||
41 | #ifndef _OBJLAYOUT_H | ||
42 | #define _OBJLAYOUT_H | ||
43 | |||
44 | #include <linux/nfs_fs.h> | ||
45 | #include <linux/pnfs_osd_xdr.h> | ||
46 | #include "../pnfs.h" | ||
47 | |||
48 | /* | ||
49 | * per-inode layout | ||
50 | */ | ||
51 | struct objlayout { | ||
52 | struct pnfs_layout_hdr pnfs_layout; | ||
53 | |||
54 | /* for layout_commit */ | ||
55 | enum osd_delta_space_valid_enum { | ||
56 | OBJ_DSU_INIT = 0, | ||
57 | OBJ_DSU_VALID, | ||
58 | OBJ_DSU_INVALID, | ||
59 | } delta_space_valid; | ||
60 | s64 delta_space_used; /* consumed by write ops */ | ||
61 | |||
62 | /* for layout_return */ | ||
63 | spinlock_t lock; | ||
64 | struct list_head err_list; | ||
65 | }; | ||
66 | |||
67 | static inline struct objlayout * | ||
68 | OBJLAYOUT(struct pnfs_layout_hdr *lo) | ||
69 | { | ||
70 | return container_of(lo, struct objlayout, pnfs_layout); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * per-I/O operation state | ||
75 | * embedded in objects provider io_state data structure | ||
76 | */ | ||
77 | struct objlayout_io_state { | ||
78 | struct pnfs_layout_segment *lseg; | ||
79 | |||
80 | struct page **pages; | ||
81 | unsigned pgbase; | ||
82 | unsigned nr_pages; | ||
83 | unsigned long count; | ||
84 | loff_t offset; | ||
85 | bool sync; | ||
86 | |||
87 | void *rpcdata; | ||
88 | int status; /* res */ | ||
89 | int eof; /* res */ | ||
90 | int committed; /* res */ | ||
91 | |||
92 | /* Error reporting (layout_return) */ | ||
93 | struct list_head err_list; | ||
94 | unsigned num_comps; | ||
95 | /* Pointer to array of error descriptors of size num_comps. | ||
96 | * It should contain as many entries as devices in the osd_layout | ||
97 | * that participate in the I/O. It is up to the io_engine to allocate | ||
98 | * needed space and set num_comps. | ||
99 | */ | ||
100 | struct pnfs_osd_ioerr *ioerrs; | ||
101 | }; | ||
102 | |||
103 | /* | ||
104 | * Raid engine I/O API | ||
105 | */ | ||
106 | extern int objio_alloc_lseg(struct pnfs_layout_segment **outp, | ||
107 | struct pnfs_layout_hdr *pnfslay, | ||
108 | struct pnfs_layout_range *range, | ||
109 | struct xdr_stream *xdr, | ||
110 | gfp_t gfp_flags); | ||
111 | extern void objio_free_lseg(struct pnfs_layout_segment *lseg); | ||
112 | |||
113 | extern int objio_alloc_io_state( | ||
114 | struct pnfs_layout_segment *lseg, | ||
115 | struct objlayout_io_state **outp, | ||
116 | gfp_t gfp_flags); | ||
117 | extern void objio_free_io_state(struct objlayout_io_state *state); | ||
118 | |||
119 | extern ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state); | ||
120 | extern ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, | ||
121 | bool stable); | ||
122 | |||
123 | /* | ||
124 | * callback API | ||
125 | */ | ||
126 | extern void objlayout_io_set_result(struct objlayout_io_state *state, | ||
127 | unsigned index, struct pnfs_osd_objid *pooid, | ||
128 | int osd_error, u64 offset, u64 length, bool is_write); | ||
129 | |||
130 | static inline void | ||
131 | objlayout_add_delta_space_used(struct objlayout_io_state *state, s64 space_used) | ||
132 | { | ||
133 | struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout); | ||
134 | |||
135 | /* If one of the I/Os errored out and the delta_space_used was | ||
136 | * invalid we render the complete report as invalid. Protocol mandate | ||
137 | * the DSU be accurate or not reported. | ||
138 | */ | ||
139 | spin_lock(&objlay->lock); | ||
140 | if (objlay->delta_space_valid != OBJ_DSU_INVALID) { | ||
141 | objlay->delta_space_valid = OBJ_DSU_VALID; | ||
142 | objlay->delta_space_used += space_used; | ||
143 | } | ||
144 | spin_unlock(&objlay->lock); | ||
145 | } | ||
146 | |||
147 | extern void objlayout_read_done(struct objlayout_io_state *state, | ||
148 | ssize_t status, bool sync); | ||
149 | extern void objlayout_write_done(struct objlayout_io_state *state, | ||
150 | ssize_t status, bool sync); | ||
151 | |||
152 | extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, | ||
153 | struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr, | ||
154 | gfp_t gfp_flags); | ||
155 | extern void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr); | ||
156 | |||
157 | /* | ||
158 | * exported generic objects function vectors | ||
159 | */ | ||
160 | |||
161 | extern struct pnfs_layout_hdr *objlayout_alloc_layout_hdr(struct inode *, gfp_t gfp_flags); | ||
162 | extern void objlayout_free_layout_hdr(struct pnfs_layout_hdr *); | ||
163 | |||
164 | extern struct pnfs_layout_segment *objlayout_alloc_lseg( | ||
165 | struct pnfs_layout_hdr *, | ||
166 | struct nfs4_layoutget_res *, | ||
167 | gfp_t gfp_flags); | ||
168 | extern void objlayout_free_lseg(struct pnfs_layout_segment *); | ||
169 | |||
170 | extern enum pnfs_try_status objlayout_read_pagelist( | ||
171 | struct nfs_read_data *); | ||
172 | |||
173 | extern enum pnfs_try_status objlayout_write_pagelist( | ||
174 | struct nfs_write_data *, | ||
175 | int how); | ||
176 | |||
177 | extern void objlayout_encode_layoutcommit( | ||
178 | struct pnfs_layout_hdr *, | ||
179 | struct xdr_stream *, | ||
180 | const struct nfs4_layoutcommit_args *); | ||
181 | |||
182 | extern void objlayout_encode_layoutreturn( | ||
183 | struct pnfs_layout_hdr *, | ||
184 | struct xdr_stream *, | ||
185 | const struct nfs4_layoutreturn_args *); | ||
186 | |||
187 | #endif /* _OBJLAYOUT_H */ | ||
diff --git a/fs/nfs/objlayout/pnfs_osd_xdr_cli.c b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c new file mode 100644 index 000000000000..16fc758e9123 --- /dev/null +++ b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * Object-Based pNFS Layout XDR layer | ||
3 | * | ||
4 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/pnfs_osd_xdr.h> | ||
41 | |||
42 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
43 | |||
44 | /* | ||
45 | * The following implementation is based on RFC5664 | ||
46 | */ | ||
47 | |||
48 | /* | ||
49 | * struct pnfs_osd_objid { | ||
50 | * struct nfs4_deviceid oid_device_id; | ||
51 | * u64 oid_partition_id; | ||
52 | * u64 oid_object_id; | ||
53 | * }; // xdr size 32 bytes | ||
54 | */ | ||
55 | static __be32 * | ||
56 | _osd_xdr_decode_objid(__be32 *p, struct pnfs_osd_objid *objid) | ||
57 | { | ||
58 | p = xdr_decode_opaque_fixed(p, objid->oid_device_id.data, | ||
59 | sizeof(objid->oid_device_id.data)); | ||
60 | |||
61 | p = xdr_decode_hyper(p, &objid->oid_partition_id); | ||
62 | p = xdr_decode_hyper(p, &objid->oid_object_id); | ||
63 | return p; | ||
64 | } | ||
65 | /* | ||
66 | * struct pnfs_osd_opaque_cred { | ||
67 | * u32 cred_len; | ||
68 | * void *cred; | ||
69 | * }; // xdr size [variable] | ||
70 | * The return pointers are from the xdr buffer | ||
71 | */ | ||
72 | static int | ||
73 | _osd_xdr_decode_opaque_cred(struct pnfs_osd_opaque_cred *opaque_cred, | ||
74 | struct xdr_stream *xdr) | ||
75 | { | ||
76 | __be32 *p = xdr_inline_decode(xdr, 1); | ||
77 | |||
78 | if (!p) | ||
79 | return -EINVAL; | ||
80 | |||
81 | opaque_cred->cred_len = be32_to_cpu(*p++); | ||
82 | |||
83 | p = xdr_inline_decode(xdr, opaque_cred->cred_len); | ||
84 | if (!p) | ||
85 | return -EINVAL; | ||
86 | |||
87 | opaque_cred->cred = p; | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * struct pnfs_osd_object_cred { | ||
93 | * struct pnfs_osd_objid oc_object_id; | ||
94 | * u32 oc_osd_version; | ||
95 | * u32 oc_cap_key_sec; | ||
96 | * struct pnfs_osd_opaque_cred oc_cap_key | ||
97 | * struct pnfs_osd_opaque_cred oc_cap; | ||
98 | * }; // xdr size 32 + 4 + 4 + [variable] + [variable] | ||
99 | */ | ||
100 | static int | ||
101 | _osd_xdr_decode_object_cred(struct pnfs_osd_object_cred *comp, | ||
102 | struct xdr_stream *xdr) | ||
103 | { | ||
104 | __be32 *p = xdr_inline_decode(xdr, 32 + 4 + 4); | ||
105 | int ret; | ||
106 | |||
107 | if (!p) | ||
108 | return -EIO; | ||
109 | |||
110 | p = _osd_xdr_decode_objid(p, &comp->oc_object_id); | ||
111 | comp->oc_osd_version = be32_to_cpup(p++); | ||
112 | comp->oc_cap_key_sec = be32_to_cpup(p); | ||
113 | |||
114 | ret = _osd_xdr_decode_opaque_cred(&comp->oc_cap_key, xdr); | ||
115 | if (unlikely(ret)) | ||
116 | return ret; | ||
117 | |||
118 | ret = _osd_xdr_decode_opaque_cred(&comp->oc_cap, xdr); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * struct pnfs_osd_data_map { | ||
124 | * u32 odm_num_comps; | ||
125 | * u64 odm_stripe_unit; | ||
126 | * u32 odm_group_width; | ||
127 | * u32 odm_group_depth; | ||
128 | * u32 odm_mirror_cnt; | ||
129 | * u32 odm_raid_algorithm; | ||
130 | * }; // xdr size 4 + 8 + 4 + 4 + 4 + 4 | ||
131 | */ | ||
132 | static inline int | ||
133 | _osd_data_map_xdr_sz(void) | ||
134 | { | ||
135 | return 4 + 8 + 4 + 4 + 4 + 4; | ||
136 | } | ||
137 | |||
138 | static __be32 * | ||
139 | _osd_xdr_decode_data_map(__be32 *p, struct pnfs_osd_data_map *data_map) | ||
140 | { | ||
141 | data_map->odm_num_comps = be32_to_cpup(p++); | ||
142 | p = xdr_decode_hyper(p, &data_map->odm_stripe_unit); | ||
143 | data_map->odm_group_width = be32_to_cpup(p++); | ||
144 | data_map->odm_group_depth = be32_to_cpup(p++); | ||
145 | data_map->odm_mirror_cnt = be32_to_cpup(p++); | ||
146 | data_map->odm_raid_algorithm = be32_to_cpup(p++); | ||
147 | dprintk("%s: odm_num_comps=%u odm_stripe_unit=%llu odm_group_width=%u " | ||
148 | "odm_group_depth=%u odm_mirror_cnt=%u odm_raid_algorithm=%u\n", | ||
149 | __func__, | ||
150 | data_map->odm_num_comps, | ||
151 | (unsigned long long)data_map->odm_stripe_unit, | ||
152 | data_map->odm_group_width, | ||
153 | data_map->odm_group_depth, | ||
154 | data_map->odm_mirror_cnt, | ||
155 | data_map->odm_raid_algorithm); | ||
156 | return p; | ||
157 | } | ||
158 | |||
159 | int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, | ||
160 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr) | ||
161 | { | ||
162 | __be32 *p; | ||
163 | |||
164 | memset(iter, 0, sizeof(*iter)); | ||
165 | |||
166 | p = xdr_inline_decode(xdr, _osd_data_map_xdr_sz() + 4 + 4); | ||
167 | if (unlikely(!p)) | ||
168 | return -EINVAL; | ||
169 | |||
170 | p = _osd_xdr_decode_data_map(p, &layout->olo_map); | ||
171 | layout->olo_comps_index = be32_to_cpup(p++); | ||
172 | layout->olo_num_comps = be32_to_cpup(p++); | ||
173 | iter->total_comps = layout->olo_num_comps; | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, | ||
178 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, | ||
179 | int *err) | ||
180 | { | ||
181 | BUG_ON(iter->decoded_comps > iter->total_comps); | ||
182 | if (iter->decoded_comps == iter->total_comps) | ||
183 | return false; | ||
184 | |||
185 | *err = _osd_xdr_decode_object_cred(comp, xdr); | ||
186 | if (unlikely(*err)) { | ||
187 | dprintk("%s: _osd_xdr_decode_object_cred=>%d decoded_comps=%d " | ||
188 | "total_comps=%d\n", __func__, *err, | ||
189 | iter->decoded_comps, iter->total_comps); | ||
190 | return false; /* stop the loop */ | ||
191 | } | ||
192 | dprintk("%s: dev(%llx:%llx) par=0x%llx obj=0x%llx " | ||
193 | "key_len=%u cap_len=%u\n", | ||
194 | __func__, | ||
195 | _DEVID_LO(&comp->oc_object_id.oid_device_id), | ||
196 | _DEVID_HI(&comp->oc_object_id.oid_device_id), | ||
197 | comp->oc_object_id.oid_partition_id, | ||
198 | comp->oc_object_id.oid_object_id, | ||
199 | comp->oc_cap_key.cred_len, comp->oc_cap.cred_len); | ||
200 | |||
201 | iter->decoded_comps++; | ||
202 | return true; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Get Device Information Decoding | ||
207 | * | ||
208 | * Note: since Device Information is currently done synchronously, all | ||
209 | * variable strings fields are left inside the rpc buffer and are only | ||
210 | * pointed to by the pnfs_osd_deviceaddr members. So the read buffer | ||
211 | * should not be freed while the returned information is in use. | ||
212 | */ | ||
213 | /* | ||
214 | *struct nfs4_string { | ||
215 | * unsigned int len; | ||
216 | * char *data; | ||
217 | *}; // size [variable] | ||
218 | * NOTE: Returned string points to inside the XDR buffer | ||
219 | */ | ||
220 | static __be32 * | ||
221 | __read_u8_opaque(__be32 *p, struct nfs4_string *str) | ||
222 | { | ||
223 | str->len = be32_to_cpup(p++); | ||
224 | str->data = (char *)p; | ||
225 | |||
226 | p += XDR_QUADLEN(str->len); | ||
227 | return p; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * struct pnfs_osd_targetid { | ||
232 | * u32 oti_type; | ||
233 | * struct nfs4_string oti_scsi_device_id; | ||
234 | * };// size 4 + [variable] | ||
235 | */ | ||
236 | static __be32 * | ||
237 | __read_targetid(__be32 *p, struct pnfs_osd_targetid* targetid) | ||
238 | { | ||
239 | u32 oti_type; | ||
240 | |||
241 | oti_type = be32_to_cpup(p++); | ||
242 | targetid->oti_type = oti_type; | ||
243 | |||
244 | switch (oti_type) { | ||
245 | case OBJ_TARGET_SCSI_NAME: | ||
246 | case OBJ_TARGET_SCSI_DEVICE_ID: | ||
247 | p = __read_u8_opaque(p, &targetid->oti_scsi_device_id); | ||
248 | } | ||
249 | |||
250 | return p; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * struct pnfs_osd_net_addr { | ||
255 | * struct nfs4_string r_netid; | ||
256 | * struct nfs4_string r_addr; | ||
257 | * }; | ||
258 | */ | ||
259 | static __be32 * | ||
260 | __read_net_addr(__be32 *p, struct pnfs_osd_net_addr* netaddr) | ||
261 | { | ||
262 | p = __read_u8_opaque(p, &netaddr->r_netid); | ||
263 | p = __read_u8_opaque(p, &netaddr->r_addr); | ||
264 | |||
265 | return p; | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * struct pnfs_osd_targetaddr { | ||
270 | * u32 ota_available; | ||
271 | * struct pnfs_osd_net_addr ota_netaddr; | ||
272 | * }; | ||
273 | */ | ||
274 | static __be32 * | ||
275 | __read_targetaddr(__be32 *p, struct pnfs_osd_targetaddr *targetaddr) | ||
276 | { | ||
277 | u32 ota_available; | ||
278 | |||
279 | ota_available = be32_to_cpup(p++); | ||
280 | targetaddr->ota_available = ota_available; | ||
281 | |||
282 | if (ota_available) | ||
283 | p = __read_net_addr(p, &targetaddr->ota_netaddr); | ||
284 | |||
285 | |||
286 | return p; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * struct pnfs_osd_deviceaddr { | ||
291 | * struct pnfs_osd_targetid oda_targetid; | ||
292 | * struct pnfs_osd_targetaddr oda_targetaddr; | ||
293 | * u8 oda_lun[8]; | ||
294 | * struct nfs4_string oda_systemid; | ||
295 | * struct pnfs_osd_object_cred oda_root_obj_cred; | ||
296 | * struct nfs4_string oda_osdname; | ||
297 | * }; | ||
298 | */ | ||
299 | |||
300 | /* We need this version for the pnfs_osd_xdr_decode_deviceaddr which does | ||
301 | * not have an xdr_stream | ||
302 | */ | ||
303 | static __be32 * | ||
304 | __read_opaque_cred(__be32 *p, | ||
305 | struct pnfs_osd_opaque_cred *opaque_cred) | ||
306 | { | ||
307 | opaque_cred->cred_len = be32_to_cpu(*p++); | ||
308 | opaque_cred->cred = p; | ||
309 | return p + XDR_QUADLEN(opaque_cred->cred_len); | ||
310 | } | ||
311 | |||
312 | static __be32 * | ||
313 | __read_object_cred(__be32 *p, struct pnfs_osd_object_cred *comp) | ||
314 | { | ||
315 | p = _osd_xdr_decode_objid(p, &comp->oc_object_id); | ||
316 | comp->oc_osd_version = be32_to_cpup(p++); | ||
317 | comp->oc_cap_key_sec = be32_to_cpup(p++); | ||
318 | |||
319 | p = __read_opaque_cred(p, &comp->oc_cap_key); | ||
320 | p = __read_opaque_cred(p, &comp->oc_cap); | ||
321 | return p; | ||
322 | } | ||
323 | |||
324 | void pnfs_osd_xdr_decode_deviceaddr( | ||
325 | struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p) | ||
326 | { | ||
327 | p = __read_targetid(p, &deviceaddr->oda_targetid); | ||
328 | |||
329 | p = __read_targetaddr(p, &deviceaddr->oda_targetaddr); | ||
330 | |||
331 | p = xdr_decode_opaque_fixed(p, deviceaddr->oda_lun, | ||
332 | sizeof(deviceaddr->oda_lun)); | ||
333 | |||
334 | p = __read_u8_opaque(p, &deviceaddr->oda_systemid); | ||
335 | |||
336 | p = __read_object_cred(p, &deviceaddr->oda_root_obj_cred); | ||
337 | |||
338 | p = __read_u8_opaque(p, &deviceaddr->oda_osdname); | ||
339 | |||
340 | /* libosd likes this terminated in dbg. It's last, so no problems */ | ||
341 | deviceaddr->oda_osdname.data[deviceaddr->oda_osdname.len] = 0; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * struct pnfs_osd_layoutupdate { | ||
346 | * u32 dsu_valid; | ||
347 | * s64 dsu_delta; | ||
348 | * u32 olu_ioerr_flag; | ||
349 | * }; xdr size 4 + 8 + 4 | ||
350 | */ | ||
351 | int | ||
352 | pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, | ||
353 | struct pnfs_osd_layoutupdate *lou) | ||
354 | { | ||
355 | __be32 *p = xdr_reserve_space(xdr, 4 + 8 + 4); | ||
356 | |||
357 | if (!p) | ||
358 | return -E2BIG; | ||
359 | |||
360 | *p++ = cpu_to_be32(lou->dsu_valid); | ||
361 | if (lou->dsu_valid) | ||
362 | p = xdr_encode_hyper(p, lou->dsu_delta); | ||
363 | *p++ = cpu_to_be32(lou->olu_ioerr_flag); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * struct pnfs_osd_objid { | ||
369 | * struct nfs4_deviceid oid_device_id; | ||
370 | * u64 oid_partition_id; | ||
371 | * u64 oid_object_id; | ||
372 | * }; // xdr size 32 bytes | ||
373 | */ | ||
374 | static inline __be32 * | ||
375 | pnfs_osd_xdr_encode_objid(__be32 *p, struct pnfs_osd_objid *object_id) | ||
376 | { | ||
377 | p = xdr_encode_opaque_fixed(p, &object_id->oid_device_id.data, | ||
378 | sizeof(object_id->oid_device_id.data)); | ||
379 | p = xdr_encode_hyper(p, object_id->oid_partition_id); | ||
380 | p = xdr_encode_hyper(p, object_id->oid_object_id); | ||
381 | |||
382 | return p; | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * struct pnfs_osd_ioerr { | ||
387 | * struct pnfs_osd_objid oer_component; | ||
388 | * u64 oer_comp_offset; | ||
389 | * u64 oer_comp_length; | ||
390 | * u32 oer_iswrite; | ||
391 | * u32 oer_errno; | ||
392 | * }; // xdr size 32 + 24 bytes | ||
393 | */ | ||
394 | void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr) | ||
395 | { | ||
396 | p = pnfs_osd_xdr_encode_objid(p, &ioerr->oer_component); | ||
397 | p = xdr_encode_hyper(p, ioerr->oer_comp_offset); | ||
398 | p = xdr_encode_hyper(p, ioerr->oer_comp_length); | ||
399 | *p++ = cpu_to_be32(ioerr->oer_iswrite); | ||
400 | *p = cpu_to_be32(ioerr->oer_errno); | ||
401 | } | ||
402 | |||
403 | __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr) | ||
404 | { | ||
405 | __be32 *p; | ||
406 | |||
407 | p = xdr_reserve_space(xdr, 32 + 24); | ||
408 | if (unlikely(!p)) | ||
409 | dprintk("%s: out of xdr space\n", __func__); | ||
410 | |||
411 | return p; | ||
412 | } | ||
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index c80add6e2213..7913961aff22 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -204,6 +204,21 @@ nfs_wait_on_request(struct nfs_page *req) | |||
204 | TASK_UNINTERRUPTIBLE); | 204 | TASK_UNINTERRUPTIBLE); |
205 | } | 205 | } |
206 | 206 | ||
207 | static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req) | ||
208 | { | ||
209 | /* | ||
210 | * FIXME: ideally we should be able to coalesce all requests | ||
211 | * that are not block boundary aligned, but currently this | ||
212 | * is problematic for the case of bsize < PAGE_CACHE_SIZE, | ||
213 | * since nfs_flush_multi and nfs_pagein_multi assume you | ||
214 | * can have only one struct nfs_page. | ||
215 | */ | ||
216 | if (desc->pg_bsize < PAGE_SIZE) | ||
217 | return 0; | ||
218 | |||
219 | return desc->pg_count + req->wb_bytes <= desc->pg_bsize; | ||
220 | } | ||
221 | |||
207 | /** | 222 | /** |
208 | * nfs_pageio_init - initialise a page io descriptor | 223 | * nfs_pageio_init - initialise a page io descriptor |
209 | * @desc: pointer to descriptor | 224 | * @desc: pointer to descriptor |
@@ -229,6 +244,8 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
229 | desc->pg_ioflags = io_flags; | 244 | desc->pg_ioflags = io_flags; |
230 | desc->pg_error = 0; | 245 | desc->pg_error = 0; |
231 | desc->pg_lseg = NULL; | 246 | desc->pg_lseg = NULL; |
247 | desc->pg_test = nfs_generic_pg_test; | ||
248 | pnfs_pageio_init(desc, inode); | ||
232 | } | 249 | } |
233 | 250 | ||
234 | /** | 251 | /** |
@@ -242,29 +259,23 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
242 | * | 259 | * |
243 | * Return 'true' if this is the case, else return 'false'. | 260 | * Return 'true' if this is the case, else return 'false'. |
244 | */ | 261 | */ |
245 | static int nfs_can_coalesce_requests(struct nfs_page *prev, | 262 | static bool nfs_can_coalesce_requests(struct nfs_page *prev, |
246 | struct nfs_page *req, | 263 | struct nfs_page *req, |
247 | struct nfs_pageio_descriptor *pgio) | 264 | struct nfs_pageio_descriptor *pgio) |
248 | { | 265 | { |
249 | if (req->wb_context->cred != prev->wb_context->cred) | 266 | if (req->wb_context->cred != prev->wb_context->cred) |
250 | return 0; | 267 | return false; |
251 | if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) | 268 | if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) |
252 | return 0; | 269 | return false; |
253 | if (req->wb_context->state != prev->wb_context->state) | 270 | if (req->wb_context->state != prev->wb_context->state) |
254 | return 0; | 271 | return false; |
255 | if (req->wb_index != (prev->wb_index + 1)) | 272 | if (req->wb_index != (prev->wb_index + 1)) |
256 | return 0; | 273 | return false; |
257 | if (req->wb_pgbase != 0) | 274 | if (req->wb_pgbase != 0) |
258 | return 0; | 275 | return false; |
259 | if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) | 276 | if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) |
260 | return 0; | 277 | return false; |
261 | /* | 278 | return pgio->pg_test(pgio, prev, req); |
262 | * Non-whole file layouts need to check that req is inside of | ||
263 | * pgio->pg_lseg. | ||
264 | */ | ||
265 | if (pgio->pg_test && !pgio->pg_test(pgio, prev, req)) | ||
266 | return 0; | ||
267 | return 1; | ||
268 | } | 279 | } |
269 | 280 | ||
270 | /** | 281 | /** |
@@ -278,31 +289,18 @@ static int nfs_can_coalesce_requests(struct nfs_page *prev, | |||
278 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, | 289 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, |
279 | struct nfs_page *req) | 290 | struct nfs_page *req) |
280 | { | 291 | { |
281 | size_t newlen = req->wb_bytes; | ||
282 | |||
283 | if (desc->pg_count != 0) { | 292 | if (desc->pg_count != 0) { |
284 | struct nfs_page *prev; | 293 | struct nfs_page *prev; |
285 | 294 | ||
286 | /* | ||
287 | * FIXME: ideally we should be able to coalesce all requests | ||
288 | * that are not block boundary aligned, but currently this | ||
289 | * is problematic for the case of bsize < PAGE_CACHE_SIZE, | ||
290 | * since nfs_flush_multi and nfs_pagein_multi assume you | ||
291 | * can have only one struct nfs_page. | ||
292 | */ | ||
293 | if (desc->pg_bsize < PAGE_SIZE) | ||
294 | return 0; | ||
295 | newlen += desc->pg_count; | ||
296 | if (newlen > desc->pg_bsize) | ||
297 | return 0; | ||
298 | prev = nfs_list_entry(desc->pg_list.prev); | 295 | prev = nfs_list_entry(desc->pg_list.prev); |
299 | if (!nfs_can_coalesce_requests(prev, req, desc)) | 296 | if (!nfs_can_coalesce_requests(prev, req, desc)) |
300 | return 0; | 297 | return 0; |
301 | } else | 298 | } else { |
302 | desc->pg_base = req->wb_pgbase; | 299 | desc->pg_base = req->wb_pgbase; |
300 | } | ||
303 | nfs_list_remove_request(req); | 301 | nfs_list_remove_request(req); |
304 | nfs_list_add_request(req, &desc->pg_list); | 302 | nfs_list_add_request(req, &desc->pg_list); |
305 | desc->pg_count = newlen; | 303 | desc->pg_count += req->wb_bytes; |
306 | return 1; | 304 | return 1; |
307 | } | 305 | } |
308 | 306 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index f57f5281a520..8c1309d852a6 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -177,13 +177,28 @@ get_layout_hdr(struct pnfs_layout_hdr *lo) | |||
177 | atomic_inc(&lo->plh_refcount); | 177 | atomic_inc(&lo->plh_refcount); |
178 | } | 178 | } |
179 | 179 | ||
180 | static struct pnfs_layout_hdr * | ||
181 | pnfs_alloc_layout_hdr(struct inode *ino, gfp_t gfp_flags) | ||
182 | { | ||
183 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld; | ||
184 | return ld->alloc_layout_hdr ? ld->alloc_layout_hdr(ino, gfp_flags) : | ||
185 | kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags); | ||
186 | } | ||
187 | |||
188 | static void | ||
189 | pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo) | ||
190 | { | ||
191 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld; | ||
192 | return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo); | ||
193 | } | ||
194 | |||
180 | static void | 195 | static void |
181 | destroy_layout_hdr(struct pnfs_layout_hdr *lo) | 196 | destroy_layout_hdr(struct pnfs_layout_hdr *lo) |
182 | { | 197 | { |
183 | dprintk("%s: freeing layout cache %p\n", __func__, lo); | 198 | dprintk("%s: freeing layout cache %p\n", __func__, lo); |
184 | BUG_ON(!list_empty(&lo->plh_layouts)); | 199 | BUG_ON(!list_empty(&lo->plh_layouts)); |
185 | NFS_I(lo->plh_inode)->layout = NULL; | 200 | NFS_I(lo->plh_inode)->layout = NULL; |
186 | kfree(lo); | 201 | pnfs_free_layout_hdr(lo); |
187 | } | 202 | } |
188 | 203 | ||
189 | static void | 204 | static void |
@@ -228,7 +243,7 @@ put_lseg_common(struct pnfs_layout_segment *lseg) | |||
228 | { | 243 | { |
229 | struct inode *inode = lseg->pls_layout->plh_inode; | 244 | struct inode *inode = lseg->pls_layout->plh_inode; |
230 | 245 | ||
231 | BUG_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); | 246 | WARN_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); |
232 | list_del_init(&lseg->pls_list); | 247 | list_del_init(&lseg->pls_list); |
233 | if (list_empty(&lseg->pls_layout->plh_segs)) { | 248 | if (list_empty(&lseg->pls_layout->plh_segs)) { |
234 | set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags); | 249 | set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags); |
@@ -261,11 +276,72 @@ put_lseg(struct pnfs_layout_segment *lseg) | |||
261 | } | 276 | } |
262 | EXPORT_SYMBOL_GPL(put_lseg); | 277 | EXPORT_SYMBOL_GPL(put_lseg); |
263 | 278 | ||
279 | static inline u64 | ||
280 | end_offset(u64 start, u64 len) | ||
281 | { | ||
282 | u64 end; | ||
283 | |||
284 | end = start + len; | ||
285 | return end >= start ? end : NFS4_MAX_UINT64; | ||
286 | } | ||
287 | |||
288 | /* last octet in a range */ | ||
289 | static inline u64 | ||
290 | last_byte_offset(u64 start, u64 len) | ||
291 | { | ||
292 | u64 end; | ||
293 | |||
294 | BUG_ON(!len); | ||
295 | end = start + len; | ||
296 | return end > start ? end - 1 : NFS4_MAX_UINT64; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * is l2 fully contained in l1? | ||
301 | * start1 end1 | ||
302 | * [----------------------------------) | ||
303 | * start2 end2 | ||
304 | * [----------------) | ||
305 | */ | ||
306 | static inline int | ||
307 | lo_seg_contained(struct pnfs_layout_range *l1, | ||
308 | struct pnfs_layout_range *l2) | ||
309 | { | ||
310 | u64 start1 = l1->offset; | ||
311 | u64 end1 = end_offset(start1, l1->length); | ||
312 | u64 start2 = l2->offset; | ||
313 | u64 end2 = end_offset(start2, l2->length); | ||
314 | |||
315 | return (start1 <= start2) && (end1 >= end2); | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * is l1 and l2 intersecting? | ||
320 | * start1 end1 | ||
321 | * [----------------------------------) | ||
322 | * start2 end2 | ||
323 | * [----------------) | ||
324 | */ | ||
325 | static inline int | ||
326 | lo_seg_intersecting(struct pnfs_layout_range *l1, | ||
327 | struct pnfs_layout_range *l2) | ||
328 | { | ||
329 | u64 start1 = l1->offset; | ||
330 | u64 end1 = end_offset(start1, l1->length); | ||
331 | u64 start2 = l2->offset; | ||
332 | u64 end2 = end_offset(start2, l2->length); | ||
333 | |||
334 | return (end1 == NFS4_MAX_UINT64 || end1 > start2) && | ||
335 | (end2 == NFS4_MAX_UINT64 || end2 > start1); | ||
336 | } | ||
337 | |||
264 | static bool | 338 | static bool |
265 | should_free_lseg(u32 lseg_iomode, u32 recall_iomode) | 339 | should_free_lseg(struct pnfs_layout_range *lseg_range, |
340 | struct pnfs_layout_range *recall_range) | ||
266 | { | 341 | { |
267 | return (recall_iomode == IOMODE_ANY || | 342 | return (recall_range->iomode == IOMODE_ANY || |
268 | lseg_iomode == recall_iomode); | 343 | lseg_range->iomode == recall_range->iomode) && |
344 | lo_seg_intersecting(lseg_range, recall_range); | ||
269 | } | 345 | } |
270 | 346 | ||
271 | /* Returns 1 if lseg is removed from list, 0 otherwise */ | 347 | /* Returns 1 if lseg is removed from list, 0 otherwise */ |
@@ -296,7 +372,7 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg, | |||
296 | int | 372 | int |
297 | mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | 373 | mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, |
298 | struct list_head *tmp_list, | 374 | struct list_head *tmp_list, |
299 | u32 iomode) | 375 | struct pnfs_layout_range *recall_range) |
300 | { | 376 | { |
301 | struct pnfs_layout_segment *lseg, *next; | 377 | struct pnfs_layout_segment *lseg, *next; |
302 | int invalid = 0, removed = 0; | 378 | int invalid = 0, removed = 0; |
@@ -309,7 +385,8 @@ mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | |||
309 | return 0; | 385 | return 0; |
310 | } | 386 | } |
311 | list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) | 387 | list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) |
312 | if (should_free_lseg(lseg->pls_range.iomode, iomode)) { | 388 | if (!recall_range || |
389 | should_free_lseg(&lseg->pls_range, recall_range)) { | ||
313 | dprintk("%s: freeing lseg %p iomode %d " | 390 | dprintk("%s: freeing lseg %p iomode %d " |
314 | "offset %llu length %llu\n", __func__, | 391 | "offset %llu length %llu\n", __func__, |
315 | lseg, lseg->pls_range.iomode, lseg->pls_range.offset, | 392 | lseg, lseg->pls_range.iomode, lseg->pls_range.offset, |
@@ -358,7 +435,7 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) | |||
358 | lo = nfsi->layout; | 435 | lo = nfsi->layout; |
359 | if (lo) { | 436 | if (lo) { |
360 | lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ | 437 | lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ |
361 | mark_matching_lsegs_invalid(lo, &tmp_list, IOMODE_ANY); | 438 | mark_matching_lsegs_invalid(lo, &tmp_list, NULL); |
362 | } | 439 | } |
363 | spin_unlock(&nfsi->vfs_inode.i_lock); | 440 | spin_unlock(&nfsi->vfs_inode.i_lock); |
364 | pnfs_free_lseg_list(&tmp_list); | 441 | pnfs_free_lseg_list(&tmp_list); |
@@ -467,7 +544,7 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, | |||
467 | static struct pnfs_layout_segment * | 544 | static struct pnfs_layout_segment * |
468 | send_layoutget(struct pnfs_layout_hdr *lo, | 545 | send_layoutget(struct pnfs_layout_hdr *lo, |
469 | struct nfs_open_context *ctx, | 546 | struct nfs_open_context *ctx, |
470 | u32 iomode, | 547 | struct pnfs_layout_range *range, |
471 | gfp_t gfp_flags) | 548 | gfp_t gfp_flags) |
472 | { | 549 | { |
473 | struct inode *ino = lo->plh_inode; | 550 | struct inode *ino = lo->plh_inode; |
@@ -499,11 +576,11 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
499 | goto out_err_free; | 576 | goto out_err_free; |
500 | } | 577 | } |
501 | 578 | ||
502 | lgp->args.minlength = NFS4_MAX_UINT64; | 579 | lgp->args.minlength = PAGE_CACHE_SIZE; |
580 | if (lgp->args.minlength > range->length) | ||
581 | lgp->args.minlength = range->length; | ||
503 | lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; | 582 | lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; |
504 | lgp->args.range.iomode = iomode; | 583 | lgp->args.range = *range; |
505 | lgp->args.range.offset = 0; | ||
506 | lgp->args.range.length = NFS4_MAX_UINT64; | ||
507 | lgp->args.type = server->pnfs_curr_ld->id; | 584 | lgp->args.type = server->pnfs_curr_ld->id; |
508 | lgp->args.inode = ino; | 585 | lgp->args.inode = ino; |
509 | lgp->args.ctx = get_nfs_open_context(ctx); | 586 | lgp->args.ctx = get_nfs_open_context(ctx); |
@@ -518,7 +595,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
518 | nfs4_proc_layoutget(lgp); | 595 | nfs4_proc_layoutget(lgp); |
519 | if (!lseg) { | 596 | if (!lseg) { |
520 | /* remember that LAYOUTGET failed and suspend trying */ | 597 | /* remember that LAYOUTGET failed and suspend trying */ |
521 | set_bit(lo_fail_bit(iomode), &lo->plh_flags); | 598 | set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); |
522 | } | 599 | } |
523 | 600 | ||
524 | /* free xdr pages */ | 601 | /* free xdr pages */ |
@@ -542,6 +619,51 @@ out_err_free: | |||
542 | return NULL; | 619 | return NULL; |
543 | } | 620 | } |
544 | 621 | ||
622 | /* Initiates a LAYOUTRETURN(FILE) */ | ||
623 | int | ||
624 | _pnfs_return_layout(struct inode *ino) | ||
625 | { | ||
626 | struct pnfs_layout_hdr *lo = NULL; | ||
627 | struct nfs_inode *nfsi = NFS_I(ino); | ||
628 | LIST_HEAD(tmp_list); | ||
629 | struct nfs4_layoutreturn *lrp; | ||
630 | nfs4_stateid stateid; | ||
631 | int status = 0; | ||
632 | |||
633 | dprintk("--> %s\n", __func__); | ||
634 | |||
635 | spin_lock(&ino->i_lock); | ||
636 | lo = nfsi->layout; | ||
637 | if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) { | ||
638 | spin_unlock(&ino->i_lock); | ||
639 | dprintk("%s: no layout segments to return\n", __func__); | ||
640 | goto out; | ||
641 | } | ||
642 | stateid = nfsi->layout->plh_stateid; | ||
643 | /* Reference matched in nfs4_layoutreturn_release */ | ||
644 | get_layout_hdr(lo); | ||
645 | spin_unlock(&ino->i_lock); | ||
646 | pnfs_free_lseg_list(&tmp_list); | ||
647 | |||
648 | WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)); | ||
649 | |||
650 | lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); | ||
651 | if (unlikely(lrp == NULL)) { | ||
652 | status = -ENOMEM; | ||
653 | goto out; | ||
654 | } | ||
655 | |||
656 | lrp->args.stateid = stateid; | ||
657 | lrp->args.layout_type = NFS_SERVER(ino)->pnfs_curr_ld->id; | ||
658 | lrp->args.inode = ino; | ||
659 | lrp->clp = NFS_SERVER(ino)->nfs_client; | ||
660 | |||
661 | status = nfs4_proc_layoutreturn(lrp); | ||
662 | out: | ||
663 | dprintk("<-- %s status: %d\n", __func__, status); | ||
664 | return status; | ||
665 | } | ||
666 | |||
545 | bool pnfs_roc(struct inode *ino) | 667 | bool pnfs_roc(struct inode *ino) |
546 | { | 668 | { |
547 | struct pnfs_layout_hdr *lo; | 669 | struct pnfs_layout_hdr *lo; |
@@ -625,10 +747,23 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier) | |||
625 | * are seen first. | 747 | * are seen first. |
626 | */ | 748 | */ |
627 | static s64 | 749 | static s64 |
628 | cmp_layout(u32 iomode1, u32 iomode2) | 750 | cmp_layout(struct pnfs_layout_range *l1, |
751 | struct pnfs_layout_range *l2) | ||
629 | { | 752 | { |
753 | s64 d; | ||
754 | |||
755 | /* high offset > low offset */ | ||
756 | d = l1->offset - l2->offset; | ||
757 | if (d) | ||
758 | return d; | ||
759 | |||
760 | /* short length > long length */ | ||
761 | d = l2->length - l1->length; | ||
762 | if (d) | ||
763 | return d; | ||
764 | |||
630 | /* read > read/write */ | 765 | /* read > read/write */ |
631 | return (int)(iomode2 == IOMODE_READ) - (int)(iomode1 == IOMODE_READ); | 766 | return (int)(l1->iomode == IOMODE_READ) - (int)(l2->iomode == IOMODE_READ); |
632 | } | 767 | } |
633 | 768 | ||
634 | static void | 769 | static void |
@@ -636,13 +771,12 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, | |||
636 | struct pnfs_layout_segment *lseg) | 771 | struct pnfs_layout_segment *lseg) |
637 | { | 772 | { |
638 | struct pnfs_layout_segment *lp; | 773 | struct pnfs_layout_segment *lp; |
639 | int found = 0; | ||
640 | 774 | ||
641 | dprintk("%s:Begin\n", __func__); | 775 | dprintk("%s:Begin\n", __func__); |
642 | 776 | ||
643 | assert_spin_locked(&lo->plh_inode->i_lock); | 777 | assert_spin_locked(&lo->plh_inode->i_lock); |
644 | list_for_each_entry(lp, &lo->plh_segs, pls_list) { | 778 | list_for_each_entry(lp, &lo->plh_segs, pls_list) { |
645 | if (cmp_layout(lp->pls_range.iomode, lseg->pls_range.iomode) > 0) | 779 | if (cmp_layout(&lseg->pls_range, &lp->pls_range) > 0) |
646 | continue; | 780 | continue; |
647 | list_add_tail(&lseg->pls_list, &lp->pls_list); | 781 | list_add_tail(&lseg->pls_list, &lp->pls_list); |
648 | dprintk("%s: inserted lseg %p " | 782 | dprintk("%s: inserted lseg %p " |
@@ -652,16 +786,14 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, | |||
652 | lseg->pls_range.offset, lseg->pls_range.length, | 786 | lseg->pls_range.offset, lseg->pls_range.length, |
653 | lp, lp->pls_range.iomode, lp->pls_range.offset, | 787 | lp, lp->pls_range.iomode, lp->pls_range.offset, |
654 | lp->pls_range.length); | 788 | lp->pls_range.length); |
655 | found = 1; | 789 | goto out; |
656 | break; | ||
657 | } | ||
658 | if (!found) { | ||
659 | list_add_tail(&lseg->pls_list, &lo->plh_segs); | ||
660 | dprintk("%s: inserted lseg %p " | ||
661 | "iomode %d offset %llu length %llu at tail\n", | ||
662 | __func__, lseg, lseg->pls_range.iomode, | ||
663 | lseg->pls_range.offset, lseg->pls_range.length); | ||
664 | } | 790 | } |
791 | list_add_tail(&lseg->pls_list, &lo->plh_segs); | ||
792 | dprintk("%s: inserted lseg %p " | ||
793 | "iomode %d offset %llu length %llu at tail\n", | ||
794 | __func__, lseg, lseg->pls_range.iomode, | ||
795 | lseg->pls_range.offset, lseg->pls_range.length); | ||
796 | out: | ||
665 | get_layout_hdr(lo); | 797 | get_layout_hdr(lo); |
666 | 798 | ||
667 | dprintk("%s:Return\n", __func__); | 799 | dprintk("%s:Return\n", __func__); |
@@ -672,7 +804,7 @@ alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) | |||
672 | { | 804 | { |
673 | struct pnfs_layout_hdr *lo; | 805 | struct pnfs_layout_hdr *lo; |
674 | 806 | ||
675 | lo = kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags); | 807 | lo = pnfs_alloc_layout_hdr(ino, gfp_flags); |
676 | if (!lo) | 808 | if (!lo) |
677 | return NULL; | 809 | return NULL; |
678 | atomic_set(&lo->plh_refcount, 1); | 810 | atomic_set(&lo->plh_refcount, 1); |
@@ -705,7 +837,7 @@ pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) | |||
705 | if (likely(nfsi->layout == NULL)) /* Won the race? */ | 837 | if (likely(nfsi->layout == NULL)) /* Won the race? */ |
706 | nfsi->layout = new; | 838 | nfsi->layout = new; |
707 | else | 839 | else |
708 | kfree(new); | 840 | pnfs_free_layout_hdr(new); |
709 | return nfsi->layout; | 841 | return nfsi->layout; |
710 | } | 842 | } |
711 | 843 | ||
@@ -721,16 +853,28 @@ pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) | |||
721 | * READ RW true | 853 | * READ RW true |
722 | */ | 854 | */ |
723 | static int | 855 | static int |
724 | is_matching_lseg(struct pnfs_layout_segment *lseg, u32 iomode) | 856 | is_matching_lseg(struct pnfs_layout_range *ls_range, |
857 | struct pnfs_layout_range *range) | ||
725 | { | 858 | { |
726 | return (iomode != IOMODE_RW || lseg->pls_range.iomode == IOMODE_RW); | 859 | struct pnfs_layout_range range1; |
860 | |||
861 | if ((range->iomode == IOMODE_RW && | ||
862 | ls_range->iomode != IOMODE_RW) || | ||
863 | !lo_seg_intersecting(ls_range, range)) | ||
864 | return 0; | ||
865 | |||
866 | /* range1 covers only the first byte in the range */ | ||
867 | range1 = *range; | ||
868 | range1.length = 1; | ||
869 | return lo_seg_contained(ls_range, &range1); | ||
727 | } | 870 | } |
728 | 871 | ||
729 | /* | 872 | /* |
730 | * lookup range in layout | 873 | * lookup range in layout |
731 | */ | 874 | */ |
732 | static struct pnfs_layout_segment * | 875 | static struct pnfs_layout_segment * |
733 | pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) | 876 | pnfs_find_lseg(struct pnfs_layout_hdr *lo, |
877 | struct pnfs_layout_range *range) | ||
734 | { | 878 | { |
735 | struct pnfs_layout_segment *lseg, *ret = NULL; | 879 | struct pnfs_layout_segment *lseg, *ret = NULL; |
736 | 880 | ||
@@ -739,11 +883,11 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) | |||
739 | assert_spin_locked(&lo->plh_inode->i_lock); | 883 | assert_spin_locked(&lo->plh_inode->i_lock); |
740 | list_for_each_entry(lseg, &lo->plh_segs, pls_list) { | 884 | list_for_each_entry(lseg, &lo->plh_segs, pls_list) { |
741 | if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && | 885 | if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && |
742 | is_matching_lseg(lseg, iomode)) { | 886 | is_matching_lseg(&lseg->pls_range, range)) { |
743 | ret = get_lseg(lseg); | 887 | ret = get_lseg(lseg); |
744 | break; | 888 | break; |
745 | } | 889 | } |
746 | if (cmp_layout(iomode, lseg->pls_range.iomode) > 0) | 890 | if (cmp_layout(range, &lseg->pls_range) > 0) |
747 | break; | 891 | break; |
748 | } | 892 | } |
749 | 893 | ||
@@ -759,9 +903,17 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) | |||
759 | struct pnfs_layout_segment * | 903 | struct pnfs_layout_segment * |
760 | pnfs_update_layout(struct inode *ino, | 904 | pnfs_update_layout(struct inode *ino, |
761 | struct nfs_open_context *ctx, | 905 | struct nfs_open_context *ctx, |
906 | loff_t pos, | ||
907 | u64 count, | ||
762 | enum pnfs_iomode iomode, | 908 | enum pnfs_iomode iomode, |
763 | gfp_t gfp_flags) | 909 | gfp_t gfp_flags) |
764 | { | 910 | { |
911 | struct pnfs_layout_range arg = { | ||
912 | .iomode = iomode, | ||
913 | .offset = pos, | ||
914 | .length = count, | ||
915 | }; | ||
916 | unsigned pg_offset; | ||
765 | struct nfs_inode *nfsi = NFS_I(ino); | 917 | struct nfs_inode *nfsi = NFS_I(ino); |
766 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; | 918 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; |
767 | struct pnfs_layout_hdr *lo; | 919 | struct pnfs_layout_hdr *lo; |
@@ -789,7 +941,7 @@ pnfs_update_layout(struct inode *ino, | |||
789 | goto out_unlock; | 941 | goto out_unlock; |
790 | 942 | ||
791 | /* Check to see if the layout for the given range already exists */ | 943 | /* Check to see if the layout for the given range already exists */ |
792 | lseg = pnfs_find_lseg(lo, iomode); | 944 | lseg = pnfs_find_lseg(lo, &arg); |
793 | if (lseg) | 945 | if (lseg) |
794 | goto out_unlock; | 946 | goto out_unlock; |
795 | 947 | ||
@@ -811,7 +963,14 @@ pnfs_update_layout(struct inode *ino, | |||
811 | spin_unlock(&clp->cl_lock); | 963 | spin_unlock(&clp->cl_lock); |
812 | } | 964 | } |
813 | 965 | ||
814 | lseg = send_layoutget(lo, ctx, iomode, gfp_flags); | 966 | pg_offset = arg.offset & ~PAGE_CACHE_MASK; |
967 | if (pg_offset) { | ||
968 | arg.offset -= pg_offset; | ||
969 | arg.length += pg_offset; | ||
970 | } | ||
971 | arg.length = PAGE_CACHE_ALIGN(arg.length); | ||
972 | |||
973 | lseg = send_layoutget(lo, ctx, &arg, gfp_flags); | ||
815 | if (!lseg && first) { | 974 | if (!lseg && first) { |
816 | spin_lock(&clp->cl_lock); | 975 | spin_lock(&clp->cl_lock); |
817 | list_del_init(&lo->plh_layouts); | 976 | list_del_init(&lo->plh_layouts); |
@@ -838,17 +997,6 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) | |||
838 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; | 997 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; |
839 | int status = 0; | 998 | int status = 0; |
840 | 999 | ||
841 | /* Verify we got what we asked for. | ||
842 | * Note that because the xdr parsing only accepts a single | ||
843 | * element array, this can fail even if the server is behaving | ||
844 | * correctly. | ||
845 | */ | ||
846 | if (lgp->args.range.iomode > res->range.iomode || | ||
847 | res->range.offset != 0 || | ||
848 | res->range.length != NFS4_MAX_UINT64) { | ||
849 | status = -EINVAL; | ||
850 | goto out; | ||
851 | } | ||
852 | /* Inject layout blob into I/O device driver */ | 1000 | /* Inject layout blob into I/O device driver */ |
853 | lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); | 1001 | lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); |
854 | if (!lseg || IS_ERR(lseg)) { | 1002 | if (!lseg || IS_ERR(lseg)) { |
@@ -895,51 +1043,64 @@ out_forget_reply: | |||
895 | goto out; | 1043 | goto out; |
896 | } | 1044 | } |
897 | 1045 | ||
898 | static int pnfs_read_pg_test(struct nfs_pageio_descriptor *pgio, | 1046 | bool |
899 | struct nfs_page *prev, | 1047 | pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, |
900 | struct nfs_page *req) | 1048 | struct nfs_page *req) |
901 | { | 1049 | { |
1050 | enum pnfs_iomode access_type; | ||
1051 | gfp_t gfp_flags; | ||
1052 | |||
1053 | /* We assume that pg_ioflags == 0 iff we're reading a page */ | ||
1054 | if (pgio->pg_ioflags == 0) { | ||
1055 | access_type = IOMODE_READ; | ||
1056 | gfp_flags = GFP_KERNEL; | ||
1057 | } else { | ||
1058 | access_type = IOMODE_RW; | ||
1059 | gfp_flags = GFP_NOFS; | ||
1060 | } | ||
1061 | |||
902 | if (pgio->pg_count == prev->wb_bytes) { | 1062 | if (pgio->pg_count == prev->wb_bytes) { |
903 | /* This is first coelesce call for a series of nfs_pages */ | 1063 | /* This is first coelesce call for a series of nfs_pages */ |
904 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | 1064 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
905 | prev->wb_context, | 1065 | prev->wb_context, |
906 | IOMODE_READ, | 1066 | req_offset(req), |
907 | GFP_KERNEL); | 1067 | pgio->pg_count, |
1068 | access_type, | ||
1069 | gfp_flags); | ||
1070 | return true; | ||
908 | } | 1071 | } |
909 | return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); | ||
910 | } | ||
911 | 1072 | ||
912 | void | 1073 | if (pgio->pg_lseg && |
913 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode) | 1074 | req_offset(req) > end_offset(pgio->pg_lseg->pls_range.offset, |
914 | { | 1075 | pgio->pg_lseg->pls_range.length)) |
915 | struct pnfs_layoutdriver_type *ld; | 1076 | return false; |
916 | 1077 | ||
917 | ld = NFS_SERVER(inode)->pnfs_curr_ld; | 1078 | return true; |
918 | pgio->pg_test = (ld && ld->pg_test) ? pnfs_read_pg_test : NULL; | ||
919 | } | 1079 | } |
1080 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); | ||
920 | 1081 | ||
921 | static int pnfs_write_pg_test(struct nfs_pageio_descriptor *pgio, | 1082 | /* |
922 | struct nfs_page *prev, | 1083 | * Called by non rpc-based layout drivers |
923 | struct nfs_page *req) | 1084 | */ |
1085 | int | ||
1086 | pnfs_ld_write_done(struct nfs_write_data *data) | ||
924 | { | 1087 | { |
925 | if (pgio->pg_count == prev->wb_bytes) { | 1088 | int status; |
926 | /* This is first coelesce call for a series of nfs_pages */ | ||
927 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | ||
928 | prev->wb_context, | ||
929 | IOMODE_RW, | ||
930 | GFP_NOFS); | ||
931 | } | ||
932 | return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); | ||
933 | } | ||
934 | 1089 | ||
935 | void | 1090 | if (!data->pnfs_error) { |
936 | pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode) | 1091 | pnfs_set_layoutcommit(data); |
937 | { | 1092 | data->mds_ops->rpc_call_done(&data->task, data); |
938 | struct pnfs_layoutdriver_type *ld; | 1093 | data->mds_ops->rpc_release(data); |
1094 | return 0; | ||
1095 | } | ||
939 | 1096 | ||
940 | ld = NFS_SERVER(inode)->pnfs_curr_ld; | 1097 | dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, |
941 | pgio->pg_test = (ld && ld->pg_test) ? pnfs_write_pg_test : NULL; | 1098 | data->pnfs_error); |
1099 | status = nfs_initiate_write(data, NFS_CLIENT(data->inode), | ||
1100 | data->mds_ops, NFS_FILE_SYNC); | ||
1101 | return status ? : -EAGAIN; | ||
942 | } | 1102 | } |
1103 | EXPORT_SYMBOL_GPL(pnfs_ld_write_done); | ||
943 | 1104 | ||
944 | enum pnfs_try_status | 1105 | enum pnfs_try_status |
945 | pnfs_try_to_write_data(struct nfs_write_data *wdata, | 1106 | pnfs_try_to_write_data(struct nfs_write_data *wdata, |
@@ -966,6 +1127,29 @@ pnfs_try_to_write_data(struct nfs_write_data *wdata, | |||
966 | } | 1127 | } |
967 | 1128 | ||
968 | /* | 1129 | /* |
1130 | * Called by non rpc-based layout drivers | ||
1131 | */ | ||
1132 | int | ||
1133 | pnfs_ld_read_done(struct nfs_read_data *data) | ||
1134 | { | ||
1135 | int status; | ||
1136 | |||
1137 | if (!data->pnfs_error) { | ||
1138 | __nfs4_read_done_cb(data); | ||
1139 | data->mds_ops->rpc_call_done(&data->task, data); | ||
1140 | data->mds_ops->rpc_release(data); | ||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, | ||
1145 | data->pnfs_error); | ||
1146 | status = nfs_initiate_read(data, NFS_CLIENT(data->inode), | ||
1147 | data->mds_ops); | ||
1148 | return status ? : -EAGAIN; | ||
1149 | } | ||
1150 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); | ||
1151 | |||
1152 | /* | ||
969 | * Call the appropriate parallel I/O subsystem read function. | 1153 | * Call the appropriate parallel I/O subsystem read function. |
970 | */ | 1154 | */ |
971 | enum pnfs_try_status | 1155 | enum pnfs_try_status |
@@ -1009,7 +1193,7 @@ void | |||
1009 | pnfs_set_layoutcommit(struct nfs_write_data *wdata) | 1193 | pnfs_set_layoutcommit(struct nfs_write_data *wdata) |
1010 | { | 1194 | { |
1011 | struct nfs_inode *nfsi = NFS_I(wdata->inode); | 1195 | struct nfs_inode *nfsi = NFS_I(wdata->inode); |
1012 | loff_t end_pos = wdata->args.offset + wdata->res.count; | 1196 | loff_t end_pos = wdata->mds_offset + wdata->res.count; |
1013 | bool mark_as_dirty = false; | 1197 | bool mark_as_dirty = false; |
1014 | 1198 | ||
1015 | spin_lock(&nfsi->vfs_inode.i_lock); | 1199 | spin_lock(&nfsi->vfs_inode.i_lock); |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 0c015bad9e7a..48d0a8e4d062 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #ifndef FS_NFS_PNFS_H | 30 | #ifndef FS_NFS_PNFS_H |
31 | #define FS_NFS_PNFS_H | 31 | #define FS_NFS_PNFS_H |
32 | 32 | ||
33 | #include <linux/nfs_fs.h> | ||
33 | #include <linux/nfs_page.h> | 34 | #include <linux/nfs_page.h> |
34 | 35 | ||
35 | enum { | 36 | enum { |
@@ -64,17 +65,29 @@ enum { | |||
64 | NFS_LAYOUT_DESTROYED, /* no new use of layout allowed */ | 65 | NFS_LAYOUT_DESTROYED, /* no new use of layout allowed */ |
65 | }; | 66 | }; |
66 | 67 | ||
68 | enum layoutdriver_policy_flags { | ||
69 | /* Should the pNFS client commit and return the layout upon a setattr */ | ||
70 | PNFS_LAYOUTRET_ON_SETATTR = 1 << 0, | ||
71 | }; | ||
72 | |||
73 | struct nfs4_deviceid_node; | ||
74 | |||
67 | /* Per-layout driver specific registration structure */ | 75 | /* Per-layout driver specific registration structure */ |
68 | struct pnfs_layoutdriver_type { | 76 | struct pnfs_layoutdriver_type { |
69 | struct list_head pnfs_tblid; | 77 | struct list_head pnfs_tblid; |
70 | const u32 id; | 78 | const u32 id; |
71 | const char *name; | 79 | const char *name; |
72 | struct module *owner; | 80 | struct module *owner; |
81 | unsigned flags; | ||
82 | |||
83 | struct pnfs_layout_hdr * (*alloc_layout_hdr) (struct inode *inode, gfp_t gfp_flags); | ||
84 | void (*free_layout_hdr) (struct pnfs_layout_hdr *); | ||
85 | |||
73 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); | 86 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); |
74 | void (*free_lseg) (struct pnfs_layout_segment *lseg); | 87 | void (*free_lseg) (struct pnfs_layout_segment *lseg); |
75 | 88 | ||
76 | /* test for nfs page cache coalescing */ | 89 | /* test for nfs page cache coalescing */ |
77 | int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); | 90 | bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); |
78 | 91 | ||
79 | /* Returns true if layoutdriver wants to divert this request to | 92 | /* Returns true if layoutdriver wants to divert this request to |
80 | * driver's commit routine. | 93 | * driver's commit routine. |
@@ -89,6 +102,16 @@ struct pnfs_layoutdriver_type { | |||
89 | */ | 102 | */ |
90 | enum pnfs_try_status (*read_pagelist) (struct nfs_read_data *nfs_data); | 103 | enum pnfs_try_status (*read_pagelist) (struct nfs_read_data *nfs_data); |
91 | enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how); | 104 | enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how); |
105 | |||
106 | void (*free_deviceid_node) (struct nfs4_deviceid_node *); | ||
107 | |||
108 | void (*encode_layoutreturn) (struct pnfs_layout_hdr *layoutid, | ||
109 | struct xdr_stream *xdr, | ||
110 | const struct nfs4_layoutreturn_args *args); | ||
111 | |||
112 | void (*encode_layoutcommit) (struct pnfs_layout_hdr *layoutid, | ||
113 | struct xdr_stream *xdr, | ||
114 | const struct nfs4_layoutcommit_args *args); | ||
92 | }; | 115 | }; |
93 | 116 | ||
94 | struct pnfs_layout_hdr { | 117 | struct pnfs_layout_hdr { |
@@ -120,21 +143,22 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); | |||
120 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, | 143 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, |
121 | struct pnfs_device *dev); | 144 | struct pnfs_device *dev); |
122 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | 145 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); |
146 | extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); | ||
123 | 147 | ||
124 | /* pnfs.c */ | 148 | /* pnfs.c */ |
125 | void get_layout_hdr(struct pnfs_layout_hdr *lo); | 149 | void get_layout_hdr(struct pnfs_layout_hdr *lo); |
126 | void put_lseg(struct pnfs_layout_segment *lseg); | 150 | void put_lseg(struct pnfs_layout_segment *lseg); |
127 | struct pnfs_layout_segment * | 151 | struct pnfs_layout_segment * |
128 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | 152 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, |
129 | enum pnfs_iomode access_type, gfp_t gfp_flags); | 153 | loff_t pos, u64 count, enum pnfs_iomode access_type, |
154 | gfp_t gfp_flags); | ||
130 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); | 155 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); |
131 | void unset_pnfs_layoutdriver(struct nfs_server *); | 156 | void unset_pnfs_layoutdriver(struct nfs_server *); |
132 | enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, | 157 | enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, |
133 | const struct rpc_call_ops *, int); | 158 | const struct rpc_call_ops *, int); |
134 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, | 159 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, |
135 | const struct rpc_call_ops *); | 160 | const struct rpc_call_ops *); |
136 | void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); | 161 | bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); |
137 | void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *); | ||
138 | int pnfs_layout_process(struct nfs4_layoutget *lgp); | 162 | int pnfs_layout_process(struct nfs4_layoutget *lgp); |
139 | void pnfs_free_lseg_list(struct list_head *tmp_list); | 163 | void pnfs_free_lseg_list(struct list_head *tmp_list); |
140 | void pnfs_destroy_layout(struct nfs_inode *); | 164 | void pnfs_destroy_layout(struct nfs_inode *); |
@@ -148,13 +172,37 @@ int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, | |||
148 | struct nfs4_state *open_state); | 172 | struct nfs4_state *open_state); |
149 | int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | 173 | int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, |
150 | struct list_head *tmp_list, | 174 | struct list_head *tmp_list, |
151 | u32 iomode); | 175 | struct pnfs_layout_range *recall_range); |
152 | bool pnfs_roc(struct inode *ino); | 176 | bool pnfs_roc(struct inode *ino); |
153 | void pnfs_roc_release(struct inode *ino); | 177 | void pnfs_roc_release(struct inode *ino); |
154 | void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); | 178 | void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); |
155 | bool pnfs_roc_drain(struct inode *ino, u32 *barrier); | 179 | bool pnfs_roc_drain(struct inode *ino, u32 *barrier); |
156 | void pnfs_set_layoutcommit(struct nfs_write_data *wdata); | 180 | void pnfs_set_layoutcommit(struct nfs_write_data *wdata); |
157 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); | 181 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); |
182 | int _pnfs_return_layout(struct inode *); | ||
183 | int pnfs_ld_write_done(struct nfs_write_data *); | ||
184 | int pnfs_ld_read_done(struct nfs_read_data *); | ||
185 | |||
186 | /* pnfs_dev.c */ | ||
187 | struct nfs4_deviceid_node { | ||
188 | struct hlist_node node; | ||
189 | const struct pnfs_layoutdriver_type *ld; | ||
190 | const struct nfs_client *nfs_client; | ||
191 | struct nfs4_deviceid deviceid; | ||
192 | atomic_t ref; | ||
193 | }; | ||
194 | |||
195 | void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id); | ||
196 | struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); | ||
197 | struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); | ||
198 | void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); | ||
199 | void nfs4_init_deviceid_node(struct nfs4_deviceid_node *, | ||
200 | const struct pnfs_layoutdriver_type *, | ||
201 | const struct nfs_client *, | ||
202 | const struct nfs4_deviceid *); | ||
203 | struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *); | ||
204 | bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *); | ||
205 | void nfs4_deviceid_purge_client(const struct nfs_client *); | ||
158 | 206 | ||
159 | static inline int lo_fail_bit(u32 iomode) | 207 | static inline int lo_fail_bit(u32 iomode) |
160 | { | 208 | { |
@@ -223,6 +271,36 @@ static inline void pnfs_clear_request_commit(struct nfs_page *req) | |||
223 | put_lseg(req->wb_commit_lseg); | 271 | put_lseg(req->wb_commit_lseg); |
224 | } | 272 | } |
225 | 273 | ||
274 | /* Should the pNFS client commit and return the layout upon a setattr */ | ||
275 | static inline bool | ||
276 | pnfs_ld_layoutret_on_setattr(struct inode *inode) | ||
277 | { | ||
278 | if (!pnfs_enabled_sb(NFS_SERVER(inode))) | ||
279 | return false; | ||
280 | return NFS_SERVER(inode)->pnfs_curr_ld->flags & | ||
281 | PNFS_LAYOUTRET_ON_SETATTR; | ||
282 | } | ||
283 | |||
284 | static inline int pnfs_return_layout(struct inode *ino) | ||
285 | { | ||
286 | struct nfs_inode *nfsi = NFS_I(ino); | ||
287 | struct nfs_server *nfss = NFS_SERVER(ino); | ||
288 | |||
289 | if (pnfs_enabled_sb(nfss) && nfsi->layout) | ||
290 | return _pnfs_return_layout(ino); | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio, | ||
296 | struct inode *inode) | ||
297 | { | ||
298 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld; | ||
299 | |||
300 | if (ld) | ||
301 | pgio->pg_test = ld->pg_test; | ||
302 | } | ||
303 | |||
226 | #else /* CONFIG_NFS_V4_1 */ | 304 | #else /* CONFIG_NFS_V4_1 */ |
227 | 305 | ||
228 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) | 306 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) |
@@ -245,7 +323,8 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg) | |||
245 | 323 | ||
246 | static inline struct pnfs_layout_segment * | 324 | static inline struct pnfs_layout_segment * |
247 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | 325 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, |
248 | enum pnfs_iomode access_type, gfp_t gfp_flags) | 326 | loff_t pos, u64 count, enum pnfs_iomode access_type, |
327 | gfp_t gfp_flags) | ||
249 | { | 328 | { |
250 | return NULL; | 329 | return NULL; |
251 | } | 330 | } |
@@ -264,6 +343,17 @@ pnfs_try_to_write_data(struct nfs_write_data *data, | |||
264 | return PNFS_NOT_ATTEMPTED; | 343 | return PNFS_NOT_ATTEMPTED; |
265 | } | 344 | } |
266 | 345 | ||
346 | static inline int pnfs_return_layout(struct inode *ino) | ||
347 | { | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static inline bool | ||
352 | pnfs_ld_layoutret_on_setattr(struct inode *inode) | ||
353 | { | ||
354 | return false; | ||
355 | } | ||
356 | |||
267 | static inline bool | 357 | static inline bool |
268 | pnfs_roc(struct inode *ino) | 358 | pnfs_roc(struct inode *ino) |
269 | { | 359 | { |
@@ -294,16 +384,9 @@ static inline void unset_pnfs_layoutdriver(struct nfs_server *s) | |||
294 | { | 384 | { |
295 | } | 385 | } |
296 | 386 | ||
297 | static inline void | 387 | static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio, |
298 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino) | 388 | struct inode *inode) |
299 | { | ||
300 | pgio->pg_test = NULL; | ||
301 | } | ||
302 | |||
303 | static inline void | ||
304 | pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino) | ||
305 | { | 389 | { |
306 | pgio->pg_test = NULL; | ||
307 | } | 390 | } |
308 | 391 | ||
309 | static inline void | 392 | static inline void |
@@ -331,6 +414,10 @@ static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync) | |||
331 | { | 414 | { |
332 | return 0; | 415 | return 0; |
333 | } | 416 | } |
417 | |||
418 | static inline void nfs4_deviceid_purge_client(struct nfs_client *ncl) | ||
419 | { | ||
420 | } | ||
334 | #endif /* CONFIG_NFS_V4_1 */ | 421 | #endif /* CONFIG_NFS_V4_1 */ |
335 | 422 | ||
336 | #endif /* FS_NFS_PNFS_H */ | 423 | #endif /* FS_NFS_PNFS_H */ |
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c new file mode 100644 index 000000000000..c65e133ce9c0 --- /dev/null +++ b/fs/nfs/pnfs_dev.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Device operations for the pnfs client. | ||
3 | * | ||
4 | * Copyright (c) 2002 | ||
5 | * The Regents of the University of Michigan | ||
6 | * All Rights Reserved | ||
7 | * | ||
8 | * Dean Hildebrand <dhildebz@umich.edu> | ||
9 | * Garth Goodson <Garth.Goodson@netapp.com> | ||
10 | * | ||
11 | * Permission is granted to use, copy, create derivative works, and | ||
12 | * redistribute this software and such derivative works for any purpose, | ||
13 | * so long as the name of the University of Michigan is not used in | ||
14 | * any advertising or publicity pertaining to the use or distribution | ||
15 | * of this software without specific, written prior authorization. If | ||
16 | * the above copyright notice or any other identification of the | ||
17 | * University of Michigan is included in any copy of any portion of | ||
18 | * this software, then the disclaimer below must also be included. | ||
19 | * | ||
20 | * This software is provided as is, without representation or warranty | ||
21 | * of any kind either express or implied, including without limitation | ||
22 | * the implied warranties of merchantability, fitness for a particular | ||
23 | * purpose, or noninfringement. The Regents of the University of | ||
24 | * Michigan shall not be liable for any damages, including special, | ||
25 | * indirect, incidental, or consequential damages, with respect to any | ||
26 | * claim arising out of or in connection with the use of the software, | ||
27 | * even if it has been or is hereafter advised of the possibility of | ||
28 | * such damages. | ||
29 | */ | ||
30 | |||
31 | #include "pnfs.h" | ||
32 | |||
33 | #define NFSDBG_FACILITY NFSDBG_PNFS | ||
34 | |||
35 | /* | ||
36 | * Device ID RCU cache. A device ID is unique per server and layout type. | ||
37 | */ | ||
38 | #define NFS4_DEVICE_ID_HASH_BITS 5 | ||
39 | #define NFS4_DEVICE_ID_HASH_SIZE (1 << NFS4_DEVICE_ID_HASH_BITS) | ||
40 | #define NFS4_DEVICE_ID_HASH_MASK (NFS4_DEVICE_ID_HASH_SIZE - 1) | ||
41 | |||
42 | static struct hlist_head nfs4_deviceid_cache[NFS4_DEVICE_ID_HASH_SIZE]; | ||
43 | static DEFINE_SPINLOCK(nfs4_deviceid_lock); | ||
44 | |||
45 | void | ||
46 | nfs4_print_deviceid(const struct nfs4_deviceid *id) | ||
47 | { | ||
48 | u32 *p = (u32 *)id; | ||
49 | |||
50 | dprintk("%s: device id= [%x%x%x%x]\n", __func__, | ||
51 | p[0], p[1], p[2], p[3]); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(nfs4_print_deviceid); | ||
54 | |||
55 | static inline u32 | ||
56 | nfs4_deviceid_hash(const struct nfs4_deviceid *id) | ||
57 | { | ||
58 | unsigned char *cptr = (unsigned char *)id->data; | ||
59 | unsigned int nbytes = NFS4_DEVICEID4_SIZE; | ||
60 | u32 x = 0; | ||
61 | |||
62 | while (nbytes--) { | ||
63 | x *= 37; | ||
64 | x += *cptr++; | ||
65 | } | ||
66 | return x & NFS4_DEVICE_ID_HASH_MASK; | ||
67 | } | ||
68 | |||
69 | static struct nfs4_deviceid_node * | ||
70 | _lookup_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
71 | const struct nfs_client *clp, const struct nfs4_deviceid *id, | ||
72 | long hash) | ||
73 | { | ||
74 | struct nfs4_deviceid_node *d; | ||
75 | struct hlist_node *n; | ||
76 | |||
77 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) | ||
78 | if (d->ld == ld && d->nfs_client == clp && | ||
79 | !memcmp(&d->deviceid, id, sizeof(*id))) { | ||
80 | if (atomic_read(&d->ref)) | ||
81 | return d; | ||
82 | else | ||
83 | continue; | ||
84 | } | ||
85 | return NULL; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Lookup a deviceid in cache and get a reference count on it if found | ||
90 | * | ||
91 | * @clp nfs_client associated with deviceid | ||
92 | * @id deviceid to look up | ||
93 | */ | ||
94 | struct nfs4_deviceid_node * | ||
95 | _find_get_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
96 | const struct nfs_client *clp, const struct nfs4_deviceid *id, | ||
97 | long hash) | ||
98 | { | ||
99 | struct nfs4_deviceid_node *d; | ||
100 | |||
101 | rcu_read_lock(); | ||
102 | d = _lookup_deviceid(ld, clp, id, hash); | ||
103 | if (d && !atomic_inc_not_zero(&d->ref)) | ||
104 | d = NULL; | ||
105 | rcu_read_unlock(); | ||
106 | return d; | ||
107 | } | ||
108 | |||
109 | struct nfs4_deviceid_node * | ||
110 | nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
111 | const struct nfs_client *clp, const struct nfs4_deviceid *id) | ||
112 | { | ||
113 | return _find_get_deviceid(ld, clp, id, nfs4_deviceid_hash(id)); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid); | ||
116 | |||
117 | /* | ||
118 | * Unhash and put deviceid | ||
119 | * | ||
120 | * @clp nfs_client associated with deviceid | ||
121 | * @id the deviceid to unhash | ||
122 | * | ||
123 | * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise. | ||
124 | */ | ||
125 | struct nfs4_deviceid_node * | ||
126 | nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
127 | const struct nfs_client *clp, const struct nfs4_deviceid *id) | ||
128 | { | ||
129 | struct nfs4_deviceid_node *d; | ||
130 | |||
131 | spin_lock(&nfs4_deviceid_lock); | ||
132 | rcu_read_lock(); | ||
133 | d = _lookup_deviceid(ld, clp, id, nfs4_deviceid_hash(id)); | ||
134 | rcu_read_unlock(); | ||
135 | if (!d) { | ||
136 | spin_unlock(&nfs4_deviceid_lock); | ||
137 | return NULL; | ||
138 | } | ||
139 | hlist_del_init_rcu(&d->node); | ||
140 | spin_unlock(&nfs4_deviceid_lock); | ||
141 | synchronize_rcu(); | ||
142 | |||
143 | /* balance the initial ref set in pnfs_insert_deviceid */ | ||
144 | if (atomic_dec_and_test(&d->ref)) | ||
145 | return d; | ||
146 | |||
147 | return NULL; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid); | ||
150 | |||
151 | /* | ||
152 | * Delete a deviceid from cache | ||
153 | * | ||
154 | * @clp struct nfs_client qualifying the deviceid | ||
155 | * @id deviceid to delete | ||
156 | */ | ||
157 | void | ||
158 | nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
159 | const struct nfs_client *clp, const struct nfs4_deviceid *id) | ||
160 | { | ||
161 | struct nfs4_deviceid_node *d; | ||
162 | |||
163 | d = nfs4_unhash_put_deviceid(ld, clp, id); | ||
164 | if (!d) | ||
165 | return; | ||
166 | d->ld->free_deviceid_node(d); | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(nfs4_delete_deviceid); | ||
169 | |||
170 | void | ||
171 | nfs4_init_deviceid_node(struct nfs4_deviceid_node *d, | ||
172 | const struct pnfs_layoutdriver_type *ld, | ||
173 | const struct nfs_client *nfs_client, | ||
174 | const struct nfs4_deviceid *id) | ||
175 | { | ||
176 | INIT_HLIST_NODE(&d->node); | ||
177 | d->ld = ld; | ||
178 | d->nfs_client = nfs_client; | ||
179 | d->deviceid = *id; | ||
180 | atomic_set(&d->ref, 1); | ||
181 | } | ||
182 | EXPORT_SYMBOL_GPL(nfs4_init_deviceid_node); | ||
183 | |||
184 | /* | ||
185 | * Uniquely initialize and insert a deviceid node into cache | ||
186 | * | ||
187 | * @new new deviceid node | ||
188 | * Note that the caller must set up the following members: | ||
189 | * new->ld | ||
190 | * new->nfs_client | ||
191 | * new->deviceid | ||
192 | * | ||
193 | * @ret the inserted node, if none found, otherwise, the found entry. | ||
194 | */ | ||
195 | struct nfs4_deviceid_node * | ||
196 | nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new) | ||
197 | { | ||
198 | struct nfs4_deviceid_node *d; | ||
199 | long hash; | ||
200 | |||
201 | spin_lock(&nfs4_deviceid_lock); | ||
202 | hash = nfs4_deviceid_hash(&new->deviceid); | ||
203 | d = _find_get_deviceid(new->ld, new->nfs_client, &new->deviceid, hash); | ||
204 | if (d) { | ||
205 | spin_unlock(&nfs4_deviceid_lock); | ||
206 | return d; | ||
207 | } | ||
208 | |||
209 | hlist_add_head_rcu(&new->node, &nfs4_deviceid_cache[hash]); | ||
210 | spin_unlock(&nfs4_deviceid_lock); | ||
211 | |||
212 | return new; | ||
213 | } | ||
214 | EXPORT_SYMBOL_GPL(nfs4_insert_deviceid_node); | ||
215 | |||
216 | /* | ||
217 | * Dereference a deviceid node and delete it when its reference count drops | ||
218 | * to zero. | ||
219 | * | ||
220 | * @d deviceid node to put | ||
221 | * | ||
222 | * @ret true iff the node was deleted | ||
223 | */ | ||
224 | bool | ||
225 | nfs4_put_deviceid_node(struct nfs4_deviceid_node *d) | ||
226 | { | ||
227 | if (!atomic_dec_and_lock(&d->ref, &nfs4_deviceid_lock)) | ||
228 | return false; | ||
229 | hlist_del_init_rcu(&d->node); | ||
230 | spin_unlock(&nfs4_deviceid_lock); | ||
231 | synchronize_rcu(); | ||
232 | d->ld->free_deviceid_node(d); | ||
233 | return true; | ||
234 | } | ||
235 | EXPORT_SYMBOL_GPL(nfs4_put_deviceid_node); | ||
236 | |||
237 | static void | ||
238 | _deviceid_purge_client(const struct nfs_client *clp, long hash) | ||
239 | { | ||
240 | struct nfs4_deviceid_node *d; | ||
241 | struct hlist_node *n, *next; | ||
242 | HLIST_HEAD(tmp); | ||
243 | |||
244 | rcu_read_lock(); | ||
245 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) | ||
246 | if (d->nfs_client == clp && atomic_read(&d->ref)) { | ||
247 | hlist_del_init_rcu(&d->node); | ||
248 | hlist_add_head(&d->node, &tmp); | ||
249 | } | ||
250 | rcu_read_unlock(); | ||
251 | |||
252 | if (hlist_empty(&tmp)) | ||
253 | return; | ||
254 | |||
255 | synchronize_rcu(); | ||
256 | hlist_for_each_entry_safe(d, n, next, &tmp, node) | ||
257 | if (atomic_dec_and_test(&d->ref)) | ||
258 | d->ld->free_deviceid_node(d); | ||
259 | } | ||
260 | |||
261 | void | ||
262 | nfs4_deviceid_purge_client(const struct nfs_client *clp) | ||
263 | { | ||
264 | long h; | ||
265 | |||
266 | spin_lock(&nfs4_deviceid_lock); | ||
267 | for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) | ||
268 | _deviceid_purge_client(clp, h); | ||
269 | spin_unlock(&nfs4_deviceid_lock); | ||
270 | } | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 2bcf0dc306a1..20a7f952e244 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -288,7 +288,9 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
288 | atomic_set(&req->wb_complete, requests); | 288 | atomic_set(&req->wb_complete, requests); |
289 | 289 | ||
290 | BUG_ON(desc->pg_lseg != NULL); | 290 | BUG_ON(desc->pg_lseg != NULL); |
291 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); | 291 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
292 | req_offset(req), desc->pg_count, | ||
293 | IOMODE_READ, GFP_KERNEL); | ||
292 | ClearPageError(page); | 294 | ClearPageError(page); |
293 | offset = 0; | 295 | offset = 0; |
294 | nbytes = desc->pg_count; | 296 | nbytes = desc->pg_count; |
@@ -351,7 +353,9 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) | |||
351 | } | 353 | } |
352 | req = nfs_list_entry(data->pages.next); | 354 | req = nfs_list_entry(data->pages.next); |
353 | if ((!lseg) && list_is_singular(&data->pages)) | 355 | if ((!lseg) && list_is_singular(&data->pages)) |
354 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); | 356 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
357 | req_offset(req), desc->pg_count, | ||
358 | IOMODE_READ, GFP_KERNEL); | ||
355 | 359 | ||
356 | ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, | 360 | ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, |
357 | 0, lseg); | 361 | 0, lseg); |
@@ -660,7 +664,6 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
660 | if (ret == 0) | 664 | if (ret == 0) |
661 | goto read_complete; /* all pages were read */ | 665 | goto read_complete; /* all pages were read */ |
662 | 666 | ||
663 | pnfs_pageio_init_read(&pgio, inode); | ||
664 | if (rsize < PAGE_CACHE_SIZE) | 667 | if (rsize < PAGE_CACHE_SIZE) |
665 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); | 668 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); |
666 | else | 669 | else |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e288f06d3fa7..ce40e5c568ba 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include "iostat.h" | 63 | #include "iostat.h" |
64 | #include "internal.h" | 64 | #include "internal.h" |
65 | #include "fscache.h" | 65 | #include "fscache.h" |
66 | #include "pnfs.h" | ||
66 | 67 | ||
67 | #define NFSDBG_FACILITY NFSDBG_VFS | 68 | #define NFSDBG_FACILITY NFSDBG_VFS |
68 | 69 | ||
@@ -732,6 +733,28 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
732 | 733 | ||
733 | return 0; | 734 | return 0; |
734 | } | 735 | } |
736 | #ifdef CONFIG_NFS_V4_1 | ||
737 | void show_sessions(struct seq_file *m, struct nfs_server *server) | ||
738 | { | ||
739 | if (nfs4_has_session(server->nfs_client)) | ||
740 | seq_printf(m, ",sessions"); | ||
741 | } | ||
742 | #else | ||
743 | void show_sessions(struct seq_file *m, struct nfs_server *server) {} | ||
744 | #endif | ||
745 | |||
746 | #ifdef CONFIG_NFS_V4_1 | ||
747 | void show_pnfs(struct seq_file *m, struct nfs_server *server) | ||
748 | { | ||
749 | seq_printf(m, ",pnfs="); | ||
750 | if (server->pnfs_curr_ld) | ||
751 | seq_printf(m, "%s", server->pnfs_curr_ld->name); | ||
752 | else | ||
753 | seq_printf(m, "not configured"); | ||
754 | } | ||
755 | #else /* CONFIG_NFS_V4_1 */ | ||
756 | void show_pnfs(struct seq_file *m, struct nfs_server *server) {} | ||
757 | #endif /* CONFIG_NFS_V4_1 */ | ||
735 | 758 | ||
736 | static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) | 759 | static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) |
737 | { | 760 | { |
@@ -792,6 +815,8 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | |||
792 | seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); | 815 | seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); |
793 | seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); | 816 | seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); |
794 | seq_printf(m, ",acl=0x%x", nfss->acl_bitmask); | 817 | seq_printf(m, ",acl=0x%x", nfss->acl_bitmask); |
818 | show_sessions(m, nfss); | ||
819 | show_pnfs(m, nfss); | ||
795 | } | 820 | } |
796 | #endif | 821 | #endif |
797 | 822 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 49c715b4ac92..e268e3b23497 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -939,7 +939,9 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) | |||
939 | atomic_set(&req->wb_complete, requests); | 939 | atomic_set(&req->wb_complete, requests); |
940 | 940 | ||
941 | BUG_ON(desc->pg_lseg); | 941 | BUG_ON(desc->pg_lseg); |
942 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); | 942 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
943 | req_offset(req), desc->pg_count, | ||
944 | IOMODE_RW, GFP_NOFS); | ||
943 | ClearPageError(page); | 945 | ClearPageError(page); |
944 | offset = 0; | 946 | offset = 0; |
945 | nbytes = desc->pg_count; | 947 | nbytes = desc->pg_count; |
@@ -1013,7 +1015,9 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc) | |||
1013 | } | 1015 | } |
1014 | req = nfs_list_entry(data->pages.next); | 1016 | req = nfs_list_entry(data->pages.next); |
1015 | if ((!lseg) && list_is_singular(&data->pages)) | 1017 | if ((!lseg) && list_is_singular(&data->pages)) |
1016 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); | 1018 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
1019 | req_offset(req), desc->pg_count, | ||
1020 | IOMODE_RW, GFP_NOFS); | ||
1017 | 1021 | ||
1018 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && | 1022 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && |
1019 | (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) | 1023 | (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) |
@@ -1032,8 +1036,6 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, | |||
1032 | { | 1036 | { |
1033 | size_t wsize = NFS_SERVER(inode)->wsize; | 1037 | size_t wsize = NFS_SERVER(inode)->wsize; |
1034 | 1038 | ||
1035 | pnfs_pageio_init_write(pgio, inode); | ||
1036 | |||
1037 | if (wsize < PAGE_CACHE_SIZE) | 1039 | if (wsize < PAGE_CACHE_SIZE) |
1038 | nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); | 1040 | nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); |
1039 | else | 1041 | else |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index ad000aeb21a2..b9566e46219f 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1354,12 +1354,6 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
1354 | if (IS_ERR(exp)) | 1354 | if (IS_ERR(exp)) |
1355 | return nfserrno(PTR_ERR(exp)); | 1355 | return nfserrno(PTR_ERR(exp)); |
1356 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); | 1356 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); |
1357 | if (rv) | ||
1358 | goto out; | ||
1359 | rv = check_nfsd_access(exp, rqstp); | ||
1360 | if (rv) | ||
1361 | fh_put(fhp); | ||
1362 | out: | ||
1363 | exp_put(exp); | 1357 | exp_put(exp); |
1364 | return rv; | 1358 | return rv; |
1365 | } | 1359 | } |
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 2247fc91d5e9..9095f3c21df9 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
@@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, | |||
245 | } | 245 | } |
246 | 246 | ||
247 | /* Now create the file and set attributes */ | 247 | /* Now create the file and set attributes */ |
248 | nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, | 248 | nfserr = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len, |
249 | attr, newfhp, | 249 | attr, newfhp, |
250 | argp->createmode, argp->verf, NULL, NULL); | 250 | argp->createmode, argp->verf, NULL, NULL); |
251 | 251 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index ad48faca20fc..08c6e36ab2eb 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -842,7 +842,7 @@ out: | |||
842 | return rv; | 842 | return rv; |
843 | } | 843 | } |
844 | 844 | ||
845 | __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) | 845 | static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) |
846 | { | 846 | { |
847 | struct svc_fh fh; | 847 | struct svc_fh fh; |
848 | int err; | 848 | int err; |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5fcb1396a7e3..3a6dbd70b34b 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -196,9 +196,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o | |||
196 | 196 | ||
197 | /* | 197 | /* |
198 | * Note: create modes (UNCHECKED,GUARDED...) are the same | 198 | * Note: create modes (UNCHECKED,GUARDED...) are the same |
199 | * in NFSv4 as in v3. | 199 | * in NFSv4 as in v3 except EXCLUSIVE4_1. |
200 | */ | 200 | */ |
201 | status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, | 201 | status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, |
202 | open->op_fname.len, &open->op_iattr, | 202 | open->op_fname.len, &open->op_iattr, |
203 | &resfh, open->op_createmode, | 203 | &resfh, open->op_createmode, |
204 | (u32 *)open->op_verf.data, | 204 | (u32 *)open->op_verf.data, |
@@ -403,7 +403,7 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
403 | cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; | 403 | cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; |
404 | memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, | 404 | memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, |
405 | putfh->pf_fhlen); | 405 | putfh->pf_fhlen); |
406 | return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); | 406 | return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); |
407 | } | 407 | } |
408 | 408 | ||
409 | static __be32 | 409 | static __be32 |
@@ -762,6 +762,9 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
762 | __be32 err; | 762 | __be32 err; |
763 | 763 | ||
764 | fh_init(&resfh, NFS4_FHSIZE); | 764 | fh_init(&resfh, NFS4_FHSIZE); |
765 | err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC); | ||
766 | if (err) | ||
767 | return err; | ||
765 | err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, | 768 | err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, |
766 | secinfo->si_name, secinfo->si_namelen, | 769 | secinfo->si_name, secinfo->si_namelen, |
767 | &exp, &dentry); | 770 | &exp, &dentry); |
@@ -986,6 +989,9 @@ enum nfsd4_op_flags { | |||
986 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ | 989 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ |
987 | ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ | 990 | ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ |
988 | ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ | 991 | ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ |
992 | /* For rfc 5661 section 2.6.3.1.1: */ | ||
993 | OP_HANDLES_WRONGSEC = 1 << 3, | ||
994 | OP_IS_PUTFH_LIKE = 1 << 4, | ||
989 | }; | 995 | }; |
990 | 996 | ||
991 | struct nfsd4_operation { | 997 | struct nfsd4_operation { |
@@ -1031,6 +1037,44 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) | |||
1031 | return nfs_ok; | 1037 | return nfs_ok; |
1032 | } | 1038 | } |
1033 | 1039 | ||
1040 | static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) | ||
1041 | { | ||
1042 | return &nfsd4_ops[op->opnum]; | ||
1043 | } | ||
1044 | |||
1045 | static bool need_wrongsec_check(struct svc_rqst *rqstp) | ||
1046 | { | ||
1047 | struct nfsd4_compoundres *resp = rqstp->rq_resp; | ||
1048 | struct nfsd4_compoundargs *argp = rqstp->rq_argp; | ||
1049 | struct nfsd4_op *this = &argp->ops[resp->opcnt - 1]; | ||
1050 | struct nfsd4_op *next = &argp->ops[resp->opcnt]; | ||
1051 | struct nfsd4_operation *thisd; | ||
1052 | struct nfsd4_operation *nextd; | ||
1053 | |||
1054 | thisd = OPDESC(this); | ||
1055 | /* | ||
1056 | * Most ops check wronsec on our own; only the putfh-like ops | ||
1057 | * have special rules. | ||
1058 | */ | ||
1059 | if (!(thisd->op_flags & OP_IS_PUTFH_LIKE)) | ||
1060 | return false; | ||
1061 | /* | ||
1062 | * rfc 5661 2.6.3.1.1.6: don't bother erroring out a | ||
1063 | * put-filehandle operation if we're not going to use the | ||
1064 | * result: | ||
1065 | */ | ||
1066 | if (argp->opcnt == resp->opcnt) | ||
1067 | return false; | ||
1068 | |||
1069 | nextd = OPDESC(next); | ||
1070 | /* | ||
1071 | * Rest of 2.6.3.1.1: certain operations will return WRONGSEC | ||
1072 | * errors themselves as necessary; others should check for them | ||
1073 | * now: | ||
1074 | */ | ||
1075 | return !(nextd->op_flags & OP_HANDLES_WRONGSEC); | ||
1076 | } | ||
1077 | |||
1034 | /* | 1078 | /* |
1035 | * COMPOUND call. | 1079 | * COMPOUND call. |
1036 | */ | 1080 | */ |
@@ -1108,7 +1152,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1108 | goto encode_op; | 1152 | goto encode_op; |
1109 | } | 1153 | } |
1110 | 1154 | ||
1111 | opdesc = &nfsd4_ops[op->opnum]; | 1155 | opdesc = OPDESC(op); |
1112 | 1156 | ||
1113 | if (!cstate->current_fh.fh_dentry) { | 1157 | if (!cstate->current_fh.fh_dentry) { |
1114 | if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { | 1158 | if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { |
@@ -1126,6 +1170,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1126 | else | 1170 | else |
1127 | BUG_ON(op->status == nfs_ok); | 1171 | BUG_ON(op->status == nfs_ok); |
1128 | 1172 | ||
1173 | if (!op->status && need_wrongsec_check(rqstp)) | ||
1174 | op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); | ||
1175 | |||
1129 | encode_op: | 1176 | encode_op: |
1130 | /* Only from SEQUENCE */ | 1177 | /* Only from SEQUENCE */ |
1131 | if (resp->cstate.status == nfserr_replay_cache) { | 1178 | if (resp->cstate.status == nfserr_replay_cache) { |
@@ -1217,10 +1264,12 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1217 | }, | 1264 | }, |
1218 | [OP_LOOKUP] = { | 1265 | [OP_LOOKUP] = { |
1219 | .op_func = (nfsd4op_func)nfsd4_lookup, | 1266 | .op_func = (nfsd4op_func)nfsd4_lookup, |
1267 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1220 | .op_name = "OP_LOOKUP", | 1268 | .op_name = "OP_LOOKUP", |
1221 | }, | 1269 | }, |
1222 | [OP_LOOKUPP] = { | 1270 | [OP_LOOKUPP] = { |
1223 | .op_func = (nfsd4op_func)nfsd4_lookupp, | 1271 | .op_func = (nfsd4op_func)nfsd4_lookupp, |
1272 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1224 | .op_name = "OP_LOOKUPP", | 1273 | .op_name = "OP_LOOKUPP", |
1225 | }, | 1274 | }, |
1226 | [OP_NVERIFY] = { | 1275 | [OP_NVERIFY] = { |
@@ -1229,6 +1278,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1229 | }, | 1278 | }, |
1230 | [OP_OPEN] = { | 1279 | [OP_OPEN] = { |
1231 | .op_func = (nfsd4op_func)nfsd4_open, | 1280 | .op_func = (nfsd4op_func)nfsd4_open, |
1281 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1232 | .op_name = "OP_OPEN", | 1282 | .op_name = "OP_OPEN", |
1233 | }, | 1283 | }, |
1234 | [OP_OPEN_CONFIRM] = { | 1284 | [OP_OPEN_CONFIRM] = { |
@@ -1241,17 +1291,20 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1241 | }, | 1291 | }, |
1242 | [OP_PUTFH] = { | 1292 | [OP_PUTFH] = { |
1243 | .op_func = (nfsd4op_func)nfsd4_putfh, | 1293 | .op_func = (nfsd4op_func)nfsd4_putfh, |
1244 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1294 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1295 | | OP_IS_PUTFH_LIKE, | ||
1245 | .op_name = "OP_PUTFH", | 1296 | .op_name = "OP_PUTFH", |
1246 | }, | 1297 | }, |
1247 | [OP_PUTPUBFH] = { | 1298 | [OP_PUTPUBFH] = { |
1248 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1299 | .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1249 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1300 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1301 | | OP_IS_PUTFH_LIKE, | ||
1250 | .op_name = "OP_PUTPUBFH", | 1302 | .op_name = "OP_PUTPUBFH", |
1251 | }, | 1303 | }, |
1252 | [OP_PUTROOTFH] = { | 1304 | [OP_PUTROOTFH] = { |
1253 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1305 | .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1254 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1306 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1307 | | OP_IS_PUTFH_LIKE, | ||
1255 | .op_name = "OP_PUTROOTFH", | 1308 | .op_name = "OP_PUTROOTFH", |
1256 | }, | 1309 | }, |
1257 | [OP_READ] = { | 1310 | [OP_READ] = { |
@@ -1281,15 +1334,18 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1281 | }, | 1334 | }, |
1282 | [OP_RESTOREFH] = { | 1335 | [OP_RESTOREFH] = { |
1283 | .op_func = (nfsd4op_func)nfsd4_restorefh, | 1336 | .op_func = (nfsd4op_func)nfsd4_restorefh, |
1284 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1337 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1338 | | OP_IS_PUTFH_LIKE, | ||
1285 | .op_name = "OP_RESTOREFH", | 1339 | .op_name = "OP_RESTOREFH", |
1286 | }, | 1340 | }, |
1287 | [OP_SAVEFH] = { | 1341 | [OP_SAVEFH] = { |
1288 | .op_func = (nfsd4op_func)nfsd4_savefh, | 1342 | .op_func = (nfsd4op_func)nfsd4_savefh, |
1343 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1289 | .op_name = "OP_SAVEFH", | 1344 | .op_name = "OP_SAVEFH", |
1290 | }, | 1345 | }, |
1291 | [OP_SECINFO] = { | 1346 | [OP_SECINFO] = { |
1292 | .op_func = (nfsd4op_func)nfsd4_secinfo, | 1347 | .op_func = (nfsd4op_func)nfsd4_secinfo, |
1348 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1293 | .op_name = "OP_SECINFO", | 1349 | .op_name = "OP_SECINFO", |
1294 | }, | 1350 | }, |
1295 | [OP_SETATTR] = { | 1351 | [OP_SETATTR] = { |
@@ -1353,6 +1409,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1353 | }, | 1409 | }, |
1354 | [OP_SECINFO_NO_NAME] = { | 1410 | [OP_SECINFO_NO_NAME] = { |
1355 | .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, | 1411 | .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, |
1412 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1356 | .op_name = "OP_SECINFO_NO_NAME", | 1413 | .op_name = "OP_SECINFO_NO_NAME", |
1357 | }, | 1414 | }, |
1358 | }; | 1415 | }; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4cf04e11c66c..e98f3c2e9492 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1519,6 +1519,9 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1519 | bool confirm_me = false; | 1519 | bool confirm_me = false; |
1520 | int status = 0; | 1520 | int status = 0; |
1521 | 1521 | ||
1522 | if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) | ||
1523 | return nfserr_inval; | ||
1524 | |||
1522 | nfs4_lock_state(); | 1525 | nfs4_lock_state(); |
1523 | unconf = find_unconfirmed_client(&cr_ses->clientid); | 1526 | unconf = find_unconfirmed_client(&cr_ses->clientid); |
1524 | conf = find_confirmed_client(&cr_ses->clientid); | 1527 | conf = find_confirmed_client(&cr_ses->clientid); |
@@ -1637,8 +1640,9 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, | |||
1637 | return nfserr_badsession; | 1640 | return nfserr_badsession; |
1638 | 1641 | ||
1639 | status = nfsd4_map_bcts_dir(&bcts->dir); | 1642 | status = nfsd4_map_bcts_dir(&bcts->dir); |
1640 | nfsd4_new_conn(rqstp, cstate->session, bcts->dir); | 1643 | if (!status) |
1641 | return nfs_ok; | 1644 | nfsd4_new_conn(rqstp, cstate->session, bcts->dir); |
1645 | return status; | ||
1642 | } | 1646 | } |
1643 | 1647 | ||
1644 | static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) | 1648 | static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) |
@@ -1725,6 +1729,13 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi | |||
1725 | return; | 1729 | return; |
1726 | } | 1730 | } |
1727 | 1731 | ||
1732 | static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session) | ||
1733 | { | ||
1734 | struct nfsd4_compoundargs *args = rqstp->rq_argp; | ||
1735 | |||
1736 | return args->opcnt > session->se_fchannel.maxops; | ||
1737 | } | ||
1738 | |||
1728 | __be32 | 1739 | __be32 |
1729 | nfsd4_sequence(struct svc_rqst *rqstp, | 1740 | nfsd4_sequence(struct svc_rqst *rqstp, |
1730 | struct nfsd4_compound_state *cstate, | 1741 | struct nfsd4_compound_state *cstate, |
@@ -1753,6 +1764,10 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
1753 | if (!session) | 1764 | if (!session) |
1754 | goto out; | 1765 | goto out; |
1755 | 1766 | ||
1767 | status = nfserr_too_many_ops; | ||
1768 | if (nfsd4_session_too_many_ops(rqstp, session)) | ||
1769 | goto out; | ||
1770 | |||
1756 | status = nfserr_badslot; | 1771 | status = nfserr_badslot; |
1757 | if (seq->slotid >= session->se_fchannel.maxreqs) | 1772 | if (seq->slotid >= session->se_fchannel.maxreqs) |
1758 | goto out; | 1773 | goto out; |
@@ -1808,6 +1823,8 @@ out: | |||
1808 | __be32 | 1823 | __be32 |
1809 | nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) | 1824 | nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) |
1810 | { | 1825 | { |
1826 | int status = 0; | ||
1827 | |||
1811 | if (rc->rca_one_fs) { | 1828 | if (rc->rca_one_fs) { |
1812 | if (!cstate->current_fh.fh_dentry) | 1829 | if (!cstate->current_fh.fh_dentry) |
1813 | return nfserr_nofilehandle; | 1830 | return nfserr_nofilehandle; |
@@ -1817,9 +1834,14 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta | |||
1817 | */ | 1834 | */ |
1818 | return nfs_ok; | 1835 | return nfs_ok; |
1819 | } | 1836 | } |
1837 | |||
1820 | nfs4_lock_state(); | 1838 | nfs4_lock_state(); |
1821 | if (is_client_expired(cstate->session->se_client)) { | 1839 | status = nfserr_complete_already; |
1822 | nfs4_unlock_state(); | 1840 | if (cstate->session->se_client->cl_firststate) |
1841 | goto out; | ||
1842 | |||
1843 | status = nfserr_stale_clientid; | ||
1844 | if (is_client_expired(cstate->session->se_client)) | ||
1823 | /* | 1845 | /* |
1824 | * The following error isn't really legal. | 1846 | * The following error isn't really legal. |
1825 | * But we only get here if the client just explicitly | 1847 | * But we only get here if the client just explicitly |
@@ -1827,11 +1849,13 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta | |||
1827 | * error it gets back on an operation for the dead | 1849 | * error it gets back on an operation for the dead |
1828 | * client. | 1850 | * client. |
1829 | */ | 1851 | */ |
1830 | return nfserr_stale_clientid; | 1852 | goto out; |
1831 | } | 1853 | |
1854 | status = nfs_ok; | ||
1832 | nfsd4_create_clid_dir(cstate->session->se_client); | 1855 | nfsd4_create_clid_dir(cstate->session->se_client); |
1856 | out: | ||
1833 | nfs4_unlock_state(); | 1857 | nfs4_unlock_state(); |
1834 | return nfs_ok; | 1858 | return status; |
1835 | } | 1859 | } |
1836 | 1860 | ||
1837 | __be32 | 1861 | __be32 |
@@ -2462,7 +2486,7 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid) | |||
2462 | return NULL; | 2486 | return NULL; |
2463 | } | 2487 | } |
2464 | 2488 | ||
2465 | int share_access_to_flags(u32 share_access) | 2489 | static int share_access_to_flags(u32 share_access) |
2466 | { | 2490 | { |
2467 | share_access &= ~NFS4_SHARE_WANT_MASK; | 2491 | share_access &= ~NFS4_SHARE_WANT_MASK; |
2468 | 2492 | ||
@@ -2882,7 +2906,7 @@ out: | |||
2882 | return status; | 2906 | return status; |
2883 | } | 2907 | } |
2884 | 2908 | ||
2885 | struct lock_manager nfsd4_manager = { | 2909 | static struct lock_manager nfsd4_manager = { |
2886 | }; | 2910 | }; |
2887 | 2911 | ||
2888 | static void | 2912 | static void |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index c6766af00d98..990181103214 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -424,15 +424,12 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access | |||
424 | static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) | 424 | static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) |
425 | { | 425 | { |
426 | DECODE_HEAD; | 426 | DECODE_HEAD; |
427 | u32 dummy; | ||
428 | 427 | ||
429 | READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); | 428 | READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); |
430 | COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); | 429 | COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); |
431 | READ32(bcts->dir); | 430 | READ32(bcts->dir); |
432 | /* XXX: Perhaps Tom Tucker could help us figure out how we | 431 | /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker |
433 | * should be using ctsa_use_conn_in_rdma_mode: */ | 432 | * could help us figure out we should be using it. */ |
434 | READ32(dummy); | ||
435 | |||
436 | DECODE_TAIL; | 433 | DECODE_TAIL; |
437 | } | 434 | } |
438 | 435 | ||
@@ -588,8 +585,6 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) | |||
588 | READ_BUF(lockt->lt_owner.len); | 585 | READ_BUF(lockt->lt_owner.len); |
589 | READMEM(lockt->lt_owner.data, lockt->lt_owner.len); | 586 | READMEM(lockt->lt_owner.data, lockt->lt_owner.len); |
590 | 587 | ||
591 | if (argp->minorversion && !zero_clientid(&lockt->lt_clientid)) | ||
592 | return nfserr_inval; | ||
593 | DECODE_TAIL; | 588 | DECODE_TAIL; |
594 | } | 589 | } |
595 | 590 | ||
@@ -3120,7 +3115,7 @@ nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, | |||
3120 | return nfserr; | 3115 | return nfserr; |
3121 | } | 3116 | } |
3122 | 3117 | ||
3123 | __be32 | 3118 | static __be32 |
3124 | nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, | 3119 | nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, |
3125 | struct nfsd4_sequence *seq) | 3120 | struct nfsd4_sequence *seq) |
3126 | { | 3121 | { |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 55c8e63af0be..90c6aa6d5e0f 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -344,7 +344,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
344 | * which clients virtually always use auth_sys for, | 344 | * which clients virtually always use auth_sys for, |
345 | * even while using RPCSEC_GSS for NFS. | 345 | * even while using RPCSEC_GSS for NFS. |
346 | */ | 346 | */ |
347 | if (access & NFSD_MAY_LOCK) | 347 | if (access & NFSD_MAY_LOCK || access & NFSD_MAY_BYPASS_GSS) |
348 | goto skip_pseudoflavor_check; | 348 | goto skip_pseudoflavor_check; |
349 | /* | 349 | /* |
350 | * Clients may expect to be able to use auth_sys during mount, | 350 | * Clients may expect to be able to use auth_sys during mount, |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 129f3c9f62d5..d5718273bb32 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -181,16 +181,10 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
181 | struct svc_export *exp; | 181 | struct svc_export *exp; |
182 | struct dentry *dparent; | 182 | struct dentry *dparent; |
183 | struct dentry *dentry; | 183 | struct dentry *dentry; |
184 | __be32 err; | ||
185 | int host_err; | 184 | int host_err; |
186 | 185 | ||
187 | dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); | 186 | dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); |
188 | 187 | ||
189 | /* Obtain dentry and export. */ | ||
190 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); | ||
191 | if (err) | ||
192 | return err; | ||
193 | |||
194 | dparent = fhp->fh_dentry; | 188 | dparent = fhp->fh_dentry; |
195 | exp = fhp->fh_export; | 189 | exp = fhp->fh_export; |
196 | exp_get(exp); | 190 | exp_get(exp); |
@@ -254,6 +248,9 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | |||
254 | struct dentry *dentry; | 248 | struct dentry *dentry; |
255 | __be32 err; | 249 | __be32 err; |
256 | 250 | ||
251 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); | ||
252 | if (err) | ||
253 | return err; | ||
257 | err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry); | 254 | err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry); |
258 | if (err) | 255 | if (err) |
259 | return err; | 256 | return err; |
@@ -877,13 +874,11 @@ static __be32 | |||
877 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 874 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, |
878 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) | 875 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) |
879 | { | 876 | { |
880 | struct inode *inode; | ||
881 | mm_segment_t oldfs; | 877 | mm_segment_t oldfs; |
882 | __be32 err; | 878 | __be32 err; |
883 | int host_err; | 879 | int host_err; |
884 | 880 | ||
885 | err = nfserr_perm; | 881 | err = nfserr_perm; |
886 | inode = file->f_path.dentry->d_inode; | ||
887 | 882 | ||
888 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { | 883 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { |
889 | struct splice_desc sd = { | 884 | struct splice_desc sd = { |
@@ -1340,11 +1335,18 @@ out_nfserr: | |||
1340 | } | 1335 | } |
1341 | 1336 | ||
1342 | #ifdef CONFIG_NFSD_V3 | 1337 | #ifdef CONFIG_NFSD_V3 |
1338 | |||
1339 | static inline int nfsd_create_is_exclusive(int createmode) | ||
1340 | { | ||
1341 | return createmode == NFS3_CREATE_EXCLUSIVE | ||
1342 | || createmode == NFS4_CREATE_EXCLUSIVE4_1; | ||
1343 | } | ||
1344 | |||
1343 | /* | 1345 | /* |
1344 | * NFSv3 version of nfsd_create | 1346 | * NFSv3 and NFSv4 version of nfsd_create |
1345 | */ | 1347 | */ |
1346 | __be32 | 1348 | __be32 |
1347 | nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | 1349 | do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, |
1348 | char *fname, int flen, struct iattr *iap, | 1350 | char *fname, int flen, struct iattr *iap, |
1349 | struct svc_fh *resfhp, int createmode, u32 *verifier, | 1351 | struct svc_fh *resfhp, int createmode, u32 *verifier, |
1350 | int *truncp, int *created) | 1352 | int *truncp, int *created) |
@@ -1396,7 +1398,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1396 | if (err) | 1398 | if (err) |
1397 | goto out; | 1399 | goto out; |
1398 | 1400 | ||
1399 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1401 | if (nfsd_create_is_exclusive(createmode)) { |
1400 | /* solaris7 gets confused (bugid 4218508) if these have | 1402 | /* solaris7 gets confused (bugid 4218508) if these have |
1401 | * the high bit set, so just clear the high bits. If this is | 1403 | * the high bit set, so just clear the high bits. If this is |
1402 | * ever changed to use different attrs for storing the | 1404 | * ever changed to use different attrs for storing the |
@@ -1437,6 +1439,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1437 | && dchild->d_inode->i_atime.tv_sec == v_atime | 1439 | && dchild->d_inode->i_atime.tv_sec == v_atime |
1438 | && dchild->d_inode->i_size == 0 ) | 1440 | && dchild->d_inode->i_size == 0 ) |
1439 | break; | 1441 | break; |
1442 | case NFS4_CREATE_EXCLUSIVE4_1: | ||
1443 | if ( dchild->d_inode->i_mtime.tv_sec == v_mtime | ||
1444 | && dchild->d_inode->i_atime.tv_sec == v_atime | ||
1445 | && dchild->d_inode->i_size == 0 ) | ||
1446 | goto set_attr; | ||
1440 | /* fallthru */ | 1447 | /* fallthru */ |
1441 | case NFS3_CREATE_GUARDED: | 1448 | case NFS3_CREATE_GUARDED: |
1442 | err = nfserr_exist; | 1449 | err = nfserr_exist; |
@@ -1455,7 +1462,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1455 | 1462 | ||
1456 | nfsd_check_ignore_resizing(iap); | 1463 | nfsd_check_ignore_resizing(iap); |
1457 | 1464 | ||
1458 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1465 | if (nfsd_create_is_exclusive(createmode)) { |
1459 | /* Cram the verifier into atime/mtime */ | 1466 | /* Cram the verifier into atime/mtime */ |
1460 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME | 1467 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME |
1461 | | ATTR_MTIME_SET|ATTR_ATIME_SET; | 1468 | | ATTR_MTIME_SET|ATTR_ATIME_SET; |
@@ -2034,7 +2041,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2034 | struct inode *inode = dentry->d_inode; | 2041 | struct inode *inode = dentry->d_inode; |
2035 | int err; | 2042 | int err; |
2036 | 2043 | ||
2037 | if (acc == NFSD_MAY_NOP) | 2044 | if ((acc & NFSD_MAY_MASK) == NFSD_MAY_NOP) |
2038 | return 0; | 2045 | return 0; |
2039 | #if 0 | 2046 | #if 0 |
2040 | dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n", | 2047 | dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n", |
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 9a370a5e36b7..e0bbac04d1dd 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h | |||
@@ -17,10 +17,14 @@ | |||
17 | #define NFSD_MAY_SATTR 8 | 17 | #define NFSD_MAY_SATTR 8 |
18 | #define NFSD_MAY_TRUNC 16 | 18 | #define NFSD_MAY_TRUNC 16 |
19 | #define NFSD_MAY_LOCK 32 | 19 | #define NFSD_MAY_LOCK 32 |
20 | #define NFSD_MAY_MASK 63 | ||
21 | |||
22 | /* extra hints to permission and open routines: */ | ||
20 | #define NFSD_MAY_OWNER_OVERRIDE 64 | 23 | #define NFSD_MAY_OWNER_OVERRIDE 64 |
21 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ | 24 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ |
22 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 | 25 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 |
23 | #define NFSD_MAY_NOT_BREAK_LEASE 512 | 26 | #define NFSD_MAY_NOT_BREAK_LEASE 512 |
27 | #define NFSD_MAY_BYPASS_GSS 1024 | ||
24 | 28 | ||
25 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) | 29 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) |
26 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) | 30 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) |
@@ -54,7 +58,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, | |||
54 | int type, dev_t rdev, struct svc_fh *res); | 58 | int type, dev_t rdev, struct svc_fh *res); |
55 | #ifdef CONFIG_NFSD_V3 | 59 | #ifdef CONFIG_NFSD_V3 |
56 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); | 60 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); |
57 | __be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, | 61 | __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, |
58 | char *name, int len, struct iattr *attrs, | 62 | char *name, int len, struct iattr *attrs, |
59 | struct svc_fh *res, int createmode, | 63 | struct svc_fh *res, int createmode, |
60 | u32 *verifier, int *truncp, int *created); | 64 | u32 *verifier, int *truncp, int *created); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 587f18432832..b954878ad6ce 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -917,7 +917,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
917 | * construction. This function can be called both as a single operation | 917 | * construction. This function can be called both as a single operation |
918 | * and as a part of indivisible file operations. | 918 | * and as a part of indivisible file operations. |
919 | */ | 919 | */ |
920 | void nilfs_dirty_inode(struct inode *inode) | 920 | void nilfs_dirty_inode(struct inode *inode, int flags) |
921 | { | 921 | { |
922 | struct nilfs_transaction_info ti; | 922 | struct nilfs_transaction_info ti; |
923 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | 923 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 1102a5fbb744..546849b3e88f 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -334,8 +334,6 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
334 | struct nilfs_transaction_info ti; | 334 | struct nilfs_transaction_info ti; |
335 | int err; | 335 | int err; |
336 | 336 | ||
337 | dentry_unhash(dentry); | ||
338 | |||
339 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); | 337 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); |
340 | if (err) | 338 | if (err) |
341 | return err; | 339 | return err; |
@@ -371,9 +369,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
371 | struct nilfs_transaction_info ti; | 369 | struct nilfs_transaction_info ti; |
372 | int err; | 370 | int err; |
373 | 371 | ||
374 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
375 | dentry_unhash(new_dentry); | ||
376 | |||
377 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); | 372 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); |
378 | if (unlikely(err)) | 373 | if (unlikely(err)) |
379 | return err; | 374 | return err; |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index a9c6a531f80c..f02b9ad43a21 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -269,7 +269,7 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); | |||
269 | extern int nilfs_inode_dirty(struct inode *); | 269 | extern int nilfs_inode_dirty(struct inode *); |
270 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); | 270 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); |
271 | extern int nilfs_mark_inode_dirty(struct inode *); | 271 | extern int nilfs_mark_inode_dirty(struct inode *); |
272 | extern void nilfs_dirty_inode(struct inode *); | 272 | extern void nilfs_dirty_inode(struct inode *, int flags); |
273 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 273 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
274 | __u64 start, __u64 len); | 274 | __u64 start, __u64 len); |
275 | 275 | ||
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index c368360c35a1..3b8d3979e03b 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c | |||
@@ -241,11 +241,9 @@ static int omfs_remove(struct inode *dir, struct dentry *dentry) | |||
241 | int ret; | 241 | int ret; |
242 | 242 | ||
243 | 243 | ||
244 | if (S_ISDIR(inode->i_mode)) { | 244 | if (S_ISDIR(inode->i_mode) && |
245 | dentry_unhash(dentry); | 245 | !omfs_dir_is_empty(inode)) |
246 | if (!omfs_dir_is_empty(inode)) | 246 | return -ENOTEMPTY; |
247 | return -ENOTEMPTY; | ||
248 | } | ||
249 | 247 | ||
250 | ret = omfs_delete_entry(dentry); | 248 | ret = omfs_delete_entry(dentry); |
251 | if (ret) | 249 | if (ret) |
@@ -382,9 +380,6 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
382 | int err; | 380 | int err; |
383 | 381 | ||
384 | if (new_inode) { | 382 | if (new_inode) { |
385 | if (S_ISDIR(new_inode->i_mode)) | ||
386 | dentry_unhash(new_dentry); | ||
387 | |||
388 | /* overwriting existing file/dir */ | 383 | /* overwriting existing file/dir */ |
389 | err = omfs_remove(new_dir, new_dentry); | 384 | err = omfs_remove(new_dir, new_dentry); |
390 | if (err) | 385 | if (err) |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4ede550517a6..14def991d9dd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -83,6 +83,9 @@ | |||
83 | #include <linux/pid_namespace.h> | 83 | #include <linux/pid_namespace.h> |
84 | #include <linux/fs_struct.h> | 84 | #include <linux/fs_struct.h> |
85 | #include <linux/slab.h> | 85 | #include <linux/slab.h> |
86 | #ifdef CONFIG_HARDWALL | ||
87 | #include <asm/hardwall.h> | ||
88 | #endif | ||
86 | #include "internal.h" | 89 | #include "internal.h" |
87 | 90 | ||
88 | /* NOTE: | 91 | /* NOTE: |
@@ -2842,6 +2845,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2842 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2845 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2843 | INF("io", S_IRUGO, proc_tgid_io_accounting), | 2846 | INF("io", S_IRUGO, proc_tgid_io_accounting), |
2844 | #endif | 2847 | #endif |
2848 | #ifdef CONFIG_HARDWALL | ||
2849 | INF("hardwall", S_IRUGO, proc_pid_hardwall), | ||
2850 | #endif | ||
2845 | }; | 2851 | }; |
2846 | 2852 | ||
2847 | static int proc_tgid_base_readdir(struct file * filp, | 2853 | static int proc_tgid_base_readdir(struct file * filp, |
@@ -3181,6 +3187,9 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3181 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 3187 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
3182 | INF("io", S_IRUGO, proc_tid_io_accounting), | 3188 | INF("io", S_IRUGO, proc_tid_io_accounting), |
3183 | #endif | 3189 | #endif |
3190 | #ifdef CONFIG_HARDWALL | ||
3191 | INF("hardwall", S_IRUGO, proc_pid_hardwall), | ||
3192 | #endif | ||
3184 | }; | 3193 | }; |
3185 | 3194 | ||
3186 | static int proc_tid_base_readdir(struct file * filp, | 3195 | static int proc_tid_base_readdir(struct file * filp, |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 76c8164d5651..118662690cdf 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -831,8 +831,6 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
831 | INITIALIZE_PATH(path); | 831 | INITIALIZE_PATH(path); |
832 | struct reiserfs_dir_entry de; | 832 | struct reiserfs_dir_entry de; |
833 | 833 | ||
834 | dentry_unhash(dentry); | ||
835 | |||
836 | /* we will be doing 2 balancings and update 2 stat data, we change quotas | 834 | /* we will be doing 2 balancings and update 2 stat data, we change quotas |
837 | * of the owner of the directory and of the owner of the parent directory. | 835 | * of the owner of the directory and of the owner of the parent directory. |
838 | * The quota structure is possibly deleted only on last iput => outside | 836 | * The quota structure is possibly deleted only on last iput => outside |
@@ -1227,9 +1225,6 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1227 | unsigned long savelink = 1; | 1225 | unsigned long savelink = 1; |
1228 | struct timespec ctime; | 1226 | struct timespec ctime; |
1229 | 1227 | ||
1230 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
1231 | dentry_unhash(new_dentry); | ||
1232 | |||
1233 | /* three balancings: (1) old name removal, (2) new name insertion | 1228 | /* three balancings: (1) old name removal, (2) new name insertion |
1234 | and (3) maybe "save" link insertion | 1229 | and (3) maybe "save" link insertion |
1235 | stat data updates: (1) old directory, | 1230 | stat data updates: (1) old directory, |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b216ff6be1c9..aa91089162cb 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -568,7 +568,7 @@ static void destroy_inodecache(void) | |||
568 | } | 568 | } |
569 | 569 | ||
570 | /* we don't mark inodes dirty, we just log them */ | 570 | /* we don't mark inodes dirty, we just log them */ |
571 | static void reiserfs_dirty_inode(struct inode *inode) | 571 | static void reiserfs_dirty_inode(struct inode *inode, int flags) |
572 | { | 572 | { |
573 | struct reiserfs_transaction_handle th; | 573 | struct reiserfs_transaction_handle th; |
574 | 574 | ||
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 50f1abccd1cd..e8a62f41b458 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -98,7 +98,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
98 | 98 | ||
99 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, | 99 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
100 | I_MUTEX_CHILD, dir->i_sb); | 100 | I_MUTEX_CHILD, dir->i_sb); |
101 | dentry_unhash(dentry); | ||
102 | error = dir->i_op->rmdir(dir, dentry); | 101 | error = dir->i_op->rmdir(dir, dentry); |
103 | if (!error) | 102 | if (!error) |
104 | dentry->d_inode->i_flags |= S_DEAD; | 103 | dentry->d_inode->i_flags |= S_DEAD; |
diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c index 730c56248c9b..5e1101ff276f 100644 --- a/fs/squashfs/export.c +++ b/fs/squashfs/export.c | |||
@@ -147,7 +147,7 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, | |||
147 | * table[0] points to the first inode lookup table metadata block, | 147 | * table[0] points to the first inode lookup table metadata block, |
148 | * this should be less than lookup_table_start | 148 | * this should be less than lookup_table_start |
149 | */ | 149 | */ |
150 | if (!IS_ERR(table) && table[0] >= lookup_table_start) { | 150 | if (!IS_ERR(table) && le64_to_cpu(table[0]) >= lookup_table_start) { |
151 | kfree(table); | 151 | kfree(table); |
152 | return ERR_PTR(-EINVAL); | 152 | return ERR_PTR(-EINVAL); |
153 | } | 153 | } |
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c index 1516a6490bfb..0ed6edbc5c71 100644 --- a/fs/squashfs/fragment.c +++ b/fs/squashfs/fragment.c | |||
@@ -90,7 +90,7 @@ __le64 *squashfs_read_fragment_index_table(struct super_block *sb, | |||
90 | * table[0] points to the first fragment table metadata block, this | 90 | * table[0] points to the first fragment table metadata block, this |
91 | * should be less than fragment_table_start | 91 | * should be less than fragment_table_start |
92 | */ | 92 | */ |
93 | if (!IS_ERR(table) && table[0] >= fragment_table_start) { | 93 | if (!IS_ERR(table) && le64_to_cpu(table[0]) >= fragment_table_start) { |
94 | kfree(table); | 94 | kfree(table); |
95 | return ERR_PTR(-EINVAL); | 95 | return ERR_PTR(-EINVAL); |
96 | } | 96 | } |
diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c index a70858e0fb44..d38ea3dab951 100644 --- a/fs/squashfs/id.c +++ b/fs/squashfs/id.c | |||
@@ -93,7 +93,7 @@ __le64 *squashfs_read_id_index_table(struct super_block *sb, | |||
93 | * table[0] points to the first id lookup table metadata block, this | 93 | * table[0] points to the first id lookup table metadata block, this |
94 | * should be less than id_table_start | 94 | * should be less than id_table_start |
95 | */ | 95 | */ |
96 | if (!IS_ERR(table) && table[0] >= id_table_start) { | 96 | if (!IS_ERR(table) && le64_to_cpu(table[0]) >= id_table_start) { |
97 | kfree(table); | 97 | kfree(table); |
98 | return ERR_PTR(-EINVAL); | 98 | return ERR_PTR(-EINVAL); |
99 | } | 99 | } |
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 6f26abee3597..7438850c62d0 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -245,7 +245,7 @@ allocate_id_index_table: | |||
245 | msblk->id_table = NULL; | 245 | msblk->id_table = NULL; |
246 | goto failed_mount; | 246 | goto failed_mount; |
247 | } | 247 | } |
248 | next_table = msblk->id_table[0]; | 248 | next_table = le64_to_cpu(msblk->id_table[0]); |
249 | 249 | ||
250 | /* Handle inode lookup table */ | 250 | /* Handle inode lookup table */ |
251 | lookup_table_start = le64_to_cpu(sblk->lookup_table_start); | 251 | lookup_table_start = le64_to_cpu(sblk->lookup_table_start); |
@@ -261,7 +261,7 @@ allocate_id_index_table: | |||
261 | msblk->inode_lookup_table = NULL; | 261 | msblk->inode_lookup_table = NULL; |
262 | goto failed_mount; | 262 | goto failed_mount; |
263 | } | 263 | } |
264 | next_table = msblk->inode_lookup_table[0]; | 264 | next_table = le64_to_cpu(msblk->inode_lookup_table[0]); |
265 | 265 | ||
266 | sb->s_export_op = &squashfs_export_ops; | 266 | sb->s_export_op = &squashfs_export_ops; |
267 | 267 | ||
@@ -286,7 +286,7 @@ handle_fragments: | |||
286 | msblk->fragment_index = NULL; | 286 | msblk->fragment_index = NULL; |
287 | goto failed_mount; | 287 | goto failed_mount; |
288 | } | 288 | } |
289 | next_table = msblk->fragment_index[0]; | 289 | next_table = le64_to_cpu(msblk->fragment_index[0]); |
290 | 290 | ||
291 | check_directory_table: | 291 | check_directory_table: |
292 | /* Sanity check directory_table */ | 292 | /* Sanity check directory_table */ |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index e2cc6756f3b1..e474fbcf8bde 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -196,8 +196,6 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry) | |||
196 | struct inode *inode = dentry->d_inode; | 196 | struct inode *inode = dentry->d_inode; |
197 | int err = -ENOTEMPTY; | 197 | int err = -ENOTEMPTY; |
198 | 198 | ||
199 | dentry_unhash(dentry); | ||
200 | |||
201 | if (sysv_empty_dir(inode)) { | 199 | if (sysv_empty_dir(inode)) { |
202 | err = sysv_unlink(dir, dentry); | 200 | err = sysv_unlink(dir, dentry); |
203 | if (!err) { | 201 | if (!err) { |
@@ -224,9 +222,6 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, | |||
224 | struct sysv_dir_entry * old_de; | 222 | struct sysv_dir_entry * old_de; |
225 | int err = -ENOENT; | 223 | int err = -ENOENT; |
226 | 224 | ||
227 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
228 | dentry_unhash(new_dentry); | ||
229 | |||
230 | old_de = sysv_find_entry(old_dentry, &old_page); | 225 | old_de = sysv_find_entry(old_dentry, &old_page); |
231 | if (!old_de) | 226 | if (!old_de) |
232 | goto out; | 227 | goto out; |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index c2b80943560d..ef5abd38f0bf 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -656,8 +656,6 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) | |||
656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | 656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; | 657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; |
658 | 658 | ||
659 | dentry_unhash(dentry); | ||
660 | |||
661 | /* | 659 | /* |
662 | * Budget request settings: deletion direntry, deletion inode and | 660 | * Budget request settings: deletion direntry, deletion inode and |
663 | * changing the parent inode. If budgeting fails, go ahead anyway | 661 | * changing the parent inode. If budgeting fails, go ahead anyway |
@@ -978,9 +976,6 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
978 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; | 976 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
979 | struct timespec time; | 977 | struct timespec time; |
980 | 978 | ||
981 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
982 | dentry_unhash(new_dentry); | ||
983 | |||
984 | /* | 979 | /* |
985 | * Budget request settings: deletion direntry, new direntry, removing | 980 | * Budget request settings: deletion direntry, new direntry, removing |
986 | * the old inode, and changing old and new parent directory inodes. | 981 | * the old inode, and changing old and new parent directory inodes. |
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c index 46961c003236..ca953a945029 100644 --- a/fs/ubifs/shrinker.c +++ b/fs/ubifs/shrinker.c | |||
@@ -277,8 +277,9 @@ static int kick_a_thread(void) | |||
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | int ubifs_shrinker(struct shrinker *shrink, int nr, gfp_t gfp_mask) | 280 | int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc) |
281 | { | 281 | { |
282 | int nr = sc->nr_to_scan; | ||
282 | int freed, contention = 0; | 283 | int freed, contention = 0; |
283 | long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt); | 284 | long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt); |
284 | 285 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 6db0bdaa9f74..1ab0d22e4c94 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -382,7 +382,7 @@ done: | |||
382 | end_writeback(inode); | 382 | end_writeback(inode); |
383 | } | 383 | } |
384 | 384 | ||
385 | static void ubifs_dirty_inode(struct inode *inode) | 385 | static void ubifs_dirty_inode(struct inode *inode, int flags) |
386 | { | 386 | { |
387 | struct ubifs_inode *ui = ubifs_inode(inode); | 387 | struct ubifs_inode *ui = ubifs_inode(inode); |
388 | 388 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 93d1412a06f0..a70d7b4ffb25 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -1614,7 +1614,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot); | |||
1614 | int ubifs_tnc_end_commit(struct ubifs_info *c); | 1614 | int ubifs_tnc_end_commit(struct ubifs_info *c); |
1615 | 1615 | ||
1616 | /* shrinker.c */ | 1616 | /* shrinker.c */ |
1617 | int ubifs_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask); | 1617 | int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc); |
1618 | 1618 | ||
1619 | /* commit.c */ | 1619 | /* commit.c */ |
1620 | int ubifs_bg_thread(void *info); | 1620 | int ubifs_bg_thread(void *info); |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 4d76594c2a8f..f1dce848ef96 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -783,8 +783,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
783 | struct fileIdentDesc *fi, cfi; | 783 | struct fileIdentDesc *fi, cfi; |
784 | struct kernel_lb_addr tloc; | 784 | struct kernel_lb_addr tloc; |
785 | 785 | ||
786 | dentry_unhash(dentry); | ||
787 | |||
788 | retval = -ENOENT; | 786 | retval = -ENOENT; |
789 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 787 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
790 | if (!fi) | 788 | if (!fi) |
@@ -1083,9 +1081,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1083 | struct kernel_lb_addr tloc; | 1081 | struct kernel_lb_addr tloc; |
1084 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1082 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1085 | 1083 | ||
1086 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
1087 | dentry_unhash(new_dentry); | ||
1088 | |||
1089 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1084 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1090 | if (ofi) { | 1085 | if (ofi) { |
1091 | if (ofibh.sbh != ofibh.ebh) | 1086 | if (ofibh.sbh != ofibh.ebh) |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 953ebdfc5bf7..29309e25417f 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -258,8 +258,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
258 | struct inode * inode = dentry->d_inode; | 258 | struct inode * inode = dentry->d_inode; |
259 | int err= -ENOTEMPTY; | 259 | int err= -ENOTEMPTY; |
260 | 260 | ||
261 | dentry_unhash(dentry); | ||
262 | |||
263 | lock_ufs(dir->i_sb); | 261 | lock_ufs(dir->i_sb); |
264 | if (ufs_empty_dir (inode)) { | 262 | if (ufs_empty_dir (inode)) { |
265 | err = ufs_unlink(dir, dentry); | 263 | err = ufs_unlink(dir, dentry); |
@@ -284,9 +282,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
284 | struct ufs_dir_entry *old_de; | 282 | struct ufs_dir_entry *old_de; |
285 | int err = -ENOENT; | 283 | int err = -ENOENT; |
286 | 284 | ||
287 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
288 | dentry_unhash(new_dentry); | ||
289 | |||
290 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 285 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
291 | if (!old_de) | 286 | if (!old_de) |
292 | goto out; | 287 | goto out; |
diff --git a/fs/xattr.c b/fs/xattr.c index f1ef94974dea..f060663ab70c 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -46,18 +46,22 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
46 | return 0; | 46 | return 0; |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * The trusted.* namespace can only be accessed by a privileged user. | 49 | * The trusted.* namespace can only be accessed by privileged users. |
50 | */ | 50 | */ |
51 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | 51 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { |
52 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | 52 | if (!capable(CAP_SYS_ADMIN)) |
53 | return (mask & MAY_WRITE) ? -EPERM : -ENODATA; | ||
54 | return 0; | ||
55 | } | ||
53 | 56 | ||
54 | /* In user.* namespace, only regular files and directories can have | 57 | /* |
58 | * In the user.* namespace, only regular files and directories can have | ||
55 | * extended attributes. For sticky directories, only the owner and | 59 | * extended attributes. For sticky directories, only the owner and |
56 | * privileged user can write attributes. | 60 | * privileged users can write attributes. |
57 | */ | 61 | */ |
58 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { | 62 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { |
59 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) | 63 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
60 | return -EPERM; | 64 | return (mask & MAY_WRITE) ? -EPERM : -ENODATA; |
61 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && | 65 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && |
62 | (mask & MAY_WRITE) && !inode_owner_or_capable(inode)) | 66 | (mask & MAY_WRITE) && !inode_owner_or_capable(inode)) |
63 | return -EPERM; | 67 | return -EPERM; |
@@ -87,7 +91,11 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | |||
87 | { | 91 | { |
88 | struct inode *inode = dentry->d_inode; | 92 | struct inode *inode = dentry->d_inode; |
89 | int error = -EOPNOTSUPP; | 93 | int error = -EOPNOTSUPP; |
94 | int issec = !strncmp(name, XATTR_SECURITY_PREFIX, | ||
95 | XATTR_SECURITY_PREFIX_LEN); | ||
90 | 96 | ||
97 | if (issec) | ||
98 | inode->i_flags &= ~S_NOSEC; | ||
91 | if (inode->i_op->setxattr) { | 99 | if (inode->i_op->setxattr) { |
92 | error = inode->i_op->setxattr(dentry, name, value, size, flags); | 100 | error = inode->i_op->setxattr(dentry, name, value, size, flags); |
93 | if (!error) { | 101 | if (!error) { |
@@ -95,8 +103,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | |||
95 | security_inode_post_setxattr(dentry, name, value, | 103 | security_inode_post_setxattr(dentry, name, value, |
96 | size, flags); | 104 | size, flags); |
97 | } | 105 | } |
98 | } else if (!strncmp(name, XATTR_SECURITY_PREFIX, | 106 | } else if (issec) { |
99 | XATTR_SECURITY_PREFIX_LEN)) { | ||
100 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | 107 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; |
101 | error = security_inode_setsecurity(inode, suffix, value, | 108 | error = security_inode_setsecurity(inode, suffix, value, |
102 | size, flags); | 109 | size, flags); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 98b9c91fcdf1..1e3a7ce804dc 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -925,7 +925,8 @@ xfs_fs_inode_init_once( | |||
925 | */ | 925 | */ |
926 | STATIC void | 926 | STATIC void |
927 | xfs_fs_dirty_inode( | 927 | xfs_fs_dirty_inode( |
928 | struct inode *inode) | 928 | struct inode *inode, |
929 | int flags) | ||
929 | { | 930 | { |
930 | barrier(); | 931 | barrier(); |
931 | XFS_I(inode)->i_update_core = 1; | 932 | XFS_I(inode)->i_update_core = 1; |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index a3252a5ead66..a756bc8d866d 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -98,6 +98,9 @@ acpi_os_table_override(struct acpi_table_header *existing_table, | |||
98 | /* | 98 | /* |
99 | * Spinlock primitives | 99 | * Spinlock primitives |
100 | */ | 100 | */ |
101 | acpi_status | ||
102 | acpi_os_create_lock(acpi_spinlock *out_handle); | ||
103 | |||
101 | void acpi_os_delete_lock(acpi_spinlock handle); | 104 | void acpi_os_delete_lock(acpi_spinlock handle); |
102 | 105 | ||
103 | acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle); | 106 | acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle); |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index f6ad63d25b73..2ed0a8486c19 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
49 | 49 | ||
50 | #define ACPI_CA_VERSION 0x20110316 | 50 | #define ACPI_CA_VERSION 0x20110413 |
51 | 51 | ||
52 | #include "actypes.h" | 52 | #include "actypes.h" |
53 | #include "actbl.h" | 53 | #include "actbl.h" |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 64f838beaabf..b67231bef632 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -501,8 +501,9 @@ typedef u64 acpi_integer; | |||
501 | #define ACPI_STATE_D1 (u8) 1 | 501 | #define ACPI_STATE_D1 (u8) 1 |
502 | #define ACPI_STATE_D2 (u8) 2 | 502 | #define ACPI_STATE_D2 (u8) 2 |
503 | #define ACPI_STATE_D3 (u8) 3 | 503 | #define ACPI_STATE_D3 (u8) 3 |
504 | #define ACPI_D_STATES_MAX ACPI_STATE_D3 | 504 | #define ACPI_STATE_D3_COLD (u8) 4 |
505 | #define ACPI_D_STATE_COUNT 4 | 505 | #define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD |
506 | #define ACPI_D_STATE_COUNT 5 | ||
506 | 507 | ||
507 | #define ACPI_STATE_C0 (u8) 0 | 508 | #define ACPI_STATE_C0 (u8) 0 |
508 | #define ACPI_STATE_C1 (u8) 1 | 509 | #define ACPI_STATE_C1 (u8) 1 |
@@ -712,8 +713,24 @@ typedef u8 acpi_adr_space_type; | |||
712 | #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 | 713 | #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 |
713 | #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 | 714 | #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 |
714 | #define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 | 715 | #define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 |
715 | #define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 8 | 716 | |
716 | #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 | 717 | #define ACPI_NUM_PREDEFINED_REGIONS 8 |
718 | |||
719 | /* | ||
720 | * Special Address Spaces | ||
721 | * | ||
722 | * Note: A Data Table region is a special type of operation region | ||
723 | * that has its own AML opcode. However, internally, the AML | ||
724 | * interpreter simply creates an operation region with an an address | ||
725 | * space type of ACPI_ADR_SPACE_DATA_TABLE. | ||
726 | */ | ||
727 | #define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 0x7E /* Internal to ACPICA only */ | ||
728 | #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 0x7F | ||
729 | |||
730 | /* Values for _REG connection code */ | ||
731 | |||
732 | #define ACPI_REG_DISCONNECT 0 | ||
733 | #define ACPI_REG_CONNECT 1 | ||
717 | 734 | ||
718 | /* | 735 | /* |
719 | * bit_register IDs | 736 | * bit_register IDs |
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 55192ac0cede..ba4928cae473 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -310,14 +310,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | |||
310 | 310 | ||
311 | /* in processor_core.c */ | 311 | /* in processor_core.c */ |
312 | void acpi_processor_set_pdc(acpi_handle handle); | 312 | void acpi_processor_set_pdc(acpi_handle handle); |
313 | #ifdef CONFIG_SMP | ||
314 | int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); | 313 | int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); |
315 | #else | ||
316 | static inline int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | ||
317 | { | ||
318 | return -1; | ||
319 | } | ||
320 | #endif | ||
321 | 314 | ||
322 | /* in processor_throttling.c */ | 315 | /* in processor_throttling.c */ |
323 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | 316 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index ff5c66080c8c..fcdcb5d5c995 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -35,9 +35,9 @@ | |||
35 | * platform data and other tables. | 35 | * platform data and other tables. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | static inline int gpio_is_valid(int number) | 38 | static inline bool gpio_is_valid(int number) |
39 | { | 39 | { |
40 | return ((unsigned)number) < ARCH_NR_GPIOS; | 40 | return number >= 0 && number < ARCH_NR_GPIOS; |
41 | } | 41 | } |
42 | 42 | ||
43 | struct device; | 43 | struct device; |
@@ -193,8 +193,8 @@ struct gpio { | |||
193 | }; | 193 | }; |
194 | 194 | ||
195 | extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); | 195 | extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); |
196 | extern int gpio_request_array(struct gpio *array, size_t num); | 196 | extern int gpio_request_array(const struct gpio *array, size_t num); |
197 | extern void gpio_free_array(struct gpio *array, size_t num); | 197 | extern void gpio_free_array(const struct gpio *array, size_t num); |
198 | 198 | ||
199 | #ifdef CONFIG_GPIO_SYSFS | 199 | #ifdef CONFIG_GPIO_SYSFS |
200 | 200 | ||
@@ -212,7 +212,7 @@ extern void gpio_unexport(unsigned gpio); | |||
212 | 212 | ||
213 | #else /* !CONFIG_GPIOLIB */ | 213 | #else /* !CONFIG_GPIOLIB */ |
214 | 214 | ||
215 | static inline int gpio_is_valid(int number) | 215 | static inline bool gpio_is_valid(int number) |
216 | { | 216 | { |
217 | /* only non-negative numbers are valid */ | 217 | /* only non-negative numbers are valid */ |
218 | return number >= 0; | 218 | return number >= 0; |
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index 33d524704883..ae90e0f63995 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h | |||
@@ -681,9 +681,11 @@ __SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \ | |||
681 | __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) | 681 | __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) |
682 | #define __NR_syncfs 267 | 682 | #define __NR_syncfs 267 |
683 | __SYSCALL(__NR_syncfs, sys_syncfs) | 683 | __SYSCALL(__NR_syncfs, sys_syncfs) |
684 | #define __NR_setns 268 | ||
685 | __SYSCALL(__NR_setns, sys_setns) | ||
684 | 686 | ||
685 | #undef __NR_syscalls | 687 | #undef __NR_syscalls |
686 | #define __NR_syscalls 268 | 688 | #define __NR_syscalls 269 |
687 | 689 | ||
688 | /* | 690 | /* |
689 | * All syscalls below here should go away really, | 691 | * All syscalls below here should go away really, |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index a2e910e01293..1deb2a73c2da 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -150,8 +150,7 @@ extern int ec_read(u8 addr, u8 *val); | |||
150 | extern int ec_write(u8 addr, u8 val); | 150 | extern int ec_write(u8 addr, u8 val); |
151 | extern int ec_transaction(u8 command, | 151 | extern int ec_transaction(u8 command, |
152 | const u8 *wdata, unsigned wdata_len, | 152 | const u8 *wdata, unsigned wdata_len, |
153 | u8 *rdata, unsigned rdata_len, | 153 | u8 *rdata, unsigned rdata_len); |
154 | int force_poll); | ||
155 | 154 | ||
156 | #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) | 155 | #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) |
157 | 156 | ||
diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 96c038e43d66..ee456c79b0e6 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h | |||
@@ -34,4 +34,17 @@ static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) | |||
34 | } | 34 | } |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #ifndef CONFIG_ARCH_HAS_ATOMIC_OR | ||
38 | static inline void atomic_or(int i, atomic_t *v) | ||
39 | { | ||
40 | int old; | ||
41 | int new; | ||
42 | |||
43 | do { | ||
44 | old = atomic_read(v); | ||
45 | new = old | i; | ||
46 | } while (atomic_cmpxchg(v, old, new) != old); | ||
47 | } | ||
48 | #endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */ | ||
49 | |||
37 | #endif /* _LINUX_ATOMIC_H */ | 50 | #endif /* _LINUX_ATOMIC_H */ |
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index f20eb8f16025..e9eaec522655 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h | |||
@@ -146,7 +146,7 @@ static inline void cpuset_cpus_allowed(struct task_struct *p, | |||
146 | 146 | ||
147 | static inline int cpuset_cpus_allowed_fallback(struct task_struct *p) | 147 | static inline int cpuset_cpus_allowed_fallback(struct task_struct *p) |
148 | { | 148 | { |
149 | cpumask_copy(&p->cpus_allowed, cpu_possible_mask); | 149 | do_set_cpus_allowed(p, cpu_possible_mask); |
150 | return cpumask_any(cpu_active_mask); | 150 | return cpumask_any(cpu_active_mask); |
151 | } | 151 | } |
152 | 152 | ||
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 32a4423710f5..4427e0454051 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -191,6 +191,12 @@ struct dm_target { | |||
191 | 191 | ||
192 | /* Used to provide an error string from the ctr */ | 192 | /* Used to provide an error string from the ctr */ |
193 | char *error; | 193 | char *error; |
194 | |||
195 | /* | ||
196 | * Set if this target needs to receive discards regardless of | ||
197 | * whether or not its underlying devices have support. | ||
198 | */ | ||
199 | unsigned discards_supported:1; | ||
194 | }; | 200 | }; |
195 | 201 | ||
196 | /* Each target can link one of these into the table */ | 202 | /* Each target can link one of these into the table */ |
diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h index 5c9186b93fff..f4b0aa3126f5 100644 --- a/include/linux/dm-io.h +++ b/include/linux/dm-io.h | |||
@@ -69,8 +69,7 @@ struct dm_io_request { | |||
69 | * | 69 | * |
70 | * Create/destroy may block. | 70 | * Create/destroy may block. |
71 | */ | 71 | */ |
72 | struct dm_io_client *dm_io_client_create(unsigned num_pages); | 72 | struct dm_io_client *dm_io_client_create(void); |
73 | int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client); | ||
74 | void dm_io_client_destroy(struct dm_io_client *client); | 73 | void dm_io_client_destroy(struct dm_io_client *client); |
75 | 74 | ||
76 | /* | 75 | /* |
diff --git a/include/linux/dm-kcopyd.h b/include/linux/dm-kcopyd.h index 5db216311695..298d587e349b 100644 --- a/include/linux/dm-kcopyd.h +++ b/include/linux/dm-kcopyd.h | |||
@@ -25,8 +25,7 @@ | |||
25 | * To use kcopyd you must first create a dm_kcopyd_client object. | 25 | * To use kcopyd you must first create a dm_kcopyd_client object. |
26 | */ | 26 | */ |
27 | struct dm_kcopyd_client; | 27 | struct dm_kcopyd_client; |
28 | int dm_kcopyd_client_create(unsigned num_pages, | 28 | struct dm_kcopyd_client *dm_kcopyd_client_create(void); |
29 | struct dm_kcopyd_client **result); | ||
30 | void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); | 29 | void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); |
31 | 30 | ||
32 | /* | 31 | /* |
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h index 5619f8522738..bbd8661b3473 100644 --- a/include/linux/dma_remapping.h +++ b/include/linux/dma_remapping.h | |||
@@ -9,8 +9,12 @@ | |||
9 | #define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) | 9 | #define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) |
10 | #define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) | 10 | #define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) |
11 | 11 | ||
12 | #define VTD_STRIDE_SHIFT (9) | ||
13 | #define VTD_STRIDE_MASK (((u64)-1) << VTD_STRIDE_SHIFT) | ||
14 | |||
12 | #define DMA_PTE_READ (1) | 15 | #define DMA_PTE_READ (1) |
13 | #define DMA_PTE_WRITE (2) | 16 | #define DMA_PTE_WRITE (2) |
17 | #define DMA_PTE_LARGE_PAGE (1 << 7) | ||
14 | #define DMA_PTE_SNP (1 << 11) | 18 | #define DMA_PTE_SNP (1 << 11) |
15 | 19 | ||
16 | #define CONTEXT_TT_MULTI_LEVEL 0 | 20 | #define CONTEXT_TT_MULTI_LEVEL 0 |
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h index 6998d9376ef9..4bfe0a2f7d50 100644 --- a/include/linux/dw_dmac.h +++ b/include/linux/dw_dmac.h | |||
@@ -3,6 +3,7 @@ | |||
3 | * AVR32 systems.) | 3 | * AVR32 systems.) |
4 | * | 4 | * |
5 | * Copyright (C) 2007 Atmel Corporation | 5 | * Copyright (C) 2007 Atmel Corporation |
6 | * Copyright (C) 2010-2011 ST Microelectronics | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 33fa1203024e..e376270cd26e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -299,6 +299,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource, | |||
299 | struct resource *data_resource, struct resource *bss_resource); | 299 | struct resource *data_resource, struct resource *bss_resource); |
300 | extern unsigned long efi_get_time(void); | 300 | extern unsigned long efi_get_time(void); |
301 | extern int efi_set_rtc_mmss(unsigned long nowtime); | 301 | extern int efi_set_rtc_mmss(unsigned long nowtime); |
302 | extern void efi_reserve_boot_services(void); | ||
302 | extern struct efi_memory_map memmap; | 303 | extern struct efi_memory_map memmap; |
303 | 304 | ||
304 | /** | 305 | /** |
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 85c1d302c12e..5e06acf95d0f 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -909,7 +909,7 @@ extern int ext3_setattr (struct dentry *, struct iattr *); | |||
909 | extern void ext3_evict_inode (struct inode *); | 909 | extern void ext3_evict_inode (struct inode *); |
910 | extern int ext3_sync_inode (handle_t *, struct inode *); | 910 | extern int ext3_sync_inode (handle_t *, struct inode *); |
911 | extern void ext3_discard_reservation (struct inode *); | 911 | extern void ext3_discard_reservation (struct inode *); |
912 | extern void ext3_dirty_inode(struct inode *); | 912 | extern void ext3_dirty_inode(struct inode *, int); |
913 | extern int ext3_change_inode_journal_flag(struct inode *, int); | 913 | extern int ext3_change_inode_journal_flag(struct inode *, int); |
914 | extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); | 914 | extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); |
915 | extern int ext3_can_truncate(struct inode *inode); | 915 | extern int ext3_can_truncate(struct inode *inode); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 241609346dfb..c55d6b7cd5d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -237,6 +237,7 @@ struct inodes_stat_t { | |||
237 | #define S_PRIVATE 512 /* Inode is fs-internal */ | 237 | #define S_PRIVATE 512 /* Inode is fs-internal */ |
238 | #define S_IMA 1024 /* Inode has an associated IMA struct */ | 238 | #define S_IMA 1024 /* Inode has an associated IMA struct */ |
239 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ | 239 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ |
240 | #define S_NOSEC 4096 /* no suid or xattr security attributes */ | ||
240 | 241 | ||
241 | /* | 242 | /* |
242 | * Note that nosuid etc flags are inode-specific: setting some file-system | 243 | * Note that nosuid etc flags are inode-specific: setting some file-system |
@@ -273,6 +274,7 @@ struct inodes_stat_t { | |||
273 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) | 274 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) |
274 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) | 275 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) |
275 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) | 276 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) |
277 | #define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) | ||
276 | 278 | ||
277 | /* the read-only stuff doesn't really belong here, but any other place is | 279 | /* the read-only stuff doesn't really belong here, but any other place is |
278 | probably as bad and I don't want to create yet another include file. */ | 280 | probably as bad and I don't want to create yet another include file. */ |
@@ -1618,7 +1620,7 @@ struct super_operations { | |||
1618 | struct inode *(*alloc_inode)(struct super_block *sb); | 1620 | struct inode *(*alloc_inode)(struct super_block *sb); |
1619 | void (*destroy_inode)(struct inode *); | 1621 | void (*destroy_inode)(struct inode *); |
1620 | 1622 | ||
1621 | void (*dirty_inode) (struct inode *); | 1623 | void (*dirty_inode) (struct inode *, int flags); |
1622 | int (*write_inode) (struct inode *, struct writeback_control *wbc); | 1624 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
1623 | int (*drop_inode) (struct inode *); | 1625 | int (*drop_inode) (struct inode *); |
1624 | void (*evict_inode) (struct inode *); | 1626 | void (*evict_inode) (struct inode *); |
@@ -2582,5 +2584,16 @@ int __init get_filesystem_list(char *buf); | |||
2582 | #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ | 2584 | #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ |
2583 | (flag & __FMODE_NONOTIFY))) | 2585 | (flag & __FMODE_NONOTIFY))) |
2584 | 2586 | ||
2587 | static inline int is_sxid(mode_t mode) | ||
2588 | { | ||
2589 | return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP)); | ||
2590 | } | ||
2591 | |||
2592 | static inline void inode_has_no_xattr(struct inode *inode) | ||
2593 | { | ||
2594 | if (!is_sxid(inode->i_mode)) | ||
2595 | inode->i_flags |= S_NOSEC; | ||
2596 | } | ||
2597 | |||
2585 | #endif /* __KERNEL__ */ | 2598 | #endif /* __KERNEL__ */ |
2586 | #endif /* _LINUX_FS_H */ | 2599 | #endif /* _LINUX_FS_H */ |
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index b5a550a39a70..59d3ef100eb9 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -16,6 +16,11 @@ struct trace_print_flags { | |||
16 | const char *name; | 16 | const char *name; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | struct trace_print_flags_u64 { | ||
20 | unsigned long long mask; | ||
21 | const char *name; | ||
22 | }; | ||
23 | |||
19 | const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, | 24 | const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, |
20 | unsigned long flags, | 25 | unsigned long flags, |
21 | const struct trace_print_flags *flag_array); | 26 | const struct trace_print_flags *flag_array); |
@@ -23,6 +28,13 @@ const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, | |||
23 | const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, | 28 | const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, |
24 | const struct trace_print_flags *symbol_array); | 29 | const struct trace_print_flags *symbol_array); |
25 | 30 | ||
31 | #if BITS_PER_LONG == 32 | ||
32 | const char *ftrace_print_symbols_seq_u64(struct trace_seq *p, | ||
33 | unsigned long long val, | ||
34 | const struct trace_print_flags_u64 | ||
35 | *symbol_array); | ||
36 | #endif | ||
37 | |||
26 | const char *ftrace_print_hex_seq(struct trace_seq *p, | 38 | const char *ftrace_print_hex_seq(struct trace_seq *p, |
27 | const unsigned char *buf, int len); | 39 | const unsigned char *buf, int len); |
28 | 40 | ||
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 32720baf70f1..32d47e710661 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
@@ -25,9 +25,9 @@ struct gpio_chip; | |||
25 | * warning when something is wrongly called. | 25 | * warning when something is wrongly called. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | static inline int gpio_is_valid(int number) | 28 | static inline bool gpio_is_valid(int number) |
29 | { | 29 | { |
30 | return 0; | 30 | return false; |
31 | } | 31 | } |
32 | 32 | ||
33 | static inline int gpio_request(unsigned gpio, const char *label) | 33 | static inline int gpio_request(unsigned gpio, const char *label) |
@@ -41,7 +41,7 @@ static inline int gpio_request_one(unsigned gpio, | |||
41 | return -ENOSYS; | 41 | return -ENOSYS; |
42 | } | 42 | } |
43 | 43 | ||
44 | static inline int gpio_request_array(struct gpio *array, size_t num) | 44 | static inline int gpio_request_array(const struct gpio *array, size_t num) |
45 | { | 45 | { |
46 | return -ENOSYS; | 46 | return -ENOSYS; |
47 | } | 47 | } |
@@ -54,7 +54,7 @@ static inline void gpio_free(unsigned gpio) | |||
54 | WARN_ON(1); | 54 | WARN_ON(1); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline void gpio_free_array(struct gpio *array, size_t num) | 57 | static inline void gpio_free_array(const struct gpio *array, size_t num) |
58 | { | 58 | { |
59 | might_sleep(); | 59 | might_sleep(); |
60 | 60 | ||
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 2a78aae78c69..027935c86c68 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -264,6 +264,8 @@ struct mm_struct { | |||
264 | 264 | ||
265 | struct linux_binfmt *binfmt; | 265 | struct linux_binfmt *binfmt; |
266 | 266 | ||
267 | cpumask_var_t cpu_vm_mask_var; | ||
268 | |||
267 | /* Architecture-specific MM context */ | 269 | /* Architecture-specific MM context */ |
268 | mm_context_t context; | 270 | mm_context_t context; |
269 | 271 | ||
@@ -311,10 +313,18 @@ struct mm_struct { | |||
311 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 313 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
312 | pgtable_t pmd_huge_pte; /* protected by page_table_lock */ | 314 | pgtable_t pmd_huge_pte; /* protected by page_table_lock */ |
313 | #endif | 315 | #endif |
314 | 316 | #ifdef CONFIG_CPUMASK_OFFSTACK | |
315 | cpumask_var_t cpu_vm_mask_var; | 317 | struct cpumask cpumask_allocation; |
318 | #endif | ||
316 | }; | 319 | }; |
317 | 320 | ||
321 | static inline void mm_init_cpumask(struct mm_struct *mm) | ||
322 | { | ||
323 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
324 | mm->cpu_vm_mask_var = &mm->cpumask_allocation; | ||
325 | #endif | ||
326 | } | ||
327 | |||
318 | /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ | 328 | /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ |
319 | static inline cpumask_t *mm_cpumask(struct mm_struct *mm) | 329 | static inline cpumask_t *mm_cpumask(struct mm_struct *mm) |
320 | { | 330 | { |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 29312bdf119f..c928dac6cad0 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -1051,12 +1051,14 @@ static inline struct mem_section *__pfn_to_section(unsigned long pfn) | |||
1051 | return __nr_to_section(pfn_to_section_nr(pfn)); | 1051 | return __nr_to_section(pfn_to_section_nr(pfn)); |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | #ifndef CONFIG_HAVE_ARCH_PFN_VALID | ||
1054 | static inline int pfn_valid(unsigned long pfn) | 1055 | static inline int pfn_valid(unsigned long pfn) |
1055 | { | 1056 | { |
1056 | if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) | 1057 | if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) |
1057 | return 0; | 1058 | return 0; |
1058 | return valid_section(__nr_to_section(pfn_to_section_nr(pfn))); | 1059 | return valid_section(__nr_to_section(pfn_to_section_nr(pfn))); |
1059 | } | 1060 | } |
1061 | #endif | ||
1060 | 1062 | ||
1061 | static inline int pfn_present(unsigned long pfn) | 1063 | static inline int pfn_present(unsigned long pfn) |
1062 | { | 1064 | { |
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9d5306bad117..2541fb848daa 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
@@ -322,9 +322,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) | |||
322 | 322 | ||
323 | /* Kernel-side ioctl definitions */ | 323 | /* Kernel-side ioctl definitions */ |
324 | 324 | ||
325 | extern int add_mtd_device(struct mtd_info *mtd); | 325 | struct mtd_partition; |
326 | extern int del_mtd_device (struct mtd_info *mtd); | ||
327 | 326 | ||
327 | extern int mtd_device_register(struct mtd_info *master, | ||
328 | const struct mtd_partition *parts, | ||
329 | int nr_parts); | ||
330 | extern int mtd_device_unregister(struct mtd_info *master); | ||
328 | extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); | 331 | extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); |
329 | extern int __get_mtd_device(struct mtd_info *mtd); | 332 | extern int __get_mtd_device(struct mtd_info *mtd); |
330 | extern void __put_mtd_device(struct mtd_info *mtd); | 333 | extern void __put_mtd_device(struct mtd_info *mtd); |
@@ -348,15 +351,9 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | |||
348 | int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, | 351 | int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, |
349 | unsigned long count, loff_t from, size_t *retlen); | 352 | unsigned long count, loff_t from, size_t *retlen); |
350 | 353 | ||
351 | #ifdef CONFIG_MTD_PARTITIONS | 354 | void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); |
355 | |||
352 | void mtd_erase_callback(struct erase_info *instr); | 356 | void mtd_erase_callback(struct erase_info *instr); |
353 | #else | ||
354 | static inline void mtd_erase_callback(struct erase_info *instr) | ||
355 | { | ||
356 | if (instr->callback) | ||
357 | instr->callback(instr); | ||
358 | } | ||
359 | #endif | ||
360 | 357 | ||
361 | /* | 358 | /* |
362 | * Debugging macro and defines | 359 | * Debugging macro and defines |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d44192740f6f..c2b9ac4fbc4a 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -237,9 +237,9 @@ typedef enum { | |||
237 | * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch | 237 | * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch |
238 | * the OOB area. | 238 | * the OOB area. |
239 | */ | 239 | */ |
240 | #define NAND_USE_FLASH_BBT_NO_OOB 0x00100000 | 240 | #define NAND_USE_FLASH_BBT_NO_OOB 0x00800000 |
241 | /* Create an empty BBT with no vendor information if the BBT is available */ | 241 | /* Create an empty BBT with no vendor information if the BBT is available */ |
242 | #define NAND_CREATE_EMPTY_BBT 0x00200000 | 242 | #define NAND_CREATE_EMPTY_BBT 0x01000000 |
243 | 243 | ||
244 | /* Options set by nand scan */ | 244 | /* Options set by nand scan */ |
245 | /* Nand scan has allocated controller struct */ | 245 | /* Nand scan has allocated controller struct */ |
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 4a0a8ba90a72..3a6f0372fc96 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h | |||
@@ -16,7 +16,7 @@ | |||
16 | * Partition definition structure: | 16 | * Partition definition structure: |
17 | * | 17 | * |
18 | * An array of struct partition is passed along with a MTD object to | 18 | * An array of struct partition is passed along with a MTD object to |
19 | * add_mtd_partitions() to create them. | 19 | * mtd_device_register() to create them. |
20 | * | 20 | * |
21 | * For each partition, these fields are available: | 21 | * For each partition, these fields are available: |
22 | * name: string that will be used to label the partition's MTD device. | 22 | * name: string that will be used to label the partition's MTD device. |
@@ -49,9 +49,6 @@ struct mtd_partition { | |||
49 | 49 | ||
50 | struct mtd_info; | 50 | struct mtd_info; |
51 | 51 | ||
52 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); | ||
53 | int del_mtd_partitions(struct mtd_info *); | ||
54 | |||
55 | /* | 52 | /* |
56 | * Functions dealing with the various ways of partitioning the space | 53 | * Functions dealing with the various ways of partitioning the space |
57 | */ | 54 | */ |
@@ -73,14 +70,17 @@ extern int parse_mtd_partitions(struct mtd_info *master, const char **types, | |||
73 | struct device; | 70 | struct device; |
74 | struct device_node; | 71 | struct device_node; |
75 | 72 | ||
73 | #ifdef CONFIG_MTD_OF_PARTS | ||
76 | int __devinit of_mtd_parse_partitions(struct device *dev, | 74 | int __devinit of_mtd_parse_partitions(struct device *dev, |
77 | struct device_node *node, | 75 | struct device_node *node, |
78 | struct mtd_partition **pparts); | 76 | struct mtd_partition **pparts); |
79 | |||
80 | #ifdef CONFIG_MTD_PARTITIONS | ||
81 | static inline int mtd_has_partitions(void) { return 1; } | ||
82 | #else | 77 | #else |
83 | static inline int mtd_has_partitions(void) { return 0; } | 78 | static inline int of_mtd_parse_partitions(struct device *dev, |
79 | struct device_node *node, | ||
80 | struct mtd_partition **pparts) | ||
81 | { | ||
82 | return 0; | ||
83 | } | ||
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 86 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index 49b959029417..e5f21d293c70 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | 20 | ||
21 | struct map_info; | 21 | struct map_info; |
22 | struct platform_device; | ||
22 | 23 | ||
23 | struct physmap_flash_data { | 24 | struct physmap_flash_data { |
24 | unsigned int width; | 25 | unsigned int width; |
@@ -37,8 +38,6 @@ struct physmap_flash_data { | |||
37 | void physmap_configure(unsigned long addr, unsigned long size, | 38 | void physmap_configure(unsigned long addr, unsigned long size, |
38 | int bankwidth, void (*set_vpp)(struct map_info *, int) ); | 39 | int bankwidth, void (*set_vpp)(struct map_info *, int) ); |
39 | 40 | ||
40 | #ifdef CONFIG_MTD_PARTITIONS | ||
41 | |||
42 | /* | 41 | /* |
43 | * Machines that wish to do flash partition may want to call this function in | 42 | * Machines that wish to do flash partition may want to call this function in |
44 | * their setup routine. | 43 | * their setup routine. |
@@ -50,6 +49,4 @@ void physmap_configure(unsigned long addr, unsigned long size, | |||
50 | */ | 49 | */ |
51 | void physmap_set_partitions(struct mtd_partition *parts, int num_parts); | 50 | void physmap_set_partitions(struct mtd_partition *parts, int num_parts); |
52 | 51 | ||
53 | #endif /* defined(CONFIG_MTD_PARTITIONS) */ | ||
54 | |||
55 | #endif /* __LINUX_MTD_PHYSMAP__ */ | 52 | #endif /* __LINUX_MTD_PHYSMAP__ */ |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 178fafe0ff93..504b289ba680 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
@@ -562,6 +562,7 @@ enum { | |||
562 | NFSPROC4_CLNT_LAYOUTGET, | 562 | NFSPROC4_CLNT_LAYOUTGET, |
563 | NFSPROC4_CLNT_GETDEVICEINFO, | 563 | NFSPROC4_CLNT_GETDEVICEINFO, |
564 | NFSPROC4_CLNT_LAYOUTCOMMIT, | 564 | NFSPROC4_CLNT_LAYOUTCOMMIT, |
565 | NFSPROC4_CLNT_LAYOUTRETURN, | ||
565 | }; | 566 | }; |
566 | 567 | ||
567 | /* nfs41 types */ | 568 | /* nfs41 types */ |
@@ -570,9 +571,11 @@ struct nfs4_sessionid { | |||
570 | }; | 571 | }; |
571 | 572 | ||
572 | /* Create Session Flags */ | 573 | /* Create Session Flags */ |
573 | #define SESSION4_PERSIST 0x001 | 574 | #define SESSION4_PERSIST 0x001 |
574 | #define SESSION4_BACK_CHAN 0x002 | 575 | #define SESSION4_BACK_CHAN 0x002 |
575 | #define SESSION4_RDMA 0x004 | 576 | #define SESSION4_RDMA 0x004 |
577 | |||
578 | #define SESSION4_FLAG_MASK_A 0x007 | ||
576 | 579 | ||
577 | enum state_protect_how4 { | 580 | enum state_protect_how4 { |
578 | SP4_NONE = 0, | 581 | SP4_NONE = 0, |
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 91af2e49fa3a..3a34e80ae92f 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h | |||
@@ -68,7 +68,7 @@ struct nfs_pageio_descriptor { | |||
68 | int pg_ioflags; | 68 | int pg_ioflags; |
69 | int pg_error; | 69 | int pg_error; |
70 | struct pnfs_layout_segment *pg_lseg; | 70 | struct pnfs_layout_segment *pg_lseg; |
71 | int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); | 71 | bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); |
72 | }; | 72 | }; |
73 | 73 | ||
74 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) | 74 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7e371f7df9c4..5e8444a11adf 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -269,6 +269,27 @@ struct nfs4_layoutcommit_data { | |||
269 | struct nfs4_layoutcommit_res res; | 269 | struct nfs4_layoutcommit_res res; |
270 | }; | 270 | }; |
271 | 271 | ||
272 | struct nfs4_layoutreturn_args { | ||
273 | __u32 layout_type; | ||
274 | struct inode *inode; | ||
275 | nfs4_stateid stateid; | ||
276 | struct nfs4_sequence_args seq_args; | ||
277 | }; | ||
278 | |||
279 | struct nfs4_layoutreturn_res { | ||
280 | struct nfs4_sequence_res seq_res; | ||
281 | u32 lrs_present; | ||
282 | nfs4_stateid stateid; | ||
283 | }; | ||
284 | |||
285 | struct nfs4_layoutreturn { | ||
286 | struct nfs4_layoutreturn_args args; | ||
287 | struct nfs4_layoutreturn_res res; | ||
288 | struct rpc_cred *cred; | ||
289 | struct nfs_client *clp; | ||
290 | int rpc_status; | ||
291 | }; | ||
292 | |||
272 | /* | 293 | /* |
273 | * Arguments to the open call. | 294 | * Arguments to the open call. |
274 | */ | 295 | */ |
@@ -1087,6 +1108,7 @@ struct nfs_read_data { | |||
1087 | const struct rpc_call_ops *mds_ops; | 1108 | const struct rpc_call_ops *mds_ops; |
1088 | int (*read_done_cb) (struct rpc_task *task, struct nfs_read_data *data); | 1109 | int (*read_done_cb) (struct rpc_task *task, struct nfs_read_data *data); |
1089 | __u64 mds_offset; | 1110 | __u64 mds_offset; |
1111 | int pnfs_error; | ||
1090 | struct page *page_array[NFS_PAGEVEC_SIZE]; | 1112 | struct page *page_array[NFS_PAGEVEC_SIZE]; |
1091 | }; | 1113 | }; |
1092 | 1114 | ||
@@ -1112,6 +1134,7 @@ struct nfs_write_data { | |||
1112 | unsigned long timestamp; /* For lease renewal */ | 1134 | unsigned long timestamp; /* For lease renewal */ |
1113 | #endif | 1135 | #endif |
1114 | __u64 mds_offset; /* Filelayout dense stripe */ | 1136 | __u64 mds_offset; /* Filelayout dense stripe */ |
1137 | int pnfs_error; | ||
1115 | struct page *page_array[NFS_PAGEVEC_SIZE]; | 1138 | struct page *page_array[NFS_PAGEVEC_SIZE]; |
1116 | }; | 1139 | }; |
1117 | 1140 | ||
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 79a6700b7162..6081493db68f 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -308,7 +308,7 @@ static inline void SetPageUptodate(struct page *page) | |||
308 | { | 308 | { |
309 | #ifdef CONFIG_S390 | 309 | #ifdef CONFIG_S390 |
310 | if (!test_and_set_bit(PG_uptodate, &page->flags)) | 310 | if (!test_and_set_bit(PG_uptodate, &page->flags)) |
311 | page_set_storage_key(page_to_pfn(page), PAGE_DEFAULT_KEY, 0); | 311 | page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, 0); |
312 | #else | 312 | #else |
313 | /* | 313 | /* |
314 | * Memory barrier must be issued before setting the PG_uptodate bit, | 314 | * Memory barrier must be issued before setting the PG_uptodate bit, |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 24787b751286..a311008af5e1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2483,6 +2483,7 @@ | |||
2483 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f | 2483 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f |
2484 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 | 2484 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 |
2485 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 | 2485 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 |
2486 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI 0x1e31 | ||
2486 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40 | 2487 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40 |
2487 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f | 2488 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f |
2488 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 | 2489 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 |
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h index 77cbddb3784c..a7d87f911cab 100644 --- a/include/linux/pm_qos_params.h +++ b/include/linux/pm_qos_params.h | |||
@@ -16,6 +16,10 @@ | |||
16 | #define PM_QOS_NUM_CLASSES 4 | 16 | #define PM_QOS_NUM_CLASSES 4 |
17 | #define PM_QOS_DEFAULT_VALUE -1 | 17 | #define PM_QOS_DEFAULT_VALUE -1 |
18 | 18 | ||
19 | #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) | ||
20 | #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) | ||
21 | #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 | ||
22 | |||
19 | struct pm_qos_request_list { | 23 | struct pm_qos_request_list { |
20 | struct plist_node list; | 24 | struct plist_node list; |
21 | int pm_qos_class; | 25 | int pm_qos_class; |
diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h new file mode 100644 index 000000000000..76efbdd01622 --- /dev/null +++ b/include/linux/pnfs_osd_xdr.h | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * pNFS-osd on-the-wire data structures | ||
3 | * | ||
4 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | #ifndef __PNFS_OSD_XDR_H__ | ||
40 | #define __PNFS_OSD_XDR_H__ | ||
41 | |||
42 | #include <linux/nfs_fs.h> | ||
43 | #include <linux/nfs_page.h> | ||
44 | #include <scsi/osd_protocol.h> | ||
45 | |||
46 | #define PNFS_OSD_OSDNAME_MAXSIZE 256 | ||
47 | |||
48 | /* | ||
49 | * draft-ietf-nfsv4-minorversion-22 | ||
50 | * draft-ietf-nfsv4-pnfs-obj-12 | ||
51 | */ | ||
52 | |||
53 | /* Layout Structure */ | ||
54 | |||
55 | enum pnfs_osd_raid_algorithm4 { | ||
56 | PNFS_OSD_RAID_0 = 1, | ||
57 | PNFS_OSD_RAID_4 = 2, | ||
58 | PNFS_OSD_RAID_5 = 3, | ||
59 | PNFS_OSD_RAID_PQ = 4 /* Reed-Solomon P+Q */ | ||
60 | }; | ||
61 | |||
62 | /* struct pnfs_osd_data_map4 { | ||
63 | * uint32_t odm_num_comps; | ||
64 | * length4 odm_stripe_unit; | ||
65 | * uint32_t odm_group_width; | ||
66 | * uint32_t odm_group_depth; | ||
67 | * uint32_t odm_mirror_cnt; | ||
68 | * pnfs_osd_raid_algorithm4 odm_raid_algorithm; | ||
69 | * }; | ||
70 | */ | ||
71 | struct pnfs_osd_data_map { | ||
72 | u32 odm_num_comps; | ||
73 | u64 odm_stripe_unit; | ||
74 | u32 odm_group_width; | ||
75 | u32 odm_group_depth; | ||
76 | u32 odm_mirror_cnt; | ||
77 | u32 odm_raid_algorithm; | ||
78 | }; | ||
79 | |||
80 | /* struct pnfs_osd_objid4 { | ||
81 | * deviceid4 oid_device_id; | ||
82 | * uint64_t oid_partition_id; | ||
83 | * uint64_t oid_object_id; | ||
84 | * }; | ||
85 | */ | ||
86 | struct pnfs_osd_objid { | ||
87 | struct nfs4_deviceid oid_device_id; | ||
88 | u64 oid_partition_id; | ||
89 | u64 oid_object_id; | ||
90 | }; | ||
91 | |||
92 | /* For printout. I use: | ||
93 | * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer)); | ||
94 | * BE style | ||
95 | */ | ||
96 | #define _DEVID_LO(oid_device_id) \ | ||
97 | (unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data) | ||
98 | |||
99 | #define _DEVID_HI(oid_device_id) \ | ||
100 | (unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1) | ||
101 | |||
102 | static inline int | ||
103 | pnfs_osd_objid_xdr_sz(void) | ||
104 | { | ||
105 | return (NFS4_DEVICEID4_SIZE / 4) + 2 + 2; | ||
106 | } | ||
107 | |||
108 | enum pnfs_osd_version { | ||
109 | PNFS_OSD_MISSING = 0, | ||
110 | PNFS_OSD_VERSION_1 = 1, | ||
111 | PNFS_OSD_VERSION_2 = 2 | ||
112 | }; | ||
113 | |||
114 | struct pnfs_osd_opaque_cred { | ||
115 | u32 cred_len; | ||
116 | void *cred; | ||
117 | }; | ||
118 | |||
119 | enum pnfs_osd_cap_key_sec { | ||
120 | PNFS_OSD_CAP_KEY_SEC_NONE = 0, | ||
121 | PNFS_OSD_CAP_KEY_SEC_SSV = 1, | ||
122 | }; | ||
123 | |||
124 | /* struct pnfs_osd_object_cred4 { | ||
125 | * pnfs_osd_objid4 oc_object_id; | ||
126 | * pnfs_osd_version4 oc_osd_version; | ||
127 | * pnfs_osd_cap_key_sec4 oc_cap_key_sec; | ||
128 | * opaque oc_capability_key<>; | ||
129 | * opaque oc_capability<>; | ||
130 | * }; | ||
131 | */ | ||
132 | struct pnfs_osd_object_cred { | ||
133 | struct pnfs_osd_objid oc_object_id; | ||
134 | u32 oc_osd_version; | ||
135 | u32 oc_cap_key_sec; | ||
136 | struct pnfs_osd_opaque_cred oc_cap_key; | ||
137 | struct pnfs_osd_opaque_cred oc_cap; | ||
138 | }; | ||
139 | |||
140 | /* struct pnfs_osd_layout4 { | ||
141 | * pnfs_osd_data_map4 olo_map; | ||
142 | * uint32_t olo_comps_index; | ||
143 | * pnfs_osd_object_cred4 olo_components<>; | ||
144 | * }; | ||
145 | */ | ||
146 | struct pnfs_osd_layout { | ||
147 | struct pnfs_osd_data_map olo_map; | ||
148 | u32 olo_comps_index; | ||
149 | u32 olo_num_comps; | ||
150 | struct pnfs_osd_object_cred *olo_comps; | ||
151 | }; | ||
152 | |||
153 | /* Device Address */ | ||
154 | enum pnfs_osd_targetid_type { | ||
155 | OBJ_TARGET_ANON = 1, | ||
156 | OBJ_TARGET_SCSI_NAME = 2, | ||
157 | OBJ_TARGET_SCSI_DEVICE_ID = 3, | ||
158 | }; | ||
159 | |||
160 | /* union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) { | ||
161 | * case OBJ_TARGET_SCSI_NAME: | ||
162 | * string oti_scsi_name<>; | ||
163 | * | ||
164 | * case OBJ_TARGET_SCSI_DEVICE_ID: | ||
165 | * opaque oti_scsi_device_id<>; | ||
166 | * | ||
167 | * default: | ||
168 | * void; | ||
169 | * }; | ||
170 | * | ||
171 | * union pnfs_osd_targetaddr4 switch (bool ota_available) { | ||
172 | * case TRUE: | ||
173 | * netaddr4 ota_netaddr; | ||
174 | * case FALSE: | ||
175 | * void; | ||
176 | * }; | ||
177 | * | ||
178 | * struct pnfs_osd_deviceaddr4 { | ||
179 | * pnfs_osd_targetid4 oda_targetid; | ||
180 | * pnfs_osd_targetaddr4 oda_targetaddr; | ||
181 | * uint64_t oda_lun; | ||
182 | * opaque oda_systemid<>; | ||
183 | * pnfs_osd_object_cred4 oda_root_obj_cred; | ||
184 | * opaque oda_osdname<>; | ||
185 | * }; | ||
186 | */ | ||
187 | struct pnfs_osd_targetid { | ||
188 | u32 oti_type; | ||
189 | struct nfs4_string oti_scsi_device_id; | ||
190 | }; | ||
191 | |||
192 | enum { PNFS_OSD_TARGETID_MAX = 1 + PNFS_OSD_OSDNAME_MAXSIZE / 4 }; | ||
193 | |||
194 | /* struct netaddr4 { | ||
195 | * // see struct rpcb in RFC1833 | ||
196 | * string r_netid<>; // network id | ||
197 | * string r_addr<>; // universal address | ||
198 | * }; | ||
199 | */ | ||
200 | struct pnfs_osd_net_addr { | ||
201 | struct nfs4_string r_netid; | ||
202 | struct nfs4_string r_addr; | ||
203 | }; | ||
204 | |||
205 | struct pnfs_osd_targetaddr { | ||
206 | u32 ota_available; | ||
207 | struct pnfs_osd_net_addr ota_netaddr; | ||
208 | }; | ||
209 | |||
210 | enum { | ||
211 | NETWORK_ID_MAX = 16 / 4, | ||
212 | UNIVERSAL_ADDRESS_MAX = 64 / 4, | ||
213 | PNFS_OSD_TARGETADDR_MAX = 3 + NETWORK_ID_MAX + UNIVERSAL_ADDRESS_MAX, | ||
214 | }; | ||
215 | |||
216 | struct pnfs_osd_deviceaddr { | ||
217 | struct pnfs_osd_targetid oda_targetid; | ||
218 | struct pnfs_osd_targetaddr oda_targetaddr; | ||
219 | u8 oda_lun[8]; | ||
220 | struct nfs4_string oda_systemid; | ||
221 | struct pnfs_osd_object_cred oda_root_obj_cred; | ||
222 | struct nfs4_string oda_osdname; | ||
223 | }; | ||
224 | |||
225 | enum { | ||
226 | ODA_OSDNAME_MAX = PNFS_OSD_OSDNAME_MAXSIZE / 4, | ||
227 | PNFS_OSD_DEVICEADDR_MAX = | ||
228 | PNFS_OSD_TARGETID_MAX + PNFS_OSD_TARGETADDR_MAX + | ||
229 | 2 /*oda_lun*/ + | ||
230 | 1 + OSD_SYSTEMID_LEN + | ||
231 | 1 + ODA_OSDNAME_MAX, | ||
232 | }; | ||
233 | |||
234 | /* LAYOUTCOMMIT: layoutupdate */ | ||
235 | |||
236 | /* union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) { | ||
237 | * case TRUE: | ||
238 | * int64_t dsu_delta; | ||
239 | * case FALSE: | ||
240 | * void; | ||
241 | * }; | ||
242 | * | ||
243 | * struct pnfs_osd_layoutupdate4 { | ||
244 | * pnfs_osd_deltaspaceused4 olu_delta_space_used; | ||
245 | * bool olu_ioerr_flag; | ||
246 | * }; | ||
247 | */ | ||
248 | struct pnfs_osd_layoutupdate { | ||
249 | u32 dsu_valid; | ||
250 | s64 dsu_delta; | ||
251 | u32 olu_ioerr_flag; | ||
252 | }; | ||
253 | |||
254 | /* LAYOUTRETURN: I/O Rrror Report */ | ||
255 | |||
256 | enum pnfs_osd_errno { | ||
257 | PNFS_OSD_ERR_EIO = 1, | ||
258 | PNFS_OSD_ERR_NOT_FOUND = 2, | ||
259 | PNFS_OSD_ERR_NO_SPACE = 3, | ||
260 | PNFS_OSD_ERR_BAD_CRED = 4, | ||
261 | PNFS_OSD_ERR_NO_ACCESS = 5, | ||
262 | PNFS_OSD_ERR_UNREACHABLE = 6, | ||
263 | PNFS_OSD_ERR_RESOURCE = 7 | ||
264 | }; | ||
265 | |||
266 | /* struct pnfs_osd_ioerr4 { | ||
267 | * pnfs_osd_objid4 oer_component; | ||
268 | * length4 oer_comp_offset; | ||
269 | * length4 oer_comp_length; | ||
270 | * bool oer_iswrite; | ||
271 | * pnfs_osd_errno4 oer_errno; | ||
272 | * }; | ||
273 | */ | ||
274 | struct pnfs_osd_ioerr { | ||
275 | struct pnfs_osd_objid oer_component; | ||
276 | u64 oer_comp_offset; | ||
277 | u64 oer_comp_length; | ||
278 | u32 oer_iswrite; | ||
279 | u32 oer_errno; | ||
280 | }; | ||
281 | |||
282 | /* OSD XDR API */ | ||
283 | /* Layout helpers */ | ||
284 | /* Layout decoding is done in two parts: | ||
285 | * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part | ||
286 | * of the layout. @iter members need not be initialized. | ||
287 | * Returned: | ||
288 | * @layout members are set. (@layout->olo_comps set to NULL). | ||
289 | * | ||
290 | * Zero on success, or negative error if passed xdr is broken. | ||
291 | * | ||
292 | * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns | ||
293 | * false, to decode the next component. | ||
294 | * Returned: | ||
295 | * true if there is more to decode or false if we are done or error. | ||
296 | * | ||
297 | * Example: | ||
298 | * struct pnfs_osd_xdr_decode_layout_iter iter; | ||
299 | * struct pnfs_osd_layout layout; | ||
300 | * struct pnfs_osd_object_cred comp; | ||
301 | * int status; | ||
302 | * | ||
303 | * status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); | ||
304 | * if (unlikely(status)) | ||
305 | * goto err; | ||
306 | * while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) { | ||
307 | * // All of @comp strings point to inside the xdr_buffer | ||
308 | * // or scrach buffer. Copy them out to user memory eg. | ||
309 | * copy_single_comp(dest_comp++, &comp); | ||
310 | * } | ||
311 | * if (unlikely(status)) | ||
312 | * goto err; | ||
313 | */ | ||
314 | |||
315 | struct pnfs_osd_xdr_decode_layout_iter { | ||
316 | unsigned total_comps; | ||
317 | unsigned decoded_comps; | ||
318 | }; | ||
319 | |||
320 | extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, | ||
321 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr); | ||
322 | |||
323 | extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, | ||
324 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, | ||
325 | int *err); | ||
326 | |||
327 | /* Device Info helpers */ | ||
328 | |||
329 | /* Note: All strings inside @deviceaddr point to space inside @p. | ||
330 | * @p should stay valid while @deviceaddr is in use. | ||
331 | */ | ||
332 | extern void pnfs_osd_xdr_decode_deviceaddr( | ||
333 | struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p); | ||
334 | |||
335 | /* layoutupdate (layout_commit) xdr helpers */ | ||
336 | extern int | ||
337 | pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, | ||
338 | struct pnfs_osd_layoutupdate *lou); | ||
339 | |||
340 | /* osd_ioerror encoding/decoding (layout_return) */ | ||
341 | /* Client */ | ||
342 | extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr); | ||
343 | extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr); | ||
344 | |||
345 | #endif /* __PNFS_OSD_XDR_H__ */ | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index dc8871295a5a..2a8621c4be1e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1546,7 +1546,7 @@ struct task_struct { | |||
1546 | #ifdef CONFIG_TRACING | 1546 | #ifdef CONFIG_TRACING |
1547 | /* state flags for use by tracers */ | 1547 | /* state flags for use by tracers */ |
1548 | unsigned long trace; | 1548 | unsigned long trace; |
1549 | /* bitmask of trace recursion */ | 1549 | /* bitmask and counter of trace recursion */ |
1550 | unsigned long trace_recursion; | 1550 | unsigned long trace_recursion; |
1551 | #endif /* CONFIG_TRACING */ | 1551 | #endif /* CONFIG_TRACING */ |
1552 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ | 1552 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ |
@@ -1841,9 +1841,16 @@ static inline void rcu_copy_process(struct task_struct *p) | |||
1841 | #endif | 1841 | #endif |
1842 | 1842 | ||
1843 | #ifdef CONFIG_SMP | 1843 | #ifdef CONFIG_SMP |
1844 | extern void do_set_cpus_allowed(struct task_struct *p, | ||
1845 | const struct cpumask *new_mask); | ||
1846 | |||
1844 | extern int set_cpus_allowed_ptr(struct task_struct *p, | 1847 | extern int set_cpus_allowed_ptr(struct task_struct *p, |
1845 | const struct cpumask *new_mask); | 1848 | const struct cpumask *new_mask); |
1846 | #else | 1849 | #else |
1850 | static inline void do_set_cpus_allowed(struct task_struct *p, | ||
1851 | const struct cpumask *new_mask) | ||
1852 | { | ||
1853 | } | ||
1847 | static inline int set_cpus_allowed_ptr(struct task_struct *p, | 1854 | static inline int set_cpus_allowed_ptr(struct task_struct *p, |
1848 | const struct cpumask *new_mask) | 1855 | const struct cpumask *new_mask) |
1849 | { | 1856 | { |
@@ -2187,7 +2194,6 @@ static inline void mmdrop(struct mm_struct * mm) | |||
2187 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 2194 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
2188 | __mmdrop(mm); | 2195 | __mmdrop(mm); |
2189 | } | 2196 | } |
2190 | extern int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm); | ||
2191 | 2197 | ||
2192 | /* mmput gets rid of the mappings and all user-space */ | 2198 | /* mmput gets rid of the mappings and all user-space */ |
2193 | extern void mmput(struct mm_struct *); | 2199 | extern void mmput(struct mm_struct *); |
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h index 77e624883393..c68a147939a6 100644 --- a/include/linux/sunrpc/msg_prot.h +++ b/include/linux/sunrpc/msg_prot.h | |||
@@ -145,6 +145,7 @@ typedef __be32 rpc_fraghdr; | |||
145 | #define RPCBIND_NETID_TCP "tcp" | 145 | #define RPCBIND_NETID_TCP "tcp" |
146 | #define RPCBIND_NETID_UDP6 "udp6" | 146 | #define RPCBIND_NETID_UDP6 "udp6" |
147 | #define RPCBIND_NETID_TCP6 "tcp6" | 147 | #define RPCBIND_NETID_TCP6 "tcp6" |
148 | #define RPCBIND_NETID_LOCAL "local" | ||
148 | 149 | ||
149 | /* | 150 | /* |
150 | * Note that RFC 1833 does not put any size restrictions on the | 151 | * Note that RFC 1833 does not put any size restrictions on the |
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 04dba23c59f2..85c50b40759d 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h | |||
@@ -28,6 +28,7 @@ struct svc_sock { | |||
28 | /* private TCP part */ | 28 | /* private TCP part */ |
29 | u32 sk_reclen; /* length of record */ | 29 | u32 sk_reclen; /* length of record */ |
30 | u32 sk_tcplen; /* current read length */ | 30 | u32 sk_tcplen; /* current read length */ |
31 | struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */ | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | /* | 34 | /* |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index fc84b7a19ca3..a20970ef9e4e 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -216,6 +216,8 @@ extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); | |||
216 | extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, | 216 | extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, |
217 | unsigned int base, unsigned int len); | 217 | unsigned int base, unsigned int len); |
218 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); | 218 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); |
219 | extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, | ||
220 | struct page **pages, unsigned int len); | ||
219 | extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen); | 221 | extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen); |
220 | extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); | 222 | extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); |
221 | extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); | 223 | extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index a0f998c07c65..81cce3b3ee66 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -141,7 +141,8 @@ enum xprt_transports { | |||
141 | XPRT_TRANSPORT_UDP = IPPROTO_UDP, | 141 | XPRT_TRANSPORT_UDP = IPPROTO_UDP, |
142 | XPRT_TRANSPORT_TCP = IPPROTO_TCP, | 142 | XPRT_TRANSPORT_TCP = IPPROTO_TCP, |
143 | XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, | 143 | XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, |
144 | XPRT_TRANSPORT_RDMA = 256 | 144 | XPRT_TRANSPORT_RDMA = 256, |
145 | XPRT_TRANSPORT_LOCAL = 257, | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | struct rpc_xprt { | 148 | struct rpc_xprt { |
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index d512d98dfb7d..5ca0951e1855 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h | |||
@@ -93,8 +93,8 @@ static inline unsigned long __copy_from_user_nocache(void *to, | |||
93 | * Safely read from address @src to the buffer at @dst. If a kernel fault | 93 | * Safely read from address @src to the buffer at @dst. If a kernel fault |
94 | * happens, handle that and return -EFAULT. | 94 | * happens, handle that and return -EFAULT. |
95 | */ | 95 | */ |
96 | extern long probe_kernel_read(void *dst, void *src, size_t size); | 96 | extern long probe_kernel_read(void *dst, const void *src, size_t size); |
97 | extern long __probe_kernel_read(void *dst, void *src, size_t size); | 97 | extern long __probe_kernel_read(void *dst, const void *src, size_t size); |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * probe_kernel_write(): safely attempt to write to a location | 100 | * probe_kernel_write(): safely attempt to write to a location |
@@ -105,7 +105,7 @@ extern long __probe_kernel_read(void *dst, void *src, size_t size); | |||
105 | * Safely write to address @dst from the buffer at @src. If a kernel fault | 105 | * Safely write to address @dst from the buffer at @src. If a kernel fault |
106 | * happens, handle that and return -EFAULT. | 106 | * happens, handle that and return -EFAULT. |
107 | */ | 107 | */ |
108 | extern long notrace probe_kernel_write(void *dst, void *src, size_t size); | 108 | extern long notrace probe_kernel_write(void *dst, const void *src, size_t size); |
109 | extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); | 109 | extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size); |
110 | 110 | ||
111 | #endif /* __LINUX_UACCESS_H__ */ | 111 | #endif /* __LINUX_UACCESS_H__ */ |
diff --git a/include/linux/virtio.h b/include/linux/virtio.h index aff5b4f74041..710885749605 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h | |||
@@ -51,6 +51,13 @@ struct virtqueue { | |||
51 | * This re-enables callbacks; it returns "false" if there are pending | 51 | * This re-enables callbacks; it returns "false" if there are pending |
52 | * buffers in the queue, to detect a possible race between the driver | 52 | * buffers in the queue, to detect a possible race between the driver |
53 | * checking for more work, and enabling callbacks. | 53 | * checking for more work, and enabling callbacks. |
54 | * virtqueue_enable_cb_delayed: restart callbacks after disable_cb. | ||
55 | * vq: the struct virtqueue we're talking about. | ||
56 | * This re-enables callbacks but hints to the other side to delay | ||
57 | * interrupts until most of the available buffers have been processed; | ||
58 | * it returns "false" if there are many pending buffers in the queue, | ||
59 | * to detect a possible race between the driver checking for more work, | ||
60 | * and enabling callbacks. | ||
54 | * virtqueue_detach_unused_buf: detach first unused buffer | 61 | * virtqueue_detach_unused_buf: detach first unused buffer |
55 | * vq: the struct virtqueue we're talking about. | 62 | * vq: the struct virtqueue we're talking about. |
56 | * Returns NULL or the "data" token handed to add_buf | 63 | * Returns NULL or the "data" token handed to add_buf |
@@ -86,6 +93,8 @@ void virtqueue_disable_cb(struct virtqueue *vq); | |||
86 | 93 | ||
87 | bool virtqueue_enable_cb(struct virtqueue *vq); | 94 | bool virtqueue_enable_cb(struct virtqueue *vq); |
88 | 95 | ||
96 | bool virtqueue_enable_cb_delayed(struct virtqueue *vq); | ||
97 | |||
89 | void *virtqueue_detach_unused_buf(struct virtqueue *vq); | 98 | void *virtqueue_detach_unused_buf(struct virtqueue *vq); |
90 | 99 | ||
91 | /** | 100 | /** |
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h index e68b439b2860..277c4ad44e84 100644 --- a/include/linux/virtio_9p.h +++ b/include/linux/virtio_9p.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_9P_H | 1 | #ifndef _LINUX_VIRTIO_9P_H |
2 | #define _LINUX_VIRTIO_9P_H | 2 | #define _LINUX_VIRTIO_9P_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/types.h> | 28 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 29 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 30 | #include <linux/virtio_config.h> |
diff --git a/include/linux/virtio_balloon.h b/include/linux/virtio_balloon.h index a50ecd1b81a2..652dc8bea921 100644 --- a/include/linux/virtio_balloon.h +++ b/include/linux/virtio_balloon.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_BALLOON_H | 1 | #ifndef _LINUX_VIRTIO_BALLOON_H |
2 | #define _LINUX_VIRTIO_BALLOON_H | 2 | #define _LINUX_VIRTIO_BALLOON_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/virtio_ids.h> | 28 | #include <linux/virtio_ids.h> |
6 | #include <linux/virtio_config.h> | 29 | #include <linux/virtio_config.h> |
7 | 30 | ||
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h index 167720d695ed..e0edb40ca7aa 100644 --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_BLK_H | 1 | #ifndef _LINUX_VIRTIO_BLK_H |
2 | #define _LINUX_VIRTIO_BLK_H | 2 | #define _LINUX_VIRTIO_BLK_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/types.h> | 28 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 29 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 30 | #include <linux/virtio_config.h> |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 800617b4ddd5..39c88c5ad19d 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_CONFIG_H | 1 | #ifndef _LINUX_VIRTIO_CONFIG_H |
2 | #define _LINUX_VIRTIO_CONFIG_H | 2 | #define _LINUX_VIRTIO_CONFIG_H |
3 | /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | 3 | /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so |
4 | * anyone can use the definitions to implement compatible drivers/servers. */ | 4 | * anyone can use the definitions to implement compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | 28 | ||
6 | /* Virtio devices use a standardized configuration space to define their | 29 | /* Virtio devices use a standardized configuration space to define their |
7 | * features and pass configuration information, but each implementation can | 30 | * features and pass configuration information, but each implementation can |
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index e4d333543a33..bdf4b0034739 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h | |||
@@ -5,7 +5,31 @@ | |||
5 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
6 | /* | 6 | /* |
7 | * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | 7 | * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so |
8 | * anyone can use the definitions to implement compatible drivers/servers. | 8 | * anyone can use the definitions to implement compatible drivers/servers: |
9 | * | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * 3. Neither the name of IBM nor the names of its contributors | ||
20 | * may be used to endorse or promote products derived from this software | ||
21 | * without specific prior written permission. | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | * SUCH DAMAGE. | ||
9 | * | 33 | * |
10 | * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 | 34 | * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 |
11 | * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011 | 35 | * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011 |
diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h index 06660c0a78d7..85bb0bb66ffc 100644 --- a/include/linux/virtio_ids.h +++ b/include/linux/virtio_ids.h | |||
@@ -5,7 +5,29 @@ | |||
5 | * | 5 | * |
6 | * This header is BSD licensed so anyone can use the definitions to implement | 6 | * This header is BSD licensed so anyone can use the definitions to implement |
7 | * compatible drivers/servers. | 7 | * compatible drivers/servers. |
8 | */ | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of IBM nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGE. */ | ||
9 | 31 | ||
10 | #define VIRTIO_ID_NET 1 /* virtio net */ | 32 | #define VIRTIO_ID_NET 1 /* virtio net */ |
11 | #define VIRTIO_ID_BLOCK 2 /* virtio block */ | 33 | #define VIRTIO_ID_BLOCK 2 /* virtio block */ |
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 085e42298ce5..136040bba3e3 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_NET_H | 1 | #ifndef _LINUX_VIRTIO_NET_H |
2 | #define _LINUX_VIRTIO_NET_H | 2 | #define _LINUX_VIRTIO_NET_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/types.h> | 28 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 29 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 30 | #include <linux/virtio_config.h> |
diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h index 9a3d7c48c622..ea66f3f60d63 100644 --- a/include/linux/virtio_pci.h +++ b/include/linux/virtio_pci.h | |||
@@ -11,6 +11,29 @@ | |||
11 | * | 11 | * |
12 | * This header is BSD licensed so anyone can use the definitions to implement | 12 | * This header is BSD licensed so anyone can use the definitions to implement |
13 | * compatible drivers/servers. | 13 | * compatible drivers/servers. |
14 | * | ||
15 | * Redistribution and use in source and binary forms, with or without | ||
16 | * modification, are permitted provided that the following conditions | ||
17 | * are met: | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of IBM nor the names of its contributors | ||
24 | * may be used to endorse or promote products derived from this software | ||
25 | * without specific prior written permission. | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
29 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
36 | * SUCH DAMAGE. | ||
14 | */ | 37 | */ |
15 | 38 | ||
16 | #ifndef _LINUX_VIRTIO_PCI_H | 39 | #ifndef _LINUX_VIRTIO_PCI_H |
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index e4d144b132b5..4a32cb6da425 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h | |||
@@ -7,6 +7,29 @@ | |||
7 | * This header is BSD licensed so anyone can use the definitions to implement | 7 | * This header is BSD licensed so anyone can use the definitions to implement |
8 | * compatible drivers/servers. | 8 | * compatible drivers/servers. |
9 | * | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of IBM nor the names of its contributors | ||
19 | * may be used to endorse or promote products derived from this software | ||
20 | * without specific prior written permission. | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
32 | * | ||
10 | * Copyright Rusty Russell IBM Corporation 2007. */ | 33 | * Copyright Rusty Russell IBM Corporation 2007. */ |
11 | #include <linux/types.h> | 34 | #include <linux/types.h> |
12 | 35 | ||
@@ -29,6 +52,12 @@ | |||
29 | /* We support indirect buffer descriptors */ | 52 | /* We support indirect buffer descriptors */ |
30 | #define VIRTIO_RING_F_INDIRECT_DESC 28 | 53 | #define VIRTIO_RING_F_INDIRECT_DESC 28 |
31 | 54 | ||
55 | /* The Guest publishes the used index for which it expects an interrupt | ||
56 | * at the end of the avail ring. Host should ignore the avail->flags field. */ | ||
57 | /* The Host publishes the avail index for which it expects a kick | ||
58 | * at the end of the used ring. Guest should ignore the used->flags field. */ | ||
59 | #define VIRTIO_RING_F_EVENT_IDX 29 | ||
60 | |||
32 | /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ | 61 | /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ |
33 | struct vring_desc { | 62 | struct vring_desc { |
34 | /* Address (guest-physical). */ | 63 | /* Address (guest-physical). */ |
@@ -83,6 +112,7 @@ struct vring { | |||
83 | * __u16 avail_flags; | 112 | * __u16 avail_flags; |
84 | * __u16 avail_idx; | 113 | * __u16 avail_idx; |
85 | * __u16 available[num]; | 114 | * __u16 available[num]; |
115 | * __u16 used_event_idx; | ||
86 | * | 116 | * |
87 | * // Padding to the next align boundary. | 117 | * // Padding to the next align boundary. |
88 | * char pad[]; | 118 | * char pad[]; |
@@ -91,8 +121,14 @@ struct vring { | |||
91 | * __u16 used_flags; | 121 | * __u16 used_flags; |
92 | * __u16 used_idx; | 122 | * __u16 used_idx; |
93 | * struct vring_used_elem used[num]; | 123 | * struct vring_used_elem used[num]; |
124 | * __u16 avail_event_idx; | ||
94 | * }; | 125 | * }; |
95 | */ | 126 | */ |
127 | /* We publish the used event index at the end of the available ring, and vice | ||
128 | * versa. They are at the end for backwards compatibility. */ | ||
129 | #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) | ||
130 | #define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) | ||
131 | |||
96 | static inline void vring_init(struct vring *vr, unsigned int num, void *p, | 132 | static inline void vring_init(struct vring *vr, unsigned int num, void *p, |
97 | unsigned long align) | 133 | unsigned long align) |
98 | { | 134 | { |
@@ -107,7 +143,21 @@ static inline unsigned vring_size(unsigned int num, unsigned long align) | |||
107 | { | 143 | { |
108 | return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) | 144 | return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) |
109 | + align - 1) & ~(align - 1)) | 145 | + align - 1) & ~(align - 1)) |
110 | + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num; | 146 | + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num; |
147 | } | ||
148 | |||
149 | /* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ | ||
150 | /* Assuming a given event_idx value from the other size, if | ||
151 | * we have just incremented index from old to new_idx, | ||
152 | * should we trigger an event? */ | ||
153 | static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old) | ||
154 | { | ||
155 | /* Note: Xen has similar logic for notification hold-off | ||
156 | * in include/xen/interface/io/ring.h with req_event and req_prod | ||
157 | * corresponding to event_idx + 1 and new_idx respectively. | ||
158 | * Note also that req_event and req_prod in Xen start at 1, | ||
159 | * event indexes in virtio start at 0. */ | ||
160 | return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old); | ||
111 | } | 161 | } |
112 | 162 | ||
113 | #ifdef __KERNEL__ | 163 | #ifdef __KERNEL__ |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 8f6bb9c7f3eb..ee866060f8a4 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -604,6 +604,7 @@ struct sas_domain_function_template { | |||
604 | int (*lldd_clear_aca)(struct domain_device *, u8 *lun); | 604 | int (*lldd_clear_aca)(struct domain_device *, u8 *lun); |
605 | int (*lldd_clear_task_set)(struct domain_device *, u8 *lun); | 605 | int (*lldd_clear_task_set)(struct domain_device *, u8 *lun); |
606 | int (*lldd_I_T_nexus_reset)(struct domain_device *); | 606 | int (*lldd_I_T_nexus_reset)(struct domain_device *); |
607 | int (*lldd_ata_soft_reset)(struct domain_device *); | ||
607 | int (*lldd_lu_reset)(struct domain_device *, u8 *lun); | 608 | int (*lldd_lu_reset)(struct domain_device *, u8 *lun); |
608 | int (*lldd_query_task)(struct sas_task *); | 609 | int (*lldd_query_task)(struct sas_task *); |
609 | 610 | ||
diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index d6e7994aa634..81dd12edc38c 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h | |||
@@ -9,6 +9,7 @@ | |||
9 | #define MSG_SIMPLE_TAG 0x20 | 9 | #define MSG_SIMPLE_TAG 0x20 |
10 | #define MSG_HEAD_TAG 0x21 | 10 | #define MSG_HEAD_TAG 0x21 |
11 | #define MSG_ORDERED_TAG 0x22 | 11 | #define MSG_ORDERED_TAG 0x22 |
12 | #define MSG_ACA_TAG 0x24 /* unsupported */ | ||
12 | 13 | ||
13 | #define SCSI_NO_TAG (-1) /* identify no tag in use */ | 14 | #define SCSI_NO_TAG (-1) /* identify no tag in use */ |
14 | 15 | ||
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 1d3b5b2f0dbc..561ac99def5a 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -98,6 +98,7 @@ enum transport_state_table { | |||
98 | TRANSPORT_REMOVE = 14, | 98 | TRANSPORT_REMOVE = 14, |
99 | TRANSPORT_FREE = 15, | 99 | TRANSPORT_FREE = 15, |
100 | TRANSPORT_NEW_CMD_MAP = 16, | 100 | TRANSPORT_NEW_CMD_MAP = 16, |
101 | TRANSPORT_FREE_CMD_INTR = 17, | ||
101 | }; | 102 | }; |
102 | 103 | ||
103 | /* Used for struct se_cmd->se_cmd_flags */ | 104 | /* Used for struct se_cmd->se_cmd_flags */ |
diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h index dc78f77f9450..747e1404dca0 100644 --- a/include/target/target_core_fabric_ops.h +++ b/include/target/target_core_fabric_ops.h | |||
@@ -77,7 +77,6 @@ struct target_core_fabric_ops { | |||
77 | u16 (*set_fabric_sense_len)(struct se_cmd *, u32); | 77 | u16 (*set_fabric_sense_len)(struct se_cmd *, u32); |
78 | u16 (*get_fabric_sense_len)(void); | 78 | u16 (*get_fabric_sense_len)(void); |
79 | int (*is_state_remove)(struct se_cmd *); | 79 | int (*is_state_remove)(struct se_cmd *); |
80 | u64 (*pack_lun)(unsigned int); | ||
81 | /* | 80 | /* |
82 | * fabric module calls for target_core_fabric_configfs.c | 81 | * fabric module calls for target_core_fabric_configfs.c |
83 | */ | 82 | */ |
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h index 59aa464f6ee2..24a1c6cb83c3 100644 --- a/include/target/target_core_transport.h +++ b/include/target/target_core_transport.h | |||
@@ -172,6 +172,7 @@ extern int transport_generic_handle_cdb_map(struct se_cmd *); | |||
172 | extern int transport_generic_handle_data(struct se_cmd *); | 172 | extern int transport_generic_handle_data(struct se_cmd *); |
173 | extern void transport_new_cmd_failure(struct se_cmd *); | 173 | extern void transport_new_cmd_failure(struct se_cmd *); |
174 | extern int transport_generic_handle_tmr(struct se_cmd *); | 174 | extern int transport_generic_handle_tmr(struct se_cmd *); |
175 | extern void transport_generic_free_cmd_intr(struct se_cmd *); | ||
175 | extern void __transport_stop_task_timer(struct se_task *, unsigned long *); | 176 | extern void __transport_stop_task_timer(struct se_task *, unsigned long *); |
176 | extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]); | 177 | extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]); |
177 | extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, | 178 | extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, |
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index f445cff66ab7..4114129f0794 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h | |||
@@ -28,7 +28,7 @@ struct extent_buffer; | |||
28 | { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) | 28 | { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) |
29 | 29 | ||
30 | #define __show_root_type(obj) \ | 30 | #define __show_root_type(obj) \ |
31 | __print_symbolic(obj, \ | 31 | __print_symbolic_u64(obj, \ |
32 | { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ | 32 | { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ |
33 | { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ | 33 | { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ |
34 | { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ | 34 | { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ |
@@ -125,7 +125,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, | |||
125 | ); | 125 | ); |
126 | 126 | ||
127 | #define __show_map_type(type) \ | 127 | #define __show_map_type(type) \ |
128 | __print_symbolic(type, \ | 128 | __print_symbolic_u64(type, \ |
129 | { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ | 129 | { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ |
130 | { EXTENT_MAP_HOLE, "HOLE" }, \ | 130 | { EXTENT_MAP_HOLE, "HOLE" }, \ |
131 | { EXTENT_MAP_INLINE, "INLINE" }, \ | 131 | { EXTENT_MAP_INLINE, "INLINE" }, \ |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 3e68366d485a..533c49f48047 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -205,6 +205,19 @@ | |||
205 | ftrace_print_symbols_seq(p, value, symbols); \ | 205 | ftrace_print_symbols_seq(p, value, symbols); \ |
206 | }) | 206 | }) |
207 | 207 | ||
208 | #undef __print_symbolic_u64 | ||
209 | #if BITS_PER_LONG == 32 | ||
210 | #define __print_symbolic_u64(value, symbol_array...) \ | ||
211 | ({ \ | ||
212 | static const struct trace_print_flags_u64 symbols[] = \ | ||
213 | { symbol_array, { -1, NULL } }; \ | ||
214 | ftrace_print_symbols_seq_u64(p, value, symbols); \ | ||
215 | }) | ||
216 | #else | ||
217 | #define __print_symbolic_u64(value, symbol_array...) \ | ||
218 | __print_symbolic(value, symbol_array) | ||
219 | #endif | ||
220 | |||
208 | #undef __print_hex | 221 | #undef __print_hex |
209 | #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) | 222 | #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) |
210 | 223 | ||
diff --git a/init/main.c b/init/main.c index d2f1e086bf33..cafba67c13bf 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -487,6 +487,7 @@ asmlinkage void __init start_kernel(void) | |||
487 | printk(KERN_NOTICE "%s", linux_banner); | 487 | printk(KERN_NOTICE "%s", linux_banner); |
488 | setup_arch(&command_line); | 488 | setup_arch(&command_line); |
489 | mm_init_owner(&init_mm, &init_task); | 489 | mm_init_owner(&init_mm, &init_task); |
490 | mm_init_cpumask(&init_mm); | ||
490 | setup_command_line(command_line); | 491 | setup_command_line(command_line); |
491 | setup_nr_cpu_ids(); | 492 | setup_nr_cpu_ids(); |
492 | setup_per_cpu_areas(); | 493 | setup_per_cpu_areas(); |
@@ -510,7 +511,6 @@ asmlinkage void __init start_kernel(void) | |||
510 | sort_main_extable(); | 511 | sort_main_extable(); |
511 | trap_init(); | 512 | trap_init(); |
512 | mm_init(); | 513 | mm_init(); |
513 | BUG_ON(mm_init_cpumask(&init_mm, 0)); | ||
514 | 514 | ||
515 | /* | 515 | /* |
516 | * Set up the scheduler prior starting any interrupts (such as the | 516 | * Set up the scheduler prior starting any interrupts (such as the |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 1ceeb049c827..9c9b7545c810 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -2190,7 +2190,7 @@ int cpuset_cpus_allowed_fallback(struct task_struct *tsk) | |||
2190 | rcu_read_lock(); | 2190 | rcu_read_lock(); |
2191 | cs = task_cs(tsk); | 2191 | cs = task_cs(tsk); |
2192 | if (cs) | 2192 | if (cs) |
2193 | cpumask_copy(&tsk->cpus_allowed, cs->cpus_allowed); | 2193 | do_set_cpus_allowed(tsk, cs->cpus_allowed); |
2194 | rcu_read_unlock(); | 2194 | rcu_read_unlock(); |
2195 | 2195 | ||
2196 | /* | 2196 | /* |
@@ -2217,7 +2217,7 @@ int cpuset_cpus_allowed_fallback(struct task_struct *tsk) | |||
2217 | * Like above we can temporary set any mask and rely on | 2217 | * Like above we can temporary set any mask and rely on |
2218 | * set_cpus_allowed_ptr() as synchronization point. | 2218 | * set_cpus_allowed_ptr() as synchronization point. |
2219 | */ | 2219 | */ |
2220 | cpumask_copy(&tsk->cpus_allowed, cpu_possible_mask); | 2220 | do_set_cpus_allowed(tsk, cpu_possible_mask); |
2221 | cpu = cpumask_any(cpu_active_mask); | 2221 | cpu = cpumask_any(cpu_active_mask); |
2222 | } | 2222 | } |
2223 | 2223 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index 8a15944bf9d2..9efe7108ccaf 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -5028,6 +5028,14 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, | |||
5028 | else | 5028 | else |
5029 | perf_event_output(event, nmi, data, regs); | 5029 | perf_event_output(event, nmi, data, regs); |
5030 | 5030 | ||
5031 | if (event->fasync && event->pending_kill) { | ||
5032 | if (nmi) { | ||
5033 | event->pending_wakeup = 1; | ||
5034 | irq_work_queue(&event->pending); | ||
5035 | } else | ||
5036 | perf_event_wakeup(event); | ||
5037 | } | ||
5038 | |||
5031 | return ret; | 5039 | return ret; |
5032 | } | 5040 | } |
5033 | 5041 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index ca406d916713..0276c30401a0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -484,20 +484,6 @@ static void mm_init_aio(struct mm_struct *mm) | |||
484 | #endif | 484 | #endif |
485 | } | 485 | } |
486 | 486 | ||
487 | int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm) | ||
488 | { | ||
489 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
490 | if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL)) | ||
491 | return -ENOMEM; | ||
492 | |||
493 | if (oldmm) | ||
494 | cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm)); | ||
495 | else | ||
496 | memset(mm_cpumask(mm), 0, cpumask_size()); | ||
497 | #endif | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 487 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) |
502 | { | 488 | { |
503 | atomic_set(&mm->mm_users, 1); | 489 | atomic_set(&mm->mm_users, 1); |
@@ -538,17 +524,8 @@ struct mm_struct * mm_alloc(void) | |||
538 | return NULL; | 524 | return NULL; |
539 | 525 | ||
540 | memset(mm, 0, sizeof(*mm)); | 526 | memset(mm, 0, sizeof(*mm)); |
541 | mm = mm_init(mm, current); | 527 | mm_init_cpumask(mm); |
542 | if (!mm) | 528 | return mm_init(mm, current); |
543 | return NULL; | ||
544 | |||
545 | if (mm_init_cpumask(mm, NULL)) { | ||
546 | mm_free_pgd(mm); | ||
547 | free_mm(mm); | ||
548 | return NULL; | ||
549 | } | ||
550 | |||
551 | return mm; | ||
552 | } | 529 | } |
553 | 530 | ||
554 | /* | 531 | /* |
@@ -559,7 +536,6 @@ struct mm_struct * mm_alloc(void) | |||
559 | void __mmdrop(struct mm_struct *mm) | 536 | void __mmdrop(struct mm_struct *mm) |
560 | { | 537 | { |
561 | BUG_ON(mm == &init_mm); | 538 | BUG_ON(mm == &init_mm); |
562 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
563 | mm_free_pgd(mm); | 539 | mm_free_pgd(mm); |
564 | destroy_context(mm); | 540 | destroy_context(mm); |
565 | mmu_notifier_mm_destroy(mm); | 541 | mmu_notifier_mm_destroy(mm); |
@@ -753,6 +729,7 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
753 | goto fail_nomem; | 729 | goto fail_nomem; |
754 | 730 | ||
755 | memcpy(mm, oldmm, sizeof(*mm)); | 731 | memcpy(mm, oldmm, sizeof(*mm)); |
732 | mm_init_cpumask(mm); | ||
756 | 733 | ||
757 | /* Initializing for Swap token stuff */ | 734 | /* Initializing for Swap token stuff */ |
758 | mm->token_priority = 0; | 735 | mm->token_priority = 0; |
@@ -765,9 +742,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
765 | if (!mm_init(mm, tsk)) | 742 | if (!mm_init(mm, tsk)) |
766 | goto fail_nomem; | 743 | goto fail_nomem; |
767 | 744 | ||
768 | if (mm_init_cpumask(mm, oldmm)) | ||
769 | goto fail_nocpumask; | ||
770 | |||
771 | if (init_new_context(tsk, mm)) | 745 | if (init_new_context(tsk, mm)) |
772 | goto fail_nocontext; | 746 | goto fail_nocontext; |
773 | 747 | ||
@@ -794,9 +768,6 @@ fail_nomem: | |||
794 | return NULL; | 768 | return NULL; |
795 | 769 | ||
796 | fail_nocontext: | 770 | fail_nocontext: |
797 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
798 | |||
799 | fail_nocpumask: | ||
800 | /* | 771 | /* |
801 | * If init_new_context() failed, we cannot use mmput() to free the mm | 772 | * If init_new_context() failed, we cannot use mmput() to free the mm |
802 | * because it calls destroy_context() | 773 | * because it calls destroy_context() |
@@ -1591,6 +1562,13 @@ void __init proc_caches_init(void) | |||
1591 | fs_cachep = kmem_cache_create("fs_cache", | 1562 | fs_cachep = kmem_cache_create("fs_cache", |
1592 | sizeof(struct fs_struct), 0, | 1563 | sizeof(struct fs_struct), 0, |
1593 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); | 1564 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
1565 | /* | ||
1566 | * FIXME! The "sizeof(struct mm_struct)" currently includes the | ||
1567 | * whole struct cpumask for the OFFSTACK case. We could change | ||
1568 | * this to *only* allocate as much of it as required by the | ||
1569 | * maximum number of CPU's we can ever have. The cpumask_allocation | ||
1570 | * is at the end of the structure, exactly for that reason. | ||
1571 | */ | ||
1594 | mm_cachep = kmem_cache_create("mm_struct", | 1572 | mm_cachep = kmem_cache_create("mm_struct", |
1595 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, | 1573 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
1596 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); | 1574 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 74d1c099fbd1..fa27e750dbc0 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
@@ -105,9 +105,12 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start, | |||
105 | } | 105 | } |
106 | 106 | ||
107 | static void __jump_label_update(struct jump_label_key *key, | 107 | static void __jump_label_update(struct jump_label_key *key, |
108 | struct jump_entry *entry, int enable) | 108 | struct jump_entry *entry, |
109 | struct jump_entry *stop, int enable) | ||
109 | { | 110 | { |
110 | for (; entry->key == (jump_label_t)(unsigned long)key; entry++) { | 111 | for (; (entry < stop) && |
112 | (entry->key == (jump_label_t)(unsigned long)key); | ||
113 | entry++) { | ||
111 | /* | 114 | /* |
112 | * entry->code set to 0 invalidates module init text sections | 115 | * entry->code set to 0 invalidates module init text sections |
113 | * kernel_text_address() verifies we are not in core kernel | 116 | * kernel_text_address() verifies we are not in core kernel |
@@ -181,7 +184,11 @@ static void __jump_label_mod_update(struct jump_label_key *key, int enable) | |||
181 | struct jump_label_mod *mod = key->next; | 184 | struct jump_label_mod *mod = key->next; |
182 | 185 | ||
183 | while (mod) { | 186 | while (mod) { |
184 | __jump_label_update(key, mod->entries, enable); | 187 | struct module *m = mod->mod; |
188 | |||
189 | __jump_label_update(key, mod->entries, | ||
190 | m->jump_entries + m->num_jump_entries, | ||
191 | enable); | ||
185 | mod = mod->next; | 192 | mod = mod->next; |
186 | } | 193 | } |
187 | } | 194 | } |
@@ -245,7 +252,8 @@ static int jump_label_add_module(struct module *mod) | |||
245 | key->next = jlm; | 252 | key->next = jlm; |
246 | 253 | ||
247 | if (jump_label_enabled(key)) | 254 | if (jump_label_enabled(key)) |
248 | __jump_label_update(key, iter, JUMP_LABEL_ENABLE); | 255 | __jump_label_update(key, iter, iter_stop, |
256 | JUMP_LABEL_ENABLE); | ||
249 | } | 257 | } |
250 | 258 | ||
251 | return 0; | 259 | return 0; |
@@ -371,7 +379,7 @@ static void jump_label_update(struct jump_label_key *key, int enable) | |||
371 | 379 | ||
372 | /* if there are no users, entry can be NULL */ | 380 | /* if there are no users, entry can be NULL */ |
373 | if (entry) | 381 | if (entry) |
374 | __jump_label_update(key, entry, enable); | 382 | __jump_label_update(key, entry, __stop___jump_table, enable); |
375 | 383 | ||
376 | #ifdef CONFIG_MODULES | 384 | #ifdef CONFIG_MODULES |
377 | __jump_label_mod_update(key, enable); | 385 | __jump_label_mod_update(key, enable); |
diff --git a/kernel/kthread.c b/kernel/kthread.c index 3b34d2732bce..4ba7cccb4994 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -202,8 +202,8 @@ void kthread_bind(struct task_struct *p, unsigned int cpu) | |||
202 | return; | 202 | return; |
203 | } | 203 | } |
204 | 204 | ||
205 | p->cpus_allowed = cpumask_of_cpu(cpu); | 205 | /* It's safe because the task is inactive. */ |
206 | p->rt.nr_cpus_allowed = 1; | 206 | do_set_cpus_allowed(p, cpumask_of(cpu)); |
207 | p->flags |= PF_THREAD_BOUND; | 207 | p->flags |= PF_THREAD_BOUND; |
208 | } | 208 | } |
209 | EXPORT_SYMBOL(kthread_bind); | 209 | EXPORT_SYMBOL(kthread_bind); |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index fd8d1e035df9..6824ca7d4d0c 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -54,11 +54,17 @@ enum pm_qos_type { | |||
54 | PM_QOS_MIN /* return the smallest value */ | 54 | PM_QOS_MIN /* return the smallest value */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* | ||
58 | * Note: The lockless read path depends on the CPU accessing | ||
59 | * target_value atomically. Atomic access is only guaranteed on all CPU | ||
60 | * types linux supports for 32 bit quantites | ||
61 | */ | ||
57 | struct pm_qos_object { | 62 | struct pm_qos_object { |
58 | struct plist_head requests; | 63 | struct plist_head requests; |
59 | struct blocking_notifier_head *notifiers; | 64 | struct blocking_notifier_head *notifiers; |
60 | struct miscdevice pm_qos_power_miscdev; | 65 | struct miscdevice pm_qos_power_miscdev; |
61 | char *name; | 66 | char *name; |
67 | s32 target_value; /* Do not change to 64 bit */ | ||
62 | s32 default_value; | 68 | s32 default_value; |
63 | enum pm_qos_type type; | 69 | enum pm_qos_type type; |
64 | }; | 70 | }; |
@@ -71,7 +77,8 @@ static struct pm_qos_object cpu_dma_pm_qos = { | |||
71 | .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), | 77 | .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), |
72 | .notifiers = &cpu_dma_lat_notifier, | 78 | .notifiers = &cpu_dma_lat_notifier, |
73 | .name = "cpu_dma_latency", | 79 | .name = "cpu_dma_latency", |
74 | .default_value = 2000 * USEC_PER_SEC, | 80 | .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, |
81 | .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, | ||
75 | .type = PM_QOS_MIN, | 82 | .type = PM_QOS_MIN, |
76 | }; | 83 | }; |
77 | 84 | ||
@@ -80,7 +87,8 @@ static struct pm_qos_object network_lat_pm_qos = { | |||
80 | .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), | 87 | .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), |
81 | .notifiers = &network_lat_notifier, | 88 | .notifiers = &network_lat_notifier, |
82 | .name = "network_latency", | 89 | .name = "network_latency", |
83 | .default_value = 2000 * USEC_PER_SEC, | 90 | .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, |
91 | .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, | ||
84 | .type = PM_QOS_MIN | 92 | .type = PM_QOS_MIN |
85 | }; | 93 | }; |
86 | 94 | ||
@@ -90,7 +98,8 @@ static struct pm_qos_object network_throughput_pm_qos = { | |||
90 | .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), | 98 | .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), |
91 | .notifiers = &network_throughput_notifier, | 99 | .notifiers = &network_throughput_notifier, |
92 | .name = "network_throughput", | 100 | .name = "network_throughput", |
93 | .default_value = 0, | 101 | .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, |
102 | .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, | ||
94 | .type = PM_QOS_MAX, | 103 | .type = PM_QOS_MAX, |
95 | }; | 104 | }; |
96 | 105 | ||
@@ -136,6 +145,16 @@ static inline int pm_qos_get_value(struct pm_qos_object *o) | |||
136 | } | 145 | } |
137 | } | 146 | } |
138 | 147 | ||
148 | static inline s32 pm_qos_read_value(struct pm_qos_object *o) | ||
149 | { | ||
150 | return o->target_value; | ||
151 | } | ||
152 | |||
153 | static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) | ||
154 | { | ||
155 | o->target_value = value; | ||
156 | } | ||
157 | |||
139 | static void update_target(struct pm_qos_object *o, struct plist_node *node, | 158 | static void update_target(struct pm_qos_object *o, struct plist_node *node, |
140 | int del, int value) | 159 | int del, int value) |
141 | { | 160 | { |
@@ -160,6 +179,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node, | |||
160 | plist_add(node, &o->requests); | 179 | plist_add(node, &o->requests); |
161 | } | 180 | } |
162 | curr_value = pm_qos_get_value(o); | 181 | curr_value = pm_qos_get_value(o); |
182 | pm_qos_set_value(o, curr_value); | ||
163 | spin_unlock_irqrestore(&pm_qos_lock, flags); | 183 | spin_unlock_irqrestore(&pm_qos_lock, flags); |
164 | 184 | ||
165 | if (prev_value != curr_value) | 185 | if (prev_value != curr_value) |
@@ -194,18 +214,11 @@ static int find_pm_qos_object_by_minor(int minor) | |||
194 | * pm_qos_request - returns current system wide qos expectation | 214 | * pm_qos_request - returns current system wide qos expectation |
195 | * @pm_qos_class: identification of which qos value is requested | 215 | * @pm_qos_class: identification of which qos value is requested |
196 | * | 216 | * |
197 | * This function returns the current target value in an atomic manner. | 217 | * This function returns the current target value. |
198 | */ | 218 | */ |
199 | int pm_qos_request(int pm_qos_class) | 219 | int pm_qos_request(int pm_qos_class) |
200 | { | 220 | { |
201 | unsigned long flags; | 221 | return pm_qos_read_value(pm_qos_array[pm_qos_class]); |
202 | int value; | ||
203 | |||
204 | spin_lock_irqsave(&pm_qos_lock, flags); | ||
205 | value = pm_qos_get_value(pm_qos_array[pm_qos_class]); | ||
206 | spin_unlock_irqrestore(&pm_qos_lock, flags); | ||
207 | |||
208 | return value; | ||
209 | } | 222 | } |
210 | EXPORT_SYMBOL_GPL(pm_qos_request); | 223 | EXPORT_SYMBOL_GPL(pm_qos_request); |
211 | 224 | ||
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index f07d2f03181a..89419ff92e99 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/nmi.h> | 38 | #include <linux/nmi.h> |
39 | #include <asm/atomic.h> | 39 | #include <linux/atomic.h> |
40 | #include <linux/bitops.h> | 40 | #include <linux/bitops.h> |
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | #include <linux/completion.h> | 42 | #include <linux/completion.h> |
@@ -95,7 +95,6 @@ static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); | |||
95 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | 95 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); |
96 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); | 96 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); |
97 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); | 97 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); |
98 | static DEFINE_PER_CPU(wait_queue_head_t, rcu_cpu_wq); | ||
99 | DEFINE_PER_CPU(char, rcu_cpu_has_work); | 98 | DEFINE_PER_CPU(char, rcu_cpu_has_work); |
100 | static char rcu_kthreads_spawnable; | 99 | static char rcu_kthreads_spawnable; |
101 | 100 | ||
@@ -163,7 +162,7 @@ EXPORT_SYMBOL_GPL(rcu_note_context_switch); | |||
163 | #ifdef CONFIG_NO_HZ | 162 | #ifdef CONFIG_NO_HZ |
164 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { | 163 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { |
165 | .dynticks_nesting = 1, | 164 | .dynticks_nesting = 1, |
166 | .dynticks = 1, | 165 | .dynticks = ATOMIC_INIT(1), |
167 | }; | 166 | }; |
168 | #endif /* #ifdef CONFIG_NO_HZ */ | 167 | #endif /* #ifdef CONFIG_NO_HZ */ |
169 | 168 | ||
@@ -322,13 +321,25 @@ void rcu_enter_nohz(void) | |||
322 | unsigned long flags; | 321 | unsigned long flags; |
323 | struct rcu_dynticks *rdtp; | 322 | struct rcu_dynticks *rdtp; |
324 | 323 | ||
325 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | ||
326 | local_irq_save(flags); | 324 | local_irq_save(flags); |
327 | rdtp = &__get_cpu_var(rcu_dynticks); | 325 | rdtp = &__get_cpu_var(rcu_dynticks); |
328 | rdtp->dynticks++; | 326 | if (--rdtp->dynticks_nesting) { |
329 | rdtp->dynticks_nesting--; | 327 | local_irq_restore(flags); |
330 | WARN_ON_ONCE(rdtp->dynticks & 0x1); | 328 | return; |
329 | } | ||
330 | /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ | ||
331 | smp_mb__before_atomic_inc(); /* See above. */ | ||
332 | atomic_inc(&rdtp->dynticks); | ||
333 | smp_mb__after_atomic_inc(); /* Force ordering with next sojourn. */ | ||
334 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); | ||
331 | local_irq_restore(flags); | 335 | local_irq_restore(flags); |
336 | |||
337 | /* If the interrupt queued a callback, get out of dyntick mode. */ | ||
338 | if (in_irq() && | ||
339 | (__get_cpu_var(rcu_sched_data).nxtlist || | ||
340 | __get_cpu_var(rcu_bh_data).nxtlist || | ||
341 | rcu_preempt_needs_cpu(smp_processor_id()))) | ||
342 | set_need_resched(); | ||
332 | } | 343 | } |
333 | 344 | ||
334 | /* | 345 | /* |
@@ -344,11 +355,16 @@ void rcu_exit_nohz(void) | |||
344 | 355 | ||
345 | local_irq_save(flags); | 356 | local_irq_save(flags); |
346 | rdtp = &__get_cpu_var(rcu_dynticks); | 357 | rdtp = &__get_cpu_var(rcu_dynticks); |
347 | rdtp->dynticks++; | 358 | if (rdtp->dynticks_nesting++) { |
348 | rdtp->dynticks_nesting++; | 359 | local_irq_restore(flags); |
349 | WARN_ON_ONCE(!(rdtp->dynticks & 0x1)); | 360 | return; |
361 | } | ||
362 | smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */ | ||
363 | atomic_inc(&rdtp->dynticks); | ||
364 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ | ||
365 | smp_mb__after_atomic_inc(); /* See above. */ | ||
366 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); | ||
350 | local_irq_restore(flags); | 367 | local_irq_restore(flags); |
351 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | ||
352 | } | 368 | } |
353 | 369 | ||
354 | /** | 370 | /** |
@@ -362,11 +378,15 @@ void rcu_nmi_enter(void) | |||
362 | { | 378 | { |
363 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 379 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); |
364 | 380 | ||
365 | if (rdtp->dynticks & 0x1) | 381 | if (rdtp->dynticks_nmi_nesting == 0 && |
382 | (atomic_read(&rdtp->dynticks) & 0x1)) | ||
366 | return; | 383 | return; |
367 | rdtp->dynticks_nmi++; | 384 | rdtp->dynticks_nmi_nesting++; |
368 | WARN_ON_ONCE(!(rdtp->dynticks_nmi & 0x1)); | 385 | smp_mb__before_atomic_inc(); /* Force delay from prior write. */ |
369 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | 386 | atomic_inc(&rdtp->dynticks); |
387 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ | ||
388 | smp_mb__after_atomic_inc(); /* See above. */ | ||
389 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); | ||
370 | } | 390 | } |
371 | 391 | ||
372 | /** | 392 | /** |
@@ -380,11 +400,14 @@ void rcu_nmi_exit(void) | |||
380 | { | 400 | { |
381 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 401 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); |
382 | 402 | ||
383 | if (rdtp->dynticks & 0x1) | 403 | if (rdtp->dynticks_nmi_nesting == 0 || |
404 | --rdtp->dynticks_nmi_nesting != 0) | ||
384 | return; | 405 | return; |
385 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | 406 | /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ |
386 | rdtp->dynticks_nmi++; | 407 | smp_mb__before_atomic_inc(); /* See above. */ |
387 | WARN_ON_ONCE(rdtp->dynticks_nmi & 0x1); | 408 | atomic_inc(&rdtp->dynticks); |
409 | smp_mb__after_atomic_inc(); /* Force delay to next write. */ | ||
410 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); | ||
388 | } | 411 | } |
389 | 412 | ||
390 | /** | 413 | /** |
@@ -395,13 +418,7 @@ void rcu_nmi_exit(void) | |||
395 | */ | 418 | */ |
396 | void rcu_irq_enter(void) | 419 | void rcu_irq_enter(void) |
397 | { | 420 | { |
398 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 421 | rcu_exit_nohz(); |
399 | |||
400 | if (rdtp->dynticks_nesting++) | ||
401 | return; | ||
402 | rdtp->dynticks++; | ||
403 | WARN_ON_ONCE(!(rdtp->dynticks & 0x1)); | ||
404 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | ||
405 | } | 422 | } |
406 | 423 | ||
407 | /** | 424 | /** |
@@ -413,18 +430,7 @@ void rcu_irq_enter(void) | |||
413 | */ | 430 | */ |
414 | void rcu_irq_exit(void) | 431 | void rcu_irq_exit(void) |
415 | { | 432 | { |
416 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 433 | rcu_enter_nohz(); |
417 | |||
418 | if (--rdtp->dynticks_nesting) | ||
419 | return; | ||
420 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | ||
421 | rdtp->dynticks++; | ||
422 | WARN_ON_ONCE(rdtp->dynticks & 0x1); | ||
423 | |||
424 | /* If the interrupt queued a callback, get out of dyntick mode. */ | ||
425 | if (__this_cpu_read(rcu_sched_data.nxtlist) || | ||
426 | __this_cpu_read(rcu_bh_data.nxtlist)) | ||
427 | set_need_resched(); | ||
428 | } | 434 | } |
429 | 435 | ||
430 | #ifdef CONFIG_SMP | 436 | #ifdef CONFIG_SMP |
@@ -436,19 +442,8 @@ void rcu_irq_exit(void) | |||
436 | */ | 442 | */ |
437 | static int dyntick_save_progress_counter(struct rcu_data *rdp) | 443 | static int dyntick_save_progress_counter(struct rcu_data *rdp) |
438 | { | 444 | { |
439 | int ret; | 445 | rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks); |
440 | int snap; | 446 | return 0; |
441 | int snap_nmi; | ||
442 | |||
443 | snap = rdp->dynticks->dynticks; | ||
444 | snap_nmi = rdp->dynticks->dynticks_nmi; | ||
445 | smp_mb(); /* Order sampling of snap with end of grace period. */ | ||
446 | rdp->dynticks_snap = snap; | ||
447 | rdp->dynticks_nmi_snap = snap_nmi; | ||
448 | ret = ((snap & 0x1) == 0) && ((snap_nmi & 0x1) == 0); | ||
449 | if (ret) | ||
450 | rdp->dynticks_fqs++; | ||
451 | return ret; | ||
452 | } | 447 | } |
453 | 448 | ||
454 | /* | 449 | /* |
@@ -459,16 +454,11 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp) | |||
459 | */ | 454 | */ |
460 | static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) | 455 | static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) |
461 | { | 456 | { |
462 | long curr; | 457 | unsigned long curr; |
463 | long curr_nmi; | 458 | unsigned long snap; |
464 | long snap; | ||
465 | long snap_nmi; | ||
466 | 459 | ||
467 | curr = rdp->dynticks->dynticks; | 460 | curr = (unsigned long)atomic_add_return(0, &rdp->dynticks->dynticks); |
468 | snap = rdp->dynticks_snap; | 461 | snap = (unsigned long)rdp->dynticks_snap; |
469 | curr_nmi = rdp->dynticks->dynticks_nmi; | ||
470 | snap_nmi = rdp->dynticks_nmi_snap; | ||
471 | smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ | ||
472 | 462 | ||
473 | /* | 463 | /* |
474 | * If the CPU passed through or entered a dynticks idle phase with | 464 | * If the CPU passed through or entered a dynticks idle phase with |
@@ -478,8 +468,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) | |||
478 | * read-side critical section that started before the beginning | 468 | * read-side critical section that started before the beginning |
479 | * of the current RCU grace period. | 469 | * of the current RCU grace period. |
480 | */ | 470 | */ |
481 | if ((curr != snap || (curr & 0x1) == 0) && | 471 | if ((curr & 0x1) == 0 || ULONG_CMP_GE(curr, snap + 2)) { |
482 | (curr_nmi != snap_nmi || (curr_nmi & 0x1) == 0)) { | ||
483 | rdp->dynticks_fqs++; | 472 | rdp->dynticks_fqs++; |
484 | return 1; | 473 | return 1; |
485 | } | 474 | } |
@@ -908,6 +897,12 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags) | |||
908 | unsigned long gp_duration; | 897 | unsigned long gp_duration; |
909 | 898 | ||
910 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); | 899 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); |
900 | |||
901 | /* | ||
902 | * Ensure that all grace-period and pre-grace-period activity | ||
903 | * is seen before the assignment to rsp->completed. | ||
904 | */ | ||
905 | smp_mb(); /* See above block comment. */ | ||
911 | gp_duration = jiffies - rsp->gp_start; | 906 | gp_duration = jiffies - rsp->gp_start; |
912 | if (gp_duration > rsp->gp_max) | 907 | if (gp_duration > rsp->gp_max) |
913 | rsp->gp_max = gp_duration; | 908 | rsp->gp_max = gp_duration; |
@@ -1455,25 +1450,11 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1455 | */ | 1450 | */ |
1456 | static void rcu_process_callbacks(void) | 1451 | static void rcu_process_callbacks(void) |
1457 | { | 1452 | { |
1458 | /* | ||
1459 | * Memory references from any prior RCU read-side critical sections | ||
1460 | * executed by the interrupted code must be seen before any RCU | ||
1461 | * grace-period manipulations below. | ||
1462 | */ | ||
1463 | smp_mb(); /* See above block comment. */ | ||
1464 | |||
1465 | __rcu_process_callbacks(&rcu_sched_state, | 1453 | __rcu_process_callbacks(&rcu_sched_state, |
1466 | &__get_cpu_var(rcu_sched_data)); | 1454 | &__get_cpu_var(rcu_sched_data)); |
1467 | __rcu_process_callbacks(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); | 1455 | __rcu_process_callbacks(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); |
1468 | rcu_preempt_process_callbacks(); | 1456 | rcu_preempt_process_callbacks(); |
1469 | 1457 | ||
1470 | /* | ||
1471 | * Memory references from any later RCU read-side critical sections | ||
1472 | * executed by the interrupted code must be seen after any RCU | ||
1473 | * grace-period manipulations above. | ||
1474 | */ | ||
1475 | smp_mb(); /* See above block comment. */ | ||
1476 | |||
1477 | /* If we are last CPU on way to dyntick-idle mode, accelerate it. */ | 1458 | /* If we are last CPU on way to dyntick-idle mode, accelerate it. */ |
1478 | rcu_needs_cpu_flush(); | 1459 | rcu_needs_cpu_flush(); |
1479 | } | 1460 | } |
@@ -1494,7 +1475,7 @@ static void invoke_rcu_cpu_kthread(void) | |||
1494 | local_irq_restore(flags); | 1475 | local_irq_restore(flags); |
1495 | return; | 1476 | return; |
1496 | } | 1477 | } |
1497 | wake_up(&__get_cpu_var(rcu_cpu_wq)); | 1478 | wake_up_process(__this_cpu_read(rcu_cpu_kthread_task)); |
1498 | local_irq_restore(flags); | 1479 | local_irq_restore(flags); |
1499 | } | 1480 | } |
1500 | 1481 | ||
@@ -1544,13 +1525,10 @@ static void rcu_cpu_kthread_setrt(int cpu, int to_rt) | |||
1544 | */ | 1525 | */ |
1545 | static void rcu_cpu_kthread_timer(unsigned long arg) | 1526 | static void rcu_cpu_kthread_timer(unsigned long arg) |
1546 | { | 1527 | { |
1547 | unsigned long flags; | ||
1548 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, arg); | 1528 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, arg); |
1549 | struct rcu_node *rnp = rdp->mynode; | 1529 | struct rcu_node *rnp = rdp->mynode; |
1550 | 1530 | ||
1551 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1531 | atomic_or(rdp->grpmask, &rnp->wakemask); |
1552 | rnp->wakemask |= rdp->grpmask; | ||
1553 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | ||
1554 | invoke_rcu_node_kthread(rnp); | 1532 | invoke_rcu_node_kthread(rnp); |
1555 | } | 1533 | } |
1556 | 1534 | ||
@@ -1617,14 +1595,12 @@ static int rcu_cpu_kthread(void *arg) | |||
1617 | unsigned long flags; | 1595 | unsigned long flags; |
1618 | int spincnt = 0; | 1596 | int spincnt = 0; |
1619 | unsigned int *statusp = &per_cpu(rcu_cpu_kthread_status, cpu); | 1597 | unsigned int *statusp = &per_cpu(rcu_cpu_kthread_status, cpu); |
1620 | wait_queue_head_t *wqp = &per_cpu(rcu_cpu_wq, cpu); | ||
1621 | char work; | 1598 | char work; |
1622 | char *workp = &per_cpu(rcu_cpu_has_work, cpu); | 1599 | char *workp = &per_cpu(rcu_cpu_has_work, cpu); |
1623 | 1600 | ||
1624 | for (;;) { | 1601 | for (;;) { |
1625 | *statusp = RCU_KTHREAD_WAITING; | 1602 | *statusp = RCU_KTHREAD_WAITING; |
1626 | wait_event_interruptible(*wqp, | 1603 | rcu_wait(*workp != 0 || kthread_should_stop()); |
1627 | *workp != 0 || kthread_should_stop()); | ||
1628 | local_bh_disable(); | 1604 | local_bh_disable(); |
1629 | if (rcu_cpu_kthread_should_stop(cpu)) { | 1605 | if (rcu_cpu_kthread_should_stop(cpu)) { |
1630 | local_bh_enable(); | 1606 | local_bh_enable(); |
@@ -1675,7 +1651,6 @@ static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu) | |||
1675 | per_cpu(rcu_cpu_kthread_cpu, cpu) = cpu; | 1651 | per_cpu(rcu_cpu_kthread_cpu, cpu) = cpu; |
1676 | WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL); | 1652 | WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL); |
1677 | per_cpu(rcu_cpu_kthread_task, cpu) = t; | 1653 | per_cpu(rcu_cpu_kthread_task, cpu) = t; |
1678 | wake_up_process(t); | ||
1679 | sp.sched_priority = RCU_KTHREAD_PRIO; | 1654 | sp.sched_priority = RCU_KTHREAD_PRIO; |
1680 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); | 1655 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); |
1681 | return 0; | 1656 | return 0; |
@@ -1698,11 +1673,10 @@ static int rcu_node_kthread(void *arg) | |||
1698 | 1673 | ||
1699 | for (;;) { | 1674 | for (;;) { |
1700 | rnp->node_kthread_status = RCU_KTHREAD_WAITING; | 1675 | rnp->node_kthread_status = RCU_KTHREAD_WAITING; |
1701 | wait_event_interruptible(rnp->node_wq, rnp->wakemask != 0); | 1676 | rcu_wait(atomic_read(&rnp->wakemask) != 0); |
1702 | rnp->node_kthread_status = RCU_KTHREAD_RUNNING; | 1677 | rnp->node_kthread_status = RCU_KTHREAD_RUNNING; |
1703 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1678 | raw_spin_lock_irqsave(&rnp->lock, flags); |
1704 | mask = rnp->wakemask; | 1679 | mask = atomic_xchg(&rnp->wakemask, 0); |
1705 | rnp->wakemask = 0; | ||
1706 | rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */ | 1680 | rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */ |
1707 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) { | 1681 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) { |
1708 | if ((mask & 0x1) == 0) | 1682 | if ((mask & 0x1) == 0) |
@@ -1783,13 +1757,14 @@ static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp, | |||
1783 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1757 | raw_spin_lock_irqsave(&rnp->lock, flags); |
1784 | rnp->node_kthread_task = t; | 1758 | rnp->node_kthread_task = t; |
1785 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 1759 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
1786 | wake_up_process(t); | ||
1787 | sp.sched_priority = 99; | 1760 | sp.sched_priority = 99; |
1788 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); | 1761 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); |
1789 | } | 1762 | } |
1790 | return rcu_spawn_one_boost_kthread(rsp, rnp, rnp_index); | 1763 | return rcu_spawn_one_boost_kthread(rsp, rnp, rnp_index); |
1791 | } | 1764 | } |
1792 | 1765 | ||
1766 | static void rcu_wake_one_boost_kthread(struct rcu_node *rnp); | ||
1767 | |||
1793 | /* | 1768 | /* |
1794 | * Spawn all kthreads -- called as soon as the scheduler is running. | 1769 | * Spawn all kthreads -- called as soon as the scheduler is running. |
1795 | */ | 1770 | */ |
@@ -1797,24 +1772,31 @@ static int __init rcu_spawn_kthreads(void) | |||
1797 | { | 1772 | { |
1798 | int cpu; | 1773 | int cpu; |
1799 | struct rcu_node *rnp; | 1774 | struct rcu_node *rnp; |
1775 | struct task_struct *t; | ||
1800 | 1776 | ||
1801 | rcu_kthreads_spawnable = 1; | 1777 | rcu_kthreads_spawnable = 1; |
1802 | for_each_possible_cpu(cpu) { | 1778 | for_each_possible_cpu(cpu) { |
1803 | init_waitqueue_head(&per_cpu(rcu_cpu_wq, cpu)); | ||
1804 | per_cpu(rcu_cpu_has_work, cpu) = 0; | 1779 | per_cpu(rcu_cpu_has_work, cpu) = 0; |
1805 | if (cpu_online(cpu)) | 1780 | if (cpu_online(cpu)) { |
1806 | (void)rcu_spawn_one_cpu_kthread(cpu); | 1781 | (void)rcu_spawn_one_cpu_kthread(cpu); |
1782 | t = per_cpu(rcu_cpu_kthread_task, cpu); | ||
1783 | if (t) | ||
1784 | wake_up_process(t); | ||
1785 | } | ||
1807 | } | 1786 | } |
1808 | rnp = rcu_get_root(rcu_state); | 1787 | rnp = rcu_get_root(rcu_state); |
1809 | init_waitqueue_head(&rnp->node_wq); | ||
1810 | rcu_init_boost_waitqueue(rnp); | ||
1811 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); | 1788 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); |
1812 | if (NUM_RCU_NODES > 1) | 1789 | if (rnp->node_kthread_task) |
1790 | wake_up_process(rnp->node_kthread_task); | ||
1791 | if (NUM_RCU_NODES > 1) { | ||
1813 | rcu_for_each_leaf_node(rcu_state, rnp) { | 1792 | rcu_for_each_leaf_node(rcu_state, rnp) { |
1814 | init_waitqueue_head(&rnp->node_wq); | ||
1815 | rcu_init_boost_waitqueue(rnp); | ||
1816 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); | 1793 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); |
1794 | t = rnp->node_kthread_task; | ||
1795 | if (t) | ||
1796 | wake_up_process(t); | ||
1797 | rcu_wake_one_boost_kthread(rnp); | ||
1817 | } | 1798 | } |
1799 | } | ||
1818 | return 0; | 1800 | return 0; |
1819 | } | 1801 | } |
1820 | early_initcall(rcu_spawn_kthreads); | 1802 | early_initcall(rcu_spawn_kthreads); |
@@ -2218,14 +2200,14 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible) | |||
2218 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); | 2200 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); |
2219 | } | 2201 | } |
2220 | 2202 | ||
2221 | static void __cpuinit rcu_online_cpu(int cpu) | 2203 | static void __cpuinit rcu_prepare_cpu(int cpu) |
2222 | { | 2204 | { |
2223 | rcu_init_percpu_data(cpu, &rcu_sched_state, 0); | 2205 | rcu_init_percpu_data(cpu, &rcu_sched_state, 0); |
2224 | rcu_init_percpu_data(cpu, &rcu_bh_state, 0); | 2206 | rcu_init_percpu_data(cpu, &rcu_bh_state, 0); |
2225 | rcu_preempt_init_percpu_data(cpu); | 2207 | rcu_preempt_init_percpu_data(cpu); |
2226 | } | 2208 | } |
2227 | 2209 | ||
2228 | static void __cpuinit rcu_online_kthreads(int cpu) | 2210 | static void __cpuinit rcu_prepare_kthreads(int cpu) |
2229 | { | 2211 | { |
2230 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); | 2212 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); |
2231 | struct rcu_node *rnp = rdp->mynode; | 2213 | struct rcu_node *rnp = rdp->mynode; |
@@ -2239,6 +2221,31 @@ static void __cpuinit rcu_online_kthreads(int cpu) | |||
2239 | } | 2221 | } |
2240 | 2222 | ||
2241 | /* | 2223 | /* |
2224 | * kthread_create() creates threads in TASK_UNINTERRUPTIBLE state, | ||
2225 | * but the RCU threads are woken on demand, and if demand is low this | ||
2226 | * could be a while triggering the hung task watchdog. | ||
2227 | * | ||
2228 | * In order to avoid this, poke all tasks once the CPU is fully | ||
2229 | * up and running. | ||
2230 | */ | ||
2231 | static void __cpuinit rcu_online_kthreads(int cpu) | ||
2232 | { | ||
2233 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); | ||
2234 | struct rcu_node *rnp = rdp->mynode; | ||
2235 | struct task_struct *t; | ||
2236 | |||
2237 | t = per_cpu(rcu_cpu_kthread_task, cpu); | ||
2238 | if (t) | ||
2239 | wake_up_process(t); | ||
2240 | |||
2241 | t = rnp->node_kthread_task; | ||
2242 | if (t) | ||
2243 | wake_up_process(t); | ||
2244 | |||
2245 | rcu_wake_one_boost_kthread(rnp); | ||
2246 | } | ||
2247 | |||
2248 | /* | ||
2242 | * Handle CPU online/offline notification events. | 2249 | * Handle CPU online/offline notification events. |
2243 | */ | 2250 | */ |
2244 | static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | 2251 | static int __cpuinit rcu_cpu_notify(struct notifier_block *self, |
@@ -2251,10 +2258,11 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | |||
2251 | switch (action) { | 2258 | switch (action) { |
2252 | case CPU_UP_PREPARE: | 2259 | case CPU_UP_PREPARE: |
2253 | case CPU_UP_PREPARE_FROZEN: | 2260 | case CPU_UP_PREPARE_FROZEN: |
2254 | rcu_online_cpu(cpu); | 2261 | rcu_prepare_cpu(cpu); |
2255 | rcu_online_kthreads(cpu); | 2262 | rcu_prepare_kthreads(cpu); |
2256 | break; | 2263 | break; |
2257 | case CPU_ONLINE: | 2264 | case CPU_ONLINE: |
2265 | rcu_online_kthreads(cpu); | ||
2258 | case CPU_DOWN_FAILED: | 2266 | case CPU_DOWN_FAILED: |
2259 | rcu_node_kthread_setaffinity(rnp, -1); | 2267 | rcu_node_kthread_setaffinity(rnp, -1); |
2260 | rcu_cpu_kthread_setrt(cpu, 1); | 2268 | rcu_cpu_kthread_setrt(cpu, 1); |
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 257664815d5d..7b9a08b4aaea 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -84,11 +84,9 @@ | |||
84 | * Dynticks per-CPU state. | 84 | * Dynticks per-CPU state. |
85 | */ | 85 | */ |
86 | struct rcu_dynticks { | 86 | struct rcu_dynticks { |
87 | int dynticks_nesting; /* Track nesting level, sort of. */ | 87 | int dynticks_nesting; /* Track irq/process nesting level. */ |
88 | int dynticks; /* Even value for dynticks-idle, else odd. */ | 88 | int dynticks_nmi_nesting; /* Track NMI nesting level. */ |
89 | int dynticks_nmi; /* Even value for either dynticks-idle or */ | 89 | atomic_t dynticks; /* Even value for dynticks-idle, else odd. */ |
90 | /* not in nmi handler, else odd. So this */ | ||
91 | /* remains even for nmi from irq handler. */ | ||
92 | }; | 90 | }; |
93 | 91 | ||
94 | /* RCU's kthread states for tracing. */ | 92 | /* RCU's kthread states for tracing. */ |
@@ -121,7 +119,9 @@ struct rcu_node { | |||
121 | /* elements that need to drain to allow the */ | 119 | /* elements that need to drain to allow the */ |
122 | /* current expedited grace period to */ | 120 | /* current expedited grace period to */ |
123 | /* complete (only for TREE_PREEMPT_RCU). */ | 121 | /* complete (only for TREE_PREEMPT_RCU). */ |
124 | unsigned long wakemask; /* CPUs whose kthread needs to be awakened. */ | 122 | atomic_t wakemask; /* CPUs whose kthread needs to be awakened. */ |
123 | /* Since this has meaning only for leaf */ | ||
124 | /* rcu_node structures, 32 bits suffices. */ | ||
125 | unsigned long qsmaskinit; | 125 | unsigned long qsmaskinit; |
126 | /* Per-GP initial value for qsmask & expmask. */ | 126 | /* Per-GP initial value for qsmask & expmask. */ |
127 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ | 127 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ |
@@ -159,9 +159,6 @@ struct rcu_node { | |||
159 | struct task_struct *boost_kthread_task; | 159 | struct task_struct *boost_kthread_task; |
160 | /* kthread that takes care of priority */ | 160 | /* kthread that takes care of priority */ |
161 | /* boosting for this rcu_node structure. */ | 161 | /* boosting for this rcu_node structure. */ |
162 | wait_queue_head_t boost_wq; | ||
163 | /* Wait queue on which to park the boost */ | ||
164 | /* kthread. */ | ||
165 | unsigned int boost_kthread_status; | 162 | unsigned int boost_kthread_status; |
166 | /* State of boost_kthread_task for tracing. */ | 163 | /* State of boost_kthread_task for tracing. */ |
167 | unsigned long n_tasks_boosted; | 164 | unsigned long n_tasks_boosted; |
@@ -188,9 +185,6 @@ struct rcu_node { | |||
188 | /* kthread that takes care of this rcu_node */ | 185 | /* kthread that takes care of this rcu_node */ |
189 | /* structure, for example, awakening the */ | 186 | /* structure, for example, awakening the */ |
190 | /* per-CPU kthreads as needed. */ | 187 | /* per-CPU kthreads as needed. */ |
191 | wait_queue_head_t node_wq; | ||
192 | /* Wait queue on which to park the per-node */ | ||
193 | /* kthread. */ | ||
194 | unsigned int node_kthread_status; | 188 | unsigned int node_kthread_status; |
195 | /* State of node_kthread_task for tracing. */ | 189 | /* State of node_kthread_task for tracing. */ |
196 | } ____cacheline_internodealigned_in_smp; | 190 | } ____cacheline_internodealigned_in_smp; |
@@ -284,7 +278,6 @@ struct rcu_data { | |||
284 | /* 3) dynticks interface. */ | 278 | /* 3) dynticks interface. */ |
285 | struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ | 279 | struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ |
286 | int dynticks_snap; /* Per-GP tracking for dynticks. */ | 280 | int dynticks_snap; /* Per-GP tracking for dynticks. */ |
287 | int dynticks_nmi_snap; /* Per-GP tracking for dynticks_nmi. */ | ||
288 | #endif /* #ifdef CONFIG_NO_HZ */ | 281 | #endif /* #ifdef CONFIG_NO_HZ */ |
289 | 282 | ||
290 | /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ | 283 | /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ |
@@ -337,6 +330,16 @@ struct rcu_data { | |||
337 | /* scheduling clock irq */ | 330 | /* scheduling clock irq */ |
338 | /* before ratting on them. */ | 331 | /* before ratting on them. */ |
339 | 332 | ||
333 | #define rcu_wait(cond) \ | ||
334 | do { \ | ||
335 | for (;;) { \ | ||
336 | set_current_state(TASK_INTERRUPTIBLE); \ | ||
337 | if (cond) \ | ||
338 | break; \ | ||
339 | schedule(); \ | ||
340 | } \ | ||
341 | __set_current_state(TASK_RUNNING); \ | ||
342 | } while (0) | ||
340 | 343 | ||
341 | /* | 344 | /* |
342 | * RCU global state, including node hierarchy. This hierarchy is | 345 | * RCU global state, including node hierarchy. This hierarchy is |
@@ -446,7 +449,6 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu); | |||
446 | static void rcu_preempt_send_cbs_to_online(void); | 449 | static void rcu_preempt_send_cbs_to_online(void); |
447 | static void __init __rcu_init_preempt(void); | 450 | static void __init __rcu_init_preempt(void); |
448 | static void rcu_needs_cpu_flush(void); | 451 | static void rcu_needs_cpu_flush(void); |
449 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp); | ||
450 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); | 452 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); |
451 | static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, | 453 | static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, |
452 | cpumask_var_t cm); | 454 | cpumask_var_t cm); |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 3f6559a5f5cd..c8bff3099a89 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -1196,8 +1196,7 @@ static int rcu_boost_kthread(void *arg) | |||
1196 | 1196 | ||
1197 | for (;;) { | 1197 | for (;;) { |
1198 | rnp->boost_kthread_status = RCU_KTHREAD_WAITING; | 1198 | rnp->boost_kthread_status = RCU_KTHREAD_WAITING; |
1199 | wait_event_interruptible(rnp->boost_wq, rnp->boost_tasks || | 1199 | rcu_wait(rnp->boost_tasks || rnp->exp_tasks); |
1200 | rnp->exp_tasks); | ||
1201 | rnp->boost_kthread_status = RCU_KTHREAD_RUNNING; | 1200 | rnp->boost_kthread_status = RCU_KTHREAD_RUNNING; |
1202 | more2boost = rcu_boost(rnp); | 1201 | more2boost = rcu_boost(rnp); |
1203 | if (more2boost) | 1202 | if (more2boost) |
@@ -1275,14 +1274,6 @@ static void rcu_preempt_boost_start_gp(struct rcu_node *rnp) | |||
1275 | } | 1274 | } |
1276 | 1275 | ||
1277 | /* | 1276 | /* |
1278 | * Initialize the RCU-boost waitqueue. | ||
1279 | */ | ||
1280 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp) | ||
1281 | { | ||
1282 | init_waitqueue_head(&rnp->boost_wq); | ||
1283 | } | ||
1284 | |||
1285 | /* | ||
1286 | * Create an RCU-boost kthread for the specified node if one does not | 1277 | * Create an RCU-boost kthread for the specified node if one does not |
1287 | * already exist. We only create this kthread for preemptible RCU. | 1278 | * already exist. We only create this kthread for preemptible RCU. |
1288 | * Returns zero if all is well, a negated errno otherwise. | 1279 | * Returns zero if all is well, a negated errno otherwise. |
@@ -1306,12 +1297,17 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | |||
1306 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1297 | raw_spin_lock_irqsave(&rnp->lock, flags); |
1307 | rnp->boost_kthread_task = t; | 1298 | rnp->boost_kthread_task = t; |
1308 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 1299 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
1309 | wake_up_process(t); | ||
1310 | sp.sched_priority = RCU_KTHREAD_PRIO; | 1300 | sp.sched_priority = RCU_KTHREAD_PRIO; |
1311 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); | 1301 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); |
1312 | return 0; | 1302 | return 0; |
1313 | } | 1303 | } |
1314 | 1304 | ||
1305 | static void __cpuinit rcu_wake_one_boost_kthread(struct rcu_node *rnp) | ||
1306 | { | ||
1307 | if (rnp->boost_kthread_task) | ||
1308 | wake_up_process(rnp->boost_kthread_task); | ||
1309 | } | ||
1310 | |||
1315 | #else /* #ifdef CONFIG_RCU_BOOST */ | 1311 | #else /* #ifdef CONFIG_RCU_BOOST */ |
1316 | 1312 | ||
1317 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) | 1313 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) |
@@ -1328,10 +1324,6 @@ static void rcu_preempt_boost_start_gp(struct rcu_node *rnp) | |||
1328 | { | 1324 | { |
1329 | } | 1325 | } |
1330 | 1326 | ||
1331 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp) | ||
1332 | { | ||
1333 | } | ||
1334 | |||
1335 | static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | 1327 | static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, |
1336 | struct rcu_node *rnp, | 1328 | struct rcu_node *rnp, |
1337 | int rnp_index) | 1329 | int rnp_index) |
@@ -1339,6 +1331,10 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | |||
1339 | return 0; | 1331 | return 0; |
1340 | } | 1332 | } |
1341 | 1333 | ||
1334 | static void __cpuinit rcu_wake_one_boost_kthread(struct rcu_node *rnp) | ||
1335 | { | ||
1336 | } | ||
1337 | |||
1342 | #endif /* #else #ifdef CONFIG_RCU_BOOST */ | 1338 | #endif /* #else #ifdef CONFIG_RCU_BOOST */ |
1343 | 1339 | ||
1344 | #ifndef CONFIG_SMP | 1340 | #ifndef CONFIG_SMP |
@@ -1520,7 +1516,6 @@ int rcu_needs_cpu(int cpu) | |||
1520 | { | 1516 | { |
1521 | int c = 0; | 1517 | int c = 0; |
1522 | int snap; | 1518 | int snap; |
1523 | int snap_nmi; | ||
1524 | int thatcpu; | 1519 | int thatcpu; |
1525 | 1520 | ||
1526 | /* Check for being in the holdoff period. */ | 1521 | /* Check for being in the holdoff period. */ |
@@ -1531,10 +1526,10 @@ int rcu_needs_cpu(int cpu) | |||
1531 | for_each_online_cpu(thatcpu) { | 1526 | for_each_online_cpu(thatcpu) { |
1532 | if (thatcpu == cpu) | 1527 | if (thatcpu == cpu) |
1533 | continue; | 1528 | continue; |
1534 | snap = per_cpu(rcu_dynticks, thatcpu).dynticks; | 1529 | snap = atomic_add_return(0, &per_cpu(rcu_dynticks, |
1535 | snap_nmi = per_cpu(rcu_dynticks, thatcpu).dynticks_nmi; | 1530 | thatcpu).dynticks); |
1536 | smp_mb(); /* Order sampling of snap with end of grace period. */ | 1531 | smp_mb(); /* Order sampling of snap with end of grace period. */ |
1537 | if (((snap & 0x1) != 0) || ((snap_nmi & 0x1) != 0)) { | 1532 | if ((snap & 0x1) != 0) { |
1538 | per_cpu(rcu_dyntick_drain, cpu) = 0; | 1533 | per_cpu(rcu_dyntick_drain, cpu) = 0; |
1539 | per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1; | 1534 | per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1; |
1540 | return rcu_needs_cpu_quick_check(cpu); | 1535 | return rcu_needs_cpu_quick_check(cpu); |
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index aa0fd72b4bc7..9678cc3650f5 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c | |||
@@ -69,10 +69,10 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
69 | rdp->passed_quiesc, rdp->passed_quiesc_completed, | 69 | rdp->passed_quiesc, rdp->passed_quiesc_completed, |
70 | rdp->qs_pending); | 70 | rdp->qs_pending); |
71 | #ifdef CONFIG_NO_HZ | 71 | #ifdef CONFIG_NO_HZ |
72 | seq_printf(m, " dt=%d/%d dn=%d df=%lu", | 72 | seq_printf(m, " dt=%d/%d/%d df=%lu", |
73 | rdp->dynticks->dynticks, | 73 | atomic_read(&rdp->dynticks->dynticks), |
74 | rdp->dynticks->dynticks_nesting, | 74 | rdp->dynticks->dynticks_nesting, |
75 | rdp->dynticks->dynticks_nmi, | 75 | rdp->dynticks->dynticks_nmi_nesting, |
76 | rdp->dynticks_fqs); | 76 | rdp->dynticks_fqs); |
77 | #endif /* #ifdef CONFIG_NO_HZ */ | 77 | #endif /* #ifdef CONFIG_NO_HZ */ |
78 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); | 78 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); |
@@ -141,9 +141,9 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) | |||
141 | rdp->qs_pending); | 141 | rdp->qs_pending); |
142 | #ifdef CONFIG_NO_HZ | 142 | #ifdef CONFIG_NO_HZ |
143 | seq_printf(m, ",%d,%d,%d,%lu", | 143 | seq_printf(m, ",%d,%d,%d,%lu", |
144 | rdp->dynticks->dynticks, | 144 | atomic_read(&rdp->dynticks->dynticks), |
145 | rdp->dynticks->dynticks_nesting, | 145 | rdp->dynticks->dynticks_nesting, |
146 | rdp->dynticks->dynticks_nmi, | 146 | rdp->dynticks->dynticks_nmi_nesting, |
147 | rdp->dynticks_fqs); | 147 | rdp->dynticks_fqs); |
148 | #endif /* #ifdef CONFIG_NO_HZ */ | 148 | #endif /* #ifdef CONFIG_NO_HZ */ |
149 | seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi); | 149 | seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi); |
@@ -167,7 +167,7 @@ static int show_rcudata_csv(struct seq_file *m, void *unused) | |||
167 | { | 167 | { |
168 | seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\","); | 168 | seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\","); |
169 | #ifdef CONFIG_NO_HZ | 169 | #ifdef CONFIG_NO_HZ |
170 | seq_puts(m, "\"dt\",\"dt nesting\",\"dn\",\"df\","); | 170 | seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); |
171 | #endif /* #ifdef CONFIG_NO_HZ */ | 171 | #endif /* #ifdef CONFIG_NO_HZ */ |
172 | seq_puts(m, "\"of\",\"ri\",\"ql\",\"b\",\"ci\",\"co\",\"ca\"\n"); | 172 | seq_puts(m, "\"of\",\"ri\",\"ql\",\"b\",\"ci\",\"co\",\"ca\"\n"); |
173 | #ifdef CONFIG_TREE_PREEMPT_RCU | 173 | #ifdef CONFIG_TREE_PREEMPT_RCU |
diff --git a/kernel/sched.c b/kernel/sched.c index 5e43e9dc65d1..cbb3a0eee58e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2573,7 +2573,26 @@ static void ttwu_queue_remote(struct task_struct *p, int cpu) | |||
2573 | if (!next) | 2573 | if (!next) |
2574 | smp_send_reschedule(cpu); | 2574 | smp_send_reschedule(cpu); |
2575 | } | 2575 | } |
2576 | #endif | 2576 | |
2577 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
2578 | static int ttwu_activate_remote(struct task_struct *p, int wake_flags) | ||
2579 | { | ||
2580 | struct rq *rq; | ||
2581 | int ret = 0; | ||
2582 | |||
2583 | rq = __task_rq_lock(p); | ||
2584 | if (p->on_cpu) { | ||
2585 | ttwu_activate(rq, p, ENQUEUE_WAKEUP); | ||
2586 | ttwu_do_wakeup(rq, p, wake_flags); | ||
2587 | ret = 1; | ||
2588 | } | ||
2589 | __task_rq_unlock(rq); | ||
2590 | |||
2591 | return ret; | ||
2592 | |||
2593 | } | ||
2594 | #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */ | ||
2595 | #endif /* CONFIG_SMP */ | ||
2577 | 2596 | ||
2578 | static void ttwu_queue(struct task_struct *p, int cpu) | 2597 | static void ttwu_queue(struct task_struct *p, int cpu) |
2579 | { | 2598 | { |
@@ -2631,17 +2650,17 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
2631 | while (p->on_cpu) { | 2650 | while (p->on_cpu) { |
2632 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | 2651 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW |
2633 | /* | 2652 | /* |
2634 | * If called from interrupt context we could have landed in the | 2653 | * In case the architecture enables interrupts in |
2635 | * middle of schedule(), in this case we should take care not | 2654 | * context_switch(), we cannot busy wait, since that |
2636 | * to spin on ->on_cpu if p is current, since that would | 2655 | * would lead to deadlocks when an interrupt hits and |
2637 | * deadlock. | 2656 | * tries to wake up @prev. So bail and do a complete |
2657 | * remote wakeup. | ||
2638 | */ | 2658 | */ |
2639 | if (p == current) { | 2659 | if (ttwu_activate_remote(p, wake_flags)) |
2640 | ttwu_queue(p, cpu); | ||
2641 | goto stat; | 2660 | goto stat; |
2642 | } | 2661 | #else |
2643 | #endif | ||
2644 | cpu_relax(); | 2662 | cpu_relax(); |
2663 | #endif | ||
2645 | } | 2664 | } |
2646 | /* | 2665 | /* |
2647 | * Pairs with the smp_wmb() in finish_lock_switch(). | 2666 | * Pairs with the smp_wmb() in finish_lock_switch(). |
@@ -5841,7 +5860,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) | |||
5841 | idle->state = TASK_RUNNING; | 5860 | idle->state = TASK_RUNNING; |
5842 | idle->se.exec_start = sched_clock(); | 5861 | idle->se.exec_start = sched_clock(); |
5843 | 5862 | ||
5844 | cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu)); | 5863 | do_set_cpus_allowed(idle, cpumask_of(cpu)); |
5845 | /* | 5864 | /* |
5846 | * We're having a chicken and egg problem, even though we are | 5865 | * We're having a chicken and egg problem, even though we are |
5847 | * holding rq->lock, the cpu isn't yet set to this cpu so the | 5866 | * holding rq->lock, the cpu isn't yet set to this cpu so the |
@@ -5929,6 +5948,16 @@ static inline void sched_init_granularity(void) | |||
5929 | } | 5948 | } |
5930 | 5949 | ||
5931 | #ifdef CONFIG_SMP | 5950 | #ifdef CONFIG_SMP |
5951 | void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) | ||
5952 | { | ||
5953 | if (p->sched_class && p->sched_class->set_cpus_allowed) | ||
5954 | p->sched_class->set_cpus_allowed(p, new_mask); | ||
5955 | else { | ||
5956 | cpumask_copy(&p->cpus_allowed, new_mask); | ||
5957 | p->rt.nr_cpus_allowed = cpumask_weight(new_mask); | ||
5958 | } | ||
5959 | } | ||
5960 | |||
5932 | /* | 5961 | /* |
5933 | * This is how migration works: | 5962 | * This is how migration works: |
5934 | * | 5963 | * |
@@ -5974,12 +6003,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) | |||
5974 | goto out; | 6003 | goto out; |
5975 | } | 6004 | } |
5976 | 6005 | ||
5977 | if (p->sched_class->set_cpus_allowed) | 6006 | do_set_cpus_allowed(p, new_mask); |
5978 | p->sched_class->set_cpus_allowed(p, new_mask); | ||
5979 | else { | ||
5980 | cpumask_copy(&p->cpus_allowed, new_mask); | ||
5981 | p->rt.nr_cpus_allowed = cpumask_weight(new_mask); | ||
5982 | } | ||
5983 | 6007 | ||
5984 | /* Can the task run on the task's current CPU? If so, we're done */ | 6008 | /* Can the task run on the task's current CPU? If so, we're done */ |
5985 | if (cpumask_test_cpu(task_cpu(p), new_mask)) | 6009 | if (cpumask_test_cpu(task_cpu(p), new_mask)) |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index e32a9b70ee9c..433491c2dc8f 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -1076,8 +1076,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) | |||
1076 | se->on_rq = 0; | 1076 | se->on_rq = 0; |
1077 | update_cfs_load(cfs_rq, 0); | 1077 | update_cfs_load(cfs_rq, 0); |
1078 | account_entity_dequeue(cfs_rq, se); | 1078 | account_entity_dequeue(cfs_rq, se); |
1079 | update_min_vruntime(cfs_rq); | ||
1080 | update_cfs_shares(cfs_rq); | ||
1081 | 1079 | ||
1082 | /* | 1080 | /* |
1083 | * Normalize the entity after updating the min_vruntime because the | 1081 | * Normalize the entity after updating the min_vruntime because the |
@@ -1086,6 +1084,9 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) | |||
1086 | */ | 1084 | */ |
1087 | if (!(flags & DEQUEUE_SLEEP)) | 1085 | if (!(flags & DEQUEUE_SLEEP)) |
1088 | se->vruntime -= cfs_rq->min_vruntime; | 1086 | se->vruntime -= cfs_rq->min_vruntime; |
1087 | |||
1088 | update_min_vruntime(cfs_rq); | ||
1089 | update_cfs_shares(cfs_rq); | ||
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | /* | 1092 | /* |
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 64b2a37c07d0..88725c939e0b 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -1263,6 +1263,7 @@ static int find_lowest_rq(struct task_struct *task) | |||
1263 | if (!cpumask_test_cpu(this_cpu, lowest_mask)) | 1263 | if (!cpumask_test_cpu(this_cpu, lowest_mask)) |
1264 | this_cpu = -1; /* Skip this_cpu opt if not among lowest */ | 1264 | this_cpu = -1; /* Skip this_cpu opt if not among lowest */ |
1265 | 1265 | ||
1266 | rcu_read_lock(); | ||
1266 | for_each_domain(cpu, sd) { | 1267 | for_each_domain(cpu, sd) { |
1267 | if (sd->flags & SD_WAKE_AFFINE) { | 1268 | if (sd->flags & SD_WAKE_AFFINE) { |
1268 | int best_cpu; | 1269 | int best_cpu; |
@@ -1272,15 +1273,20 @@ static int find_lowest_rq(struct task_struct *task) | |||
1272 | * remote processor. | 1273 | * remote processor. |
1273 | */ | 1274 | */ |
1274 | if (this_cpu != -1 && | 1275 | if (this_cpu != -1 && |
1275 | cpumask_test_cpu(this_cpu, sched_domain_span(sd))) | 1276 | cpumask_test_cpu(this_cpu, sched_domain_span(sd))) { |
1277 | rcu_read_unlock(); | ||
1276 | return this_cpu; | 1278 | return this_cpu; |
1279 | } | ||
1277 | 1280 | ||
1278 | best_cpu = cpumask_first_and(lowest_mask, | 1281 | best_cpu = cpumask_first_and(lowest_mask, |
1279 | sched_domain_span(sd)); | 1282 | sched_domain_span(sd)); |
1280 | if (best_cpu < nr_cpu_ids) | 1283 | if (best_cpu < nr_cpu_ids) { |
1284 | rcu_read_unlock(); | ||
1281 | return best_cpu; | 1285 | return best_cpu; |
1286 | } | ||
1282 | } | 1287 | } |
1283 | } | 1288 | } |
1289 | rcu_read_unlock(); | ||
1284 | 1290 | ||
1285 | /* | 1291 | /* |
1286 | * And finally, if there were no matches within the domains | 1292 | * And finally, if there were no matches within the domains |
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index 48ddf431db0e..331e01bcd026 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h | |||
@@ -37,7 +37,7 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
37 | 37 | ||
38 | #ifdef CONFIG_SMP | 38 | #ifdef CONFIG_SMP |
39 | /* domain-specific stats */ | 39 | /* domain-specific stats */ |
40 | preempt_disable(); | 40 | rcu_read_lock(); |
41 | for_each_domain(cpu, sd) { | 41 | for_each_domain(cpu, sd) { |
42 | enum cpu_idle_type itype; | 42 | enum cpu_idle_type itype; |
43 | 43 | ||
@@ -64,7 +64,7 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
64 | sd->ttwu_wake_remote, sd->ttwu_move_affine, | 64 | sd->ttwu_wake_remote, sd->ttwu_move_affine, |
65 | sd->ttwu_move_balance); | 65 | sd->ttwu_move_balance); |
66 | } | 66 | } |
67 | preempt_enable(); | 67 | rcu_read_unlock(); |
68 | #endif | 68 | #endif |
69 | } | 69 | } |
70 | kfree(mask_str); | 70 | kfree(mask_str); |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d017c2c82c44..1ee417fcbfa5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -109,12 +109,18 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip); | |||
109 | static void ftrace_global_list_func(unsigned long ip, | 109 | static void ftrace_global_list_func(unsigned long ip, |
110 | unsigned long parent_ip) | 110 | unsigned long parent_ip) |
111 | { | 111 | { |
112 | struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | 112 | struct ftrace_ops *op; |
113 | |||
114 | if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) | ||
115 | return; | ||
113 | 116 | ||
117 | trace_recursion_set(TRACE_GLOBAL_BIT); | ||
118 | op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | ||
114 | while (op != &ftrace_list_end) { | 119 | while (op != &ftrace_list_end) { |
115 | op->func(ip, parent_ip); | 120 | op->func(ip, parent_ip); |
116 | op = rcu_dereference_raw(op->next); /*see above*/ | 121 | op = rcu_dereference_raw(op->next); /*see above*/ |
117 | }; | 122 | }; |
123 | trace_recursion_clear(TRACE_GLOBAL_BIT); | ||
118 | } | 124 | } |
119 | 125 | ||
120 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) | 126 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) |
@@ -1638,12 +1644,12 @@ static void ftrace_startup_enable(int command) | |||
1638 | ftrace_run_update_code(command); | 1644 | ftrace_run_update_code(command); |
1639 | } | 1645 | } |
1640 | 1646 | ||
1641 | static void ftrace_startup(struct ftrace_ops *ops, int command) | 1647 | static int ftrace_startup(struct ftrace_ops *ops, int command) |
1642 | { | 1648 | { |
1643 | bool hash_enable = true; | 1649 | bool hash_enable = true; |
1644 | 1650 | ||
1645 | if (unlikely(ftrace_disabled)) | 1651 | if (unlikely(ftrace_disabled)) |
1646 | return; | 1652 | return -ENODEV; |
1647 | 1653 | ||
1648 | ftrace_start_up++; | 1654 | ftrace_start_up++; |
1649 | command |= FTRACE_ENABLE_CALLS; | 1655 | command |= FTRACE_ENABLE_CALLS; |
@@ -1662,6 +1668,8 @@ static void ftrace_startup(struct ftrace_ops *ops, int command) | |||
1662 | ftrace_hash_rec_enable(ops, 1); | 1668 | ftrace_hash_rec_enable(ops, 1); |
1663 | 1669 | ||
1664 | ftrace_startup_enable(command); | 1670 | ftrace_startup_enable(command); |
1671 | |||
1672 | return 0; | ||
1665 | } | 1673 | } |
1666 | 1674 | ||
1667 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) | 1675 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) |
@@ -2501,7 +2509,7 @@ static void __enable_ftrace_function_probe(void) | |||
2501 | 2509 | ||
2502 | ret = __register_ftrace_function(&trace_probe_ops); | 2510 | ret = __register_ftrace_function(&trace_probe_ops); |
2503 | if (!ret) | 2511 | if (!ret) |
2504 | ftrace_startup(&trace_probe_ops, 0); | 2512 | ret = ftrace_startup(&trace_probe_ops, 0); |
2505 | 2513 | ||
2506 | ftrace_probe_registered = 1; | 2514 | ftrace_probe_registered = 1; |
2507 | } | 2515 | } |
@@ -3466,7 +3474,11 @@ device_initcall(ftrace_nodyn_init); | |||
3466 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } | 3474 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } |
3467 | static inline void ftrace_startup_enable(int command) { } | 3475 | static inline void ftrace_startup_enable(int command) { } |
3468 | /* Keep as macros so we do not need to define the commands */ | 3476 | /* Keep as macros so we do not need to define the commands */ |
3469 | # define ftrace_startup(ops, command) do { } while (0) | 3477 | # define ftrace_startup(ops, command) \ |
3478 | ({ \ | ||
3479 | (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ | ||
3480 | 0; \ | ||
3481 | }) | ||
3470 | # define ftrace_shutdown(ops, command) do { } while (0) | 3482 | # define ftrace_shutdown(ops, command) do { } while (0) |
3471 | # define ftrace_startup_sysctl() do { } while (0) | 3483 | # define ftrace_startup_sysctl() do { } while (0) |
3472 | # define ftrace_shutdown_sysctl() do { } while (0) | 3484 | # define ftrace_shutdown_sysctl() do { } while (0) |
@@ -3484,6 +3496,10 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3484 | { | 3496 | { |
3485 | struct ftrace_ops *op; | 3497 | struct ftrace_ops *op; |
3486 | 3498 | ||
3499 | if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) | ||
3500 | return; | ||
3501 | |||
3502 | trace_recursion_set(TRACE_INTERNAL_BIT); | ||
3487 | /* | 3503 | /* |
3488 | * Some of the ops may be dynamically allocated, | 3504 | * Some of the ops may be dynamically allocated, |
3489 | * they must be freed after a synchronize_sched(). | 3505 | * they must be freed after a synchronize_sched(). |
@@ -3496,6 +3512,7 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3496 | op = rcu_dereference_raw(op->next); | 3512 | op = rcu_dereference_raw(op->next); |
3497 | }; | 3513 | }; |
3498 | preempt_enable_notrace(); | 3514 | preempt_enable_notrace(); |
3515 | trace_recursion_clear(TRACE_INTERNAL_BIT); | ||
3499 | } | 3516 | } |
3500 | 3517 | ||
3501 | static void clear_ftrace_swapper(void) | 3518 | static void clear_ftrace_swapper(void) |
@@ -3799,7 +3816,7 @@ int register_ftrace_function(struct ftrace_ops *ops) | |||
3799 | 3816 | ||
3800 | ret = __register_ftrace_function(ops); | 3817 | ret = __register_ftrace_function(ops); |
3801 | if (!ret) | 3818 | if (!ret) |
3802 | ftrace_startup(ops, 0); | 3819 | ret = ftrace_startup(ops, 0); |
3803 | 3820 | ||
3804 | 3821 | ||
3805 | out_unlock: | 3822 | out_unlock: |
@@ -4045,7 +4062,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, | |||
4045 | ftrace_graph_return = retfunc; | 4062 | ftrace_graph_return = retfunc; |
4046 | ftrace_graph_entry = entryfunc; | 4063 | ftrace_graph_entry = entryfunc; |
4047 | 4064 | ||
4048 | ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); | 4065 | ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); |
4049 | 4066 | ||
4050 | out: | 4067 | out: |
4051 | mutex_unlock(&ftrace_lock); | 4068 | mutex_unlock(&ftrace_lock); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0ef7b4b2a1f7..b0c7aa407943 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -2216,7 +2216,7 @@ static noinline void trace_recursive_fail(void) | |||
2216 | 2216 | ||
2217 | printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" | 2217 | printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" |
2218 | "HC[%lu]:SC[%lu]:NMI[%lu]\n", | 2218 | "HC[%lu]:SC[%lu]:NMI[%lu]\n", |
2219 | current->trace_recursion, | 2219 | trace_recursion_buffer(), |
2220 | hardirq_count() >> HARDIRQ_SHIFT, | 2220 | hardirq_count() >> HARDIRQ_SHIFT, |
2221 | softirq_count() >> SOFTIRQ_SHIFT, | 2221 | softirq_count() >> SOFTIRQ_SHIFT, |
2222 | in_nmi()); | 2222 | in_nmi()); |
@@ -2226,9 +2226,9 @@ static noinline void trace_recursive_fail(void) | |||
2226 | 2226 | ||
2227 | static inline int trace_recursive_lock(void) | 2227 | static inline int trace_recursive_lock(void) |
2228 | { | 2228 | { |
2229 | current->trace_recursion++; | 2229 | trace_recursion_inc(); |
2230 | 2230 | ||
2231 | if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH)) | 2231 | if (likely(trace_recursion_buffer() < TRACE_RECURSIVE_DEPTH)) |
2232 | return 0; | 2232 | return 0; |
2233 | 2233 | ||
2234 | trace_recursive_fail(); | 2234 | trace_recursive_fail(); |
@@ -2238,9 +2238,9 @@ static inline int trace_recursive_lock(void) | |||
2238 | 2238 | ||
2239 | static inline void trace_recursive_unlock(void) | 2239 | static inline void trace_recursive_unlock(void) |
2240 | { | 2240 | { |
2241 | WARN_ON_ONCE(!current->trace_recursion); | 2241 | WARN_ON_ONCE(!trace_recursion_buffer()); |
2242 | 2242 | ||
2243 | current->trace_recursion--; | 2243 | trace_recursion_dec(); |
2244 | } | 2244 | } |
2245 | 2245 | ||
2246 | #else | 2246 | #else |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6b69c4bd306f..229f8591f61d 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -784,4 +784,19 @@ extern const char *__stop___trace_bprintk_fmt[]; | |||
784 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) | 784 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) |
785 | #include "trace_entries.h" | 785 | #include "trace_entries.h" |
786 | 786 | ||
787 | /* Only current can touch trace_recursion */ | ||
788 | #define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) | ||
789 | #define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) | ||
790 | |||
791 | /* Ring buffer has the 10 LSB bits to count */ | ||
792 | #define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) | ||
793 | |||
794 | /* for function tracing recursion */ | ||
795 | #define TRACE_INTERNAL_BIT (1<<11) | ||
796 | #define TRACE_GLOBAL_BIT (1<<12) | ||
797 | |||
798 | #define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) | ||
799 | #define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) | ||
800 | #define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) | ||
801 | |||
787 | #endif /* _LINUX_KERNEL_TRACE_H */ | 802 | #endif /* _LINUX_KERNEL_TRACE_H */ |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 2fe110341359..686ec399f2a8 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1657,7 +1657,12 @@ static struct ftrace_ops trace_ops __initdata = | |||
1657 | 1657 | ||
1658 | static __init void event_trace_self_test_with_function(void) | 1658 | static __init void event_trace_self_test_with_function(void) |
1659 | { | 1659 | { |
1660 | register_ftrace_function(&trace_ops); | 1660 | int ret; |
1661 | ret = register_ftrace_function(&trace_ops); | ||
1662 | if (WARN_ON(ret < 0)) { | ||
1663 | pr_info("Failed to enable function tracer for event tests\n"); | ||
1664 | return; | ||
1665 | } | ||
1661 | pr_info("Running tests again, along with the function tracer\n"); | 1666 | pr_info("Running tests again, along with the function tracer\n"); |
1662 | event_trace_self_tests(); | 1667 | event_trace_self_tests(); |
1663 | unregister_ftrace_function(&trace_ops); | 1668 | unregister_ftrace_function(&trace_ops); |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index cf535ccedc86..e37de492a9e1 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -353,6 +353,33 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, | |||
353 | } | 353 | } |
354 | EXPORT_SYMBOL(ftrace_print_symbols_seq); | 354 | EXPORT_SYMBOL(ftrace_print_symbols_seq); |
355 | 355 | ||
356 | #if BITS_PER_LONG == 32 | ||
357 | const char * | ||
358 | ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, | ||
359 | const struct trace_print_flags_u64 *symbol_array) | ||
360 | { | ||
361 | int i; | ||
362 | const char *ret = p->buffer + p->len; | ||
363 | |||
364 | for (i = 0; symbol_array[i].name; i++) { | ||
365 | |||
366 | if (val != symbol_array[i].mask) | ||
367 | continue; | ||
368 | |||
369 | trace_seq_puts(p, symbol_array[i].name); | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | if (!p->len) | ||
374 | trace_seq_printf(p, "0x%llx", val); | ||
375 | |||
376 | trace_seq_putc(p, 0); | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | EXPORT_SYMBOL(ftrace_print_symbols_seq_u64); | ||
381 | #endif | ||
382 | |||
356 | const char * | 383 | const char * |
357 | ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) | 384 | ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) |
358 | { | 385 | { |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 7daa4b072e9f..3d0c56ad4792 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -415,15 +415,13 @@ static void watchdog_nmi_disable(int cpu) { return; } | |||
415 | #endif /* CONFIG_HARDLOCKUP_DETECTOR */ | 415 | #endif /* CONFIG_HARDLOCKUP_DETECTOR */ |
416 | 416 | ||
417 | /* prepare/enable/disable routines */ | 417 | /* prepare/enable/disable routines */ |
418 | static int watchdog_prepare_cpu(int cpu) | 418 | static void watchdog_prepare_cpu(int cpu) |
419 | { | 419 | { |
420 | struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu); | 420 | struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu); |
421 | 421 | ||
422 | WARN_ON(per_cpu(softlockup_watchdog, cpu)); | 422 | WARN_ON(per_cpu(softlockup_watchdog, cpu)); |
423 | hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 423 | hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
424 | hrtimer->function = watchdog_timer_fn; | 424 | hrtimer->function = watchdog_timer_fn; |
425 | |||
426 | return 0; | ||
427 | } | 425 | } |
428 | 426 | ||
429 | static int watchdog_enable(int cpu) | 427 | static int watchdog_enable(int cpu) |
@@ -542,17 +540,16 @@ static int __cpuinit | |||
542 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 540 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
543 | { | 541 | { |
544 | int hotcpu = (unsigned long)hcpu; | 542 | int hotcpu = (unsigned long)hcpu; |
545 | int err = 0; | ||
546 | 543 | ||
547 | switch (action) { | 544 | switch (action) { |
548 | case CPU_UP_PREPARE: | 545 | case CPU_UP_PREPARE: |
549 | case CPU_UP_PREPARE_FROZEN: | 546 | case CPU_UP_PREPARE_FROZEN: |
550 | err = watchdog_prepare_cpu(hotcpu); | 547 | watchdog_prepare_cpu(hotcpu); |
551 | break; | 548 | break; |
552 | case CPU_ONLINE: | 549 | case CPU_ONLINE: |
553 | case CPU_ONLINE_FROZEN: | 550 | case CPU_ONLINE_FROZEN: |
554 | if (watchdog_enabled) | 551 | if (watchdog_enabled) |
555 | err = watchdog_enable(hotcpu); | 552 | watchdog_enable(hotcpu); |
556 | break; | 553 | break; |
557 | #ifdef CONFIG_HOTPLUG_CPU | 554 | #ifdef CONFIG_HOTPLUG_CPU |
558 | case CPU_UP_CANCELED: | 555 | case CPU_UP_CANCELED: |
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 619313ed6c46..507a22fab738 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -144,7 +144,7 @@ static void init_shared_classes(void) | |||
144 | 144 | ||
145 | #define HARDIRQ_ENTER() \ | 145 | #define HARDIRQ_ENTER() \ |
146 | local_irq_disable(); \ | 146 | local_irq_disable(); \ |
147 | irq_enter(); \ | 147 | __irq_enter(); \ |
148 | WARN_ON(!in_irq()); | 148 | WARN_ON(!in_irq()); |
149 | 149 | ||
150 | #define HARDIRQ_EXIT() \ | 150 | #define HARDIRQ_EXIT() \ |
diff --git a/mm/filemap.c b/mm/filemap.c index bcdc393b6580..d7b10578a64b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1982,16 +1982,26 @@ static int __remove_suid(struct dentry *dentry, int kill) | |||
1982 | int file_remove_suid(struct file *file) | 1982 | int file_remove_suid(struct file *file) |
1983 | { | 1983 | { |
1984 | struct dentry *dentry = file->f_path.dentry; | 1984 | struct dentry *dentry = file->f_path.dentry; |
1985 | int killsuid = should_remove_suid(dentry); | 1985 | struct inode *inode = dentry->d_inode; |
1986 | int killpriv = security_inode_need_killpriv(dentry); | 1986 | int killsuid; |
1987 | int killpriv; | ||
1987 | int error = 0; | 1988 | int error = 0; |
1988 | 1989 | ||
1990 | /* Fast path for nothing security related */ | ||
1991 | if (IS_NOSEC(inode)) | ||
1992 | return 0; | ||
1993 | |||
1994 | killsuid = should_remove_suid(dentry); | ||
1995 | killpriv = security_inode_need_killpriv(dentry); | ||
1996 | |||
1989 | if (killpriv < 0) | 1997 | if (killpriv < 0) |
1990 | return killpriv; | 1998 | return killpriv; |
1991 | if (killpriv) | 1999 | if (killpriv) |
1992 | error = security_inode_killpriv(dentry); | 2000 | error = security_inode_killpriv(dentry); |
1993 | if (!error && killsuid) | 2001 | if (!error && killsuid) |
1994 | error = __remove_suid(dentry, killsuid); | 2002 | error = __remove_suid(dentry, killsuid); |
2003 | if (!error) | ||
2004 | inode->i_flags |= S_NOSEC; | ||
1995 | 2005 | ||
1996 | return error; | 2006 | return error; |
1997 | } | 2007 | } |
@@ -2327,7 +2337,7 @@ struct page *grab_cache_page_write_begin(struct address_space *mapping, | |||
2327 | repeat: | 2337 | repeat: |
2328 | page = find_lock_page(mapping, index); | 2338 | page = find_lock_page(mapping, index); |
2329 | if (page) | 2339 | if (page) |
2330 | return page; | 2340 | goto found; |
2331 | 2341 | ||
2332 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); | 2342 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); |
2333 | if (!page) | 2343 | if (!page) |
@@ -2340,6 +2350,8 @@ repeat: | |||
2340 | goto repeat; | 2350 | goto repeat; |
2341 | return NULL; | 2351 | return NULL; |
2342 | } | 2352 | } |
2353 | found: | ||
2354 | wait_on_page_writeback(page); | ||
2343 | return page; | 2355 | return page; |
2344 | } | 2356 | } |
2345 | EXPORT_SYMBOL(grab_cache_page_write_begin); | 2357 | EXPORT_SYMBOL(grab_cache_page_write_begin); |
diff --git a/mm/maccess.c b/mm/maccess.c index e2b6f5634e0d..4cee182ab5f3 100644 --- a/mm/maccess.c +++ b/mm/maccess.c | |||
@@ -15,10 +15,10 @@ | |||
15 | * happens, handle that and return -EFAULT. | 15 | * happens, handle that and return -EFAULT. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | long __weak probe_kernel_read(void *dst, void *src, size_t size) | 18 | long __weak probe_kernel_read(void *dst, const void *src, size_t size) |
19 | __attribute__((alias("__probe_kernel_read"))); | 19 | __attribute__((alias("__probe_kernel_read"))); |
20 | 20 | ||
21 | long __probe_kernel_read(void *dst, void *src, size_t size) | 21 | long __probe_kernel_read(void *dst, const void *src, size_t size) |
22 | { | 22 | { |
23 | long ret; | 23 | long ret; |
24 | mm_segment_t old_fs = get_fs(); | 24 | mm_segment_t old_fs = get_fs(); |
@@ -43,10 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); | |||
43 | * Safely write to address @dst from the buffer at @src. If a kernel fault | 43 | * Safely write to address @dst from the buffer at @src. If a kernel fault |
44 | * happens, handle that and return -EFAULT. | 44 | * happens, handle that and return -EFAULT. |
45 | */ | 45 | */ |
46 | long __weak probe_kernel_write(void *dst, void *src, size_t size) | 46 | long __weak probe_kernel_write(void *dst, const void *src, size_t size) |
47 | __attribute__((alias("__probe_kernel_write"))); | 47 | __attribute__((alias("__probe_kernel_write"))); |
48 | 48 | ||
49 | long __probe_kernel_write(void *dst, void *src, size_t size) | 49 | long __probe_kernel_write(void *dst, const void *src, size_t size) |
50 | { | 50 | { |
51 | long ret; | 51 | long ret; |
52 | mm_segment_t old_fs = get_fs(); | 52 | mm_segment_t old_fs = get_fs(); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a4e1db3f1981..4e8985acdab8 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2247,10 +2247,6 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, | |||
2247 | 2247 | ||
2248 | if (should_fail_alloc_page(gfp_mask, order)) | 2248 | if (should_fail_alloc_page(gfp_mask, order)) |
2249 | return NULL; | 2249 | return NULL; |
2250 | #ifndef CONFIG_ZONE_DMA | ||
2251 | if (WARN_ON_ONCE(gfp_mask & __GFP_DMA)) | ||
2252 | return NULL; | ||
2253 | #endif | ||
2254 | 2250 | ||
2255 | /* | 2251 | /* |
2256 | * Check the zones suitable for the gfp_mask contain at least one | 2252 | * Check the zones suitable for the gfp_mask contain at least one |
@@ -352,6 +352,11 @@ void __init anon_vma_init(void) | |||
352 | * The page might have been remapped to a different anon_vma or the anon_vma | 352 | * The page might have been remapped to a different anon_vma or the anon_vma |
353 | * returned may already be freed (and even reused). | 353 | * returned may already be freed (and even reused). |
354 | * | 354 | * |
355 | * In case it was remapped to a different anon_vma, the new anon_vma will be a | ||
356 | * child of the old anon_vma, and the anon_vma lifetime rules will therefore | ||
357 | * ensure that any anon_vma obtained from the page will still be valid for as | ||
358 | * long as we observe page_mapped() [ hence all those page_mapped() tests ]. | ||
359 | * | ||
355 | * All users of this function must be very careful when walking the anon_vma | 360 | * All users of this function must be very careful when walking the anon_vma |
356 | * chain and verify that the page in question is indeed mapped in it | 361 | * chain and verify that the page in question is indeed mapped in it |
357 | * [ something equivalent to page_mapped_in_vma() ]. | 362 | * [ something equivalent to page_mapped_in_vma() ]. |
@@ -405,6 +410,7 @@ out: | |||
405 | struct anon_vma *page_lock_anon_vma(struct page *page) | 410 | struct anon_vma *page_lock_anon_vma(struct page *page) |
406 | { | 411 | { |
407 | struct anon_vma *anon_vma = NULL; | 412 | struct anon_vma *anon_vma = NULL; |
413 | struct anon_vma *root_anon_vma; | ||
408 | unsigned long anon_mapping; | 414 | unsigned long anon_mapping; |
409 | 415 | ||
410 | rcu_read_lock(); | 416 | rcu_read_lock(); |
@@ -415,13 +421,15 @@ struct anon_vma *page_lock_anon_vma(struct page *page) | |||
415 | goto out; | 421 | goto out; |
416 | 422 | ||
417 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); | 423 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); |
418 | if (mutex_trylock(&anon_vma->root->mutex)) { | 424 | root_anon_vma = ACCESS_ONCE(anon_vma->root); |
425 | if (mutex_trylock(&root_anon_vma->mutex)) { | ||
419 | /* | 426 | /* |
420 | * If we observe a !0 refcount, then holding the lock ensures | 427 | * If the page is still mapped, then this anon_vma is still |
421 | * the anon_vma will not go away, see __put_anon_vma(). | 428 | * its anon_vma, and holding the mutex ensures that it will |
429 | * not go away, see anon_vma_free(). | ||
422 | */ | 430 | */ |
423 | if (!atomic_read(&anon_vma->refcount)) { | 431 | if (!page_mapped(page)) { |
424 | anon_vma_unlock(anon_vma); | 432 | mutex_unlock(&root_anon_vma->mutex); |
425 | anon_vma = NULL; | 433 | anon_vma = NULL; |
426 | } | 434 | } |
427 | goto out; | 435 | goto out; |
@@ -1014,7 +1022,7 @@ void do_page_add_anon_rmap(struct page *page, | |||
1014 | return; | 1022 | return; |
1015 | 1023 | ||
1016 | VM_BUG_ON(!PageLocked(page)); | 1024 | VM_BUG_ON(!PageLocked(page)); |
1017 | VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 1025 | /* address might be in next vma when migration races vma_adjust */ |
1018 | if (first) | 1026 | if (first) |
1019 | __page_set_anon_rmap(page, vma, address, exclusive); | 1027 | __page_set_anon_rmap(page, vma, address, exclusive); |
1020 | else | 1028 | else |
@@ -1709,7 +1717,7 @@ void hugepage_add_anon_rmap(struct page *page, | |||
1709 | 1717 | ||
1710 | BUG_ON(!PageLocked(page)); | 1718 | BUG_ON(!PageLocked(page)); |
1711 | BUG_ON(!anon_vma); | 1719 | BUG_ON(!anon_vma); |
1712 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 1720 | /* address might be in next vma when migration races vma_adjust */ |
1713 | first = atomic_inc_and_test(&page->_mapcount); | 1721 | first = atomic_inc_and_test(&page->_mapcount); |
1714 | if (first) | 1722 | if (first) |
1715 | __hugepage_set_anon_rmap(page, vma, address, 0); | 1723 | __hugepage_set_anon_rmap(page, vma, address, 0); |
diff --git a/mm/shmem.c b/mm/shmem.c index 1acfb2687bfa..d221a1cfd7b1 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1114,8 +1114,8 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) | |||
1114 | delete_from_page_cache(page); | 1114 | delete_from_page_cache(page); |
1115 | shmem_swp_set(info, entry, swap.val); | 1115 | shmem_swp_set(info, entry, swap.val); |
1116 | shmem_swp_unmap(entry); | 1116 | shmem_swp_unmap(entry); |
1117 | spin_unlock(&info->lock); | ||
1118 | swap_shmem_alloc(swap); | 1117 | swap_shmem_alloc(swap); |
1118 | spin_unlock(&info->lock); | ||
1119 | BUG_ON(page_mapped(page)); | 1119 | BUG_ON(page_mapped(page)); |
1120 | swap_writepage(page, wbc); | 1120 | swap_writepage(page, wbc); |
1121 | return 0; | 1121 | return 0; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8d83f9d48713..b84d7395535e 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -13,10 +13,6 @@ | |||
13 | * and need to be refreshed, or when a packet was damaged in transit. | 13 | * and need to be refreshed, or when a packet was damaged in transit. |
14 | * This may be have to be moved to the VFS layer. | 14 | * This may be have to be moved to the VFS layer. |
15 | * | 15 | * |
16 | * NB: BSD uses a more intelligent approach to guessing when a request | ||
17 | * or reply has been lost by keeping the RTO estimate for each procedure. | ||
18 | * We currently make do with a constant timeout value. | ||
19 | * | ||
20 | * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> | 16 | * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> |
21 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> | 17 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> |
22 | */ | 18 | */ |
@@ -32,7 +28,9 @@ | |||
32 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
33 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
34 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/in.h> | ||
35 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
33 | #include <linux/un.h> | ||
36 | 34 | ||
37 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
38 | #include <linux/sunrpc/rpc_pipe_fs.h> | 36 | #include <linux/sunrpc/rpc_pipe_fs.h> |
@@ -298,22 +296,27 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
298 | * up a string representation of the passed-in address. | 296 | * up a string representation of the passed-in address. |
299 | */ | 297 | */ |
300 | if (args->servername == NULL) { | 298 | if (args->servername == NULL) { |
299 | struct sockaddr_un *sun = | ||
300 | (struct sockaddr_un *)args->address; | ||
301 | struct sockaddr_in *sin = | ||
302 | (struct sockaddr_in *)args->address; | ||
303 | struct sockaddr_in6 *sin6 = | ||
304 | (struct sockaddr_in6 *)args->address; | ||
305 | |||
301 | servername[0] = '\0'; | 306 | servername[0] = '\0'; |
302 | switch (args->address->sa_family) { | 307 | switch (args->address->sa_family) { |
303 | case AF_INET: { | 308 | case AF_LOCAL: |
304 | struct sockaddr_in *sin = | 309 | snprintf(servername, sizeof(servername), "%s", |
305 | (struct sockaddr_in *)args->address; | 310 | sun->sun_path); |
311 | break; | ||
312 | case AF_INET: | ||
306 | snprintf(servername, sizeof(servername), "%pI4", | 313 | snprintf(servername, sizeof(servername), "%pI4", |
307 | &sin->sin_addr.s_addr); | 314 | &sin->sin_addr.s_addr); |
308 | break; | 315 | break; |
309 | } | 316 | case AF_INET6: |
310 | case AF_INET6: { | ||
311 | struct sockaddr_in6 *sin = | ||
312 | (struct sockaddr_in6 *)args->address; | ||
313 | snprintf(servername, sizeof(servername), "%pI6", | 317 | snprintf(servername, sizeof(servername), "%pI6", |
314 | &sin->sin6_addr); | 318 | &sin6->sin6_addr); |
315 | break; | 319 | break; |
316 | } | ||
317 | default: | 320 | default: |
318 | /* caller wants default server name, but | 321 | /* caller wants default server name, but |
319 | * address family isn't recognized. */ | 322 | * address family isn't recognized. */ |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index c652e4cc9fe9..9a80a922c527 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/socket.h> | 18 | #include <linux/socket.h> |
19 | #include <linux/un.h> | ||
19 | #include <linux/in.h> | 20 | #include <linux/in.h> |
20 | #include <linux/in6.h> | 21 | #include <linux/in6.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
@@ -32,6 +33,8 @@ | |||
32 | # define RPCDBG_FACILITY RPCDBG_BIND | 33 | # define RPCDBG_FACILITY RPCDBG_BIND |
33 | #endif | 34 | #endif |
34 | 35 | ||
36 | #define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock" | ||
37 | |||
35 | #define RPCBIND_PROGRAM (100000u) | 38 | #define RPCBIND_PROGRAM (100000u) |
36 | #define RPCBIND_PORT (111u) | 39 | #define RPCBIND_PORT (111u) |
37 | 40 | ||
@@ -158,20 +161,69 @@ static void rpcb_map_release(void *data) | |||
158 | kfree(map); | 161 | kfree(map); |
159 | } | 162 | } |
160 | 163 | ||
161 | static const struct sockaddr_in rpcb_inaddr_loopback = { | 164 | /* |
162 | .sin_family = AF_INET, | 165 | * Returns zero on success, otherwise a negative errno value |
163 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | 166 | * is returned. |
164 | .sin_port = htons(RPCBIND_PORT), | 167 | */ |
165 | }; | 168 | static int rpcb_create_local_unix(void) |
169 | { | ||
170 | static const struct sockaddr_un rpcb_localaddr_rpcbind = { | ||
171 | .sun_family = AF_LOCAL, | ||
172 | .sun_path = RPCBIND_SOCK_PATHNAME, | ||
173 | }; | ||
174 | struct rpc_create_args args = { | ||
175 | .net = &init_net, | ||
176 | .protocol = XPRT_TRANSPORT_LOCAL, | ||
177 | .address = (struct sockaddr *)&rpcb_localaddr_rpcbind, | ||
178 | .addrsize = sizeof(rpcb_localaddr_rpcbind), | ||
179 | .servername = "localhost", | ||
180 | .program = &rpcb_program, | ||
181 | .version = RPCBVERS_2, | ||
182 | .authflavor = RPC_AUTH_NULL, | ||
183 | }; | ||
184 | struct rpc_clnt *clnt, *clnt4; | ||
185 | int result = 0; | ||
186 | |||
187 | /* | ||
188 | * Because we requested an RPC PING at transport creation time, | ||
189 | * this works only if the user space portmapper is rpcbind, and | ||
190 | * it's listening on AF_LOCAL on the named socket. | ||
191 | */ | ||
192 | clnt = rpc_create(&args); | ||
193 | if (IS_ERR(clnt)) { | ||
194 | dprintk("RPC: failed to create AF_LOCAL rpcbind " | ||
195 | "client (errno %ld).\n", PTR_ERR(clnt)); | ||
196 | result = -PTR_ERR(clnt); | ||
197 | goto out; | ||
198 | } | ||
199 | |||
200 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); | ||
201 | if (IS_ERR(clnt4)) { | ||
202 | dprintk("RPC: failed to bind second program to " | ||
203 | "rpcbind v4 client (errno %ld).\n", | ||
204 | PTR_ERR(clnt4)); | ||
205 | clnt4 = NULL; | ||
206 | } | ||
207 | |||
208 | /* Protected by rpcb_create_local_mutex */ | ||
209 | rpcb_local_clnt = clnt; | ||
210 | rpcb_local_clnt4 = clnt4; | ||
166 | 211 | ||
167 | static DEFINE_MUTEX(rpcb_create_local_mutex); | 212 | out: |
213 | return result; | ||
214 | } | ||
168 | 215 | ||
169 | /* | 216 | /* |
170 | * Returns zero on success, otherwise a negative errno value | 217 | * Returns zero on success, otherwise a negative errno value |
171 | * is returned. | 218 | * is returned. |
172 | */ | 219 | */ |
173 | static int rpcb_create_local(void) | 220 | static int rpcb_create_local_net(void) |
174 | { | 221 | { |
222 | static const struct sockaddr_in rpcb_inaddr_loopback = { | ||
223 | .sin_family = AF_INET, | ||
224 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | ||
225 | .sin_port = htons(RPCBIND_PORT), | ||
226 | }; | ||
175 | struct rpc_create_args args = { | 227 | struct rpc_create_args args = { |
176 | .net = &init_net, | 228 | .net = &init_net, |
177 | .protocol = XPRT_TRANSPORT_TCP, | 229 | .protocol = XPRT_TRANSPORT_TCP, |
@@ -186,13 +238,6 @@ static int rpcb_create_local(void) | |||
186 | struct rpc_clnt *clnt, *clnt4; | 238 | struct rpc_clnt *clnt, *clnt4; |
187 | int result = 0; | 239 | int result = 0; |
188 | 240 | ||
189 | if (rpcb_local_clnt) | ||
190 | return result; | ||
191 | |||
192 | mutex_lock(&rpcb_create_local_mutex); | ||
193 | if (rpcb_local_clnt) | ||
194 | goto out; | ||
195 | |||
196 | clnt = rpc_create(&args); | 241 | clnt = rpc_create(&args); |
197 | if (IS_ERR(clnt)) { | 242 | if (IS_ERR(clnt)) { |
198 | dprintk("RPC: failed to create local rpcbind " | 243 | dprintk("RPC: failed to create local rpcbind " |
@@ -214,10 +259,34 @@ static int rpcb_create_local(void) | |||
214 | clnt4 = NULL; | 259 | clnt4 = NULL; |
215 | } | 260 | } |
216 | 261 | ||
262 | /* Protected by rpcb_create_local_mutex */ | ||
217 | rpcb_local_clnt = clnt; | 263 | rpcb_local_clnt = clnt; |
218 | rpcb_local_clnt4 = clnt4; | 264 | rpcb_local_clnt4 = clnt4; |
219 | 265 | ||
220 | out: | 266 | out: |
267 | return result; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Returns zero on success, otherwise a negative errno value | ||
272 | * is returned. | ||
273 | */ | ||
274 | static int rpcb_create_local(void) | ||
275 | { | ||
276 | static DEFINE_MUTEX(rpcb_create_local_mutex); | ||
277 | int result = 0; | ||
278 | |||
279 | if (rpcb_local_clnt) | ||
280 | return result; | ||
281 | |||
282 | mutex_lock(&rpcb_create_local_mutex); | ||
283 | if (rpcb_local_clnt) | ||
284 | goto out; | ||
285 | |||
286 | if (rpcb_create_local_unix() != 0) | ||
287 | result = rpcb_create_local_net(); | ||
288 | |||
289 | out: | ||
221 | mutex_unlock(&rpcb_create_local_mutex); | 290 | mutex_unlock(&rpcb_create_local_mutex); |
222 | return result; | 291 | return result; |
223 | } | 292 | } |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 08e05a8ce025..2b90292e9505 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -942,6 +942,8 @@ static void svc_unregister(const struct svc_serv *serv) | |||
942 | if (progp->pg_vers[i]->vs_hidden) | 942 | if (progp->pg_vers[i]->vs_hidden) |
943 | continue; | 943 | continue; |
944 | 944 | ||
945 | dprintk("svc: attempting to unregister %sv%u\n", | ||
946 | progp->pg_name, i); | ||
945 | __svc_unregister(progp->pg_prog, i, progp->pg_name); | 947 | __svc_unregister(progp->pg_prog, i, progp->pg_name); |
946 | } | 948 | } |
947 | } | 949 | } |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index b7d435c3f19e..af04f779ce9f 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -387,6 +387,33 @@ static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, | |||
387 | return len; | 387 | return len; |
388 | } | 388 | } |
389 | 389 | ||
390 | static int svc_partial_recvfrom(struct svc_rqst *rqstp, | ||
391 | struct kvec *iov, int nr, | ||
392 | int buflen, unsigned int base) | ||
393 | { | ||
394 | size_t save_iovlen; | ||
395 | void __user *save_iovbase; | ||
396 | unsigned int i; | ||
397 | int ret; | ||
398 | |||
399 | if (base == 0) | ||
400 | return svc_recvfrom(rqstp, iov, nr, buflen); | ||
401 | |||
402 | for (i = 0; i < nr; i++) { | ||
403 | if (iov[i].iov_len > base) | ||
404 | break; | ||
405 | base -= iov[i].iov_len; | ||
406 | } | ||
407 | save_iovlen = iov[i].iov_len; | ||
408 | save_iovbase = iov[i].iov_base; | ||
409 | iov[i].iov_len -= base; | ||
410 | iov[i].iov_base += base; | ||
411 | ret = svc_recvfrom(rqstp, &iov[i], nr - i, buflen); | ||
412 | iov[i].iov_len = save_iovlen; | ||
413 | iov[i].iov_base = save_iovbase; | ||
414 | return ret; | ||
415 | } | ||
416 | |||
390 | /* | 417 | /* |
391 | * Set socket snd and rcv buffer lengths | 418 | * Set socket snd and rcv buffer lengths |
392 | */ | 419 | */ |
@@ -409,7 +436,6 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd, | |||
409 | lock_sock(sock->sk); | 436 | lock_sock(sock->sk); |
410 | sock->sk->sk_sndbuf = snd * 2; | 437 | sock->sk->sk_sndbuf = snd * 2; |
411 | sock->sk->sk_rcvbuf = rcv * 2; | 438 | sock->sk->sk_rcvbuf = rcv * 2; |
412 | sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK; | ||
413 | sock->sk->sk_write_space(sock->sk); | 439 | sock->sk->sk_write_space(sock->sk); |
414 | release_sock(sock->sk); | 440 | release_sock(sock->sk); |
415 | #endif | 441 | #endif |
@@ -884,6 +910,56 @@ failed: | |||
884 | return NULL; | 910 | return NULL; |
885 | } | 911 | } |
886 | 912 | ||
913 | static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst *rqstp) | ||
914 | { | ||
915 | unsigned int i, len, npages; | ||
916 | |||
917 | if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) | ||
918 | return 0; | ||
919 | len = svsk->sk_tcplen - sizeof(rpc_fraghdr); | ||
920 | npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
921 | for (i = 0; i < npages; i++) { | ||
922 | if (rqstp->rq_pages[i] != NULL) | ||
923 | put_page(rqstp->rq_pages[i]); | ||
924 | BUG_ON(svsk->sk_pages[i] == NULL); | ||
925 | rqstp->rq_pages[i] = svsk->sk_pages[i]; | ||
926 | svsk->sk_pages[i] = NULL; | ||
927 | } | ||
928 | rqstp->rq_arg.head[0].iov_base = page_address(rqstp->rq_pages[0]); | ||
929 | return len; | ||
930 | } | ||
931 | |||
932 | static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp) | ||
933 | { | ||
934 | unsigned int i, len, npages; | ||
935 | |||
936 | if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) | ||
937 | return; | ||
938 | len = svsk->sk_tcplen - sizeof(rpc_fraghdr); | ||
939 | npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
940 | for (i = 0; i < npages; i++) { | ||
941 | svsk->sk_pages[i] = rqstp->rq_pages[i]; | ||
942 | rqstp->rq_pages[i] = NULL; | ||
943 | } | ||
944 | } | ||
945 | |||
946 | static void svc_tcp_clear_pages(struct svc_sock *svsk) | ||
947 | { | ||
948 | unsigned int i, len, npages; | ||
949 | |||
950 | if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) | ||
951 | goto out; | ||
952 | len = svsk->sk_tcplen - sizeof(rpc_fraghdr); | ||
953 | npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
954 | for (i = 0; i < npages; i++) { | ||
955 | BUG_ON(svsk->sk_pages[i] == NULL); | ||
956 | put_page(svsk->sk_pages[i]); | ||
957 | svsk->sk_pages[i] = NULL; | ||
958 | } | ||
959 | out: | ||
960 | svsk->sk_tcplen = 0; | ||
961 | } | ||
962 | |||
887 | /* | 963 | /* |
888 | * Receive data. | 964 | * Receive data. |
889 | * If we haven't gotten the record length yet, get the next four bytes. | 965 | * If we haven't gotten the record length yet, get the next four bytes. |
@@ -893,31 +969,15 @@ failed: | |||
893 | static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | 969 | static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) |
894 | { | 970 | { |
895 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | 971 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; |
972 | unsigned int want; | ||
896 | int len; | 973 | int len; |
897 | 974 | ||
898 | if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) | ||
899 | /* sndbuf needs to have room for one request | ||
900 | * per thread, otherwise we can stall even when the | ||
901 | * network isn't a bottleneck. | ||
902 | * | ||
903 | * We count all threads rather than threads in a | ||
904 | * particular pool, which provides an upper bound | ||
905 | * on the number of threads which will access the socket. | ||
906 | * | ||
907 | * rcvbuf just needs to be able to hold a few requests. | ||
908 | * Normally they will be removed from the queue | ||
909 | * as soon a a complete request arrives. | ||
910 | */ | ||
911 | svc_sock_setbufsize(svsk->sk_sock, | ||
912 | (serv->sv_nrthreads+3) * serv->sv_max_mesg, | ||
913 | 3 * serv->sv_max_mesg); | ||
914 | |||
915 | clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 975 | clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
916 | 976 | ||
917 | if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) { | 977 | if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) { |
918 | int want = sizeof(rpc_fraghdr) - svsk->sk_tcplen; | ||
919 | struct kvec iov; | 978 | struct kvec iov; |
920 | 979 | ||
980 | want = sizeof(rpc_fraghdr) - svsk->sk_tcplen; | ||
921 | iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen; | 981 | iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen; |
922 | iov.iov_len = want; | 982 | iov.iov_len = want; |
923 | if ((len = svc_recvfrom(rqstp, &iov, 1, want)) < 0) | 983 | if ((len = svc_recvfrom(rqstp, &iov, 1, want)) < 0) |
@@ -927,7 +987,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
927 | if (len < want) { | 987 | if (len < want) { |
928 | dprintk("svc: short recvfrom while reading record " | 988 | dprintk("svc: short recvfrom while reading record " |
929 | "length (%d of %d)\n", len, want); | 989 | "length (%d of %d)\n", len, want); |
930 | goto err_again; /* record header not complete */ | 990 | return -EAGAIN; |
931 | } | 991 | } |
932 | 992 | ||
933 | svsk->sk_reclen = ntohl(svsk->sk_reclen); | 993 | svsk->sk_reclen = ntohl(svsk->sk_reclen); |
@@ -954,83 +1014,75 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
954 | } | 1014 | } |
955 | } | 1015 | } |
956 | 1016 | ||
957 | /* Check whether enough data is available */ | 1017 | if (svsk->sk_reclen < 8) |
958 | len = svc_recv_available(svsk); | 1018 | goto err_delete; /* client is nuts. */ |
959 | if (len < 0) | ||
960 | goto error; | ||
961 | 1019 | ||
962 | if (len < svsk->sk_reclen) { | ||
963 | dprintk("svc: incomplete TCP record (%d of %d)\n", | ||
964 | len, svsk->sk_reclen); | ||
965 | goto err_again; /* record not complete */ | ||
966 | } | ||
967 | len = svsk->sk_reclen; | 1020 | len = svsk->sk_reclen; |
968 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | ||
969 | 1021 | ||
970 | return len; | 1022 | return len; |
971 | error: | 1023 | error: |
972 | if (len == -EAGAIN) | 1024 | dprintk("RPC: TCP recv_record got %d\n", len); |
973 | dprintk("RPC: TCP recv_record got EAGAIN\n"); | ||
974 | return len; | 1025 | return len; |
975 | err_delete: | 1026 | err_delete: |
976 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 1027 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
977 | err_again: | ||
978 | return -EAGAIN; | 1028 | return -EAGAIN; |
979 | } | 1029 | } |
980 | 1030 | ||
981 | static int svc_process_calldir(struct svc_sock *svsk, struct svc_rqst *rqstp, | 1031 | static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) |
982 | struct rpc_rqst **reqpp, struct kvec *vec) | ||
983 | { | 1032 | { |
1033 | struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt; | ||
984 | struct rpc_rqst *req = NULL; | 1034 | struct rpc_rqst *req = NULL; |
985 | u32 *p; | 1035 | struct kvec *src, *dst; |
986 | u32 xid; | 1036 | __be32 *p = (__be32 *)rqstp->rq_arg.head[0].iov_base; |
987 | u32 calldir; | 1037 | __be32 xid; |
988 | int len; | 1038 | __be32 calldir; |
989 | |||
990 | len = svc_recvfrom(rqstp, vec, 1, 8); | ||
991 | if (len < 0) | ||
992 | goto error; | ||
993 | 1039 | ||
994 | p = (u32 *)rqstp->rq_arg.head[0].iov_base; | ||
995 | xid = *p++; | 1040 | xid = *p++; |
996 | calldir = *p; | 1041 | calldir = *p; |
997 | 1042 | ||
998 | if (calldir == 0) { | 1043 | if (bc_xprt) |
999 | /* REQUEST is the most common case */ | 1044 | req = xprt_lookup_rqst(bc_xprt, xid); |
1000 | vec[0] = rqstp->rq_arg.head[0]; | ||
1001 | } else { | ||
1002 | /* REPLY */ | ||
1003 | struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt; | ||
1004 | |||
1005 | if (bc_xprt) | ||
1006 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1007 | |||
1008 | if (!req) { | ||
1009 | printk(KERN_NOTICE | ||
1010 | "%s: Got unrecognized reply: " | ||
1011 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1012 | __func__, ntohl(calldir), | ||
1013 | bc_xprt, xid); | ||
1014 | vec[0] = rqstp->rq_arg.head[0]; | ||
1015 | goto out; | ||
1016 | } | ||
1017 | 1045 | ||
1018 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, | 1046 | if (!req) { |
1019 | sizeof(struct xdr_buf)); | 1047 | printk(KERN_NOTICE |
1020 | /* copy the xid and call direction */ | 1048 | "%s: Got unrecognized reply: " |
1021 | memcpy(req->rq_private_buf.head[0].iov_base, | 1049 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", |
1022 | rqstp->rq_arg.head[0].iov_base, 8); | 1050 | __func__, ntohl(calldir), |
1023 | vec[0] = req->rq_private_buf.head[0]; | 1051 | bc_xprt, xid); |
1052 | return -EAGAIN; | ||
1024 | } | 1053 | } |
1025 | out: | 1054 | |
1026 | vec[0].iov_base += 8; | 1055 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); |
1027 | vec[0].iov_len -= 8; | 1056 | /* |
1028 | len = svsk->sk_reclen - 8; | 1057 | * XXX!: cheating for now! Only copying HEAD. |
1029 | error: | 1058 | * But we know this is good enough for now (in fact, for any |
1030 | *reqpp = req; | 1059 | * callback reply in the forseeable future). |
1031 | return len; | 1060 | */ |
1061 | dst = &req->rq_private_buf.head[0]; | ||
1062 | src = &rqstp->rq_arg.head[0]; | ||
1063 | if (dst->iov_len < src->iov_len) | ||
1064 | return -EAGAIN; /* whatever; just giving up. */ | ||
1065 | memcpy(dst->iov_base, src->iov_base, src->iov_len); | ||
1066 | xprt_complete_rqst(req->rq_task, svsk->sk_reclen); | ||
1067 | rqstp->rq_arg.len = 0; | ||
1068 | return 0; | ||
1032 | } | 1069 | } |
1033 | 1070 | ||
1071 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) | ||
1072 | { | ||
1073 | int i = 0; | ||
1074 | int t = 0; | ||
1075 | |||
1076 | while (t < len) { | ||
1077 | vec[i].iov_base = page_address(pages[i]); | ||
1078 | vec[i].iov_len = PAGE_SIZE; | ||
1079 | i++; | ||
1080 | t += PAGE_SIZE; | ||
1081 | } | ||
1082 | return i; | ||
1083 | } | ||
1084 | |||
1085 | |||
1034 | /* | 1086 | /* |
1035 | * Receive data from a TCP socket. | 1087 | * Receive data from a TCP socket. |
1036 | */ | 1088 | */ |
@@ -1041,8 +1093,10 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1041 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | 1093 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; |
1042 | int len; | 1094 | int len; |
1043 | struct kvec *vec; | 1095 | struct kvec *vec; |
1044 | int pnum, vlen; | 1096 | unsigned int want, base; |
1045 | struct rpc_rqst *req = NULL; | 1097 | __be32 *p; |
1098 | __be32 calldir; | ||
1099 | int pnum; | ||
1046 | 1100 | ||
1047 | dprintk("svc: tcp_recv %p data %d conn %d close %d\n", | 1101 | dprintk("svc: tcp_recv %p data %d conn %d close %d\n", |
1048 | svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags), | 1102 | svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags), |
@@ -1053,87 +1107,73 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1053 | if (len < 0) | 1107 | if (len < 0) |
1054 | goto error; | 1108 | goto error; |
1055 | 1109 | ||
1110 | base = svc_tcp_restore_pages(svsk, rqstp); | ||
1111 | want = svsk->sk_reclen - base; | ||
1112 | |||
1056 | vec = rqstp->rq_vec; | 1113 | vec = rqstp->rq_vec; |
1057 | vec[0] = rqstp->rq_arg.head[0]; | ||
1058 | vlen = PAGE_SIZE; | ||
1059 | 1114 | ||
1060 | /* | 1115 | pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], |
1061 | * We have enough data for the whole tcp record. Let's try and read the | 1116 | svsk->sk_reclen); |
1062 | * first 8 bytes to get the xid and the call direction. We can use this | ||
1063 | * to figure out if this is a call or a reply to a callback. If | ||
1064 | * sk_reclen is < 8 (xid and calldir), then this is a malformed packet. | ||
1065 | * In that case, don't bother with the calldir and just read the data. | ||
1066 | * It will be rejected in svc_process. | ||
1067 | */ | ||
1068 | if (len >= 8) { | ||
1069 | len = svc_process_calldir(svsk, rqstp, &req, vec); | ||
1070 | if (len < 0) | ||
1071 | goto err_again; | ||
1072 | vlen -= 8; | ||
1073 | } | ||
1074 | 1117 | ||
1075 | pnum = 1; | ||
1076 | while (vlen < len) { | ||
1077 | vec[pnum].iov_base = (req) ? | ||
1078 | page_address(req->rq_private_buf.pages[pnum - 1]) : | ||
1079 | page_address(rqstp->rq_pages[pnum]); | ||
1080 | vec[pnum].iov_len = PAGE_SIZE; | ||
1081 | pnum++; | ||
1082 | vlen += PAGE_SIZE; | ||
1083 | } | ||
1084 | rqstp->rq_respages = &rqstp->rq_pages[pnum]; | 1118 | rqstp->rq_respages = &rqstp->rq_pages[pnum]; |
1085 | 1119 | ||
1086 | /* Now receive data */ | 1120 | /* Now receive data */ |
1087 | len = svc_recvfrom(rqstp, vec, pnum, len); | 1121 | len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); |
1088 | if (len < 0) | 1122 | if (len >= 0) |
1089 | goto err_again; | 1123 | svsk->sk_tcplen += len; |
1090 | 1124 | if (len != want) { | |
1091 | /* | 1125 | if (len < 0 && len != -EAGAIN) |
1092 | * Account for the 8 bytes we read earlier | 1126 | goto err_other; |
1093 | */ | 1127 | svc_tcp_save_pages(svsk, rqstp); |
1094 | len += 8; | 1128 | dprintk("svc: incomplete TCP record (%d of %d)\n", |
1095 | 1129 | svsk->sk_tcplen, svsk->sk_reclen); | |
1096 | if (req) { | 1130 | goto err_noclose; |
1097 | xprt_complete_rqst(req->rq_task, len); | ||
1098 | len = 0; | ||
1099 | goto out; | ||
1100 | } | 1131 | } |
1101 | dprintk("svc: TCP complete record (%d bytes)\n", len); | 1132 | |
1102 | rqstp->rq_arg.len = len; | 1133 | rqstp->rq_arg.len = svsk->sk_reclen; |
1103 | rqstp->rq_arg.page_base = 0; | 1134 | rqstp->rq_arg.page_base = 0; |
1104 | if (len <= rqstp->rq_arg.head[0].iov_len) { | 1135 | if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { |
1105 | rqstp->rq_arg.head[0].iov_len = len; | 1136 | rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len; |
1106 | rqstp->rq_arg.page_len = 0; | 1137 | rqstp->rq_arg.page_len = 0; |
1107 | } else { | 1138 | } else |
1108 | rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len; | 1139 | rqstp->rq_arg.page_len = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; |
1109 | } | ||
1110 | 1140 | ||
1111 | rqstp->rq_xprt_ctxt = NULL; | 1141 | rqstp->rq_xprt_ctxt = NULL; |
1112 | rqstp->rq_prot = IPPROTO_TCP; | 1142 | rqstp->rq_prot = IPPROTO_TCP; |
1113 | 1143 | ||
1114 | out: | 1144 | p = (__be32 *)rqstp->rq_arg.head[0].iov_base; |
1145 | calldir = p[1]; | ||
1146 | if (calldir) | ||
1147 | len = receive_cb_reply(svsk, rqstp); | ||
1148 | |||
1115 | /* Reset TCP read info */ | 1149 | /* Reset TCP read info */ |
1116 | svsk->sk_reclen = 0; | 1150 | svsk->sk_reclen = 0; |
1117 | svsk->sk_tcplen = 0; | 1151 | svsk->sk_tcplen = 0; |
1152 | /* If we have more data, signal svc_xprt_enqueue() to try again */ | ||
1153 | if (svc_recv_available(svsk) > sizeof(rpc_fraghdr)) | ||
1154 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | ||
1155 | |||
1156 | if (len < 0) | ||
1157 | goto error; | ||
1118 | 1158 | ||
1119 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); | 1159 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); |
1120 | if (serv->sv_stats) | 1160 | if (serv->sv_stats) |
1121 | serv->sv_stats->nettcpcnt++; | 1161 | serv->sv_stats->nettcpcnt++; |
1122 | 1162 | ||
1123 | return len; | 1163 | dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len); |
1164 | return rqstp->rq_arg.len; | ||
1124 | 1165 | ||
1125 | err_again: | ||
1126 | if (len == -EAGAIN) { | ||
1127 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); | ||
1128 | return len; | ||
1129 | } | ||
1130 | error: | 1166 | error: |
1131 | if (len != -EAGAIN) { | 1167 | if (len != -EAGAIN) |
1132 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", | 1168 | goto err_other; |
1133 | svsk->sk_xprt.xpt_server->sv_name, -len); | 1169 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); |
1134 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | ||
1135 | } | ||
1136 | return -EAGAIN; | 1170 | return -EAGAIN; |
1171 | err_other: | ||
1172 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", | ||
1173 | svsk->sk_xprt.xpt_server->sv_name, -len); | ||
1174 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | ||
1175 | err_noclose: | ||
1176 | return -EAGAIN; /* record not complete */ | ||
1137 | } | 1177 | } |
1138 | 1178 | ||
1139 | /* | 1179 | /* |
@@ -1304,18 +1344,10 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | |||
1304 | 1344 | ||
1305 | svsk->sk_reclen = 0; | 1345 | svsk->sk_reclen = 0; |
1306 | svsk->sk_tcplen = 0; | 1346 | svsk->sk_tcplen = 0; |
1347 | memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); | ||
1307 | 1348 | ||
1308 | tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; | 1349 | tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; |
1309 | 1350 | ||
1310 | /* initialise setting must have enough space to | ||
1311 | * receive and respond to one request. | ||
1312 | * svc_tcp_recvfrom will re-adjust if necessary | ||
1313 | */ | ||
1314 | svc_sock_setbufsize(svsk->sk_sock, | ||
1315 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, | ||
1316 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); | ||
1317 | |||
1318 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); | ||
1319 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 1351 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
1320 | if (sk->sk_state != TCP_ESTABLISHED) | 1352 | if (sk->sk_state != TCP_ESTABLISHED) |
1321 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 1353 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
@@ -1379,8 +1411,14 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1379 | /* Initialize the socket */ | 1411 | /* Initialize the socket */ |
1380 | if (sock->type == SOCK_DGRAM) | 1412 | if (sock->type == SOCK_DGRAM) |
1381 | svc_udp_init(svsk, serv); | 1413 | svc_udp_init(svsk, serv); |
1382 | else | 1414 | else { |
1415 | /* initialise setting must have enough space to | ||
1416 | * receive and respond to one request. | ||
1417 | */ | ||
1418 | svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg, | ||
1419 | 4 * serv->sv_max_mesg); | ||
1383 | svc_tcp_init(svsk, serv); | 1420 | svc_tcp_init(svsk, serv); |
1421 | } | ||
1384 | 1422 | ||
1385 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", | 1423 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", |
1386 | svsk, svsk->sk_sk); | 1424 | svsk, svsk->sk_sk); |
@@ -1562,8 +1600,10 @@ static void svc_tcp_sock_detach(struct svc_xprt *xprt) | |||
1562 | 1600 | ||
1563 | svc_sock_detach(xprt); | 1601 | svc_sock_detach(xprt); |
1564 | 1602 | ||
1565 | if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) | 1603 | if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) { |
1604 | svc_tcp_clear_pages(svsk); | ||
1566 | kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); | 1605 | kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); |
1606 | } | ||
1567 | } | 1607 | } |
1568 | 1608 | ||
1569 | /* | 1609 | /* |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 679cd674b81d..f008c14ad34c 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -638,6 +638,25 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | |||
638 | } | 638 | } |
639 | EXPORT_SYMBOL_GPL(xdr_init_decode); | 639 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
640 | 640 | ||
641 | /** | ||
642 | * xdr_init_decode - Initialize an xdr_stream for decoding data. | ||
643 | * @xdr: pointer to xdr_stream struct | ||
644 | * @buf: pointer to XDR buffer from which to decode data | ||
645 | * @pages: list of pages to decode into | ||
646 | * @len: length in bytes of buffer in pages | ||
647 | */ | ||
648 | void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, | ||
649 | struct page **pages, unsigned int len) | ||
650 | { | ||
651 | memset(buf, 0, sizeof(*buf)); | ||
652 | buf->pages = pages; | ||
653 | buf->page_len = len; | ||
654 | buf->buflen = len; | ||
655 | buf->len = len; | ||
656 | xdr_init_decode(xdr, buf, NULL); | ||
657 | } | ||
658 | EXPORT_SYMBOL_GPL(xdr_init_decode_pages); | ||
659 | |||
641 | static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) | 660 | static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) |
642 | { | 661 | { |
643 | __be32 *p = xdr->p; | 662 | __be32 *p = xdr->p; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index bf005d3c65ef..72abb7358933 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/string.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
@@ -28,6 +29,7 @@ | |||
28 | #include <linux/in.h> | 29 | #include <linux/in.h> |
29 | #include <linux/net.h> | 30 | #include <linux/net.h> |
30 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/un.h> | ||
31 | #include <linux/udp.h> | 33 | #include <linux/udp.h> |
32 | #include <linux/tcp.h> | 34 | #include <linux/tcp.h> |
33 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
@@ -45,6 +47,9 @@ | |||
45 | #include <net/tcp.h> | 47 | #include <net/tcp.h> |
46 | 48 | ||
47 | #include "sunrpc.h" | 49 | #include "sunrpc.h" |
50 | |||
51 | static void xs_close(struct rpc_xprt *xprt); | ||
52 | |||
48 | /* | 53 | /* |
49 | * xprtsock tunables | 54 | * xprtsock tunables |
50 | */ | 55 | */ |
@@ -261,6 +266,11 @@ static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) | |||
261 | return (struct sockaddr *) &xprt->addr; | 266 | return (struct sockaddr *) &xprt->addr; |
262 | } | 267 | } |
263 | 268 | ||
269 | static inline struct sockaddr_un *xs_addr_un(struct rpc_xprt *xprt) | ||
270 | { | ||
271 | return (struct sockaddr_un *) &xprt->addr; | ||
272 | } | ||
273 | |||
264 | static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) | 274 | static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) |
265 | { | 275 | { |
266 | return (struct sockaddr_in *) &xprt->addr; | 276 | return (struct sockaddr_in *) &xprt->addr; |
@@ -276,23 +286,34 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt) | |||
276 | struct sockaddr *sap = xs_addr(xprt); | 286 | struct sockaddr *sap = xs_addr(xprt); |
277 | struct sockaddr_in6 *sin6; | 287 | struct sockaddr_in6 *sin6; |
278 | struct sockaddr_in *sin; | 288 | struct sockaddr_in *sin; |
289 | struct sockaddr_un *sun; | ||
279 | char buf[128]; | 290 | char buf[128]; |
280 | 291 | ||
281 | (void)rpc_ntop(sap, buf, sizeof(buf)); | ||
282 | xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL); | ||
283 | |||
284 | switch (sap->sa_family) { | 292 | switch (sap->sa_family) { |
293 | case AF_LOCAL: | ||
294 | sun = xs_addr_un(xprt); | ||
295 | strlcpy(buf, sun->sun_path, sizeof(buf)); | ||
296 | xprt->address_strings[RPC_DISPLAY_ADDR] = | ||
297 | kstrdup(buf, GFP_KERNEL); | ||
298 | break; | ||
285 | case AF_INET: | 299 | case AF_INET: |
300 | (void)rpc_ntop(sap, buf, sizeof(buf)); | ||
301 | xprt->address_strings[RPC_DISPLAY_ADDR] = | ||
302 | kstrdup(buf, GFP_KERNEL); | ||
286 | sin = xs_addr_in(xprt); | 303 | sin = xs_addr_in(xprt); |
287 | snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); | 304 | snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); |
288 | break; | 305 | break; |
289 | case AF_INET6: | 306 | case AF_INET6: |
307 | (void)rpc_ntop(sap, buf, sizeof(buf)); | ||
308 | xprt->address_strings[RPC_DISPLAY_ADDR] = | ||
309 | kstrdup(buf, GFP_KERNEL); | ||
290 | sin6 = xs_addr_in6(xprt); | 310 | sin6 = xs_addr_in6(xprt); |
291 | snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); | 311 | snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); |
292 | break; | 312 | break; |
293 | default: | 313 | default: |
294 | BUG(); | 314 | BUG(); |
295 | } | 315 | } |
316 | |||
296 | xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); | 317 | xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); |
297 | } | 318 | } |
298 | 319 | ||
@@ -495,6 +516,70 @@ static int xs_nospace(struct rpc_task *task) | |||
495 | return ret; | 516 | return ret; |
496 | } | 517 | } |
497 | 518 | ||
519 | /* | ||
520 | * Construct a stream transport record marker in @buf. | ||
521 | */ | ||
522 | static inline void xs_encode_stream_record_marker(struct xdr_buf *buf) | ||
523 | { | ||
524 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | ||
525 | rpc_fraghdr *base = buf->head[0].iov_base; | ||
526 | *base = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | reclen); | ||
527 | } | ||
528 | |||
529 | /** | ||
530 | * xs_local_send_request - write an RPC request to an AF_LOCAL socket | ||
531 | * @task: RPC task that manages the state of an RPC request | ||
532 | * | ||
533 | * Return values: | ||
534 | * 0: The request has been sent | ||
535 | * EAGAIN: The socket was blocked, please call again later to | ||
536 | * complete the request | ||
537 | * ENOTCONN: Caller needs to invoke connect logic then call again | ||
538 | * other: Some other error occured, the request was not sent | ||
539 | */ | ||
540 | static int xs_local_send_request(struct rpc_task *task) | ||
541 | { | ||
542 | struct rpc_rqst *req = task->tk_rqstp; | ||
543 | struct rpc_xprt *xprt = req->rq_xprt; | ||
544 | struct sock_xprt *transport = | ||
545 | container_of(xprt, struct sock_xprt, xprt); | ||
546 | struct xdr_buf *xdr = &req->rq_snd_buf; | ||
547 | int status; | ||
548 | |||
549 | xs_encode_stream_record_marker(&req->rq_snd_buf); | ||
550 | |||
551 | xs_pktdump("packet data:", | ||
552 | req->rq_svec->iov_base, req->rq_svec->iov_len); | ||
553 | |||
554 | status = xs_sendpages(transport->sock, NULL, 0, | ||
555 | xdr, req->rq_bytes_sent); | ||
556 | dprintk("RPC: %s(%u) = %d\n", | ||
557 | __func__, xdr->len - req->rq_bytes_sent, status); | ||
558 | if (likely(status >= 0)) { | ||
559 | req->rq_bytes_sent += status; | ||
560 | req->rq_xmit_bytes_sent += status; | ||
561 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { | ||
562 | req->rq_bytes_sent = 0; | ||
563 | return 0; | ||
564 | } | ||
565 | status = -EAGAIN; | ||
566 | } | ||
567 | |||
568 | switch (status) { | ||
569 | case -EAGAIN: | ||
570 | status = xs_nospace(task); | ||
571 | break; | ||
572 | default: | ||
573 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | ||
574 | -status); | ||
575 | case -EPIPE: | ||
576 | xs_close(xprt); | ||
577 | status = -ENOTCONN; | ||
578 | } | ||
579 | |||
580 | return status; | ||
581 | } | ||
582 | |||
498 | /** | 583 | /** |
499 | * xs_udp_send_request - write an RPC request to a UDP socket | 584 | * xs_udp_send_request - write an RPC request to a UDP socket |
500 | * @task: address of RPC task that manages the state of an RPC request | 585 | * @task: address of RPC task that manages the state of an RPC request |
@@ -574,13 +659,6 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt) | |||
574 | kernel_sock_shutdown(sock, SHUT_WR); | 659 | kernel_sock_shutdown(sock, SHUT_WR); |
575 | } | 660 | } |
576 | 661 | ||
577 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) | ||
578 | { | ||
579 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | ||
580 | rpc_fraghdr *base = buf->head[0].iov_base; | ||
581 | *base = htonl(RPC_LAST_STREAM_FRAGMENT | reclen); | ||
582 | } | ||
583 | |||
584 | /** | 662 | /** |
585 | * xs_tcp_send_request - write an RPC request to a TCP socket | 663 | * xs_tcp_send_request - write an RPC request to a TCP socket |
586 | * @task: address of RPC task that manages the state of an RPC request | 664 | * @task: address of RPC task that manages the state of an RPC request |
@@ -603,7 +681,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
603 | struct xdr_buf *xdr = &req->rq_snd_buf; | 681 | struct xdr_buf *xdr = &req->rq_snd_buf; |
604 | int status; | 682 | int status; |
605 | 683 | ||
606 | xs_encode_tcp_record_marker(&req->rq_snd_buf); | 684 | xs_encode_stream_record_marker(&req->rq_snd_buf); |
607 | 685 | ||
608 | xs_pktdump("packet data:", | 686 | xs_pktdump("packet data:", |
609 | req->rq_svec->iov_base, | 687 | req->rq_svec->iov_base, |
@@ -785,6 +863,88 @@ static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) | |||
785 | return (struct rpc_xprt *) sk->sk_user_data; | 863 | return (struct rpc_xprt *) sk->sk_user_data; |
786 | } | 864 | } |
787 | 865 | ||
866 | static int xs_local_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) | ||
867 | { | ||
868 | struct xdr_skb_reader desc = { | ||
869 | .skb = skb, | ||
870 | .offset = sizeof(rpc_fraghdr), | ||
871 | .count = skb->len - sizeof(rpc_fraghdr), | ||
872 | }; | ||
873 | |||
874 | if (xdr_partial_copy_from_skb(xdr, 0, &desc, xdr_skb_read_bits) < 0) | ||
875 | return -1; | ||
876 | if (desc.count) | ||
877 | return -1; | ||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | /** | ||
882 | * xs_local_data_ready - "data ready" callback for AF_LOCAL sockets | ||
883 | * @sk: socket with data to read | ||
884 | * @len: how much data to read | ||
885 | * | ||
886 | * Currently this assumes we can read the whole reply in a single gulp. | ||
887 | */ | ||
888 | static void xs_local_data_ready(struct sock *sk, int len) | ||
889 | { | ||
890 | struct rpc_task *task; | ||
891 | struct rpc_xprt *xprt; | ||
892 | struct rpc_rqst *rovr; | ||
893 | struct sk_buff *skb; | ||
894 | int err, repsize, copied; | ||
895 | u32 _xid; | ||
896 | __be32 *xp; | ||
897 | |||
898 | read_lock_bh(&sk->sk_callback_lock); | ||
899 | dprintk("RPC: %s...\n", __func__); | ||
900 | xprt = xprt_from_sock(sk); | ||
901 | if (xprt == NULL) | ||
902 | goto out; | ||
903 | |||
904 | skb = skb_recv_datagram(sk, 0, 1, &err); | ||
905 | if (skb == NULL) | ||
906 | goto out; | ||
907 | |||
908 | if (xprt->shutdown) | ||
909 | goto dropit; | ||
910 | |||
911 | repsize = skb->len - sizeof(rpc_fraghdr); | ||
912 | if (repsize < 4) { | ||
913 | dprintk("RPC: impossible RPC reply size %d\n", repsize); | ||
914 | goto dropit; | ||
915 | } | ||
916 | |||
917 | /* Copy the XID from the skb... */ | ||
918 | xp = skb_header_pointer(skb, sizeof(rpc_fraghdr), sizeof(_xid), &_xid); | ||
919 | if (xp == NULL) | ||
920 | goto dropit; | ||
921 | |||
922 | /* Look up and lock the request corresponding to the given XID */ | ||
923 | spin_lock(&xprt->transport_lock); | ||
924 | rovr = xprt_lookup_rqst(xprt, *xp); | ||
925 | if (!rovr) | ||
926 | goto out_unlock; | ||
927 | task = rovr->rq_task; | ||
928 | |||
929 | copied = rovr->rq_private_buf.buflen; | ||
930 | if (copied > repsize) | ||
931 | copied = repsize; | ||
932 | |||
933 | if (xs_local_copy_to_xdr(&rovr->rq_private_buf, skb)) { | ||
934 | dprintk("RPC: sk_buff copy failed\n"); | ||
935 | goto out_unlock; | ||
936 | } | ||
937 | |||
938 | xprt_complete_rqst(task, copied); | ||
939 | |||
940 | out_unlock: | ||
941 | spin_unlock(&xprt->transport_lock); | ||
942 | dropit: | ||
943 | skb_free_datagram(sk, skb); | ||
944 | out: | ||
945 | read_unlock_bh(&sk->sk_callback_lock); | ||
946 | } | ||
947 | |||
788 | /** | 948 | /** |
789 | * xs_udp_data_ready - "data ready" callback for UDP sockets | 949 | * xs_udp_data_ready - "data ready" callback for UDP sockets |
790 | * @sk: socket with data to read | 950 | * @sk: socket with data to read |
@@ -1344,7 +1504,6 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1344 | case TCP_CLOSE_WAIT: | 1504 | case TCP_CLOSE_WAIT: |
1345 | /* The server initiated a shutdown of the socket */ | 1505 | /* The server initiated a shutdown of the socket */ |
1346 | xprt_force_disconnect(xprt); | 1506 | xprt_force_disconnect(xprt); |
1347 | case TCP_SYN_SENT: | ||
1348 | xprt->connect_cookie++; | 1507 | xprt->connect_cookie++; |
1349 | case TCP_CLOSING: | 1508 | case TCP_CLOSING: |
1350 | /* | 1509 | /* |
@@ -1571,11 +1730,31 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) | |||
1571 | return err; | 1730 | return err; |
1572 | } | 1731 | } |
1573 | 1732 | ||
1733 | /* | ||
1734 | * We don't support autobind on AF_LOCAL sockets | ||
1735 | */ | ||
1736 | static void xs_local_rpcbind(struct rpc_task *task) | ||
1737 | { | ||
1738 | xprt_set_bound(task->tk_xprt); | ||
1739 | } | ||
1740 | |||
1741 | static void xs_local_set_port(struct rpc_xprt *xprt, unsigned short port) | ||
1742 | { | ||
1743 | } | ||
1574 | 1744 | ||
1575 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 1745 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
1576 | static struct lock_class_key xs_key[2]; | 1746 | static struct lock_class_key xs_key[2]; |
1577 | static struct lock_class_key xs_slock_key[2]; | 1747 | static struct lock_class_key xs_slock_key[2]; |
1578 | 1748 | ||
1749 | static inline void xs_reclassify_socketu(struct socket *sock) | ||
1750 | { | ||
1751 | struct sock *sk = sock->sk; | ||
1752 | |||
1753 | BUG_ON(sock_owned_by_user(sk)); | ||
1754 | sock_lock_init_class_and_name(sk, "slock-AF_LOCAL-RPC", | ||
1755 | &xs_slock_key[1], "sk_lock-AF_LOCAL-RPC", &xs_key[1]); | ||
1756 | } | ||
1757 | |||
1579 | static inline void xs_reclassify_socket4(struct socket *sock) | 1758 | static inline void xs_reclassify_socket4(struct socket *sock) |
1580 | { | 1759 | { |
1581 | struct sock *sk = sock->sk; | 1760 | struct sock *sk = sock->sk; |
@@ -1597,6 +1776,9 @@ static inline void xs_reclassify_socket6(struct socket *sock) | |||
1597 | static inline void xs_reclassify_socket(int family, struct socket *sock) | 1776 | static inline void xs_reclassify_socket(int family, struct socket *sock) |
1598 | { | 1777 | { |
1599 | switch (family) { | 1778 | switch (family) { |
1779 | case AF_LOCAL: | ||
1780 | xs_reclassify_socketu(sock); | ||
1781 | break; | ||
1600 | case AF_INET: | 1782 | case AF_INET: |
1601 | xs_reclassify_socket4(sock); | 1783 | xs_reclassify_socket4(sock); |
1602 | break; | 1784 | break; |
@@ -1606,6 +1788,10 @@ static inline void xs_reclassify_socket(int family, struct socket *sock) | |||
1606 | } | 1788 | } |
1607 | } | 1789 | } |
1608 | #else | 1790 | #else |
1791 | static inline void xs_reclassify_socketu(struct socket *sock) | ||
1792 | { | ||
1793 | } | ||
1794 | |||
1609 | static inline void xs_reclassify_socket4(struct socket *sock) | 1795 | static inline void xs_reclassify_socket4(struct socket *sock) |
1610 | { | 1796 | { |
1611 | } | 1797 | } |
@@ -1644,6 +1830,94 @@ out: | |||
1644 | return ERR_PTR(err); | 1830 | return ERR_PTR(err); |
1645 | } | 1831 | } |
1646 | 1832 | ||
1833 | static int xs_local_finish_connecting(struct rpc_xprt *xprt, | ||
1834 | struct socket *sock) | ||
1835 | { | ||
1836 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, | ||
1837 | xprt); | ||
1838 | |||
1839 | if (!transport->inet) { | ||
1840 | struct sock *sk = sock->sk; | ||
1841 | |||
1842 | write_lock_bh(&sk->sk_callback_lock); | ||
1843 | |||
1844 | xs_save_old_callbacks(transport, sk); | ||
1845 | |||
1846 | sk->sk_user_data = xprt; | ||
1847 | sk->sk_data_ready = xs_local_data_ready; | ||
1848 | sk->sk_write_space = xs_udp_write_space; | ||
1849 | sk->sk_error_report = xs_error_report; | ||
1850 | sk->sk_allocation = GFP_ATOMIC; | ||
1851 | |||
1852 | xprt_clear_connected(xprt); | ||
1853 | |||
1854 | /* Reset to new socket */ | ||
1855 | transport->sock = sock; | ||
1856 | transport->inet = sk; | ||
1857 | |||
1858 | write_unlock_bh(&sk->sk_callback_lock); | ||
1859 | } | ||
1860 | |||
1861 | /* Tell the socket layer to start connecting... */ | ||
1862 | xprt->stat.connect_count++; | ||
1863 | xprt->stat.connect_start = jiffies; | ||
1864 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, 0); | ||
1865 | } | ||
1866 | |||
1867 | /** | ||
1868 | * xs_local_setup_socket - create AF_LOCAL socket, connect to a local endpoint | ||
1869 | * @xprt: RPC transport to connect | ||
1870 | * @transport: socket transport to connect | ||
1871 | * @create_sock: function to create a socket of the correct type | ||
1872 | * | ||
1873 | * Invoked by a work queue tasklet. | ||
1874 | */ | ||
1875 | static void xs_local_setup_socket(struct work_struct *work) | ||
1876 | { | ||
1877 | struct sock_xprt *transport = | ||
1878 | container_of(work, struct sock_xprt, connect_worker.work); | ||
1879 | struct rpc_xprt *xprt = &transport->xprt; | ||
1880 | struct socket *sock; | ||
1881 | int status = -EIO; | ||
1882 | |||
1883 | if (xprt->shutdown) | ||
1884 | goto out; | ||
1885 | |||
1886 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | ||
1887 | status = __sock_create(xprt->xprt_net, AF_LOCAL, | ||
1888 | SOCK_STREAM, 0, &sock, 1); | ||
1889 | if (status < 0) { | ||
1890 | dprintk("RPC: can't create AF_LOCAL " | ||
1891 | "transport socket (%d).\n", -status); | ||
1892 | goto out; | ||
1893 | } | ||
1894 | xs_reclassify_socketu(sock); | ||
1895 | |||
1896 | dprintk("RPC: worker connecting xprt %p via AF_LOCAL to %s\n", | ||
1897 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1898 | |||
1899 | status = xs_local_finish_connecting(xprt, sock); | ||
1900 | switch (status) { | ||
1901 | case 0: | ||
1902 | dprintk("RPC: xprt %p connected to %s\n", | ||
1903 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1904 | xprt_set_connected(xprt); | ||
1905 | break; | ||
1906 | case -ENOENT: | ||
1907 | dprintk("RPC: xprt %p: socket %s does not exist\n", | ||
1908 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1909 | break; | ||
1910 | default: | ||
1911 | printk(KERN_ERR "%s: unhandled error (%d) connecting to %s\n", | ||
1912 | __func__, -status, | ||
1913 | xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1914 | } | ||
1915 | |||
1916 | out: | ||
1917 | xprt_clear_connecting(xprt); | ||
1918 | xprt_wake_pending_tasks(xprt, status); | ||
1919 | } | ||
1920 | |||
1647 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1921 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1648 | { | 1922 | { |
1649 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1923 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -1758,6 +2032,7 @@ static void xs_tcp_reuse_connection(struct sock_xprt *transport) | |||
1758 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 2032 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1759 | { | 2033 | { |
1760 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 2034 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
2035 | int ret = -ENOTCONN; | ||
1761 | 2036 | ||
1762 | if (!transport->inet) { | 2037 | if (!transport->inet) { |
1763 | struct sock *sk = sock->sk; | 2038 | struct sock *sk = sock->sk; |
@@ -1789,12 +2064,22 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1789 | } | 2064 | } |
1790 | 2065 | ||
1791 | if (!xprt_bound(xprt)) | 2066 | if (!xprt_bound(xprt)) |
1792 | return -ENOTCONN; | 2067 | goto out; |
1793 | 2068 | ||
1794 | /* Tell the socket layer to start connecting... */ | 2069 | /* Tell the socket layer to start connecting... */ |
1795 | xprt->stat.connect_count++; | 2070 | xprt->stat.connect_count++; |
1796 | xprt->stat.connect_start = jiffies; | 2071 | xprt->stat.connect_start = jiffies; |
1797 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); | 2072 | ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
2073 | switch (ret) { | ||
2074 | case 0: | ||
2075 | case -EINPROGRESS: | ||
2076 | /* SYN_SENT! */ | ||
2077 | xprt->connect_cookie++; | ||
2078 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | ||
2079 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
2080 | } | ||
2081 | out: | ||
2082 | return ret; | ||
1798 | } | 2083 | } |
1799 | 2084 | ||
1800 | /** | 2085 | /** |
@@ -1917,6 +2202,32 @@ static void xs_connect(struct rpc_task *task) | |||
1917 | } | 2202 | } |
1918 | 2203 | ||
1919 | /** | 2204 | /** |
2205 | * xs_local_print_stats - display AF_LOCAL socket-specifc stats | ||
2206 | * @xprt: rpc_xprt struct containing statistics | ||
2207 | * @seq: output file | ||
2208 | * | ||
2209 | */ | ||
2210 | static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | ||
2211 | { | ||
2212 | long idle_time = 0; | ||
2213 | |||
2214 | if (xprt_connected(xprt)) | ||
2215 | idle_time = (long)(jiffies - xprt->last_used) / HZ; | ||
2216 | |||
2217 | seq_printf(seq, "\txprt:\tlocal %lu %lu %lu %ld %lu %lu %lu " | ||
2218 | "%llu %llu\n", | ||
2219 | xprt->stat.bind_count, | ||
2220 | xprt->stat.connect_count, | ||
2221 | xprt->stat.connect_time, | ||
2222 | idle_time, | ||
2223 | xprt->stat.sends, | ||
2224 | xprt->stat.recvs, | ||
2225 | xprt->stat.bad_xids, | ||
2226 | xprt->stat.req_u, | ||
2227 | xprt->stat.bklog_u); | ||
2228 | } | ||
2229 | |||
2230 | /** | ||
1920 | * xs_udp_print_stats - display UDP socket-specifc stats | 2231 | * xs_udp_print_stats - display UDP socket-specifc stats |
1921 | * @xprt: rpc_xprt struct containing statistics | 2232 | * @xprt: rpc_xprt struct containing statistics |
1922 | * @seq: output file | 2233 | * @seq: output file |
@@ -2014,10 +2325,7 @@ static int bc_sendto(struct rpc_rqst *req) | |||
2014 | unsigned long headoff; | 2325 | unsigned long headoff; |
2015 | unsigned long tailoff; | 2326 | unsigned long tailoff; |
2016 | 2327 | ||
2017 | /* | 2328 | xs_encode_stream_record_marker(xbufp); |
2018 | * Set up the rpc header and record marker stuff | ||
2019 | */ | ||
2020 | xs_encode_tcp_record_marker(xbufp); | ||
2021 | 2329 | ||
2022 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; | 2330 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; |
2023 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; | 2331 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; |
@@ -2089,6 +2397,21 @@ static void bc_destroy(struct rpc_xprt *xprt) | |||
2089 | { | 2397 | { |
2090 | } | 2398 | } |
2091 | 2399 | ||
2400 | static struct rpc_xprt_ops xs_local_ops = { | ||
2401 | .reserve_xprt = xprt_reserve_xprt, | ||
2402 | .release_xprt = xs_tcp_release_xprt, | ||
2403 | .rpcbind = xs_local_rpcbind, | ||
2404 | .set_port = xs_local_set_port, | ||
2405 | .connect = xs_connect, | ||
2406 | .buf_alloc = rpc_malloc, | ||
2407 | .buf_free = rpc_free, | ||
2408 | .send_request = xs_local_send_request, | ||
2409 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | ||
2410 | .close = xs_close, | ||
2411 | .destroy = xs_destroy, | ||
2412 | .print_stats = xs_local_print_stats, | ||
2413 | }; | ||
2414 | |||
2092 | static struct rpc_xprt_ops xs_udp_ops = { | 2415 | static struct rpc_xprt_ops xs_udp_ops = { |
2093 | .set_buffer_size = xs_udp_set_buffer_size, | 2416 | .set_buffer_size = xs_udp_set_buffer_size, |
2094 | .reserve_xprt = xprt_reserve_xprt_cong, | 2417 | .reserve_xprt = xprt_reserve_xprt_cong, |
@@ -2150,6 +2473,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap) | |||
2150 | }; | 2473 | }; |
2151 | 2474 | ||
2152 | switch (family) { | 2475 | switch (family) { |
2476 | case AF_LOCAL: | ||
2477 | break; | ||
2153 | case AF_INET: | 2478 | case AF_INET: |
2154 | memcpy(sap, &sin, sizeof(sin)); | 2479 | memcpy(sap, &sin, sizeof(sin)); |
2155 | break; | 2480 | break; |
@@ -2197,6 +2522,70 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
2197 | return xprt; | 2522 | return xprt; |
2198 | } | 2523 | } |
2199 | 2524 | ||
2525 | static const struct rpc_timeout xs_local_default_timeout = { | ||
2526 | .to_initval = 10 * HZ, | ||
2527 | .to_maxval = 10 * HZ, | ||
2528 | .to_retries = 2, | ||
2529 | }; | ||
2530 | |||
2531 | /** | ||
2532 | * xs_setup_local - Set up transport to use an AF_LOCAL socket | ||
2533 | * @args: rpc transport creation arguments | ||
2534 | * | ||
2535 | * AF_LOCAL is a "tpi_cots_ord" transport, just like TCP | ||
2536 | */ | ||
2537 | static struct rpc_xprt *xs_setup_local(struct xprt_create *args) | ||
2538 | { | ||
2539 | struct sockaddr_un *sun = (struct sockaddr_un *)args->dstaddr; | ||
2540 | struct sock_xprt *transport; | ||
2541 | struct rpc_xprt *xprt; | ||
2542 | struct rpc_xprt *ret; | ||
2543 | |||
2544 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | ||
2545 | if (IS_ERR(xprt)) | ||
2546 | return xprt; | ||
2547 | transport = container_of(xprt, struct sock_xprt, xprt); | ||
2548 | |||
2549 | xprt->prot = 0; | ||
2550 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | ||
2551 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | ||
2552 | |||
2553 | xprt->bind_timeout = XS_BIND_TO; | ||
2554 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
2555 | xprt->idle_timeout = XS_IDLE_DISC_TO; | ||
2556 | |||
2557 | xprt->ops = &xs_local_ops; | ||
2558 | xprt->timeout = &xs_local_default_timeout; | ||
2559 | |||
2560 | switch (sun->sun_family) { | ||
2561 | case AF_LOCAL: | ||
2562 | if (sun->sun_path[0] != '/') { | ||
2563 | dprintk("RPC: bad AF_LOCAL address: %s\n", | ||
2564 | sun->sun_path); | ||
2565 | ret = ERR_PTR(-EINVAL); | ||
2566 | goto out_err; | ||
2567 | } | ||
2568 | xprt_set_bound(xprt); | ||
2569 | INIT_DELAYED_WORK(&transport->connect_worker, | ||
2570 | xs_local_setup_socket); | ||
2571 | xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); | ||
2572 | break; | ||
2573 | default: | ||
2574 | ret = ERR_PTR(-EAFNOSUPPORT); | ||
2575 | goto out_err; | ||
2576 | } | ||
2577 | |||
2578 | dprintk("RPC: set up xprt to %s via AF_LOCAL\n", | ||
2579 | xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
2580 | |||
2581 | if (try_module_get(THIS_MODULE)) | ||
2582 | return xprt; | ||
2583 | ret = ERR_PTR(-EINVAL); | ||
2584 | out_err: | ||
2585 | xprt_free(xprt); | ||
2586 | return ret; | ||
2587 | } | ||
2588 | |||
2200 | static const struct rpc_timeout xs_udp_default_timeout = { | 2589 | static const struct rpc_timeout xs_udp_default_timeout = { |
2201 | .to_initval = 5 * HZ, | 2590 | .to_initval = 5 * HZ, |
2202 | .to_maxval = 30 * HZ, | 2591 | .to_maxval = 30 * HZ, |
@@ -2438,6 +2827,14 @@ out_err: | |||
2438 | return ret; | 2827 | return ret; |
2439 | } | 2828 | } |
2440 | 2829 | ||
2830 | static struct xprt_class xs_local_transport = { | ||
2831 | .list = LIST_HEAD_INIT(xs_local_transport.list), | ||
2832 | .name = "named UNIX socket", | ||
2833 | .owner = THIS_MODULE, | ||
2834 | .ident = XPRT_TRANSPORT_LOCAL, | ||
2835 | .setup = xs_setup_local, | ||
2836 | }; | ||
2837 | |||
2441 | static struct xprt_class xs_udp_transport = { | 2838 | static struct xprt_class xs_udp_transport = { |
2442 | .list = LIST_HEAD_INIT(xs_udp_transport.list), | 2839 | .list = LIST_HEAD_INIT(xs_udp_transport.list), |
2443 | .name = "udp", | 2840 | .name = "udp", |
@@ -2473,6 +2870,7 @@ int init_socket_xprt(void) | |||
2473 | sunrpc_table_header = register_sysctl_table(sunrpc_table); | 2870 | sunrpc_table_header = register_sysctl_table(sunrpc_table); |
2474 | #endif | 2871 | #endif |
2475 | 2872 | ||
2873 | xprt_register_transport(&xs_local_transport); | ||
2476 | xprt_register_transport(&xs_udp_transport); | 2874 | xprt_register_transport(&xs_udp_transport); |
2477 | xprt_register_transport(&xs_tcp_transport); | 2875 | xprt_register_transport(&xs_tcp_transport); |
2478 | xprt_register_transport(&xs_bc_tcp_transport); | 2876 | xprt_register_transport(&xs_bc_tcp_transport); |
@@ -2493,6 +2891,7 @@ void cleanup_socket_xprt(void) | |||
2493 | } | 2891 | } |
2494 | #endif | 2892 | #endif |
2495 | 2893 | ||
2894 | xprt_unregister_transport(&xs_local_transport); | ||
2496 | xprt_unregister_transport(&xs_udp_transport); | 2895 | xprt_unregister_transport(&xs_udp_transport); |
2497 | xprt_unregister_transport(&xs_tcp_transport); | 2896 | xprt_unregister_transport(&xs_tcp_transport); |
2498 | xprt_unregister_transport(&xs_bc_tcp_transport); | 2897 | xprt_unregister_transport(&xs_bc_tcp_transport); |
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 4be60364a405..f40a6af6bf40 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
@@ -43,6 +43,7 @@ | |||
43 | #undef ELF_R_INFO | 43 | #undef ELF_R_INFO |
44 | #undef Elf_r_info | 44 | #undef Elf_r_info |
45 | #undef ELF_ST_BIND | 45 | #undef ELF_ST_BIND |
46 | #undef ELF_ST_TYPE | ||
46 | #undef fn_ELF_R_SYM | 47 | #undef fn_ELF_R_SYM |
47 | #undef fn_ELF_R_INFO | 48 | #undef fn_ELF_R_INFO |
48 | #undef uint_t | 49 | #undef uint_t |
@@ -76,6 +77,7 @@ | |||
76 | # define ELF_R_INFO ELF64_R_INFO | 77 | # define ELF_R_INFO ELF64_R_INFO |
77 | # define Elf_r_info Elf64_r_info | 78 | # define Elf_r_info Elf64_r_info |
78 | # define ELF_ST_BIND ELF64_ST_BIND | 79 | # define ELF_ST_BIND ELF64_ST_BIND |
80 | # define ELF_ST_TYPE ELF64_ST_TYPE | ||
79 | # define fn_ELF_R_SYM fn_ELF64_R_SYM | 81 | # define fn_ELF_R_SYM fn_ELF64_R_SYM |
80 | # define fn_ELF_R_INFO fn_ELF64_R_INFO | 82 | # define fn_ELF_R_INFO fn_ELF64_R_INFO |
81 | # define uint_t uint64_t | 83 | # define uint_t uint64_t |
@@ -108,6 +110,7 @@ | |||
108 | # define ELF_R_INFO ELF32_R_INFO | 110 | # define ELF_R_INFO ELF32_R_INFO |
109 | # define Elf_r_info Elf32_r_info | 111 | # define Elf_r_info Elf32_r_info |
110 | # define ELF_ST_BIND ELF32_ST_BIND | 112 | # define ELF_ST_BIND ELF32_ST_BIND |
113 | # define ELF_ST_TYPE ELF32_ST_TYPE | ||
111 | # define fn_ELF_R_SYM fn_ELF32_R_SYM | 114 | # define fn_ELF_R_SYM fn_ELF32_R_SYM |
112 | # define fn_ELF_R_INFO fn_ELF32_R_INFO | 115 | # define fn_ELF_R_INFO fn_ELF32_R_INFO |
113 | # define uint_t uint32_t | 116 | # define uint_t uint32_t |
@@ -427,6 +430,11 @@ static unsigned find_secsym_ndx(unsigned const txtndx, | |||
427 | if (txtndx == w2(symp->st_shndx) | 430 | if (txtndx == w2(symp->st_shndx) |
428 | /* avoid STB_WEAK */ | 431 | /* avoid STB_WEAK */ |
429 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { | 432 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { |
433 | /* function symbols on ARM have quirks, avoid them */ | ||
434 | if (w2(ehdr->e_machine) == EM_ARM | ||
435 | && ELF_ST_TYPE(symp->st_info) == STT_FUNC) | ||
436 | continue; | ||
437 | |||
430 | *recvalp = _w(symp->st_value); | 438 | *recvalp = _w(symp->st_value); |
431 | return symp - sym0; | 439 | return symp - sym0; |
432 | } | 440 | } |
diff --git a/scripts/tags.sh b/scripts/tags.sh index bd6185d529cf..75c5d24f1993 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
@@ -132,7 +132,7 @@ exuberant() | |||
132 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ | 132 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ |
133 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ | 133 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ |
134 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ | 134 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ |
135 | --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' | 135 | --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' |
136 | 136 | ||
137 | all_kconfigs | xargs $1 -a \ | 137 | all_kconfigs | xargs $1 -a \ |
138 | --langdef=kconfig --language-force=kconfig \ | 138 | --langdef=kconfig --language-force=kconfig \ |
@@ -152,7 +152,9 @@ emacs() | |||
152 | { | 152 | { |
153 | all_sources | xargs $1 -a \ | 153 | all_sources | xargs $1 -a \ |
154 | --regex='/^ENTRY(\([^)]*\)).*/\1/' \ | 154 | --regex='/^ENTRY(\([^)]*\)).*/\1/' \ |
155 | --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' | 155 | --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ |
156 | --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ | ||
157 | --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' | ||
156 | 158 | ||
157 | all_kconfigs | xargs $1 -a \ | 159 | all_kconfigs | xargs $1 -a \ |
158 | --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' | 160 | --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index ae3a698415e6..ec1bcecf2cda 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -593,7 +593,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, | |||
593 | sa.aad.op = OP_SETPROCATTR; | 593 | sa.aad.op = OP_SETPROCATTR; |
594 | sa.aad.info = name; | 594 | sa.aad.info = name; |
595 | sa.aad.error = -EINVAL; | 595 | sa.aad.error = -EINVAL; |
596 | return aa_audit(AUDIT_APPARMOR_DENIED, NULL, GFP_KERNEL, | 596 | return aa_audit(AUDIT_APPARMOR_DENIED, |
597 | __aa_current_profile(), GFP_KERNEL, | ||
597 | &sa, NULL); | 598 | &sa, NULL); |
598 | } | 599 | } |
599 | } else if (strcmp(name, "exec") == 0) { | 600 | } else if (strcmp(name, "exec") == 0) { |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 348705666f99..486f6deb3eee 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1085,7 +1085,7 @@ static void azx_init_pci(struct azx *chip) | |||
1085 | * codecs. | 1085 | * codecs. |
1086 | * The PCI register TCSEL is defined in the Intel manuals. | 1086 | * The PCI register TCSEL is defined in the Intel manuals. |
1087 | */ | 1087 | */ |
1088 | if (chip->driver_caps & AZX_DCAPS_NO_TCSEL) { | 1088 | if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) { |
1089 | snd_printdd(SFX "Clearing TCSEL\n"); | 1089 | snd_printdd(SFX "Clearing TCSEL\n"); |
1090 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); | 1090 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); |
1091 | } | 1091 | } |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 459566bfcd35..d155cbb58e1c 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_SOC_SAMSUNG | 1 | config SND_SOC_SAMSUNG |
2 | tristate "ASoC support for Samsung" | 2 | tristate "ASoC support for Samsung" |
3 | depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_EXYNOS4 | 3 | depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 |
4 | select S3C64XX_DMA if ARCH_S3C64XX | 4 | select S3C64XX_DMA if ARCH_S3C64XX |
5 | select S3C2410_DMA if ARCH_S3C2410 | 5 | select S3C2410_DMA if ARCH_S3C2410 |
6 | help | 6 | help |
@@ -55,7 +55,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
55 | 55 | ||
56 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 56 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
57 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 57 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
58 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210 || MACH_SMDKC110) | 58 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) |
59 | select SND_SOC_WM8580 | 59 | select SND_SOC_WM8580 |
60 | select SND_SAMSUNG_I2S | 60 | select SND_SAMSUNG_I2S |
61 | help | 61 | help |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 8aacf23d6f3a..3d26f6607aa4 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
@@ -249,7 +249,7 @@ static int __init smdk_audio_init(void) | |||
249 | int ret; | 249 | int ret; |
250 | char *str; | 250 | char *str; |
251 | 251 | ||
252 | if (machine_is_smdkc100() || machine_is_smdk6442() | 252 | if (machine_is_smdkc100() |
253 | || machine_is_smdkv210() || machine_is_smdkc110()) { | 253 | || machine_is_smdkv210() || machine_is_smdkc110()) { |
254 | smdk.num_links = 3; | 254 | smdk.num_links = 3; |
255 | /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ | 255 | /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1455413ec7a7..032ba6398a5c 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -215,11 +215,13 @@ LIB_FILE=$(OUTPUT)libperf.a | |||
215 | LIB_H += ../../include/linux/perf_event.h | 215 | LIB_H += ../../include/linux/perf_event.h |
216 | LIB_H += ../../include/linux/rbtree.h | 216 | LIB_H += ../../include/linux/rbtree.h |
217 | LIB_H += ../../include/linux/list.h | 217 | LIB_H += ../../include/linux/list.h |
218 | LIB_H += ../../include/linux/const.h | ||
218 | LIB_H += ../../include/linux/hash.h | 219 | LIB_H += ../../include/linux/hash.h |
219 | LIB_H += ../../include/linux/stringify.h | 220 | LIB_H += ../../include/linux/stringify.h |
220 | LIB_H += util/include/linux/bitmap.h | 221 | LIB_H += util/include/linux/bitmap.h |
221 | LIB_H += util/include/linux/bitops.h | 222 | LIB_H += util/include/linux/bitops.h |
222 | LIB_H += util/include/linux/compiler.h | 223 | LIB_H += util/include/linux/compiler.h |
224 | LIB_H += util/include/linux/const.h | ||
223 | LIB_H += util/include/linux/ctype.h | 225 | LIB_H += util/include/linux/ctype.h |
224 | LIB_H += util/include/linux/kernel.h | 226 | LIB_H += util/include/linux/kernel.h |
225 | LIB_H += util/include/linux/list.h | 227 | LIB_H += util/include/linux/list.h |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e18eb7ed30ae..7b139e1e7e86 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -8,8 +8,6 @@ | |||
8 | #include "builtin.h" | 8 | #include "builtin.h" |
9 | 9 | ||
10 | #include "util/util.h" | 10 | #include "util/util.h" |
11 | |||
12 | #include "util/util.h" | ||
13 | #include "util/color.h" | 11 | #include "util/color.h" |
14 | #include <linux/list.h> | 12 | #include <linux/list.h> |
15 | #include "util/cache.h" | 13 | #include "util/cache.h" |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0974f957b8fa..8e2c85798185 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -823,6 +823,16 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
823 | 823 | ||
824 | symbol__init(); | 824 | symbol__init(); |
825 | 825 | ||
826 | if (symbol_conf.kptr_restrict) | ||
827 | pr_warning( | ||
828 | "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" | ||
829 | "check /proc/sys/kernel/kptr_restrict.\n\n" | ||
830 | "Samples in kernel functions may not be resolved if a suitable vmlinux\n" | ||
831 | "file is not found in the buildid cache or in the vmlinux path.\n\n" | ||
832 | "Samples in kernel modules won't be resolved at all.\n\n" | ||
833 | "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" | ||
834 | "even with a suitable vmlinux or kallsyms file.\n\n"); | ||
835 | |||
826 | if (no_buildid_cache || no_buildid) | 836 | if (no_buildid_cache || no_buildid) |
827 | disable_buildid_cache(); | 837 | disable_buildid_cache(); |
828 | 838 | ||
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 498c6f70a747..287a173523a7 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -116,6 +116,9 @@ static int process_sample_event(union perf_event *event, | |||
116 | if (al.filtered || (hide_unresolved && al.sym == NULL)) | 116 | if (al.filtered || (hide_unresolved && al.sym == NULL)) |
117 | return 0; | 117 | return 0; |
118 | 118 | ||
119 | if (al.map != NULL) | ||
120 | al.map->dso->hit = 1; | ||
121 | |||
119 | if (perf_session__add_hist_entry(session, &al, sample, evsel)) { | 122 | if (perf_session__add_hist_entry(session, &al, sample, evsel)) { |
120 | pr_debug("problem incrementing symbol period, skipping event\n"); | 123 | pr_debug("problem incrementing symbol period, skipping event\n"); |
121 | return -1; | 124 | return -1; |
@@ -249,6 +252,8 @@ static int __cmd_report(void) | |||
249 | u64 nr_samples; | 252 | u64 nr_samples; |
250 | struct perf_session *session; | 253 | struct perf_session *session; |
251 | struct perf_evsel *pos; | 254 | struct perf_evsel *pos; |
255 | struct map *kernel_map; | ||
256 | struct kmap *kernel_kmap; | ||
252 | const char *help = "For a higher level overview, try: perf report --sort comm,dso"; | 257 | const char *help = "For a higher level overview, try: perf report --sort comm,dso"; |
253 | 258 | ||
254 | signal(SIGINT, sig_handler); | 259 | signal(SIGINT, sig_handler); |
@@ -268,6 +273,24 @@ static int __cmd_report(void) | |||
268 | if (ret) | 273 | if (ret) |
269 | goto out_delete; | 274 | goto out_delete; |
270 | 275 | ||
276 | kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION]; | ||
277 | kernel_kmap = map__kmap(kernel_map); | ||
278 | if (kernel_map == NULL || | ||
279 | (kernel_map->dso->hit && | ||
280 | (kernel_kmap->ref_reloc_sym == NULL || | ||
281 | kernel_kmap->ref_reloc_sym->addr == 0))) { | ||
282 | const struct dso *kdso = kernel_map->dso; | ||
283 | |||
284 | ui__warning( | ||
285 | "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" | ||
286 | "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" | ||
287 | "Samples in kernel modules can't be resolved as well.\n\n", | ||
288 | RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? | ||
289 | "As no suitable kallsyms nor vmlinux was found, kernel samples\n" | ||
290 | "can't be resolved." : | ||
291 | "If some relocation was applied (e.g. kexec) symbols may be misresolved."); | ||
292 | } | ||
293 | |||
271 | if (dump_trace) { | 294 | if (dump_trace) { |
272 | perf_session__fprintf_nr_events(session, stdout); | 295 | perf_session__fprintf_nr_events(session, stdout); |
273 | goto out_delete; | 296 | goto out_delete; |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 974f6d3f4e53..22747de7234b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "util/symbol.h" | 10 | #include "util/symbol.h" |
11 | #include "util/thread.h" | 11 | #include "util/thread.h" |
12 | #include "util/trace-event.h" | 12 | #include "util/trace-event.h" |
13 | #include "util/parse-options.h" | ||
14 | #include "util/util.h" | 13 | #include "util/util.h" |
15 | #include "util/evlist.h" | 14 | #include "util/evlist.h" |
16 | #include "util/evsel.h" | 15 | #include "util/evsel.h" |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index b67186228c89..2da9162262b0 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -474,7 +474,7 @@ static int test__basic_mmap(void) | |||
474 | unsigned int nr_events[nsyscalls], | 474 | unsigned int nr_events[nsyscalls], |
475 | expected_nr_events[nsyscalls], i, j; | 475 | expected_nr_events[nsyscalls], i, j; |
476 | struct perf_evsel *evsels[nsyscalls], *evsel; | 476 | struct perf_evsel *evsels[nsyscalls], *evsel; |
477 | int sample_size = perf_sample_size(attr.sample_type); | 477 | int sample_size = __perf_evsel__sample_size(attr.sample_type); |
478 | 478 | ||
479 | for (i = 0; i < nsyscalls; ++i) { | 479 | for (i = 0; i < nsyscalls; ++i) { |
480 | char name[64]; | 480 | char name[64]; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 2d7934e9de38..f2f3f4937aa2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -62,8 +62,6 @@ | |||
62 | #include <linux/unistd.h> | 62 | #include <linux/unistd.h> |
63 | #include <linux/types.h> | 63 | #include <linux/types.h> |
64 | 64 | ||
65 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | ||
66 | |||
67 | static struct perf_top top = { | 65 | static struct perf_top top = { |
68 | .count_filter = 5, | 66 | .count_filter = 5, |
69 | .delay_secs = 2, | 67 | .delay_secs = 2, |
@@ -82,6 +80,8 @@ static bool use_tui, use_stdio; | |||
82 | 80 | ||
83 | static int default_interval = 0; | 81 | static int default_interval = 0; |
84 | 82 | ||
83 | static bool kptr_restrict_warned; | ||
84 | static bool vmlinux_warned; | ||
85 | static bool inherit = false; | 85 | static bool inherit = false; |
86 | static int realtime_prio = 0; | 86 | static int realtime_prio = 0; |
87 | static bool group = false; | 87 | static bool group = false; |
@@ -740,7 +740,22 @@ static void perf_event__process_sample(const union perf_event *event, | |||
740 | al.filtered) | 740 | al.filtered) |
741 | return; | 741 | return; |
742 | 742 | ||
743 | if (!kptr_restrict_warned && | ||
744 | symbol_conf.kptr_restrict && | ||
745 | al.cpumode == PERF_RECORD_MISC_KERNEL) { | ||
746 | ui__warning( | ||
747 | "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" | ||
748 | "Check /proc/sys/kernel/kptr_restrict.\n\n" | ||
749 | "Kernel%s samples will not be resolved.\n", | ||
750 | !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? | ||
751 | " modules" : ""); | ||
752 | if (use_browser <= 0) | ||
753 | sleep(5); | ||
754 | kptr_restrict_warned = true; | ||
755 | } | ||
756 | |||
743 | if (al.sym == NULL) { | 757 | if (al.sym == NULL) { |
758 | const char *msg = "Kernel samples will not be resolved.\n"; | ||
744 | /* | 759 | /* |
745 | * As we do lazy loading of symtabs we only will know if the | 760 | * As we do lazy loading of symtabs we only will know if the |
746 | * specified vmlinux file is invalid when we actually have a | 761 | * specified vmlinux file is invalid when we actually have a |
@@ -752,12 +767,20 @@ static void perf_event__process_sample(const union perf_event *event, | |||
752 | * --hide-kernel-symbols, even if the user specifies an | 767 | * --hide-kernel-symbols, even if the user specifies an |
753 | * invalid --vmlinux ;-) | 768 | * invalid --vmlinux ;-) |
754 | */ | 769 | */ |
755 | if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && | 770 | if (!kptr_restrict_warned && !vmlinux_warned && |
771 | al.map == machine->vmlinux_maps[MAP__FUNCTION] && | ||
756 | RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { | 772 | RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { |
757 | ui__warning("The %s file can't be used\n", | 773 | if (symbol_conf.vmlinux_name) { |
758 | symbol_conf.vmlinux_name); | 774 | ui__warning("The %s file can't be used.\n%s", |
759 | exit_browser(0); | 775 | symbol_conf.vmlinux_name, msg); |
760 | exit(1); | 776 | } else { |
777 | ui__warning("A vmlinux file was not found.\n%s", | ||
778 | msg); | ||
779 | } | ||
780 | |||
781 | if (use_browser <= 0) | ||
782 | sleep(5); | ||
783 | vmlinux_warned = true; | ||
761 | } | 784 | } |
762 | 785 | ||
763 | return; | 786 | return; |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6635fcd11ca5..3c1b8a632101 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -35,22 +35,6 @@ const char *perf_event__name(unsigned int id) | |||
35 | return perf_event__names[id]; | 35 | return perf_event__names[id]; |
36 | } | 36 | } |
37 | 37 | ||
38 | int perf_sample_size(u64 sample_type) | ||
39 | { | ||
40 | u64 mask = sample_type & PERF_SAMPLE_MASK; | ||
41 | int size = 0; | ||
42 | int i; | ||
43 | |||
44 | for (i = 0; i < 64; i++) { | ||
45 | if (mask & (1ULL << i)) | ||
46 | size++; | ||
47 | } | ||
48 | |||
49 | size *= sizeof(u64); | ||
50 | |||
51 | return size; | ||
52 | } | ||
53 | |||
54 | static struct perf_sample synth_sample = { | 38 | static struct perf_sample synth_sample = { |
55 | .pid = -1, | 39 | .pid = -1, |
56 | .tid = -1, | 40 | .tid = -1, |
@@ -553,9 +537,18 @@ static int perf_event__process_kernel_mmap(union perf_event *event, | |||
553 | goto out_problem; | 537 | goto out_problem; |
554 | 538 | ||
555 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); | 539 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); |
556 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | 540 | |
557 | symbol_name, | 541 | /* |
558 | event->mmap.pgoff); | 542 | * Avoid using a zero address (kptr_restrict) for the ref reloc |
543 | * symbol. Effectively having zero here means that at record | ||
544 | * time /proc/sys/kernel/kptr_restrict was non zero. | ||
545 | */ | ||
546 | if (event->mmap.pgoff != 0) { | ||
547 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | ||
548 | symbol_name, | ||
549 | event->mmap.pgoff); | ||
550 | } | ||
551 | |||
559 | if (machine__is_default_guest(machine)) { | 552 | if (machine__is_default_guest(machine)) { |
560 | /* | 553 | /* |
561 | * preload dso of guest kernel and modules | 554 | * preload dso of guest kernel and modules |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index c08332871408..1d7f66488a88 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -82,8 +82,6 @@ struct perf_sample { | |||
82 | struct ip_callchain *callchain; | 82 | struct ip_callchain *callchain; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | int perf_sample_size(u64 sample_type); | ||
86 | |||
87 | #define BUILD_ID_SIZE 20 | 85 | #define BUILD_ID_SIZE 20 |
88 | 86 | ||
89 | struct build_id_event { | 87 | struct build_id_event { |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 50aa34879c33..b021ea9265c3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include "evlist.h" | 12 | #include "evlist.h" |
13 | #include "evsel.h" | 13 | #include "evsel.h" |
14 | #include "util.h" | 14 | #include "util.h" |
15 | #include "debug.h" | ||
16 | 15 | ||
17 | #include <sys/mman.h> | 16 | #include <sys/mman.h> |
18 | 17 | ||
@@ -257,19 +256,15 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist) | |||
257 | return evlist->mmap != NULL ? 0 : -ENOMEM; | 256 | return evlist->mmap != NULL ? 0 : -ENOMEM; |
258 | } | 257 | } |
259 | 258 | ||
260 | static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, | 259 | static int __perf_evlist__mmap(struct perf_evlist *evlist, |
261 | int idx, int prot, int mask, int fd) | 260 | int idx, int prot, int mask, int fd) |
262 | { | 261 | { |
263 | evlist->mmap[idx].prev = 0; | 262 | evlist->mmap[idx].prev = 0; |
264 | evlist->mmap[idx].mask = mask; | 263 | evlist->mmap[idx].mask = mask; |
265 | evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, | 264 | evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, |
266 | MAP_SHARED, fd, 0); | 265 | MAP_SHARED, fd, 0); |
267 | if (evlist->mmap[idx].base == MAP_FAILED) { | 266 | if (evlist->mmap[idx].base == MAP_FAILED) |
268 | if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit) | ||
269 | ui__warning("Inherit is not allowed on per-task " | ||
270 | "events using mmap.\n"); | ||
271 | return -1; | 267 | return -1; |
272 | } | ||
273 | 268 | ||
274 | perf_evlist__add_pollfd(evlist, fd); | 269 | perf_evlist__add_pollfd(evlist, fd); |
275 | return 0; | 270 | return 0; |
@@ -289,7 +284,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m | |||
289 | 284 | ||
290 | if (output == -1) { | 285 | if (output == -1) { |
291 | output = fd; | 286 | output = fd; |
292 | if (__perf_evlist__mmap(evlist, evsel, cpu, | 287 | if (__perf_evlist__mmap(evlist, cpu, |
293 | prot, mask, output) < 0) | 288 | prot, mask, output) < 0) |
294 | goto out_unmap; | 289 | goto out_unmap; |
295 | } else { | 290 | } else { |
@@ -329,7 +324,7 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in | |||
329 | 324 | ||
330 | if (output == -1) { | 325 | if (output == -1) { |
331 | output = fd; | 326 | output = fd; |
332 | if (__perf_evlist__mmap(evlist, evsel, thread, | 327 | if (__perf_evlist__mmap(evlist, thread, |
333 | prot, mask, output) < 0) | 328 | prot, mask, output) < 0) |
334 | goto out_unmap; | 329 | goto out_unmap; |
335 | } else { | 330 | } else { |
@@ -460,33 +455,46 @@ int perf_evlist__set_filters(struct perf_evlist *evlist) | |||
460 | return 0; | 455 | return 0; |
461 | } | 456 | } |
462 | 457 | ||
463 | u64 perf_evlist__sample_type(struct perf_evlist *evlist) | 458 | bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist) |
464 | { | 459 | { |
465 | struct perf_evsel *pos; | 460 | struct perf_evsel *pos, *first; |
466 | u64 type = 0; | 461 | |
467 | 462 | pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); | |
468 | list_for_each_entry(pos, &evlist->entries, node) { | 463 | |
469 | if (!type) | 464 | list_for_each_entry_continue(pos, &evlist->entries, node) { |
470 | type = pos->attr.sample_type; | 465 | if (first->attr.sample_type != pos->attr.sample_type) |
471 | else if (type != pos->attr.sample_type) | 466 | return false; |
472 | die("non matching sample_type"); | ||
473 | } | 467 | } |
474 | 468 | ||
475 | return type; | 469 | return true; |
476 | } | 470 | } |
477 | 471 | ||
478 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) | 472 | u64 perf_evlist__sample_type(const struct perf_evlist *evlist) |
473 | { | ||
474 | struct perf_evsel *first; | ||
475 | |||
476 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
477 | return first->attr.sample_type; | ||
478 | } | ||
479 | |||
480 | bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist) | ||
479 | { | 481 | { |
480 | bool value = false, first = true; | 482 | struct perf_evsel *pos, *first; |
481 | struct perf_evsel *pos; | 483 | |
482 | 484 | pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); | |
483 | list_for_each_entry(pos, &evlist->entries, node) { | 485 | |
484 | if (first) { | 486 | list_for_each_entry_continue(pos, &evlist->entries, node) { |
485 | value = pos->attr.sample_id_all; | 487 | if (first->attr.sample_id_all != pos->attr.sample_id_all) |
486 | first = false; | 488 | return false; |
487 | } else if (value != pos->attr.sample_id_all) | ||
488 | die("non matching sample_id_all"); | ||
489 | } | 489 | } |
490 | 490 | ||
491 | return value; | 491 | return true; |
492 | } | ||
493 | |||
494 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) | ||
495 | { | ||
496 | struct perf_evsel *first; | ||
497 | |||
498 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
499 | return first->attr.sample_id_all; | ||
492 | } | 500 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 0a1ef1f051f0..b2b862374f37 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -66,7 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, | |||
66 | void perf_evlist__delete_maps(struct perf_evlist *evlist); | 66 | void perf_evlist__delete_maps(struct perf_evlist *evlist); |
67 | int perf_evlist__set_filters(struct perf_evlist *evlist); | 67 | int perf_evlist__set_filters(struct perf_evlist *evlist); |
68 | 68 | ||
69 | u64 perf_evlist__sample_type(struct perf_evlist *evlist); | 69 | u64 perf_evlist__sample_type(const struct perf_evlist *evlist); |
70 | bool perf_evlist__sample_id_all(const struct perf_evlist *evlist); | 70 | bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); |
71 | 71 | ||
72 | bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); | ||
73 | bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); | ||
72 | #endif /* __PERF_EVLIST_H */ | 74 | #endif /* __PERF_EVLIST_H */ |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ee0fe0dffa71..0239eb87b232 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -15,6 +15,22 @@ | |||
15 | 15 | ||
16 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 16 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
17 | 17 | ||
18 | int __perf_evsel__sample_size(u64 sample_type) | ||
19 | { | ||
20 | u64 mask = sample_type & PERF_SAMPLE_MASK; | ||
21 | int size = 0; | ||
22 | int i; | ||
23 | |||
24 | for (i = 0; i < 64; i++) { | ||
25 | if (mask & (1ULL << i)) | ||
26 | size++; | ||
27 | } | ||
28 | |||
29 | size *= sizeof(u64); | ||
30 | |||
31 | return size; | ||
32 | } | ||
33 | |||
18 | void perf_evsel__init(struct perf_evsel *evsel, | 34 | void perf_evsel__init(struct perf_evsel *evsel, |
19 | struct perf_event_attr *attr, int idx) | 35 | struct perf_event_attr *attr, int idx) |
20 | { | 36 | { |
@@ -35,7 +51,17 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) | |||
35 | 51 | ||
36 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 52 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
37 | { | 53 | { |
54 | int cpu, thread; | ||
38 | evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); | 55 | evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); |
56 | |||
57 | if (evsel->fd) { | ||
58 | for (cpu = 0; cpu < ncpus; cpu++) { | ||
59 | for (thread = 0; thread < nthreads; thread++) { | ||
60 | FD(evsel, cpu, thread) = -1; | ||
61 | } | ||
62 | } | ||
63 | } | ||
64 | |||
39 | return evsel->fd != NULL ? 0 : -ENOMEM; | 65 | return evsel->fd != NULL ? 0 : -ENOMEM; |
40 | } | 66 | } |
41 | 67 | ||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index f79bb2c09a6c..7e9366e4490b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -149,4 +149,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, | |||
149 | return __perf_evsel__read(evsel, ncpus, nthreads, true); | 149 | return __perf_evsel__read(evsel, ncpus, nthreads, true); |
150 | } | 150 | } |
151 | 151 | ||
152 | int __perf_evsel__sample_size(u64 sample_type); | ||
153 | |||
154 | static inline int perf_evsel__sample_size(struct perf_evsel *evsel) | ||
155 | { | ||
156 | return __perf_evsel__sample_size(evsel->attr.sample_type); | ||
157 | } | ||
158 | |||
152 | #endif /* __PERF_EVSEL_H */ | 159 | #endif /* __PERF_EVSEL_H */ |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 0717bebc7649..afb0849fe530 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -193,9 +193,13 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | |||
193 | *linkname = malloc(size), *targetname; | 193 | *linkname = malloc(size), *targetname; |
194 | int len, err = -1; | 194 | int len, err = -1; |
195 | 195 | ||
196 | if (is_kallsyms) | 196 | if (is_kallsyms) { |
197 | if (symbol_conf.kptr_restrict) { | ||
198 | pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); | ||
199 | return 0; | ||
200 | } | ||
197 | realname = (char *)name; | 201 | realname = (char *)name; |
198 | else | 202 | } else |
199 | realname = realpath(name, NULL); | 203 | realname = realpath(name, NULL); |
200 | 204 | ||
201 | if (realname == NULL || filename == NULL || linkname == NULL) | 205 | if (realname == NULL || filename == NULL || linkname == NULL) |
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h new file mode 100644 index 000000000000..1b476c9ae649 --- /dev/null +++ b/tools/perf/util/include/linux/const.h | |||
@@ -0,0 +1 @@ | |||
#include "../../../../include/linux/const.h" | |||
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 69436b3200a4..a9ac0504aabd 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -674,7 +674,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
674 | struct perf_evlist *evlist = &pevlist->evlist; | 674 | struct perf_evlist *evlist = &pevlist->evlist; |
675 | union perf_event *event; | 675 | union perf_event *event; |
676 | int sample_id_all = 1, cpu; | 676 | int sample_id_all = 1, cpu; |
677 | static char *kwlist[] = {"sample_id_all", NULL, NULL}; | 677 | static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL}; |
678 | int err; | 678 | int err; |
679 | 679 | ||
680 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, | 680 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, |
@@ -692,16 +692,14 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
692 | 692 | ||
693 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | 693 | first = list_entry(evlist->entries.next, struct perf_evsel, node); |
694 | err = perf_event__parse_sample(event, first->attr.sample_type, | 694 | err = perf_event__parse_sample(event, first->attr.sample_type, |
695 | perf_sample_size(first->attr.sample_type), | 695 | perf_evsel__sample_size(first), |
696 | sample_id_all, &pevent->sample); | 696 | sample_id_all, &pevent->sample); |
697 | if (err) { | 697 | if (err) |
698 | pr_err("Can't parse sample, err = %d\n", err); | 698 | return PyErr_Format(PyExc_OSError, |
699 | goto end; | 699 | "perf: can't parse sample, err=%d", err); |
700 | } | ||
701 | |||
702 | return pyevent; | 700 | return pyevent; |
703 | } | 701 | } |
704 | end: | 702 | |
705 | Py_INCREF(Py_None); | 703 | Py_INCREF(Py_None); |
706 | return Py_None; | 704 | return Py_None; |
707 | } | 705 | } |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 64500fc78799..f5a8fbdd3f76 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force) | |||
58 | goto out_close; | 58 | goto out_close; |
59 | } | 59 | } |
60 | 60 | ||
61 | if (!perf_evlist__valid_sample_type(self->evlist)) { | ||
62 | pr_err("non matching sample_type"); | ||
63 | goto out_close; | ||
64 | } | ||
65 | |||
66 | if (!perf_evlist__valid_sample_id_all(self->evlist)) { | ||
67 | pr_err("non matching sample_id_all"); | ||
68 | goto out_close; | ||
69 | } | ||
70 | |||
61 | self->size = input_stat.st_size; | 71 | self->size = input_stat.st_size; |
62 | return 0; | 72 | return 0; |
63 | 73 | ||
@@ -97,7 +107,7 @@ out: | |||
97 | void perf_session__update_sample_type(struct perf_session *self) | 107 | void perf_session__update_sample_type(struct perf_session *self) |
98 | { | 108 | { |
99 | self->sample_type = perf_evlist__sample_type(self->evlist); | 109 | self->sample_type = perf_evlist__sample_type(self->evlist); |
100 | self->sample_size = perf_sample_size(self->sample_type); | 110 | self->sample_size = __perf_evsel__sample_size(self->sample_type); |
101 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); | 111 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); |
102 | perf_session__id_header_size(self); | 112 | perf_session__id_header_size(self); |
103 | } | 113 | } |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 516876dfbe52..eec196329fd9 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -676,9 +676,30 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
676 | return count + moved; | 676 | return count + moved; |
677 | } | 677 | } |
678 | 678 | ||
679 | static bool symbol__restricted_filename(const char *filename, | ||
680 | const char *restricted_filename) | ||
681 | { | ||
682 | bool restricted = false; | ||
683 | |||
684 | if (symbol_conf.kptr_restrict) { | ||
685 | char *r = realpath(filename, NULL); | ||
686 | |||
687 | if (r != NULL) { | ||
688 | restricted = strcmp(r, restricted_filename) == 0; | ||
689 | free(r); | ||
690 | return restricted; | ||
691 | } | ||
692 | } | ||
693 | |||
694 | return restricted; | ||
695 | } | ||
696 | |||
679 | int dso__load_kallsyms(struct dso *dso, const char *filename, | 697 | int dso__load_kallsyms(struct dso *dso, const char *filename, |
680 | struct map *map, symbol_filter_t filter) | 698 | struct map *map, symbol_filter_t filter) |
681 | { | 699 | { |
700 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | ||
701 | return -1; | ||
702 | |||
682 | if (dso__load_all_kallsyms(dso, filename, map) < 0) | 703 | if (dso__load_all_kallsyms(dso, filename, map) < 0) |
683 | return -1; | 704 | return -1; |
684 | 705 | ||
@@ -1790,6 +1811,9 @@ static int machine__create_modules(struct machine *machine) | |||
1790 | modules = path; | 1811 | modules = path; |
1791 | } | 1812 | } |
1792 | 1813 | ||
1814 | if (symbol__restricted_filename(path, "/proc/modules")) | ||
1815 | return -1; | ||
1816 | |||
1793 | file = fopen(modules, "r"); | 1817 | file = fopen(modules, "r"); |
1794 | if (file == NULL) | 1818 | if (file == NULL) |
1795 | return -1; | 1819 | return -1; |
@@ -2239,6 +2263,9 @@ static u64 machine__get_kernel_start_addr(struct machine *machine) | |||
2239 | } | 2263 | } |
2240 | } | 2264 | } |
2241 | 2265 | ||
2266 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | ||
2267 | return 0; | ||
2268 | |||
2242 | if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) | 2269 | if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) |
2243 | return 0; | 2270 | return 0; |
2244 | 2271 | ||
@@ -2410,6 +2437,25 @@ static int setup_list(struct strlist **list, const char *list_str, | |||
2410 | return 0; | 2437 | return 0; |
2411 | } | 2438 | } |
2412 | 2439 | ||
2440 | static bool symbol__read_kptr_restrict(void) | ||
2441 | { | ||
2442 | bool value = false; | ||
2443 | |||
2444 | if (geteuid() != 0) { | ||
2445 | FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); | ||
2446 | if (fp != NULL) { | ||
2447 | char line[8]; | ||
2448 | |||
2449 | if (fgets(line, sizeof(line), fp) != NULL) | ||
2450 | value = atoi(line) != 0; | ||
2451 | |||
2452 | fclose(fp); | ||
2453 | } | ||
2454 | } | ||
2455 | |||
2456 | return value; | ||
2457 | } | ||
2458 | |||
2413 | int symbol__init(void) | 2459 | int symbol__init(void) |
2414 | { | 2460 | { |
2415 | const char *symfs; | 2461 | const char *symfs; |
@@ -2456,6 +2502,8 @@ int symbol__init(void) | |||
2456 | if (symfs != symbol_conf.symfs) | 2502 | if (symfs != symbol_conf.symfs) |
2457 | free((void *)symfs); | 2503 | free((void *)symfs); |
2458 | 2504 | ||
2505 | symbol_conf.kptr_restrict = symbol__read_kptr_restrict(); | ||
2506 | |||
2459 | symbol_conf.initialized = true; | 2507 | symbol_conf.initialized = true; |
2460 | return 0; | 2508 | return 0; |
2461 | 2509 | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 242de0101a86..325ee36a9d29 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -75,7 +75,8 @@ struct symbol_conf { | |||
75 | use_callchain, | 75 | use_callchain, |
76 | exclude_other, | 76 | exclude_other, |
77 | show_cpu_utilization, | 77 | show_cpu_utilization, |
78 | initialized; | 78 | initialized, |
79 | kptr_restrict; | ||
79 | const char *vmlinux_name, | 80 | const char *vmlinux_name, |
80 | *kallsyms_name, | 81 | *kallsyms_name, |
81 | *source_prefix, | 82 | *source_prefix, |
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index df0c6d2c3860..74d3331bdaf9 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c | |||
@@ -198,6 +198,14 @@ const struct option longopts[] = { | |||
198 | .val = 'h', | 198 | .val = 'h', |
199 | }, | 199 | }, |
200 | { | 200 | { |
201 | .name = "event-idx", | ||
202 | .val = 'E', | ||
203 | }, | ||
204 | { | ||
205 | .name = "no-event-idx", | ||
206 | .val = 'e', | ||
207 | }, | ||
208 | { | ||
201 | .name = "indirect", | 209 | .name = "indirect", |
202 | .val = 'I', | 210 | .val = 'I', |
203 | }, | 211 | }, |
@@ -211,13 +219,17 @@ const struct option longopts[] = { | |||
211 | 219 | ||
212 | static void help() | 220 | static void help() |
213 | { | 221 | { |
214 | fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n"); | 222 | fprintf(stderr, "Usage: virtio_test [--help]" |
223 | " [--no-indirect]" | ||
224 | " [--no-event-idx]" | ||
225 | "\n"); | ||
215 | } | 226 | } |
216 | 227 | ||
217 | int main(int argc, char **argv) | 228 | int main(int argc, char **argv) |
218 | { | 229 | { |
219 | struct vdev_info dev; | 230 | struct vdev_info dev; |
220 | unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC; | 231 | unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | |
232 | (1ULL << VIRTIO_RING_F_EVENT_IDX); | ||
221 | int o; | 233 | int o; |
222 | 234 | ||
223 | for (;;) { | 235 | for (;;) { |
@@ -228,6 +240,9 @@ int main(int argc, char **argv) | |||
228 | case '?': | 240 | case '?': |
229 | help(); | 241 | help(); |
230 | exit(2); | 242 | exit(2); |
243 | case 'e': | ||
244 | features &= ~(1ULL << VIRTIO_RING_F_EVENT_IDX); | ||
245 | break; | ||
231 | case 'h': | 246 | case 'h': |
232 | help(); | 247 | help(); |
233 | goto done; | 248 | goto done; |