diff options
247 files changed, 8744 insertions, 3556 deletions
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index cf2fce7707da..6df1dfd18b65 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl | |||
@@ -14,7 +14,7 @@ | |||
14 | </authorgroup> | 14 | </authorgroup> |
15 | 15 | ||
16 | <copyright> | 16 | <copyright> |
17 | <year>2003</year> | 17 | <year>2003-2005</year> |
18 | <holder>Jeff Garzik</holder> | 18 | <holder>Jeff Garzik</holder> |
19 | </copyright> | 19 | </copyright> |
20 | 20 | ||
@@ -44,30 +44,38 @@ | |||
44 | 44 | ||
45 | <toc></toc> | 45 | <toc></toc> |
46 | 46 | ||
47 | <chapter id="libataThanks"> | 47 | <chapter id="libataIntroduction"> |
48 | <title>Thanks</title> | 48 | <title>Introduction</title> |
49 | <para> | 49 | <para> |
50 | The bulk of the ATA knowledge comes thanks to long conversations with | 50 | libATA is a library used inside the Linux kernel to support ATA host |
51 | Andre Hedrick (www.linux-ide.org). | 51 | controllers and devices. libATA provides an ATA driver API, class |
52 | transports for ATA and ATAPI devices, and SCSI<->ATA translation | ||
53 | for ATA devices according to the T10 SAT specification. | ||
52 | </para> | 54 | </para> |
53 | <para> | 55 | <para> |
54 | Thanks to Alan Cox for pointing out similarities | 56 | This Guide documents the libATA driver API, library functions, library |
55 | between SATA and SCSI, and in general for motivation to hack on | 57 | internals, and a couple sample ATA low-level drivers. |
56 | libata. | ||
57 | </para> | ||
58 | <para> | ||
59 | libata's device detection | ||
60 | method, ata_pio_devchk, and in general all the early probing was | ||
61 | based on extensive study of Hale Landis's probe/reset code in his | ||
62 | ATADRVR driver (www.ata-atapi.com). | ||
63 | </para> | 58 | </para> |
64 | </chapter> | 59 | </chapter> |
65 | 60 | ||
66 | <chapter id="libataDriverApi"> | 61 | <chapter id="libataDriverApi"> |
67 | <title>libata Driver API</title> | 62 | <title>libata Driver API</title> |
63 | <para> | ||
64 | struct ata_port_operations is defined for every low-level libata | ||
65 | hardware driver, and it controls how the low-level driver | ||
66 | interfaces with the ATA and SCSI layers. | ||
67 | </para> | ||
68 | <para> | ||
69 | FIS-based drivers will hook into the system with ->qc_prep() and | ||
70 | ->qc_issue() high-level hooks. Hardware which behaves in a manner | ||
71 | similar to PCI IDE hardware may utilize several generic helpers, | ||
72 | defining at a bare minimum the bus I/O addresses of the ATA shadow | ||
73 | register blocks. | ||
74 | </para> | ||
68 | <sect1> | 75 | <sect1> |
69 | <title>struct ata_port_operations</title> | 76 | <title>struct ata_port_operations</title> |
70 | 77 | ||
78 | <sect2><title>Disable ATA port</title> | ||
71 | <programlisting> | 79 | <programlisting> |
72 | void (*port_disable) (struct ata_port *); | 80 | void (*port_disable) (struct ata_port *); |
73 | </programlisting> | 81 | </programlisting> |
@@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *); | |||
78 | unplug). | 86 | unplug). |
79 | </para> | 87 | </para> |
80 | 88 | ||
89 | </sect2> | ||
90 | |||
91 | <sect2><title>Post-IDENTIFY device configuration</title> | ||
81 | <programlisting> | 92 | <programlisting> |
82 | void (*dev_config) (struct ata_port *, struct ata_device *); | 93 | void (*dev_config) (struct ata_port *, struct ata_device *); |
83 | </programlisting> | 94 | </programlisting> |
@@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *); | |||
88 | issue of SET FEATURES - XFER MODE, and prior to operation. | 99 | issue of SET FEATURES - XFER MODE, and prior to operation. |
89 | </para> | 100 | </para> |
90 | 101 | ||
102 | </sect2> | ||
103 | |||
104 | <sect2><title>Set PIO/DMA mode</title> | ||
91 | <programlisting> | 105 | <programlisting> |
92 | void (*set_piomode) (struct ata_port *, struct ata_device *); | 106 | void (*set_piomode) (struct ata_port *, struct ata_device *); |
93 | void (*set_dmamode) (struct ata_port *, struct ata_device *); | 107 | void (*set_dmamode) (struct ata_port *, struct ata_device *); |
@@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap); | |||
108 | ->set_dma_mode() is only called if DMA is possible. | 122 | ->set_dma_mode() is only called if DMA is possible. |
109 | </para> | 123 | </para> |
110 | 124 | ||
125 | </sect2> | ||
126 | |||
127 | <sect2><title>Taskfile read/write</title> | ||
111 | <programlisting> | 128 | <programlisting> |
112 | void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf); | 129 | void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf); |
113 | void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); | 130 | void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); |
@@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); | |||
120 | taskfile register values. | 137 | taskfile register values. |
121 | </para> | 138 | </para> |
122 | 139 | ||
140 | </sect2> | ||
141 | |||
142 | <sect2><title>ATA command execute</title> | ||
123 | <programlisting> | 143 | <programlisting> |
124 | void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); | 144 | void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); |
125 | </programlisting> | 145 | </programlisting> |
@@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); | |||
129 | ->tf_load(), to be initiated in hardware. | 149 | ->tf_load(), to be initiated in hardware. |
130 | </para> | 150 | </para> |
131 | 151 | ||
152 | </sect2> | ||
153 | |||
154 | <sect2><title>Per-cmd ATAPI DMA capabilities filter</title> | ||
155 | <programlisting> | ||
156 | int (*check_atapi_dma) (struct ata_queued_cmd *qc); | ||
157 | </programlisting> | ||
158 | |||
159 | <para> | ||
160 | Allow low-level driver to filter ATA PACKET commands, returning a status | ||
161 | indicating whether or not it is OK to use DMA for the supplied PACKET | ||
162 | command. | ||
163 | </para> | ||
164 | |||
165 | </sect2> | ||
166 | |||
167 | <sect2><title>Read specific ATA shadow registers</title> | ||
132 | <programlisting> | 168 | <programlisting> |
133 | u8 (*check_status)(struct ata_port *ap); | 169 | u8 (*check_status)(struct ata_port *ap); |
134 | void (*dev_select)(struct ata_port *ap, unsigned int device); | 170 | u8 (*check_altstatus)(struct ata_port *ap); |
171 | u8 (*check_err)(struct ata_port *ap); | ||
135 | </programlisting> | 172 | </programlisting> |
136 | 173 | ||
137 | <para> | 174 | <para> |
138 | Reads the Status ATA shadow register from hardware. On some | 175 | Reads the Status/AltStatus/Error ATA shadow register from |
139 | hardware, this has the side effect of clearing the interrupt | 176 | hardware. On some hardware, reading the Status register has |
140 | condition. | 177 | the side effect of clearing the interrupt condition. |
141 | </para> | 178 | </para> |
142 | 179 | ||
180 | </sect2> | ||
181 | |||
182 | <sect2><title>Select ATA device on bus</title> | ||
143 | <programlisting> | 183 | <programlisting> |
144 | void (*dev_select)(struct ata_port *ap, unsigned int device); | 184 | void (*dev_select)(struct ata_port *ap, unsigned int device); |
145 | </programlisting> | 185 | </programlisting> |
@@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); | |||
147 | <para> | 187 | <para> |
148 | Issues the low-level hardware command(s) that causes one of N | 188 | Issues the low-level hardware command(s) that causes one of N |
149 | hardware devices to be considered 'selected' (active and | 189 | hardware devices to be considered 'selected' (active and |
150 | available for use) on the ATA bus. | 190 | available for use) on the ATA bus. This generally has no |
191 | meaning on FIS-based devices. | ||
151 | </para> | 192 | </para> |
152 | 193 | ||
194 | </sect2> | ||
195 | |||
196 | <sect2><title>Reset ATA bus</title> | ||
153 | <programlisting> | 197 | <programlisting> |
154 | void (*phy_reset) (struct ata_port *ap); | 198 | void (*phy_reset) (struct ata_port *ap); |
155 | </programlisting> | 199 | </programlisting> |
@@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap); | |||
162 | functions ata_bus_reset() or sata_phy_reset() for this hook. | 206 | functions ata_bus_reset() or sata_phy_reset() for this hook. |
163 | </para> | 207 | </para> |
164 | 208 | ||
209 | </sect2> | ||
210 | |||
211 | <sect2><title>Control PCI IDE BMDMA engine</title> | ||
165 | <programlisting> | 212 | <programlisting> |
166 | void (*bmdma_setup) (struct ata_queued_cmd *qc); | 213 | void (*bmdma_setup) (struct ata_queued_cmd *qc); |
167 | void (*bmdma_start) (struct ata_queued_cmd *qc); | 214 | void (*bmdma_start) (struct ata_queued_cmd *qc); |
215 | void (*bmdma_stop) (struct ata_port *ap); | ||
216 | u8 (*bmdma_status) (struct ata_port *ap); | ||
168 | </programlisting> | 217 | </programlisting> |
169 | 218 | ||
170 | <para> | 219 | <para> |
171 | When setting up an IDE BMDMA transaction, these hooks arm | 220 | When setting up an IDE BMDMA transaction, these hooks arm |
172 | (->bmdma_setup) and fire (->bmdma_start) the hardware's DMA | 221 | (->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop) |
173 | engine. | 222 | the hardware's DMA engine. ->bmdma_status is used to read the standard |
223 | PCI IDE DMA Status register. | ||
174 | </para> | 224 | </para> |
175 | 225 | ||
226 | <para> | ||
227 | These hooks are typically either no-ops, or simply not implemented, in | ||
228 | FIS-based drivers. | ||
229 | </para> | ||
230 | |||
231 | </sect2> | ||
232 | |||
233 | <sect2><title>High-level taskfile hooks</title> | ||
176 | <programlisting> | 234 | <programlisting> |
177 | void (*qc_prep) (struct ata_queued_cmd *qc); | 235 | void (*qc_prep) (struct ata_queued_cmd *qc); |
178 | int (*qc_issue) (struct ata_queued_cmd *qc); | 236 | int (*qc_issue) (struct ata_queued_cmd *qc); |
@@ -190,20 +248,26 @@ int (*qc_issue) (struct ata_queued_cmd *qc); | |||
190 | ->qc_issue is used to make a command active, once the hardware | 248 | ->qc_issue is used to make a command active, once the hardware |
191 | and S/G tables have been prepared. IDE BMDMA drivers use the | 249 | and S/G tables have been prepared. IDE BMDMA drivers use the |
192 | helper function ata_qc_issue_prot() for taskfile protocol-based | 250 | helper function ata_qc_issue_prot() for taskfile protocol-based |
193 | dispatch. More advanced drivers roll their own ->qc_issue | 251 | dispatch. More advanced drivers implement their own ->qc_issue. |
194 | implementation, using this as the "issue new ATA command to | ||
195 | hardware" hook. | ||
196 | </para> | 252 | </para> |
197 | 253 | ||
254 | </sect2> | ||
255 | |||
256 | <sect2><title>Timeout (error) handling</title> | ||
198 | <programlisting> | 257 | <programlisting> |
199 | void (*eng_timeout) (struct ata_port *ap); | 258 | void (*eng_timeout) (struct ata_port *ap); |
200 | </programlisting> | 259 | </programlisting> |
201 | 260 | ||
202 | <para> | 261 | <para> |
203 | This is a high level error handling function, called from the | 262 | This is a high level error handling function, called from the |
204 | error handling thread, when a command times out. | 263 | error handling thread, when a command times out. Most newer |
264 | hardware will implement its own error handling code here. IDE BMDMA | ||
265 | drivers may use the helper function ata_eng_timeout(). | ||
205 | </para> | 266 | </para> |
206 | 267 | ||
268 | </sect2> | ||
269 | |||
270 | <sect2><title>Hardware interrupt handling</title> | ||
207 | <programlisting> | 271 | <programlisting> |
208 | irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); | 272 | irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); |
209 | void (*irq_clear) (struct ata_port *); | 273 | void (*irq_clear) (struct ata_port *); |
@@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *); | |||
216 | is quiet. | 280 | is quiet. |
217 | </para> | 281 | </para> |
218 | 282 | ||
283 | </sect2> | ||
284 | |||
285 | <sect2><title>SATA phy read/write</title> | ||
219 | <programlisting> | 286 | <programlisting> |
220 | u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); | 287 | u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); |
221 | void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | 288 | void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, |
@@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | |||
227 | if ->phy_reset hook called the sata_phy_reset() helper function. | 294 | if ->phy_reset hook called the sata_phy_reset() helper function. |
228 | </para> | 295 | </para> |
229 | 296 | ||
297 | </sect2> | ||
298 | |||
299 | <sect2><title>Init and shutdown</title> | ||
230 | <programlisting> | 300 | <programlisting> |
231 | int (*port_start) (struct ata_port *ap); | 301 | int (*port_start) (struct ata_port *ap); |
232 | void (*port_stop) (struct ata_port *ap); | 302 | void (*port_stop) (struct ata_port *ap); |
@@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set); | |||
240 | tasks. | 310 | tasks. |
241 | </para> | 311 | </para> |
242 | <para> | 312 | <para> |
243 | ->host_stop() is called when the rmmod or hot unplug process | ||
244 | begins. The hook must stop all hardware interrupts, DMA | ||
245 | engines, etc. | ||
246 | </para> | ||
247 | <para> | ||
248 | ->port_stop() is called after ->host_stop(). It's sole function | 313 | ->port_stop() is called after ->host_stop(). It's sole function |
249 | is to release DMA/memory resources, now that they are no longer | 314 | is to release DMA/memory resources, now that they are no longer |
250 | actively being used. | 315 | actively being used. |
251 | </para> | 316 | </para> |
317 | <para> | ||
318 | ->host_stop() is called after all ->port_stop() calls | ||
319 | have completed. The hook must finalize hardware shutdown, release DMA | ||
320 | and other resources, etc. | ||
321 | </para> | ||
322 | |||
323 | </sect2> | ||
252 | 324 | ||
253 | </sect1> | 325 | </sect1> |
254 | </chapter> | 326 | </chapter> |
@@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set); | |||
279 | !Idrivers/scsi/sata_sil.c | 351 | !Idrivers/scsi/sata_sil.c |
280 | </chapter> | 352 | </chapter> |
281 | 353 | ||
354 | <chapter id="libataThanks"> | ||
355 | <title>Thanks</title> | ||
356 | <para> | ||
357 | The bulk of the ATA knowledge comes thanks to long conversations with | ||
358 | Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA | ||
359 | and SCSI specifications. | ||
360 | </para> | ||
361 | <para> | ||
362 | Thanks to Alan Cox for pointing out similarities | ||
363 | between SATA and SCSI, and in general for motivation to hack on | ||
364 | libata. | ||
365 | </para> | ||
366 | <para> | ||
367 | libata's device detection | ||
368 | method, ata_pio_devchk, and in general all the early probing was | ||
369 | based on extensive study of Hale Landis's probe/reset code in his | ||
370 | ATADRVR driver (www.ata-atapi.com). | ||
371 | </para> | ||
372 | </chapter> | ||
373 | |||
282 | </book> | 374 | </book> |
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt new file mode 100644 index 000000000000..e2d1e760b4ba --- /dev/null +++ b/Documentation/cpu-freq/cpufreq-stats.txt | |||
@@ -0,0 +1,128 @@ | |||
1 | |||
2 | CPU frequency and voltage scaling statictics in the Linux(TM) kernel | ||
3 | |||
4 | |||
5 | L i n u x c p u f r e q - s t a t s d r i v e r | ||
6 | |||
7 | - information for users - | ||
8 | |||
9 | |||
10 | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
11 | |||
12 | Contents | ||
13 | 1. Introduction | ||
14 | 2. Statistics Provided (with example) | ||
15 | 3. Configuring cpufreq-stats | ||
16 | |||
17 | |||
18 | 1. Introduction | ||
19 | |||
20 | cpufreq-stats is a driver that provices CPU frequency statistics for each CPU. | ||
21 | This statistics is provided in /sysfs as a bunch of read_only interfaces. This | ||
22 | interface (when configured) will appear in a seperate directory under cpufreq | ||
23 | in /sysfs (<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/) for each CPU. | ||
24 | Various statistics will form read_only files under this directory. | ||
25 | |||
26 | This driver is designed to be independent of any particular cpufreq_driver | ||
27 | that may be running on your CPU. So, it will work with any cpufreq_driver. | ||
28 | |||
29 | |||
30 | 2. Statistics Provided (with example) | ||
31 | |||
32 | cpufreq stats provides following statistics (explained in detail below). | ||
33 | - time_in_state | ||
34 | - total_trans | ||
35 | - trans_table | ||
36 | |||
37 | All the statistics will be from the time the stats driver has been inserted | ||
38 | to the time when a read of a particular statistic is done. Obviously, stats | ||
39 | driver will not have any information about the the frequcny transitions before | ||
40 | the stats driver insertion. | ||
41 | |||
42 | -------------------------------------------------------------------------------- | ||
43 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # ls -l | ||
44 | total 0 | ||
45 | drwxr-xr-x 2 root root 0 May 14 16:06 . | ||
46 | drwxr-xr-x 3 root root 0 May 14 15:58 .. | ||
47 | -r--r--r-- 1 root root 4096 May 14 16:06 time_in_state | ||
48 | -r--r--r-- 1 root root 4096 May 14 16:06 total_trans | ||
49 | -r--r--r-- 1 root root 4096 May 14 16:06 trans_table | ||
50 | -------------------------------------------------------------------------------- | ||
51 | |||
52 | - time_in_state | ||
53 | This gives the amount of time spent in each of the frequencies supported by | ||
54 | this CPU. The cat output will have "<frequency> <time>" pair in each line, which | ||
55 | will mean this CPU spent <time> usertime units of time at <frequency>. Output | ||
56 | will have one line for each of the supported freuencies. usertime units here | ||
57 | is 10mS (similar to other time exported in /proc). | ||
58 | |||
59 | -------------------------------------------------------------------------------- | ||
60 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat time_in_state | ||
61 | 3600000 2089 | ||
62 | 3400000 136 | ||
63 | 3200000 34 | ||
64 | 3000000 67 | ||
65 | 2800000 172488 | ||
66 | -------------------------------------------------------------------------------- | ||
67 | |||
68 | |||
69 | - total_trans | ||
70 | This gives the total number of frequency transitions on this CPU. The cat | ||
71 | output will have a single count which is the total number of frequency | ||
72 | transitions. | ||
73 | |||
74 | -------------------------------------------------------------------------------- | ||
75 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat total_trans | ||
76 | 20 | ||
77 | -------------------------------------------------------------------------------- | ||
78 | |||
79 | - trans_table | ||
80 | This will give a fine grained information about all the CPU frequency | ||
81 | transitions. The cat output here is a two dimensional matrix, where an entry | ||
82 | <i,j> (row i, column j) represents the count of number of transitions from | ||
83 | Freq_i to Freq_j. Freq_i is in descending order with increasing rows and | ||
84 | Freq_j is in descending order with increasing columns. The output here also | ||
85 | contains the actual freq values for each row and column for better readability. | ||
86 | |||
87 | -------------------------------------------------------------------------------- | ||
88 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat trans_table | ||
89 | From : To | ||
90 | : 3600000 3400000 3200000 3000000 2800000 | ||
91 | 3600000: 0 5 0 0 0 | ||
92 | 3400000: 4 0 2 0 0 | ||
93 | 3200000: 0 1 0 2 0 | ||
94 | 3000000: 0 0 1 0 3 | ||
95 | 2800000: 0 0 0 2 0 | ||
96 | -------------------------------------------------------------------------------- | ||
97 | |||
98 | |||
99 | 3. Configuring cpufreq-stats | ||
100 | |||
101 | To configure cpufreq-stats in your kernel | ||
102 | Config Main Menu | ||
103 | Power management options (ACPI, APM) ---> | ||
104 | CPU Frequency scaling ---> | ||
105 | [*] CPU Frequency scaling | ||
106 | <*> CPU frequency translation statistics | ||
107 | [*] CPU frequency translation statistics details | ||
108 | |||
109 | |||
110 | "CPU Frequency scaling" (CONFIG_CPU_FREQ) should be enabled to configure | ||
111 | cpufreq-stats. | ||
112 | |||
113 | "CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT) provides the | ||
114 | basic statistics which includes time_in_state and total_trans. | ||
115 | |||
116 | "CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS) | ||
117 | provides fine grained cpufreq stats by trans_table. The reason for having a | ||
118 | seperate config option for trans_table is: | ||
119 | - trans_table goes against the traditional /sysfs rule of one value per | ||
120 | interface. It provides a whole bunch of value in a 2 dimensional matrix | ||
121 | form. | ||
122 | |||
123 | Once these two options are enabled and your CPU supports cpufrequency, you | ||
124 | will be able to see the CPU frequency statistics in /sysfs. | ||
125 | |||
126 | |||
127 | |||
128 | |||
diff --git a/Documentation/networking/generic-hdlc.txt b/Documentation/networking/generic-hdlc.txt index 7d1dc6b884f3..31bc8b759b75 100644 --- a/Documentation/networking/generic-hdlc.txt +++ b/Documentation/networking/generic-hdlc.txt | |||
@@ -1,21 +1,21 @@ | |||
1 | Generic HDLC layer | 1 | Generic HDLC layer |
2 | Krzysztof Halasa <khc@pm.waw.pl> | 2 | Krzysztof Halasa <khc@pm.waw.pl> |
3 | January, 2003 | ||
4 | 3 | ||
5 | 4 | ||
6 | Generic HDLC layer currently supports: | 5 | Generic HDLC layer currently supports: |
7 | - Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP). | 6 | 1. Frame Relay (ANSI, CCITT, Cisco and no LMI). |
8 | Normal (routed) and Ethernet-bridged (Ethernet device emulation) | 7 | - Normal (routed) and Ethernet-bridged (Ethernet device emulation) |
9 | interfaces can share a single PVC. | 8 | interfaces can share a single PVC. |
10 | - raw HDLC - either IP (IPv4) interface or Ethernet device emulation. | 9 | - ARP support (no InARP support in the kernel - there is an |
11 | - Cisco HDLC, | 10 | experimental InARP user-space daemon available on: |
12 | - PPP (uses syncppp.c), | 11 | http://www.kernel.org/pub/linux/utils/net/hdlc/). |
13 | - X.25 (uses X.25 routines). | 12 | 2. raw HDLC - either IP (IPv4) interface or Ethernet device emulation. |
14 | 13 | 3. Cisco HDLC. | |
15 | There are hardware drivers for the following cards: | 14 | 4. PPP (uses syncppp.c). |
16 | - C101 by Moxa Technologies Co., Ltd. | 15 | 5. X.25 (uses X.25 routines). |
17 | - RISCom/N2 by SDL Communications Inc. | 16 | |
18 | - and others, some not in the official kernel. | 17 | Generic HDLC is a protocol driver only - it needs a low-level driver |
18 | for your particular hardware. | ||
19 | 19 | ||
20 | Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible | 20 | Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible |
21 | with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). | 21 | with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). |
@@ -24,7 +24,7 @@ with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). | |||
24 | Make sure the hdlc.o and the hardware driver are loaded. It should | 24 | Make sure the hdlc.o and the hardware driver are loaded. It should |
25 | create a number of "hdlc" (hdlc0 etc) network devices, one for each | 25 | create a number of "hdlc" (hdlc0 etc) network devices, one for each |
26 | WAN port. You'll need the "sethdlc" utility, get it from: | 26 | WAN port. You'll need the "sethdlc" utility, get it from: |
27 | http://hq.pm.waw.pl/hdlc/ | 27 | http://www.kernel.org/pub/linux/utils/net/hdlc/ |
28 | 28 | ||
29 | Compile sethdlc.c utility: | 29 | Compile sethdlc.c utility: |
30 | gcc -O2 -Wall -o sethdlc sethdlc.c | 30 | gcc -O2 -Wall -o sethdlc sethdlc.c |
@@ -52,12 +52,12 @@ Setting interface: | |||
52 | * v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port | 52 | * v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port |
53 | if the card has software-selectable interfaces | 53 | if the card has software-selectable interfaces |
54 | loopback - activate hardware loopback (for testing only) | 54 | loopback - activate hardware loopback (for testing only) |
55 | * clock ext - external clock (uses DTE RX and TX clock) | 55 | * clock ext - both RX clock and TX clock external |
56 | * clock int - internal clock (provides clock signal on DCE clock output) | 56 | * clock int - both RX clock and TX clock internal |
57 | * clock txint - TX internal, RX external (provides TX clock on DCE output) | 57 | * clock txint - RX clock external, TX clock internal |
58 | * clock txfromrx - TX clock derived from RX clock (TX clock on DCE output) | 58 | * clock txfromrx - RX clock external, TX clock derived from RX clock |
59 | * rate - sets clock rate in bps (not required for external clock or | 59 | * rate - sets clock rate in bps (for "int" or "txint" clock only) |
60 | for txfromrx) | 60 | |
61 | 61 | ||
62 | Setting protocol: | 62 | Setting protocol: |
63 | 63 | ||
@@ -79,7 +79,7 @@ Setting protocol: | |||
79 | * x25 - sets X.25 mode | 79 | * x25 - sets X.25 mode |
80 | 80 | ||
81 | * fr - Frame Relay mode | 81 | * fr - Frame Relay mode |
82 | lmi ansi / ccitt / none - LMI (link management) type | 82 | lmi ansi / ccitt / cisco / none - LMI (link management) type |
83 | dce - Frame Relay DCE (network) side LMI instead of default DTE (user). | 83 | dce - Frame Relay DCE (network) side LMI instead of default DTE (user). |
84 | It has nothing to do with clocks! | 84 | It has nothing to do with clocks! |
85 | t391 - link integrity verification polling timer (in seconds) - user | 85 | t391 - link integrity verification polling timer (in seconds) - user |
@@ -119,13 +119,14 @@ or | |||
119 | 119 | ||
120 | 120 | ||
121 | 121 | ||
122 | If you have a problem with N2 or C101 card, you can issue the "private" | 122 | If you have a problem with N2, C101 or PLX200SYN card, you can issue the |
123 | command to see port's packet descriptor rings (in kernel logs): | 123 | "private" command to see port's packet descriptor rings (in kernel logs): |
124 | 124 | ||
125 | sethdlc hdlc0 private | 125 | sethdlc hdlc0 private |
126 | 126 | ||
127 | The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS. | 127 | The hardware driver has to be build with #define DEBUG_RINGS. |
128 | Attaching this info to bug reports would be helpful. Anyway, let me know | 128 | Attaching this info to bug reports would be helpful. Anyway, let me know |
129 | if you have problems using this. | 129 | if you have problems using this. |
130 | 130 | ||
131 | For patches and other info look at http://hq.pm.waw.pl/hdlc/ | 131 | For patches and other info look at: |
132 | <http://www.kernel.org/pub/linux/utils/net/hdlc/>. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 5b8483334de1..65ad8251e4bc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -239,6 +239,12 @@ L: linux-usb-devel@lists.sourceforge.net | |||
239 | W: http://www.linux-usb.org/SpeedTouch/ | 239 | W: http://www.linux-usb.org/SpeedTouch/ |
240 | S: Maintained | 240 | S: Maintained |
241 | 241 | ||
242 | ALI1563 I2C DRIVER | ||
243 | P: Rudolf Marek | ||
244 | M: r.marek@sh.cvut.cz | ||
245 | L: sensors@stimpy.netroedge.com | ||
246 | S: Maintained | ||
247 | |||
242 | ALPHA PORT | 248 | ALPHA PORT |
243 | P: Richard Henderson | 249 | P: Richard Henderson |
244 | M: rth@twiddle.net | 250 | M: rth@twiddle.net |
@@ -1023,8 +1029,8 @@ W: http://www.ia64-linux.org/ | |||
1023 | S: Maintained | 1029 | S: Maintained |
1024 | 1030 | ||
1025 | SN-IA64 (Itanium) SUB-PLATFORM | 1031 | SN-IA64 (Itanium) SUB-PLATFORM |
1026 | P: Jesse Barnes | 1032 | P: Greg Edwards |
1027 | M: jbarnes@sgi.com | 1033 | M: edwardsg@sgi.com |
1028 | L: linux-altix@sgi.com | 1034 | L: linux-altix@sgi.com |
1029 | L: linux-ia64@vger.kernel.org | 1035 | L: linux-ia64@vger.kernel.org |
1030 | W: http://www.sgi.com/altix | 1036 | W: http://www.sgi.com/altix |
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 134aec1c6d19..b5f83e9f04db 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c | |||
@@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void); | |||
54 | void default_idle(void) | 54 | void default_idle(void) |
55 | { | 55 | { |
56 | while(1) { | 56 | while(1) { |
57 | if (need_resched()) { | 57 | if (!need_resched()) { |
58 | local_irq_enable(); | 58 | local_irq_enable(); |
59 | __asm__("sleep"); | 59 | __asm__("sleep"); |
60 | local_irq_disable(); | 60 | local_irq_disable(); |
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index f25ffd74235c..0f1eb507233b 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig | |||
@@ -23,7 +23,7 @@ config X86_ACPI_CPUFREQ | |||
23 | If in doubt, say N. | 23 | If in doubt, say N. |
24 | 24 | ||
25 | config ELAN_CPUFREQ | 25 | config ELAN_CPUFREQ |
26 | tristate "AMD Elan" | 26 | tristate "AMD Elan SC400 and SC410" |
27 | select CPU_FREQ_TABLE | 27 | select CPU_FREQ_TABLE |
28 | depends on X86_ELAN | 28 | depends on X86_ELAN |
29 | ---help--- | 29 | ---help--- |
@@ -38,6 +38,18 @@ config ELAN_CPUFREQ | |||
38 | 38 | ||
39 | If in doubt, say N. | 39 | If in doubt, say N. |
40 | 40 | ||
41 | config SC520_CPUFREQ | ||
42 | tristate "AMD Elan SC520" | ||
43 | select CPU_FREQ_TABLE | ||
44 | depends on X86_ELAN | ||
45 | ---help--- | ||
46 | This adds the CPUFreq driver for AMD Elan SC520 processor. | ||
47 | |||
48 | For details, take a look at <file:Documentation/cpu-freq/>. | ||
49 | |||
50 | If in doubt, say N. | ||
51 | |||
52 | |||
41 | config X86_POWERNOW_K6 | 53 | config X86_POWERNOW_K6 |
42 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" | 54 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" |
43 | select CPU_FREQ_TABLE | 55 | select CPU_FREQ_TABLE |
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile index a922e97aeedd..2e894f1c8910 100644 --- a/arch/i386/kernel/cpu/cpufreq/Makefile +++ b/arch/i386/kernel/cpu/cpufreq/Makefile | |||
@@ -3,6 +3,7 @@ obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o | |||
3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o | 3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o |
4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o | 4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o |
5 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o | 5 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o |
6 | obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o | ||
6 | obj-$(CONFIG_X86_LONGRUN) += longrun.o | 7 | obj-$(CONFIG_X86_LONGRUN) += longrun.o |
7 | obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o | 8 | obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o |
8 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o | 9 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o |
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index ab0f9f5aac11..04e3563da4fe 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/cpufreq.h> | 29 | #include <linux/cpufreq.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/pci.h> | ||
32 | 33 | ||
33 | #include <asm/msr.h> | 34 | #include <asm/msr.h> |
34 | #include <asm/timex.h> | 35 | #include <asm/timex.h> |
@@ -119,7 +120,13 @@ static int longhaul_get_cpu_mult(void) | |||
119 | static void do_powersaver(union msr_longhaul *longhaul, | 120 | static void do_powersaver(union msr_longhaul *longhaul, |
120 | unsigned int clock_ratio_index) | 121 | unsigned int clock_ratio_index) |
121 | { | 122 | { |
123 | struct pci_dev *dev; | ||
124 | unsigned long flags; | ||
125 | unsigned int tmp_mask; | ||
122 | int version; | 126 | int version; |
127 | int i; | ||
128 | u16 pci_cmd; | ||
129 | u16 cmd_state[64]; | ||
123 | 130 | ||
124 | switch (cpu_model) { | 131 | switch (cpu_model) { |
125 | case CPU_EZRA_T: | 132 | case CPU_EZRA_T: |
@@ -137,17 +144,58 @@ static void do_powersaver(union msr_longhaul *longhaul, | |||
137 | longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; | 144 | longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; |
138 | longhaul->bits.EnableSoftBusRatio = 1; | 145 | longhaul->bits.EnableSoftBusRatio = 1; |
139 | longhaul->bits.RevisionKey = 0; | 146 | longhaul->bits.RevisionKey = 0; |
140 | local_irq_disable(); | 147 | |
141 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 148 | preempt_disable(); |
149 | local_irq_save(flags); | ||
150 | |||
151 | /* | ||
152 | * get current pci bus master state for all devices | ||
153 | * and clear bus master bit | ||
154 | */ | ||
155 | dev = NULL; | ||
156 | i = 0; | ||
157 | do { | ||
158 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
159 | if (dev != NULL) { | ||
160 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
161 | cmd_state[i++] = pci_cmd; | ||
162 | pci_cmd &= ~PCI_COMMAND_MASTER; | ||
163 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
164 | } | ||
165 | } while (dev != NULL); | ||
166 | |||
167 | tmp_mask=inb(0x21); /* works on C3. save mask. */ | ||
168 | outb(0xFE,0x21); /* TMR0 only */ | ||
169 | outb(0xFF,0x80); /* delay */ | ||
170 | |||
142 | local_irq_enable(); | 171 | local_irq_enable(); |
172 | |||
173 | __hlt(); | ||
174 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | ||
143 | __hlt(); | 175 | __hlt(); |
144 | 176 | ||
177 | local_irq_disable(); | ||
178 | |||
179 | outb(tmp_mask,0x21); /* restore mask */ | ||
180 | |||
181 | /* restore pci bus master state for all devices */ | ||
182 | dev = NULL; | ||
183 | i = 0; | ||
184 | do { | ||
185 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
186 | if (dev != NULL) { | ||
187 | pci_cmd = cmd_state[i++]; | ||
188 | pci_write_config_byte(dev, PCI_COMMAND, pci_cmd); | ||
189 | } | ||
190 | } while (dev != NULL); | ||
191 | local_irq_restore(flags); | ||
192 | preempt_enable(); | ||
193 | |||
194 | /* disable bus ratio bit */ | ||
145 | rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 195 | rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
146 | longhaul->bits.EnableSoftBusRatio = 0; | 196 | longhaul->bits.EnableSoftBusRatio = 0; |
147 | longhaul->bits.RevisionKey = version; | 197 | longhaul->bits.RevisionKey = version; |
148 | local_irq_disable(); | ||
149 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 198 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
150 | local_irq_enable(); | ||
151 | } | 199 | } |
152 | 200 | ||
153 | /** | 201 | /** |
@@ -578,7 +626,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
578 | longhaul_setup_voltagescaling(); | 626 | longhaul_setup_voltagescaling(); |
579 | 627 | ||
580 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 628 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
581 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 629 | policy->cpuinfo.transition_latency = 200000; /* nsec */ |
582 | policy->cur = calc_speed(longhaul_get_cpu_mult()); | 630 | policy->cur = calc_speed(longhaul_get_cpu_mult()); |
583 | 631 | ||
584 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); | 632 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 913f652623d9..5c530064eb74 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/dmi.h> | 23 | #include <linux/dmi.h> |
24 | 24 | ||
25 | #include <asm/msr.h> | 25 | #include <asm/msr.h> |
26 | #include <asm/timer.h> | ||
26 | #include <asm/timex.h> | 27 | #include <asm/timex.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
@@ -586,13 +587,17 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
586 | 587 | ||
587 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); | 588 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); |
588 | 589 | ||
589 | /* A K7 with powernow technology is set to max frequency by BIOS */ | 590 | /* recalibrate cpu_khz */ |
590 | fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID]; | 591 | result = recalibrate_cpu_khz(); |
592 | if (result) | ||
593 | return result; | ||
594 | |||
595 | fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; | ||
591 | if (!fsb) { | 596 | if (!fsb) { |
592 | printk(KERN_WARNING PFX "can not determine bus frequency\n"); | 597 | printk(KERN_WARNING PFX "can not determine bus frequency\n"); |
593 | return -EINVAL; | 598 | return -EINVAL; |
594 | } | 599 | } |
595 | dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000); | 600 | dprintk("FSB: %3dMHz\n", fsb/1000); |
596 | 601 | ||
597 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { | 602 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { |
598 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); | 603 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index a65ff7e32e5d..10cc096c0ade 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * GNU general public license version 2. See "COPYING" or | 4 | * GNU general public license version 2. See "COPYING" or |
5 | * http://www.gnu.org/licenses/gpl.html | 5 | * http://www.gnu.org/licenses/gpl.html |
6 | * | 6 | * |
7 | * Support : paul.devriendt@amd.com | 7 | * Support : mark.langsdorf@amd.com |
8 | * | 8 | * |
9 | * Based on the powernow-k7.c module written by Dave Jones. | 9 | * Based on the powernow-k7.c module written by Dave Jones. |
10 | * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs | 10 | * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs |
@@ -15,12 +15,13 @@ | |||
15 | * | 15 | * |
16 | * Valuable input gratefully received from Dave Jones, Pavel Machek, | 16 | * Valuable input gratefully received from Dave Jones, Pavel Machek, |
17 | * Dominik Brodowski, and others. | 17 | * Dominik Brodowski, and others. |
18 | * Originally developed by Paul Devriendt. | ||
18 | * Processor information obtained from Chapter 9 (Power and Thermal Management) | 19 | * Processor information obtained from Chapter 9 (Power and Thermal Management) |
19 | * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD | 20 | * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD |
20 | * Opteron Processors" available for download from www.amd.com | 21 | * Opteron Processors" available for download from www.amd.com |
21 | * | 22 | * |
22 | * Tables for specific CPUs can be infrerred from | 23 | * Tables for specific CPUs can be infrerred from |
23 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf | 24 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf |
24 | */ | 25 | */ |
25 | 26 | ||
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -30,6 +31,7 @@ | |||
30 | #include <linux/cpufreq.h> | 31 | #include <linux/cpufreq.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/cpumask.h> | ||
33 | 35 | ||
34 | #include <asm/msr.h> | 36 | #include <asm/msr.h> |
35 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -42,7 +44,7 @@ | |||
42 | 44 | ||
43 | #define PFX "powernow-k8: " | 45 | #define PFX "powernow-k8: " |
44 | #define BFX PFX "BIOS error: " | 46 | #define BFX PFX "BIOS error: " |
45 | #define VERSION "version 1.00.09e" | 47 | #define VERSION "version 1.40.2" |
46 | #include "powernow-k8.h" | 48 | #include "powernow-k8.h" |
47 | 49 | ||
48 | /* serialize freq changes */ | 50 | /* serialize freq changes */ |
@@ -50,6 +52,10 @@ static DECLARE_MUTEX(fidvid_sem); | |||
50 | 52 | ||
51 | static struct powernow_k8_data *powernow_data[NR_CPUS]; | 53 | static struct powernow_k8_data *powernow_data[NR_CPUS]; |
52 | 54 | ||
55 | #ifndef CONFIG_SMP | ||
56 | static cpumask_t cpu_core_map[1]; | ||
57 | #endif | ||
58 | |||
53 | /* Return a frequency in MHz, given an input fid */ | 59 | /* Return a frequency in MHz, given an input fid */ |
54 | static u32 find_freq_from_fid(u32 fid) | 60 | static u32 find_freq_from_fid(u32 fid) |
55 | { | 61 | { |
@@ -274,11 +280,18 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
274 | { | 280 | { |
275 | u32 rvosteps = data->rvo; | 281 | u32 rvosteps = data->rvo; |
276 | u32 savefid = data->currfid; | 282 | u32 savefid = data->currfid; |
283 | u32 maxvid, lo; | ||
277 | 284 | ||
278 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", | 285 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", |
279 | smp_processor_id(), | 286 | smp_processor_id(), |
280 | data->currfid, data->currvid, reqvid, data->rvo); | 287 | data->currfid, data->currvid, reqvid, data->rvo); |
281 | 288 | ||
289 | rdmsr(MSR_FIDVID_STATUS, lo, maxvid); | ||
290 | maxvid = 0x1f & (maxvid >> 16); | ||
291 | dprintk("ph1 maxvid=0x%x\n", maxvid); | ||
292 | if (reqvid < maxvid) /* lower numbers are higher voltages */ | ||
293 | reqvid = maxvid; | ||
294 | |||
282 | while (data->currvid > reqvid) { | 295 | while (data->currvid > reqvid) { |
283 | dprintk("ph1: curr 0x%x, req vid 0x%x\n", | 296 | dprintk("ph1: curr 0x%x, req vid 0x%x\n", |
284 | data->currvid, reqvid); | 297 | data->currvid, reqvid); |
@@ -286,8 +299,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
286 | return 1; | 299 | return 1; |
287 | } | 300 | } |
288 | 301 | ||
289 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { | 302 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { |
290 | if (data->currvid == 0) { | 303 | if (data->currvid == maxvid) { |
291 | rvosteps = 0; | 304 | rvosteps = 0; |
292 | } else { | 305 | } else { |
293 | dprintk("ph1: changing vid for rvo, req 0x%x\n", | 306 | dprintk("ph1: changing vid for rvo, req 0x%x\n", |
@@ -671,7 +684,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
671 | * BIOS and Kernel Developer's Guide, which is available on | 684 | * BIOS and Kernel Developer's Guide, which is available on |
672 | * www.amd.com | 685 | * www.amd.com |
673 | */ | 686 | */ |
674 | printk(KERN_ERR PFX "BIOS error - no PSB\n"); | 687 | printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n"); |
675 | return -ENODEV; | 688 | return -ENODEV; |
676 | } | 689 | } |
677 | 690 | ||
@@ -695,7 +708,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
695 | struct cpufreq_frequency_table *powernow_table; | 708 | struct cpufreq_frequency_table *powernow_table; |
696 | 709 | ||
697 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 710 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
698 | dprintk("register performance failed\n"); | 711 | dprintk("register performance failed: bad ACPI data\n"); |
699 | return -EIO; | 712 | return -EIO; |
700 | } | 713 | } |
701 | 714 | ||
@@ -746,22 +759,23 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
746 | continue; | 759 | continue; |
747 | } | 760 | } |
748 | 761 | ||
749 | if (fid < HI_FID_TABLE_BOTTOM) { | 762 | /* verify only 1 entry from the lo frequency table */ |
750 | if (cntlofreq) { | 763 | if (fid < HI_FID_TABLE_BOTTOM) { |
751 | /* if both entries are the same, ignore this | 764 | if (cntlofreq) { |
752 | * one... | 765 | /* if both entries are the same, ignore this |
753 | */ | 766 | * one... |
754 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || | 767 | */ |
755 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { | 768 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || |
756 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); | 769 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { |
757 | goto err_out_mem; | 770 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); |
758 | } | 771 | goto err_out_mem; |
759 | 772 | } | |
760 | dprintk("double low frequency table entry, ignoring it.\n"); | 773 | |
761 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 774 | dprintk("double low frequency table entry, ignoring it.\n"); |
762 | continue; | 775 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
763 | } else | 776 | continue; |
764 | cntlofreq = i; | 777 | } else |
778 | cntlofreq = i; | ||
765 | } | 779 | } |
766 | 780 | ||
767 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { | 781 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { |
@@ -816,7 +830,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
816 | { | 830 | { |
817 | u32 fid; | 831 | u32 fid; |
818 | u32 vid; | 832 | u32 vid; |
819 | int res; | 833 | int res, i; |
820 | struct cpufreq_freqs freqs; | 834 | struct cpufreq_freqs freqs; |
821 | 835 | ||
822 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); | 836 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); |
@@ -841,7 +855,8 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
841 | } | 855 | } |
842 | 856 | ||
843 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 857 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { |
844 | printk("ignoring illegal change in lo freq table-%x to 0x%x\n", | 858 | printk(KERN_ERR PFX |
859 | "ignoring illegal change in lo freq table-%x to 0x%x\n", | ||
845 | data->currfid, fid); | 860 | data->currfid, fid); |
846 | return 1; | 861 | return 1; |
847 | } | 862 | } |
@@ -850,18 +865,20 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
850 | smp_processor_id(), fid, vid); | 865 | smp_processor_id(), fid, vid); |
851 | 866 | ||
852 | freqs.cpu = data->cpu; | 867 | freqs.cpu = data->cpu; |
853 | |||
854 | freqs.old = find_khz_freq_from_fid(data->currfid); | 868 | freqs.old = find_khz_freq_from_fid(data->currfid); |
855 | freqs.new = find_khz_freq_from_fid(fid); | 869 | freqs.new = find_khz_freq_from_fid(fid); |
856 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 870 | for_each_cpu_mask(i, cpu_core_map[data->cpu]) { |
871 | freqs.cpu = i; | ||
872 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
873 | } | ||
857 | 874 | ||
858 | down(&fidvid_sem); | ||
859 | res = transition_fid_vid(data, fid, vid); | 875 | res = transition_fid_vid(data, fid, vid); |
860 | up(&fidvid_sem); | ||
861 | 876 | ||
862 | freqs.new = find_khz_freq_from_fid(data->currfid); | 877 | freqs.new = find_khz_freq_from_fid(data->currfid); |
863 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 878 | for_each_cpu_mask(i, cpu_core_map[data->cpu]) { |
864 | 879 | freqs.cpu = i; | |
880 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
881 | } | ||
865 | return res; | 882 | return res; |
866 | } | 883 | } |
867 | 884 | ||
@@ -874,6 +891,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
874 | u32 checkvid = data->currvid; | 891 | u32 checkvid = data->currvid; |
875 | unsigned int newstate; | 892 | unsigned int newstate; |
876 | int ret = -EIO; | 893 | int ret = -EIO; |
894 | int i; | ||
877 | 895 | ||
878 | /* only run on specific CPU from here on */ | 896 | /* only run on specific CPU from here on */ |
879 | oldmask = current->cpus_allowed; | 897 | oldmask = current->cpus_allowed; |
@@ -902,22 +920,41 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
902 | data->currfid, data->currvid); | 920 | data->currfid, data->currvid); |
903 | 921 | ||
904 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { | 922 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { |
905 | printk(KERN_ERR PFX | 923 | printk(KERN_INFO PFX |
906 | "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n", | 924 | "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", |
907 | checkfid, data->currfid, checkvid, data->currvid); | 925 | checkfid, data->currfid, checkvid, data->currvid); |
908 | } | 926 | } |
909 | 927 | ||
910 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) | 928 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) |
911 | goto err_out; | 929 | goto err_out; |
912 | 930 | ||
931 | down(&fidvid_sem); | ||
932 | |||
933 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
934 | /* make sure the sibling is initialized */ | ||
935 | if (!powernow_data[i]) { | ||
936 | ret = 0; | ||
937 | up(&fidvid_sem); | ||
938 | goto err_out; | ||
939 | } | ||
940 | } | ||
941 | |||
913 | powernow_k8_acpi_pst_values(data, newstate); | 942 | powernow_k8_acpi_pst_values(data, newstate); |
914 | 943 | ||
915 | if (transition_frequency(data, newstate)) { | 944 | if (transition_frequency(data, newstate)) { |
916 | printk(KERN_ERR PFX "transition frequency failed\n"); | 945 | printk(KERN_ERR PFX "transition frequency failed\n"); |
917 | ret = 1; | 946 | ret = 1; |
947 | up(&fidvid_sem); | ||
918 | goto err_out; | 948 | goto err_out; |
919 | } | 949 | } |
920 | 950 | ||
951 | /* Update all the fid/vids of our siblings */ | ||
952 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
953 | powernow_data[i]->currvid = data->currvid; | ||
954 | powernow_data[i]->currfid = data->currfid; | ||
955 | } | ||
956 | up(&fidvid_sem); | ||
957 | |||
921 | pol->cur = find_khz_freq_from_fid(data->currfid); | 958 | pol->cur = find_khz_freq_from_fid(data->currfid); |
922 | ret = 0; | 959 | ret = 0; |
923 | 960 | ||
@@ -962,7 +999,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
962 | */ | 999 | */ |
963 | 1000 | ||
964 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { | 1001 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { |
965 | printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n"); | 1002 | printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); |
966 | kfree(data); | 1003 | kfree(data); |
967 | return -ENODEV; | 1004 | return -ENODEV; |
968 | } | 1005 | } |
@@ -1003,6 +1040,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1003 | schedule(); | 1040 | schedule(); |
1004 | 1041 | ||
1005 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1042 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; |
1043 | pol->cpus = cpu_core_map[pol->cpu]; | ||
1006 | 1044 | ||
1007 | /* Take a crude guess here. | 1045 | /* Take a crude guess here. |
1008 | * That guess was in microseconds, so multiply with 1000 */ | 1046 | * That guess was in microseconds, so multiply with 1000 */ |
@@ -1069,7 +1107,7 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1069 | return 0; | 1107 | return 0; |
1070 | } | 1108 | } |
1071 | preempt_disable(); | 1109 | preempt_disable(); |
1072 | 1110 | ||
1073 | if (query_current_values_with_pending_wait(data)) | 1111 | if (query_current_values_with_pending_wait(data)) |
1074 | goto out; | 1112 | goto out; |
1075 | 1113 | ||
@@ -1127,9 +1165,10 @@ static void __exit powernowk8_exit(void) | |||
1127 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1165 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1128 | } | 1166 | } |
1129 | 1167 | ||
1130 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>"); | 1168 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com."); |
1131 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1169 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
1132 | MODULE_LICENSE("GPL"); | 1170 | MODULE_LICENSE("GPL"); |
1133 | 1171 | ||
1134 | late_initcall(powernowk8_init); | 1172 | late_initcall(powernowk8_init); |
1135 | module_exit(powernowk8_exit); | 1173 | module_exit(powernowk8_exit); |
1174 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 63ebc8470f52..9ed5bf221cb7 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -174,3 +174,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi | |||
174 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); | 174 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); |
175 | 175 | ||
176 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); | 176 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); |
177 | |||
178 | #ifndef for_each_cpu_mask | ||
179 | #define for_each_cpu_mask(i,mask) for (i=0;i<1;i++) | ||
180 | #endif | ||
181 | |||
182 | #ifdef CONFIG_SMP | ||
183 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | ||
184 | { | ||
185 | } | ||
186 | #else | ||
187 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | ||
188 | { | ||
189 | cpu_set(0, cpu_sharedcore_mask[0]); | ||
190 | } | ||
191 | #endif | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c new file mode 100644 index 000000000000..ef457d50f4ac --- /dev/null +++ b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * sc520_freq.c: cpufreq driver for the AMD Elan sc520 | ||
3 | * | ||
4 | * Copyright (C) 2005 Sean Young <sean@mess.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * Based on elanfreq.c | ||
12 | * | ||
13 | * 2005-03-30: - initial revision | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/cpufreq.h> | ||
22 | |||
23 | #include <asm/msr.h> | ||
24 | #include <asm/timex.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #define MMCR_BASE 0xfffef000 /* The default base address */ | ||
28 | #define OFFS_CPUCTL 0x2 /* CPU Control Register */ | ||
29 | |||
30 | static __u8 __iomem *cpuctl; | ||
31 | |||
32 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg) | ||
33 | |||
34 | static struct cpufreq_frequency_table sc520_freq_table[] = { | ||
35 | {0x01, 100000}, | ||
36 | {0x02, 133000}, | ||
37 | {0, CPUFREQ_TABLE_END}, | ||
38 | }; | ||
39 | |||
40 | static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | ||
41 | { | ||
42 | u8 clockspeed_reg = *cpuctl; | ||
43 | |||
44 | switch (clockspeed_reg & 0x03) { | ||
45 | default: | ||
46 | printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg); | ||
47 | case 0x01: | ||
48 | return 100000; | ||
49 | case 0x02: | ||
50 | return 133000; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | static void sc520_freq_set_cpu_state (unsigned int state) | ||
55 | { | ||
56 | |||
57 | struct cpufreq_freqs freqs; | ||
58 | u8 clockspeed_reg; | ||
59 | |||
60 | freqs.old = sc520_freq_get_cpu_frequency(0); | ||
61 | freqs.new = sc520_freq_table[state].frequency; | ||
62 | freqs.cpu = 0; /* AMD Elan is UP */ | ||
63 | |||
64 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
65 | |||
66 | dprintk("attempting to set frequency to %i kHz\n", | ||
67 | sc520_freq_table[state].frequency); | ||
68 | |||
69 | local_irq_disable(); | ||
70 | |||
71 | clockspeed_reg = *cpuctl & ~0x03; | ||
72 | *cpuctl = clockspeed_reg | sc520_freq_table[state].index; | ||
73 | |||
74 | local_irq_enable(); | ||
75 | |||
76 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
77 | }; | ||
78 | |||
79 | static int sc520_freq_verify (struct cpufreq_policy *policy) | ||
80 | { | ||
81 | return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); | ||
82 | } | ||
83 | |||
84 | static int sc520_freq_target (struct cpufreq_policy *policy, | ||
85 | unsigned int target_freq, | ||
86 | unsigned int relation) | ||
87 | { | ||
88 | unsigned int newstate = 0; | ||
89 | |||
90 | if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate)) | ||
91 | return -EINVAL; | ||
92 | |||
93 | sc520_freq_set_cpu_state(newstate); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | |||
99 | /* | ||
100 | * Module init and exit code | ||
101 | */ | ||
102 | |||
103 | static int sc520_freq_cpu_init(struct cpufreq_policy *policy) | ||
104 | { | ||
105 | struct cpuinfo_x86 *c = cpu_data; | ||
106 | int result; | ||
107 | |||
108 | /* capability check */ | ||
109 | if (c->x86_vendor != X86_VENDOR_AMD || | ||
110 | c->x86 != 4 || c->x86_model != 9) | ||
111 | return -ENODEV; | ||
112 | |||
113 | /* cpuinfo and default policy values */ | ||
114 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
115 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
116 | policy->cur = sc520_freq_get_cpu_frequency(0); | ||
117 | |||
118 | result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); | ||
119 | if (result) | ||
120 | return (result); | ||
121 | |||
122 | cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | |||
128 | static int sc520_freq_cpu_exit(struct cpufreq_policy *policy) | ||
129 | { | ||
130 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | |||
135 | static struct freq_attr* sc520_freq_attr[] = { | ||
136 | &cpufreq_freq_attr_scaling_available_freqs, | ||
137 | NULL, | ||
138 | }; | ||
139 | |||
140 | |||
141 | static struct cpufreq_driver sc520_freq_driver = { | ||
142 | .get = sc520_freq_get_cpu_frequency, | ||
143 | .verify = sc520_freq_verify, | ||
144 | .target = sc520_freq_target, | ||
145 | .init = sc520_freq_cpu_init, | ||
146 | .exit = sc520_freq_cpu_exit, | ||
147 | .name = "sc520_freq", | ||
148 | .owner = THIS_MODULE, | ||
149 | .attr = sc520_freq_attr, | ||
150 | }; | ||
151 | |||
152 | |||
153 | static int __init sc520_freq_init(void) | ||
154 | { | ||
155 | struct cpuinfo_x86 *c = cpu_data; | ||
156 | |||
157 | /* Test if we have the right hardware */ | ||
158 | if(c->x86_vendor != X86_VENDOR_AMD || | ||
159 | c->x86 != 4 || c->x86_model != 9) { | ||
160 | dprintk("no Elan SC520 processor found!\n"); | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); | ||
164 | if(!cpuctl) { | ||
165 | printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); | ||
166 | return -ENOMEM; | ||
167 | } | ||
168 | |||
169 | return cpufreq_register_driver(&sc520_freq_driver); | ||
170 | } | ||
171 | |||
172 | |||
173 | static void __exit sc520_freq_exit(void) | ||
174 | { | ||
175 | cpufreq_unregister_driver(&sc520_freq_driver); | ||
176 | iounmap(cpuctl); | ||
177 | } | ||
178 | |||
179 | |||
180 | MODULE_LICENSE("GPL"); | ||
181 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
182 | MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU"); | ||
183 | |||
184 | module_init(sc520_freq_init); | ||
185 | module_exit(sc520_freq_exit); | ||
186 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 07d5612dc00f..7dcbf70fc16f 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -54,6 +54,8 @@ enum { | |||
54 | CPU_DOTHAN_A1, | 54 | CPU_DOTHAN_A1, |
55 | CPU_DOTHAN_A2, | 55 | CPU_DOTHAN_A2, |
56 | CPU_DOTHAN_B0, | 56 | CPU_DOTHAN_B0, |
57 | CPU_MP4HT_D0, | ||
58 | CPU_MP4HT_E0, | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | static const struct cpu_id cpu_ids[] = { | 61 | static const struct cpu_id cpu_ids[] = { |
@@ -61,6 +63,8 @@ static const struct cpu_id cpu_ids[] = { | |||
61 | [CPU_DOTHAN_A1] = { 6, 13, 1 }, | 63 | [CPU_DOTHAN_A1] = { 6, 13, 1 }, |
62 | [CPU_DOTHAN_A2] = { 6, 13, 2 }, | 64 | [CPU_DOTHAN_A2] = { 6, 13, 2 }, |
63 | [CPU_DOTHAN_B0] = { 6, 13, 6 }, | 65 | [CPU_DOTHAN_B0] = { 6, 13, 6 }, |
66 | [CPU_MP4HT_D0] = {15, 3, 4 }, | ||
67 | [CPU_MP4HT_E0] = {15, 4, 1 }, | ||
64 | }; | 68 | }; |
65 | #define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) | 69 | #define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) |
66 | 70 | ||
@@ -226,6 +230,8 @@ static struct cpu_model models[] = | |||
226 | { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, | 230 | { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, |
227 | { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, | 231 | { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, |
228 | { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, | 232 | { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, |
233 | { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, | ||
234 | { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, | ||
229 | 235 | ||
230 | { NULL, } | 236 | { NULL, } |
231 | }; | 237 | }; |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index 8ba430a9c3a2..d368b3f5fce8 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | |||
@@ -336,7 +336,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
336 | if (!prev_speed) | 336 | if (!prev_speed) |
337 | return -EIO; | 337 | return -EIO; |
338 | 338 | ||
339 | dprintk("previous seped is %u\n", prev_speed); | 339 | dprintk("previous speed is %u\n", prev_speed); |
340 | 340 | ||
341 | local_irq_save(flags); | 341 | local_irq_save(flags); |
342 | 342 | ||
@@ -348,7 +348,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
348 | goto out; | 348 | goto out; |
349 | } | 349 | } |
350 | 350 | ||
351 | dprintk("low seped is %u\n", *low_speed); | 351 | dprintk("low speed is %u\n", *low_speed); |
352 | 352 | ||
353 | /* switch to high state */ | 353 | /* switch to high state */ |
354 | set_state(SPEEDSTEP_HIGH); | 354 | set_state(SPEEDSTEP_HIGH); |
@@ -358,7 +358,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
358 | goto out; | 358 | goto out; |
359 | } | 359 | } |
360 | 360 | ||
361 | dprintk("high seped is %u\n", *high_speed); | 361 | dprintk("high speed is %u\n", *high_speed); |
362 | 362 | ||
363 | if (*low_speed == *high_speed) { | 363 | if (*low_speed == *high_speed) { |
364 | ret = -ENODEV; | 364 | ret = -ENODEV; |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index 79440b3f087e..b25fb6b635ae 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | |||
@@ -357,6 +357,9 @@ static int __init speedstep_init(void) | |||
357 | case SPEEDSTEP_PROCESSOR_PIII_C: | 357 | case SPEEDSTEP_PROCESSOR_PIII_C: |
358 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: | 358 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: |
359 | break; | 359 | break; |
360 | case SPEEDSTEP_PROCESSOR_P4M: | ||
361 | printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n"); | ||
362 | break; | ||
360 | default: | 363 | default: |
361 | speedstep_processor = 0; | 364 | speedstep_processor = 0; |
362 | } | 365 | } |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index aeb5b4ef8c8b..a710dc4eb20e 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -118,7 +118,7 @@ struct _cpuid4_info { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | #define MAX_CACHE_LEAVES 4 | 120 | #define MAX_CACHE_LEAVES 4 |
121 | static unsigned short __devinitdata num_cache_leaves; | 121 | static unsigned short num_cache_leaves; |
122 | 122 | ||
123 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | 123 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) |
124 | { | 124 | { |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 945ec73163c8..2bfbddebdbf8 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -1502,11 +1502,13 @@ void __init setup_arch(char **cmdline_p) | |||
1502 | if (efi_enabled) | 1502 | if (efi_enabled) |
1503 | efi_map_memmap(); | 1503 | efi_map_memmap(); |
1504 | 1504 | ||
1505 | #ifdef CONFIG_ACPI_BOOT | ||
1505 | /* | 1506 | /* |
1506 | * Parse the ACPI tables for possible boot-time SMP configuration. | 1507 | * Parse the ACPI tables for possible boot-time SMP configuration. |
1507 | */ | 1508 | */ |
1508 | acpi_boot_table_init(); | 1509 | acpi_boot_table_init(); |
1509 | acpi_boot_init(); | 1510 | acpi_boot_init(); |
1511 | #endif | ||
1510 | 1512 | ||
1511 | #ifdef CONFIG_X86_LOCAL_APIC | 1513 | #ifdef CONFIG_X86_LOCAL_APIC |
1512 | if (smp_found_config) | 1514 | if (smp_found_config) |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 35bfe138cb1a..bc1bb6919e6a 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -1074,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1074 | cpu_set(cpu, cpu_sibling_map[cpu]); | 1074 | cpu_set(cpu, cpu_sibling_map[cpu]); |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | if (siblings != smp_num_siblings) | 1077 | if (siblings != smp_num_siblings) { |
1078 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); | 1078 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); |
1079 | smp_num_siblings = siblings; | ||
1080 | } | ||
1079 | 1081 | ||
1080 | if (c->x86_num_cores > 1) { | 1082 | if (c->x86_num_cores > 1) { |
1081 | for (i = 0; i < NR_CPUS; i++) { | 1083 | for (i = 0; i < NR_CPUS; i++) { |
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c index f7f90005e22e..8e201219f525 100644 --- a/arch/i386/kernel/timers/common.c +++ b/arch/i386/kernel/timers/common.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/timex.h> | 6 | #include <linux/timex.h> |
7 | #include <linux/errno.h> | 7 | #include <linux/errno.h> |
8 | #include <linux/jiffies.h> | 8 | #include <linux/jiffies.h> |
9 | #include <linux/module.h> | ||
9 | 10 | ||
10 | #include <asm/io.h> | 11 | #include <asm/io.h> |
11 | #include <asm/timer.h> | 12 | #include <asm/timer.h> |
@@ -24,7 +25,7 @@ | |||
24 | 25 | ||
25 | #define CALIBRATE_TIME (5 * 1000020/HZ) | 26 | #define CALIBRATE_TIME (5 * 1000020/HZ) |
26 | 27 | ||
27 | unsigned long __init calibrate_tsc(void) | 28 | unsigned long calibrate_tsc(void) |
28 | { | 29 | { |
29 | mach_prepare_counter(); | 30 | mach_prepare_counter(); |
30 | 31 | ||
@@ -139,7 +140,7 @@ bad_calibration: | |||
139 | #endif | 140 | #endif |
140 | 141 | ||
141 | /* calculate cpu_khz */ | 142 | /* calculate cpu_khz */ |
142 | void __init init_cpu_khz(void) | 143 | void init_cpu_khz(void) |
143 | { | 144 | { |
144 | if (cpu_has_tsc) { | 145 | if (cpu_has_tsc) { |
145 | unsigned long tsc_quotient = calibrate_tsc(); | 146 | unsigned long tsc_quotient = calibrate_tsc(); |
@@ -158,3 +159,4 @@ void __init init_cpu_khz(void) | |||
158 | } | 159 | } |
159 | } | 160 | } |
160 | } | 161 | } |
162 | |||
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 7926d967be00..180444d87824 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -320,6 +320,26 @@ core_initcall(cpufreq_tsc); | |||
320 | static inline void cpufreq_delayed_get(void) { return; } | 320 | static inline void cpufreq_delayed_get(void) { return; } |
321 | #endif | 321 | #endif |
322 | 322 | ||
323 | int recalibrate_cpu_khz(void) | ||
324 | { | ||
325 | #ifndef CONFIG_SMP | ||
326 | unsigned long cpu_khz_old = cpu_khz; | ||
327 | |||
328 | if (cpu_has_tsc) { | ||
329 | init_cpu_khz(); | ||
330 | cpu_data[0].loops_per_jiffy = | ||
331 | cpufreq_scale(cpu_data[0].loops_per_jiffy, | ||
332 | cpu_khz_old, | ||
333 | cpu_khz); | ||
334 | return 0; | ||
335 | } else | ||
336 | return -ENODEV; | ||
337 | #else | ||
338 | return -ENODEV; | ||
339 | #endif | ||
340 | } | ||
341 | EXPORT_SYMBOL(recalibrate_cpu_khz); | ||
342 | |||
323 | static void mark_offset_tsc(void) | 343 | static void mark_offset_tsc(void) |
324 | { | 344 | { |
325 | unsigned long lost,delay; | 345 | unsigned long lost,delay; |
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 247a21c64aea..c1e20d65dd6c 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
@@ -2427,7 +2427,7 @@ sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents, | |||
2427 | { | 2427 | { |
2428 | struct epoll_event *events64 = NULL; | 2428 | struct epoll_event *events64 = NULL; |
2429 | mm_segment_t old_fs = get_fs(); | 2429 | mm_segment_t old_fs = get_fs(); |
2430 | int error, numevents, size; | 2430 | int numevents, size; |
2431 | int evt_idx; | 2431 | int evt_idx; |
2432 | int do_free_pages = 0; | 2432 | int do_free_pages = 0; |
2433 | 2433 | ||
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 81c45d447394..d99316c9be28 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1182,7 +1182,7 @@ ENTRY(notify_resume_user) | |||
1182 | ;; | 1182 | ;; |
1183 | (pNonSys) mov out2=0 // out2==0 => not a syscall | 1183 | (pNonSys) mov out2=0 // out2==0 => not a syscall |
1184 | .fframe 16 | 1184 | .fframe 16 |
1185 | .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) | 1185 | .spillsp ar.unat, 16 |
1186 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | 1186 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it |
1187 | st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch | 1187 | st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch |
1188 | .body | 1188 | .body |
@@ -1208,7 +1208,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend) | |||
1208 | adds out2=8,sp // out2=&sigscratch->ar_pfs | 1208 | adds out2=8,sp // out2=&sigscratch->ar_pfs |
1209 | ;; | 1209 | ;; |
1210 | .fframe 16 | 1210 | .fframe 16 |
1211 | .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) | 1211 | .spillsp ar.unat, 16 |
1212 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | 1212 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it |
1213 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch | 1213 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch |
1214 | .body | 1214 | .body |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 4d6c7b8f667b..736e328b5e61 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1103,8 +1103,6 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) | |||
1103 | return IRQ_HANDLED; | 1103 | return IRQ_HANDLED; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | #endif /* CONFIG_ACPI */ | ||
1107 | |||
1108 | /* | 1106 | /* |
1109 | * ia64_mca_cpe_poll | 1107 | * ia64_mca_cpe_poll |
1110 | * | 1108 | * |
@@ -1122,6 +1120,8 @@ ia64_mca_cpe_poll (unsigned long dummy) | |||
1122 | platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); | 1120 | platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); |
1123 | } | 1121 | } |
1124 | 1122 | ||
1123 | #endif /* CONFIG_ACPI */ | ||
1124 | |||
1125 | /* | 1125 | /* |
1126 | * C portion of the OS INIT handler | 1126 | * C portion of the OS INIT handler |
1127 | * | 1127 | * |
@@ -1390,8 +1390,7 @@ ia64_mca_init(void) | |||
1390 | register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); | 1390 | register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); |
1391 | 1391 | ||
1392 | #ifdef CONFIG_ACPI | 1392 | #ifdef CONFIG_ACPI |
1393 | /* Setup the CPEI/P vector and handler */ | 1393 | /* Setup the CPEI/P handler */ |
1394 | cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); | ||
1395 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); | 1394 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); |
1396 | #endif | 1395 | #endif |
1397 | 1396 | ||
@@ -1436,6 +1435,7 @@ ia64_mca_late_init(void) | |||
1436 | 1435 | ||
1437 | #ifdef CONFIG_ACPI | 1436 | #ifdef CONFIG_ACPI |
1438 | /* Setup the CPEI/P vector and handler */ | 1437 | /* Setup the CPEI/P vector and handler */ |
1438 | cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); | ||
1439 | init_timer(&cpe_poll_timer); | 1439 | init_timer(&cpe_poll_timer); |
1440 | cpe_poll_timer.function = ia64_mca_cpe_poll; | 1440 | cpe_poll_timer.function = ia64_mca_cpe_poll; |
1441 | 1441 | ||
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h index 1dbc7b2497c9..f6d8a010d99b 100644 --- a/arch/ia64/kernel/minstate.h +++ b/arch/ia64/kernel/minstate.h | |||
@@ -41,7 +41,7 @@ | |||
41 | (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ | 41 | (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ |
42 | (pKStk) ld8 r3 = [r3];; \ | 42 | (pKStk) ld8 r3 = [r3];; \ |
43 | (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ | 43 | (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ |
44 | (pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ | 44 | (pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ |
45 | (pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ | 45 | (pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ |
46 | (pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ | 46 | (pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ |
47 | ;; \ | 47 | ;; \ |
@@ -50,7 +50,6 @@ | |||
50 | (pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ | 50 | (pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ |
51 | (pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ | 51 | (pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ |
52 | ;; \ | 52 | ;; \ |
53 | (pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ | ||
54 | (pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ | 53 | (pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ |
55 | ;; \ | 54 | ;; \ |
56 | (pUStk) mov r18=ar.bsp; \ | 55 | (pUStk) mov r18=ar.bsp; \ |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 71c101601e3e..6407bff6bfd7 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * Version Perfmon-2.x is a rewrite of perfmon-1.x | 11 | * Version Perfmon-2.x is a rewrite of perfmon-1.x |
12 | * by Stephane Eranian, Hewlett Packard Co. | 12 | * by Stephane Eranian, Hewlett Packard Co. |
13 | * | 13 | * |
14 | * Copyright (C) 1999-2003, 2005 Hewlett Packard Co | 14 | * Copyright (C) 1999-2005 Hewlett Packard Co |
15 | * Stephane Eranian <eranian@hpl.hp.com> | 15 | * Stephane Eranian <eranian@hpl.hp.com> |
16 | * David Mosberger-Tang <davidm@hpl.hp.com> | 16 | * David Mosberger-Tang <davidm@hpl.hp.com> |
17 | * | 17 | * |
@@ -497,6 +497,9 @@ typedef struct { | |||
497 | static pfm_stats_t pfm_stats[NR_CPUS]; | 497 | static pfm_stats_t pfm_stats[NR_CPUS]; |
498 | static pfm_session_t pfm_sessions; /* global sessions information */ | 498 | static pfm_session_t pfm_sessions; /* global sessions information */ |
499 | 499 | ||
500 | static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED; | ||
501 | static pfm_intr_handler_desc_t *pfm_alt_intr_handler; | ||
502 | |||
500 | static struct proc_dir_entry *perfmon_dir; | 503 | static struct proc_dir_entry *perfmon_dir; |
501 | static pfm_uuid_t pfm_null_uuid = {0,}; | 504 | static pfm_uuid_t pfm_null_uuid = {0,}; |
502 | 505 | ||
@@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info); | |||
606 | DEFINE_PER_CPU(struct task_struct *, pmu_owner); | 609 | DEFINE_PER_CPU(struct task_struct *, pmu_owner); |
607 | DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); | 610 | DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); |
608 | DEFINE_PER_CPU(unsigned long, pmu_activation_number); | 611 | DEFINE_PER_CPU(unsigned long, pmu_activation_number); |
612 | EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info); | ||
609 | 613 | ||
610 | 614 | ||
611 | /* forward declaration */ | 615 | /* forward declaration */ |
@@ -1325,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | |||
1325 | error_conflict: | 1329 | error_conflict: |
1326 | DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", | 1330 | DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", |
1327 | pfm_sessions.pfs_sys_session[cpu]->pid, | 1331 | pfm_sessions.pfs_sys_session[cpu]->pid, |
1328 | smp_processor_id())); | 1332 | cpu)); |
1329 | abort: | 1333 | abort: |
1330 | UNLOCK_PFS(flags); | 1334 | UNLOCK_PFS(flags); |
1331 | 1335 | ||
@@ -5555,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs) | |||
5555 | int ret; | 5559 | int ret; |
5556 | 5560 | ||
5557 | this_cpu = get_cpu(); | 5561 | this_cpu = get_cpu(); |
5558 | min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; | 5562 | if (likely(!pfm_alt_intr_handler)) { |
5559 | max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; | 5563 | min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; |
5564 | max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; | ||
5560 | 5565 | ||
5561 | start_cycles = ia64_get_itc(); | 5566 | start_cycles = ia64_get_itc(); |
5562 | 5567 | ||
5563 | ret = pfm_do_interrupt_handler(irq, arg, regs); | 5568 | ret = pfm_do_interrupt_handler(irq, arg, regs); |
5564 | 5569 | ||
5565 | total_cycles = ia64_get_itc(); | 5570 | total_cycles = ia64_get_itc(); |
5566 | 5571 | ||
5567 | /* | 5572 | /* |
5568 | * don't measure spurious interrupts | 5573 | * don't measure spurious interrupts |
5569 | */ | 5574 | */ |
5570 | if (likely(ret == 0)) { | 5575 | if (likely(ret == 0)) { |
5571 | total_cycles -= start_cycles; | 5576 | total_cycles -= start_cycles; |
5572 | 5577 | ||
5573 | if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; | 5578 | if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; |
5574 | if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; | 5579 | if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; |
5575 | 5580 | ||
5576 | pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; | 5581 | pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; |
5582 | } | ||
5583 | } | ||
5584 | else { | ||
5585 | (*pfm_alt_intr_handler->handler)(irq, arg, regs); | ||
5577 | } | 5586 | } |
5587 | |||
5578 | put_cpu_no_resched(); | 5588 | put_cpu_no_resched(); |
5579 | return IRQ_HANDLED; | 5589 | return IRQ_HANDLED; |
5580 | } | 5590 | } |
@@ -6425,6 +6435,141 @@ static struct irqaction perfmon_irqaction = { | |||
6425 | .name = "perfmon" | 6435 | .name = "perfmon" |
6426 | }; | 6436 | }; |
6427 | 6437 | ||
6438 | static void | ||
6439 | pfm_alt_save_pmu_state(void *data) | ||
6440 | { | ||
6441 | struct pt_regs *regs; | ||
6442 | |||
6443 | regs = ia64_task_regs(current); | ||
6444 | |||
6445 | DPRINT(("called\n")); | ||
6446 | |||
6447 | /* | ||
6448 | * should not be necessary but | ||
6449 | * let's take not risk | ||
6450 | */ | ||
6451 | pfm_clear_psr_up(); | ||
6452 | pfm_clear_psr_pp(); | ||
6453 | ia64_psr(regs)->pp = 0; | ||
6454 | |||
6455 | /* | ||
6456 | * This call is required | ||
6457 | * May cause a spurious interrupt on some processors | ||
6458 | */ | ||
6459 | pfm_freeze_pmu(); | ||
6460 | |||
6461 | ia64_srlz_d(); | ||
6462 | } | ||
6463 | |||
6464 | void | ||
6465 | pfm_alt_restore_pmu_state(void *data) | ||
6466 | { | ||
6467 | struct pt_regs *regs; | ||
6468 | |||
6469 | regs = ia64_task_regs(current); | ||
6470 | |||
6471 | DPRINT(("called\n")); | ||
6472 | |||
6473 | /* | ||
6474 | * put PMU back in state expected | ||
6475 | * by perfmon | ||
6476 | */ | ||
6477 | pfm_clear_psr_up(); | ||
6478 | pfm_clear_psr_pp(); | ||
6479 | ia64_psr(regs)->pp = 0; | ||
6480 | |||
6481 | /* | ||
6482 | * perfmon runs with PMU unfrozen at all times | ||
6483 | */ | ||
6484 | pfm_unfreeze_pmu(); | ||
6485 | |||
6486 | ia64_srlz_d(); | ||
6487 | } | ||
6488 | |||
6489 | int | ||
6490 | pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) | ||
6491 | { | ||
6492 | int ret, i; | ||
6493 | int reserve_cpu; | ||
6494 | |||
6495 | /* some sanity checks */ | ||
6496 | if (hdl == NULL || hdl->handler == NULL) return -EINVAL; | ||
6497 | |||
6498 | /* do the easy test first */ | ||
6499 | if (pfm_alt_intr_handler) return -EBUSY; | ||
6500 | |||
6501 | /* one at a time in the install or remove, just fail the others */ | ||
6502 | if (!spin_trylock(&pfm_alt_install_check)) { | ||
6503 | return -EBUSY; | ||
6504 | } | ||
6505 | |||
6506 | /* reserve our session */ | ||
6507 | for_each_online_cpu(reserve_cpu) { | ||
6508 | ret = pfm_reserve_session(NULL, 1, reserve_cpu); | ||
6509 | if (ret) goto cleanup_reserve; | ||
6510 | } | ||
6511 | |||
6512 | /* save the current system wide pmu states */ | ||
6513 | ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1); | ||
6514 | if (ret) { | ||
6515 | DPRINT(("on_each_cpu() failed: %d\n", ret)); | ||
6516 | goto cleanup_reserve; | ||
6517 | } | ||
6518 | |||
6519 | /* officially change to the alternate interrupt handler */ | ||
6520 | pfm_alt_intr_handler = hdl; | ||
6521 | |||
6522 | spin_unlock(&pfm_alt_install_check); | ||
6523 | |||
6524 | return 0; | ||
6525 | |||
6526 | cleanup_reserve: | ||
6527 | for_each_online_cpu(i) { | ||
6528 | /* don't unreserve more than we reserved */ | ||
6529 | if (i >= reserve_cpu) break; | ||
6530 | |||
6531 | pfm_unreserve_session(NULL, 1, i); | ||
6532 | } | ||
6533 | |||
6534 | spin_unlock(&pfm_alt_install_check); | ||
6535 | |||
6536 | return ret; | ||
6537 | } | ||
6538 | EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt); | ||
6539 | |||
6540 | int | ||
6541 | pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) | ||
6542 | { | ||
6543 | int i; | ||
6544 | int ret; | ||
6545 | |||
6546 | if (hdl == NULL) return -EINVAL; | ||
6547 | |||
6548 | /* cannot remove someone else's handler! */ | ||
6549 | if (pfm_alt_intr_handler != hdl) return -EINVAL; | ||
6550 | |||
6551 | /* one at a time in the install or remove, just fail the others */ | ||
6552 | if (!spin_trylock(&pfm_alt_install_check)) { | ||
6553 | return -EBUSY; | ||
6554 | } | ||
6555 | |||
6556 | pfm_alt_intr_handler = NULL; | ||
6557 | |||
6558 | ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1); | ||
6559 | if (ret) { | ||
6560 | DPRINT(("on_each_cpu() failed: %d\n", ret)); | ||
6561 | } | ||
6562 | |||
6563 | for_each_online_cpu(i) { | ||
6564 | pfm_unreserve_session(NULL, 1, i); | ||
6565 | } | ||
6566 | |||
6567 | spin_unlock(&pfm_alt_install_check); | ||
6568 | |||
6569 | return 0; | ||
6570 | } | ||
6571 | EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt); | ||
6572 | |||
6428 | /* | 6573 | /* |
6429 | * perfmon initialization routine, called from the initcall() table | 6574 | * perfmon initialization routine, called from the initcall() table |
6430 | */ | 6575 | */ |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 907464ee7273..08c8a5eb25ab 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -692,16 +692,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, | |||
692 | unsigned long cfm) | 692 | unsigned long cfm) |
693 | { | 693 | { |
694 | struct unw_frame_info info, prev_info; | 694 | struct unw_frame_info info, prev_info; |
695 | unsigned long ip, pr; | 695 | unsigned long ip, sp, pr; |
696 | 696 | ||
697 | unw_init_from_blocked_task(&info, child); | 697 | unw_init_from_blocked_task(&info, child); |
698 | while (1) { | 698 | while (1) { |
699 | prev_info = info; | 699 | prev_info = info; |
700 | if (unw_unwind(&info) < 0) | 700 | if (unw_unwind(&info) < 0) |
701 | return; | 701 | return; |
702 | if (unw_get_rp(&info, &ip) < 0) | 702 | |
703 | unw_get_sp(&info, &sp); | ||
704 | if ((long)((unsigned long)child + IA64_STK_OFFSET - sp) | ||
705 | < IA64_PT_REGS_SIZE) { | ||
706 | dprintk("ptrace.%s: ran off the top of the kernel " | ||
707 | "stack\n", __FUNCTION__); | ||
708 | return; | ||
709 | } | ||
710 | if (unw_get_pr (&prev_info, &pr) < 0) { | ||
711 | unw_get_rp(&prev_info, &ip); | ||
712 | dprintk("ptrace.%s: failed to read " | ||
713 | "predicate register (ip=0x%lx)\n", | ||
714 | __FUNCTION__, ip); | ||
703 | return; | 715 | return; |
704 | if (ip < FIXADDR_USER_END) | 716 | } |
717 | if (unw_is_intr_frame(&info) | ||
718 | && (pr & (1UL << PRED_USER_STACK))) | ||
705 | break; | 719 | break; |
706 | } | 720 | } |
707 | 721 | ||
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 0d5ee57c9865..3865f088ffa2 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -624,7 +624,7 @@ static struct { | |||
624 | __u16 thread_id; | 624 | __u16 thread_id; |
625 | __u16 proc_fixed_addr; | 625 | __u16 proc_fixed_addr; |
626 | __u8 valid; | 626 | __u8 valid; |
627 | }mt_info[NR_CPUS] __devinit; | 627 | } mt_info[NR_CPUS] __devinitdata; |
628 | 628 | ||
629 | #ifdef CONFIG_HOTPLUG_CPU | 629 | #ifdef CONFIG_HOTPLUG_CPU |
630 | static inline void | 630 | static inline void |
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index a8cf6d8a509c..770fab37928e 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c | |||
@@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un | |||
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | /* | ||
186 | * A zero mmap always succeeds in Linux, independent of whether or not the | ||
187 | * remaining arguments are valid. | ||
188 | */ | ||
189 | if (len == 0) | ||
190 | goto out; | ||
191 | |||
192 | /* Careful about overflows.. */ | 185 | /* Careful about overflows.. */ |
193 | len = PAGE_ALIGN(len); | 186 | len = PAGE_ALIGN(len); |
194 | if (!len || len > TASK_SIZE) { | 187 | if (!len || len > TASK_SIZE) { |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 4fb44984afe6..e64cb8175f7a 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -271,6 +271,8 @@ void __init sn_setup(char **cmdline_p) | |||
271 | int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); | 271 | int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); |
272 | extern void sn_cpu_init(void); | 272 | extern void sn_cpu_init(void); |
273 | 273 | ||
274 | ia64_sn_plat_set_error_handling_features(); | ||
275 | |||
274 | /* | 276 | /* |
275 | * If the generic code has enabled vga console support - lets | 277 | * If the generic code has enabled vga console support - lets |
276 | * get rid of it again. This is a kludge for the fact that ACPI | 278 | * get rid of it again. This is a kludge for the fact that ACPI |
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 2b6c9d32b7a6..c4a33f265dc0 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c | |||
@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void); | |||
45 | */ | 45 | */ |
46 | void default_idle(void) | 46 | void default_idle(void) |
47 | { | 47 | { |
48 | while(1) { | 48 | local_irq_disable(); |
49 | if (need_resched()) | 49 | while (!need_resched()) { |
50 | __asm__("stop #0x2000" : : : "cc"); | 50 | /* This stop will re-enable interrupts */ |
51 | schedule(); | 51 | __asm__("stop #0x2000" : : : "cc"); |
52 | local_irq_disable(); | ||
52 | } | 53 | } |
54 | local_irq_enable(); | ||
53 | } | 55 | } |
54 | 56 | ||
55 | void (*idle)(void) = default_idle; | 57 | void (*idle)(void) = default_idle; |
@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle; | |||
63 | void cpu_idle(void) | 65 | void cpu_idle(void) |
64 | { | 66 | { |
65 | /* endless idle loop with no priority at all */ | 67 | /* endless idle loop with no priority at all */ |
66 | idle(); | 68 | while (1) { |
69 | idle(); | ||
70 | preempt_enable_no_resched(); | ||
71 | schedule(); | ||
72 | preempt_disable(); | ||
73 | } | ||
67 | } | 74 | } |
68 | 75 | ||
69 | void machine_restart(char * __unused) | 76 | void machine_restart(char * __unused) |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 600f23d7fd33..6e6377a69d5b 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -1143,12 +1143,12 @@ config PCI_QSPAN | |||
1143 | 1143 | ||
1144 | config PCI_8260 | 1144 | config PCI_8260 |
1145 | bool | 1145 | bool |
1146 | depends on PCI && 8260 && !8272 | 1146 | depends on PCI && 8260 |
1147 | default y | 1147 | default y |
1148 | 1148 | ||
1149 | config 8260_PCI9 | 1149 | config 8260_PCI9 |
1150 | bool " Enable workaround for MPC826x erratum PCI 9" | 1150 | bool " Enable workaround for MPC826x erratum PCI 9" |
1151 | depends on PCI_8260 | 1151 | depends on PCI_8260 && !ADS8272 |
1152 | default y | 1152 | default y |
1153 | 1153 | ||
1154 | choice | 1154 | choice |
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index f850fb0fb511..c9ac5f5fa9e4 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile | |||
@@ -22,7 +22,8 @@ targets += uImage | |||
22 | $(obj)/uImage: $(obj)/vmlinux.gz | 22 | $(obj)/uImage: $(obj)/vmlinux.gz |
23 | $(Q)rm -f $@ | 23 | $(Q)rm -f $@ |
24 | $(call if_changed,uimage) | 24 | $(call if_changed,uimage) |
25 | @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made') | 25 | @echo -n ' Image: $@ ' |
26 | @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi | ||
26 | 27 | ||
27 | # Files generated that shall be removed upon make clean | 28 | # Files generated that shall be removed upon make clean |
28 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage | 29 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage |
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig index 728bd9e1a8fa..15abebf46b96 100644 --- a/arch/ppc/configs/mpc8555_cds_defconfig +++ b/arch/ppc/configs/mpc8555_cds_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc1 | 3 | # Linux kernel version: 2.6.12-rc4 |
4 | # Thu Jan 20 01:25:35 2005 | 4 | # Tue May 17 11:56:01 2005 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_GENERIC_HARDIRQS=y | 7 | CONFIG_GENERIC_HARDIRQS=y |
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y | |||
11 | CONFIG_PPC=y | 11 | CONFIG_PPC=y |
12 | CONFIG_PPC32=y | 12 | CONFIG_PPC32=y |
13 | CONFIG_GENERIC_NVRAM=y | 13 | CONFIG_GENERIC_NVRAM=y |
14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
14 | 15 | ||
15 | # | 16 | # |
16 | # Code maturity level options | 17 | # Code maturity level options |
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y | |||
18 | CONFIG_EXPERIMENTAL=y | 19 | CONFIG_EXPERIMENTAL=y |
19 | CONFIG_CLEAN_COMPILE=y | 20 | CONFIG_CLEAN_COMPILE=y |
20 | CONFIG_BROKEN_ON_SMP=y | 21 | CONFIG_BROKEN_ON_SMP=y |
22 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
21 | 23 | ||
22 | # | 24 | # |
23 | # General setup | 25 | # General setup |
@@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y | |||
29 | # CONFIG_BSD_PROCESS_ACCT is not set | 31 | # CONFIG_BSD_PROCESS_ACCT is not set |
30 | CONFIG_SYSCTL=y | 32 | CONFIG_SYSCTL=y |
31 | # CONFIG_AUDIT is not set | 33 | # CONFIG_AUDIT is not set |
32 | CONFIG_LOG_BUF_SHIFT=14 | ||
33 | # CONFIG_HOTPLUG is not set | 34 | # CONFIG_HOTPLUG is not set |
34 | CONFIG_KOBJECT_UEVENT=y | 35 | CONFIG_KOBJECT_UEVENT=y |
35 | # CONFIG_IKCONFIG is not set | 36 | # CONFIG_IKCONFIG is not set |
36 | CONFIG_EMBEDDED=y | 37 | CONFIG_EMBEDDED=y |
37 | # CONFIG_KALLSYMS is not set | 38 | # CONFIG_KALLSYMS is not set |
39 | CONFIG_PRINTK=y | ||
40 | CONFIG_BUG=y | ||
41 | CONFIG_BASE_FULL=y | ||
38 | CONFIG_FUTEX=y | 42 | CONFIG_FUTEX=y |
39 | # CONFIG_EPOLL is not set | 43 | # CONFIG_EPOLL is not set |
40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0 | |||
44 | CONFIG_CC_ALIGN_LOOPS=0 | 48 | CONFIG_CC_ALIGN_LOOPS=0 |
45 | CONFIG_CC_ALIGN_JUMPS=0 | 49 | CONFIG_CC_ALIGN_JUMPS=0 |
46 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
51 | CONFIG_BASE_SMALL=0 | ||
47 | 52 | ||
48 | # | 53 | # |
49 | # Loadable module support | 54 | # Loadable module support |
@@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
62 | CONFIG_E500=y | 67 | CONFIG_E500=y |
63 | CONFIG_BOOKE=y | 68 | CONFIG_BOOKE=y |
64 | CONFIG_FSL_BOOKE=y | 69 | CONFIG_FSL_BOOKE=y |
70 | # CONFIG_PHYS_64BIT is not set | ||
65 | CONFIG_SPE=y | 71 | CONFIG_SPE=y |
66 | CONFIG_MATH_EMULATION=y | 72 | CONFIG_MATH_EMULATION=y |
67 | # CONFIG_CPU_FREQ is not set | 73 | # CONFIG_CPU_FREQ is not set |
68 | CONFIG_PPC_GEN550=y | 74 | CONFIG_PPC_GEN550=y |
75 | # CONFIG_PM is not set | ||
69 | CONFIG_85xx=y | 76 | CONFIG_85xx=y |
70 | CONFIG_PPC_INDIRECT_PCI_BE=y | 77 | CONFIG_PPC_INDIRECT_PCI_BE=y |
71 | 78 | ||
@@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y | |||
76 | CONFIG_MPC8555_CDS=y | 83 | CONFIG_MPC8555_CDS=y |
77 | # CONFIG_MPC8560_ADS is not set | 84 | # CONFIG_MPC8560_ADS is not set |
78 | # CONFIG_SBC8560 is not set | 85 | # CONFIG_SBC8560 is not set |
86 | # CONFIG_STX_GP3 is not set | ||
79 | CONFIG_MPC8555=y | 87 | CONFIG_MPC8555=y |
80 | CONFIG_85xx_PCI2=y | 88 | CONFIG_85xx_PCI2=y |
81 | 89 | ||
@@ -90,6 +98,7 @@ CONFIG_CPM2=y | |||
90 | CONFIG_BINFMT_ELF=y | 98 | CONFIG_BINFMT_ELF=y |
91 | # CONFIG_BINFMT_MISC is not set | 99 | # CONFIG_BINFMT_MISC is not set |
92 | # CONFIG_CMDLINE_BOOL is not set | 100 | # CONFIG_CMDLINE_BOOL is not set |
101 | CONFIG_ISA_DMA_API=y | ||
93 | 102 | ||
94 | # | 103 | # |
95 | # Bus options | 104 | # Bus options |
@@ -105,10 +114,6 @@ CONFIG_PCI_NAMES=y | |||
105 | # CONFIG_PCCARD is not set | 114 | # CONFIG_PCCARD is not set |
106 | 115 | ||
107 | # | 116 | # |
108 | # PC-card bridges | ||
109 | # | ||
110 | |||
111 | # | ||
112 | # Advanced setup | 117 | # Advanced setup |
113 | # | 118 | # |
114 | # CONFIG_ADVANCED_OPTIONS is not set | 119 | # CONFIG_ADVANCED_OPTIONS is not set |
@@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y | |||
180 | # | 185 | # |
181 | # ATA/ATAPI/MFM/RLL support | 186 | # ATA/ATAPI/MFM/RLL support |
182 | # | 187 | # |
183 | # CONFIG_IDE is not set | 188 | CONFIG_IDE=y |
189 | CONFIG_BLK_DEV_IDE=y | ||
190 | |||
191 | # | ||
192 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
193 | # | ||
194 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
195 | CONFIG_BLK_DEV_IDEDISK=y | ||
196 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
197 | # CONFIG_BLK_DEV_IDECD is not set | ||
198 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
199 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
200 | # CONFIG_IDE_TASK_IOCTL is not set | ||
201 | |||
202 | # | ||
203 | # IDE chipset support/bugfixes | ||
204 | # | ||
205 | CONFIG_IDE_GENERIC=y | ||
206 | CONFIG_BLK_DEV_IDEPCI=y | ||
207 | CONFIG_IDEPCI_SHARE_IRQ=y | ||
208 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
209 | CONFIG_BLK_DEV_GENERIC=y | ||
210 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
211 | # CONFIG_BLK_DEV_SL82C105 is not set | ||
212 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
213 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
214 | CONFIG_IDEDMA_PCI_AUTO=y | ||
215 | # CONFIG_IDEDMA_ONLYDISK is not set | ||
216 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
217 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
218 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
219 | # CONFIG_BLK_DEV_CMD64X is not set | ||
220 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
221 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
222 | # CONFIG_BLK_DEV_CS5520 is not set | ||
223 | # CONFIG_BLK_DEV_CS5530 is not set | ||
224 | # CONFIG_BLK_DEV_HPT34X is not set | ||
225 | # CONFIG_BLK_DEV_HPT366 is not set | ||
226 | # CONFIG_BLK_DEV_SC1200 is not set | ||
227 | # CONFIG_BLK_DEV_PIIX is not set | ||
228 | # CONFIG_BLK_DEV_NS87415 is not set | ||
229 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
230 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
231 | # CONFIG_BLK_DEV_SVWKS is not set | ||
232 | # CONFIG_BLK_DEV_SIIMAGE is not set | ||
233 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
234 | # CONFIG_BLK_DEV_TRM290 is not set | ||
235 | CONFIG_BLK_DEV_VIA82CXXX=y | ||
236 | # CONFIG_IDE_ARM is not set | ||
237 | CONFIG_BLK_DEV_IDEDMA=y | ||
238 | # CONFIG_IDEDMA_IVB is not set | ||
239 | CONFIG_IDEDMA_AUTO=y | ||
240 | # CONFIG_BLK_DEV_HD is not set | ||
184 | 241 | ||
185 | # | 242 | # |
186 | # SCSI device support | 243 | # SCSI device support |
@@ -220,7 +277,6 @@ CONFIG_NET=y | |||
220 | # | 277 | # |
221 | CONFIG_PACKET=y | 278 | CONFIG_PACKET=y |
222 | # CONFIG_PACKET_MMAP is not set | 279 | # CONFIG_PACKET_MMAP is not set |
223 | # CONFIG_NETLINK_DEV is not set | ||
224 | CONFIG_UNIX=y | 280 | CONFIG_UNIX=y |
225 | # CONFIG_NET_KEY is not set | 281 | # CONFIG_NET_KEY is not set |
226 | CONFIG_INET=y | 282 | CONFIG_INET=y |
@@ -370,14 +426,6 @@ CONFIG_INPUT=y | |||
370 | # CONFIG_INPUT_EVBUG is not set | 426 | # CONFIG_INPUT_EVBUG is not set |
371 | 427 | ||
372 | # | 428 | # |
373 | # Input I/O drivers | ||
374 | # | ||
375 | # CONFIG_GAMEPORT is not set | ||
376 | CONFIG_SOUND_GAMEPORT=y | ||
377 | # CONFIG_SERIO is not set | ||
378 | # CONFIG_SERIO_I8042 is not set | ||
379 | |||
380 | # | ||
381 | # Input Device Drivers | 429 | # Input Device Drivers |
382 | # | 430 | # |
383 | # CONFIG_INPUT_KEYBOARD is not set | 431 | # CONFIG_INPUT_KEYBOARD is not set |
@@ -387,6 +435,13 @@ CONFIG_SOUND_GAMEPORT=y | |||
387 | # CONFIG_INPUT_MISC is not set | 435 | # CONFIG_INPUT_MISC is not set |
388 | 436 | ||
389 | # | 437 | # |
438 | # Hardware I/O ports | ||
439 | # | ||
440 | # CONFIG_SERIO is not set | ||
441 | # CONFIG_GAMEPORT is not set | ||
442 | CONFIG_SOUND_GAMEPORT=y | ||
443 | |||
444 | # | ||
390 | # Character devices | 445 | # Character devices |
391 | # | 446 | # |
392 | # CONFIG_VT is not set | 447 | # CONFIG_VT is not set |
@@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
406 | CONFIG_SERIAL_CORE=y | 461 | CONFIG_SERIAL_CORE=y |
407 | CONFIG_SERIAL_CORE_CONSOLE=y | 462 | CONFIG_SERIAL_CORE_CONSOLE=y |
408 | # CONFIG_SERIAL_CPM is not set | 463 | # CONFIG_SERIAL_CPM is not set |
464 | # CONFIG_SERIAL_JSM is not set | ||
409 | CONFIG_UNIX98_PTYS=y | 465 | CONFIG_UNIX98_PTYS=y |
410 | CONFIG_LEGACY_PTYS=y | 466 | CONFIG_LEGACY_PTYS=y |
411 | CONFIG_LEGACY_PTY_COUNT=256 | 467 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -434,6 +490,11 @@ CONFIG_GEN_RTC=y | |||
434 | # CONFIG_RAW_DRIVER is not set | 490 | # CONFIG_RAW_DRIVER is not set |
435 | 491 | ||
436 | # | 492 | # |
493 | # TPM devices | ||
494 | # | ||
495 | # CONFIG_TCG_TPM is not set | ||
496 | |||
497 | # | ||
437 | # I2C support | 498 | # I2C support |
438 | # | 499 | # |
439 | CONFIG_I2C=y | 500 | CONFIG_I2C=y |
@@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y | |||
456 | # CONFIG_I2C_AMD8111 is not set | 517 | # CONFIG_I2C_AMD8111 is not set |
457 | # CONFIG_I2C_I801 is not set | 518 | # CONFIG_I2C_I801 is not set |
458 | # CONFIG_I2C_I810 is not set | 519 | # CONFIG_I2C_I810 is not set |
520 | # CONFIG_I2C_PIIX4 is not set | ||
459 | # CONFIG_I2C_ISA is not set | 521 | # CONFIG_I2C_ISA is not set |
460 | CONFIG_I2C_MPC=y | 522 | CONFIG_I2C_MPC=y |
461 | # CONFIG_I2C_NFORCE2 is not set | 523 | # CONFIG_I2C_NFORCE2 is not set |
462 | # CONFIG_I2C_PARPORT_LIGHT is not set | 524 | # CONFIG_I2C_PARPORT_LIGHT is not set |
463 | # CONFIG_I2C_PIIX4 is not set | ||
464 | # CONFIG_I2C_PROSAVAGE is not set | 525 | # CONFIG_I2C_PROSAVAGE is not set |
465 | # CONFIG_I2C_SAVAGE4 is not set | 526 | # CONFIG_I2C_SAVAGE4 is not set |
466 | # CONFIG_SCx200_ACB is not set | 527 | # CONFIG_SCx200_ACB is not set |
@@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y | |||
483 | # CONFIG_SENSORS_ASB100 is not set | 544 | # CONFIG_SENSORS_ASB100 is not set |
484 | # CONFIG_SENSORS_DS1621 is not set | 545 | # CONFIG_SENSORS_DS1621 is not set |
485 | # CONFIG_SENSORS_FSCHER is not set | 546 | # CONFIG_SENSORS_FSCHER is not set |
547 | # CONFIG_SENSORS_FSCPOS is not set | ||
486 | # CONFIG_SENSORS_GL518SM is not set | 548 | # CONFIG_SENSORS_GL518SM is not set |
549 | # CONFIG_SENSORS_GL520SM is not set | ||
487 | # CONFIG_SENSORS_IT87 is not set | 550 | # CONFIG_SENSORS_IT87 is not set |
488 | # CONFIG_SENSORS_LM63 is not set | 551 | # CONFIG_SENSORS_LM63 is not set |
489 | # CONFIG_SENSORS_LM75 is not set | 552 | # CONFIG_SENSORS_LM75 is not set |
@@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y | |||
494 | # CONFIG_SENSORS_LM85 is not set | 557 | # CONFIG_SENSORS_LM85 is not set |
495 | # CONFIG_SENSORS_LM87 is not set | 558 | # CONFIG_SENSORS_LM87 is not set |
496 | # CONFIG_SENSORS_LM90 is not set | 559 | # CONFIG_SENSORS_LM90 is not set |
560 | # CONFIG_SENSORS_LM92 is not set | ||
497 | # CONFIG_SENSORS_MAX1619 is not set | 561 | # CONFIG_SENSORS_MAX1619 is not set |
498 | # CONFIG_SENSORS_PC87360 is not set | 562 | # CONFIG_SENSORS_PC87360 is not set |
499 | # CONFIG_SENSORS_SMSC47B397 is not set | 563 | # CONFIG_SENSORS_SMSC47B397 is not set |
564 | # CONFIG_SENSORS_SIS5595 is not set | ||
500 | # CONFIG_SENSORS_SMSC47M1 is not set | 565 | # CONFIG_SENSORS_SMSC47M1 is not set |
501 | # CONFIG_SENSORS_VIA686A is not set | 566 | # CONFIG_SENSORS_VIA686A is not set |
502 | # CONFIG_SENSORS_W83781D is not set | 567 | # CONFIG_SENSORS_W83781D is not set |
@@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y | |||
506 | # | 571 | # |
507 | # Other I2C Chip support | 572 | # Other I2C Chip support |
508 | # | 573 | # |
574 | # CONFIG_SENSORS_DS1337 is not set | ||
509 | # CONFIG_SENSORS_EEPROM is not set | 575 | # CONFIG_SENSORS_EEPROM is not set |
510 | # CONFIG_SENSORS_PCF8574 is not set | 576 | # CONFIG_SENSORS_PCF8574 is not set |
511 | # CONFIG_SENSORS_PCF8591 is not set | 577 | # CONFIG_SENSORS_PCF8591 is not set |
512 | # CONFIG_SENSORS_RTC8564 is not set | 578 | # CONFIG_SENSORS_RTC8564 is not set |
579 | # CONFIG_SENSORS_M41T00 is not set | ||
513 | # CONFIG_I2C_DEBUG_CORE is not set | 580 | # CONFIG_I2C_DEBUG_CORE is not set |
514 | # CONFIG_I2C_DEBUG_ALGO is not set | 581 | # CONFIG_I2C_DEBUG_ALGO is not set |
515 | # CONFIG_I2C_DEBUG_BUS is not set | 582 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y | |||
538 | # Graphics support | 605 | # Graphics support |
539 | # | 606 | # |
540 | # CONFIG_FB is not set | 607 | # CONFIG_FB is not set |
541 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
542 | 608 | ||
543 | # | 609 | # |
544 | # Sound | 610 | # Sound |
@@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y | |||
548 | # | 614 | # |
549 | # USB support | 615 | # USB support |
550 | # | 616 | # |
551 | # CONFIG_USB is not set | ||
552 | CONFIG_USB_ARCH_HAS_HCD=y | 617 | CONFIG_USB_ARCH_HAS_HCD=y |
553 | CONFIG_USB_ARCH_HAS_OHCI=y | 618 | CONFIG_USB_ARCH_HAS_OHCI=y |
554 | 619 | # CONFIG_USB is not set | |
555 | # | ||
556 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
557 | # | ||
558 | 620 | ||
559 | # | 621 | # |
560 | # USB Gadget Support | 622 | # USB Gadget Support |
@@ -585,6 +647,10 @@ CONFIG_JBD=y | |||
585 | CONFIG_FS_MBCACHE=y | 647 | CONFIG_FS_MBCACHE=y |
586 | # CONFIG_REISERFS_FS is not set | 648 | # CONFIG_REISERFS_FS is not set |
587 | # CONFIG_JFS_FS is not set | 649 | # CONFIG_JFS_FS is not set |
650 | |||
651 | # | ||
652 | # XFS support | ||
653 | # | ||
588 | # CONFIG_XFS_FS is not set | 654 | # CONFIG_XFS_FS is not set |
589 | # CONFIG_MINIX_FS is not set | 655 | # CONFIG_MINIX_FS is not set |
590 | # CONFIG_ROMFS_FS is not set | 656 | # CONFIG_ROMFS_FS is not set |
@@ -646,7 +712,6 @@ CONFIG_NFS_FS=y | |||
646 | # CONFIG_NFSD is not set | 712 | # CONFIG_NFSD is not set |
647 | CONFIG_ROOT_NFS=y | 713 | CONFIG_ROOT_NFS=y |
648 | CONFIG_LOCKD=y | 714 | CONFIG_LOCKD=y |
649 | # CONFIG_EXPORTFS is not set | ||
650 | CONFIG_SUNRPC=y | 715 | CONFIG_SUNRPC=y |
651 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 716 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
652 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 717 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -698,7 +763,9 @@ CONFIG_CRC32=y | |||
698 | # | 763 | # |
699 | # Kernel hacking | 764 | # Kernel hacking |
700 | # | 765 | # |
766 | # CONFIG_PRINTK_TIME is not set | ||
701 | # CONFIG_DEBUG_KERNEL is not set | 767 | # CONFIG_DEBUG_KERNEL is not set |
768 | CONFIG_LOG_BUF_SHIFT=14 | ||
702 | # CONFIG_KGDB_CONSOLE is not set | 769 | # CONFIG_KGDB_CONSOLE is not set |
703 | # CONFIG_SERIAL_TEXT_DEBUG is not set | 770 | # CONFIG_SERIAL_TEXT_DEBUG is not set |
704 | 771 | ||
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index f22ddce36135..ce36e88ba627 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
@@ -232,7 +232,8 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
232 | tlbwe | 232 | tlbwe |
233 | 233 | ||
234 | /* 7. Jump to KERNELBASE mapping */ | 234 | /* 7. Jump to KERNELBASE mapping */ |
235 | li r7,0 | 235 | lis r7,MSR_KERNEL@h |
236 | ori r7,r7,MSR_KERNEL@l | ||
236 | bl 1f /* Find our address */ | 237 | bl 1f /* Find our address */ |
237 | 1: mflr r9 | 238 | 1: mflr r9 |
238 | rlwimi r6,r9,0,20,31 | 239 | rlwimi r6,r9,0,20,31 |
@@ -293,6 +294,18 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
293 | mtspr SPRN_HID0, r2 | 294 | mtspr SPRN_HID0, r2 |
294 | #endif | 295 | #endif |
295 | 296 | ||
297 | #if !defined(CONFIG_BDI_SWITCH) | ||
298 | /* | ||
299 | * The Abatron BDI JTAG debugger does not tolerate others | ||
300 | * mucking with the debug registers. | ||
301 | */ | ||
302 | lis r2,DBCR0_IDM@h | ||
303 | mtspr SPRN_DBCR0,r2 | ||
304 | /* clear any residual debug events */ | ||
305 | li r2,-1 | ||
306 | mtspr SPRN_DBSR,r2 | ||
307 | #endif | ||
308 | |||
296 | /* | 309 | /* |
297 | * This is where the main kernel code starts. | 310 | * This is where the main kernel code starts. |
298 | */ | 311 | */ |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index f8e7e324a173..c65731e8bc65 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) | |||
408 | 408 | ||
409 | /* Early out if we are an invalid form of lswx */ | 409 | /* Early out if we are an invalid form of lswx */ |
410 | if ((instword & INST_STRING_MASK) == INST_LSWX) | 410 | if ((instword & INST_STRING_MASK) == INST_LSWX) |
411 | if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB)) | 411 | if ((rT == rA) || (rT == NB_RB)) |
412 | return -EINVAL; | ||
413 | |||
414 | /* Early out if we are an invalid form of lswi */ | ||
415 | if ((instword & INST_STRING_MASK) == INST_LSWI) | ||
416 | if ((rA >= rT) || (rT == rA)) | ||
417 | return -EINVAL; | 412 | return -EINVAL; |
418 | 413 | ||
419 | EA = (rA == 0) ? 0 : regs->gpr[rA]; | 414 | EA = (rA == 0) ? 0 : regs->gpr[rA]; |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index b3b0f51979d2..e6348b5a1ddc 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
@@ -127,7 +127,6 @@ mpc834x_sys_map_io(void) | |||
127 | { | 127 | { |
128 | /* we steal the lowest ioremap addr for virt space */ | 128 | /* we steal the lowest ioremap addr for virt space */ |
129 | io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); | 129 | io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); |
130 | io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO); | ||
131 | } | 130 | } |
132 | 131 | ||
133 | int | 132 | int |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h index f4d055ae19c1..a2f6e49d7151 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.h +++ b/arch/ppc/platforms/83xx/mpc834x_sys.h | |||
@@ -26,9 +26,14 @@ | |||
26 | #define VIRT_IMMRBAR ((uint)0xfe000000) | 26 | #define VIRT_IMMRBAR ((uint)0xfe000000) |
27 | 27 | ||
28 | #define BCSR_PHYS_ADDR ((uint)0xf8000000) | 28 | #define BCSR_PHYS_ADDR ((uint)0xf8000000) |
29 | #define BCSR_VIRT_ADDR ((uint)0xfe100000) | ||
30 | #define BCSR_SIZE ((uint)(32 * 1024)) | 29 | #define BCSR_SIZE ((uint)(32 * 1024)) |
31 | 30 | ||
31 | #define BCSR_MISC_REG2_OFF 0x07 | ||
32 | #define BCSR_MISC_REG2_PORESET 0x01 | ||
33 | |||
34 | #define BCSR_MISC_REG3_OFF 0x08 | ||
35 | #define BCSR_MISC_REG3_CNFLOCK 0x80 | ||
36 | |||
32 | #ifdef CONFIG_PCI | 37 | #ifdef CONFIG_PCI |
33 | /* PCI interrupt controller */ | 38 | /* PCI interrupt controller */ |
34 | #define PIRQA MPC83xx_IRQ_IRQ4 | 39 | #define PIRQA MPC83xx_IRQ_IRQ4 |
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 4d857d6d633d..583838ab02d8 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
@@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
210 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 210 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
211 | ppc_md.progress = gen550_progress; | 211 | ppc_md.progress = gen550_progress; |
212 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 212 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
213 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
214 | ppc_md.early_serial_map = mpc85xx_early_serial_map; | ||
215 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
213 | 216 | ||
214 | if (ppc_md.progress) | 217 | if (ppc_md.progress) |
215 | ppc_md.progress("mpc8540ads_init(): exit", 0); | 218 | ppc_md.progress("mpc8540ads_init(): exit", 0); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 6c020d67ad70..e7cfa498568c 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/machdep.h> | 44 | #include <asm/machdep.h> |
45 | #include <asm/prom.h> | 45 | #include <asm/prom.h> |
46 | #include <asm/open_pic.h> | 46 | #include <asm/open_pic.h> |
47 | #include <asm/i8259.h> | ||
47 | #include <asm/bootinfo.h> | 48 | #include <asm/bootinfo.h> |
48 | #include <asm/pci-bridge.h> | 49 | #include <asm/pci-bridge.h> |
49 | #include <asm/mpc85xx.h> | 50 | #include <asm/mpc85xx.h> |
@@ -181,6 +182,7 @@ void __init | |||
181 | mpc85xx_cds_init_IRQ(void) | 182 | mpc85xx_cds_init_IRQ(void) |
182 | { | 183 | { |
183 | bd_t *binfo = (bd_t *) __res; | 184 | bd_t *binfo = (bd_t *) __res; |
185 | int i; | ||
184 | 186 | ||
185 | /* Determine the Physical Address of the OpenPIC regs */ | 187 | /* Determine the Physical Address of the OpenPIC regs */ |
186 | phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; | 188 | phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; |
@@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void) | |||
198 | */ | 200 | */ |
199 | openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); | 201 | openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); |
200 | 202 | ||
203 | #ifdef CONFIG_PCI | ||
204 | openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); | ||
205 | |||
206 | for (i = 0; i < NUM_8259_INTERRUPTS; i++) | ||
207 | irq_desc[i].handler = &i8259_pic; | ||
208 | |||
209 | i8259_init(0); | ||
210 | #endif | ||
211 | |||
201 | #ifdef CONFIG_CPM2 | 212 | #ifdef CONFIG_CPM2 |
202 | /* Setup CPM2 PIC */ | 213 | /* Setup CPM2 PIC */ |
203 | cpm2_init_IRQ(); | 214 | cpm2_init_IRQ(); |
@@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | |||
231 | * interrupt on slot */ | 242 | * interrupt on slot */ |
232 | { | 243 | { |
233 | { 0, 1, 2, 3 }, /* 16 - PMC */ | 244 | { 0, 1, 2, 3 }, /* 16 - PMC */ |
234 | { 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */ | 245 | { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ |
235 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ | 246 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ |
236 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ | 247 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ |
237 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ | 248 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ |
@@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn) | |||
280 | return PCIBIOS_DEVICE_NOT_FOUND; | 291 | return PCIBIOS_DEVICE_NOT_FOUND; |
281 | #endif | 292 | #endif |
282 | /* We explicitly do not go past the Tundra 320 Bridge */ | 293 | /* We explicitly do not go past the Tundra 320 Bridge */ |
283 | if (bus == 1) | 294 | if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) |
284 | return PCIBIOS_DEVICE_NOT_FOUND; | 295 | return PCIBIOS_DEVICE_NOT_FOUND; |
285 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | 296 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) |
286 | return PCIBIOS_DEVICE_NOT_FOUND; | 297 | return PCIBIOS_DEVICE_NOT_FOUND; |
287 | else | 298 | else |
288 | return PCIBIOS_SUCCESSFUL; | 299 | return PCIBIOS_SUCCESSFUL; |
289 | } | 300 | } |
301 | |||
302 | void __init | ||
303 | mpc85xx_cds_enable_via(struct pci_controller *hose) | ||
304 | { | ||
305 | u32 pci_class; | ||
306 | u16 vid, did; | ||
307 | |||
308 | early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class); | ||
309 | if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI) | ||
310 | return; | ||
311 | |||
312 | /* Configure P2P so that we can reach bus 1 */ | ||
313 | early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0); | ||
314 | early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1); | ||
315 | early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff); | ||
316 | |||
317 | early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid); | ||
318 | early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did); | ||
319 | |||
320 | if ((vid != PCI_VENDOR_ID_VIA) || | ||
321 | (did != PCI_DEVICE_ID_VIA_82C686)) | ||
322 | return; | ||
323 | |||
324 | /* Enable USB and IDE functions */ | ||
325 | early_write_config_byte(hose, 1, 0x10, 0x48, 0x08); | ||
326 | } | ||
327 | |||
328 | void __init | ||
329 | mpc85xx_cds_fixup_via(struct pci_controller *hose) | ||
330 | { | ||
331 | u32 pci_class; | ||
332 | u16 vid, did; | ||
333 | |||
334 | early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class); | ||
335 | if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI) | ||
336 | return; | ||
337 | |||
338 | /* | ||
339 | * Force the backplane P2P bridge to have a window | ||
340 | * open from 0x00000000-0x00001fff in PCI I/O space. | ||
341 | * This allows legacy I/O (i8259, etc) on the VIA | ||
342 | * southbridge to be accessed. | ||
343 | */ | ||
344 | early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00); | ||
345 | early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000); | ||
346 | early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10); | ||
347 | early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000); | ||
348 | |||
349 | early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid); | ||
350 | early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did); | ||
351 | if ((vid != PCI_VENDOR_ID_VIA) || | ||
352 | (did != PCI_DEVICE_ID_VIA_82C686)) | ||
353 | return; | ||
354 | |||
355 | /* | ||
356 | * Since the P2P window was forced to cover the fixed | ||
357 | * legacy I/O addresses, it is necessary to manually | ||
358 | * place the base addresses for the IDE and USB functions | ||
359 | * within this window. | ||
360 | */ | ||
361 | /* Function 1, IDE */ | ||
362 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8); | ||
363 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4); | ||
364 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8); | ||
365 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4); | ||
366 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0); | ||
367 | |||
368 | /* Function 2, USB ports 0-1 */ | ||
369 | early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0); | ||
370 | |||
371 | /* Function 3, USB ports 2-3 */ | ||
372 | early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80); | ||
373 | |||
374 | /* Function 5, Power Management */ | ||
375 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00); | ||
376 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc); | ||
377 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8); | ||
378 | |||
379 | /* Function 6, AC97 Interface */ | ||
380 | early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00); | ||
381 | } | ||
382 | |||
383 | void __init | ||
384 | mpc85xx_cds_pcibios_fixup(void) | ||
385 | { | ||
386 | struct pci_dev *dev = NULL; | ||
387 | u_char c; | ||
388 | |||
389 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
390 | PCI_DEVICE_ID_VIA_82C586_1, NULL))) { | ||
391 | /* | ||
392 | * U-Boot does not set the enable bits | ||
393 | * for the IDE device. Force them on here. | ||
394 | */ | ||
395 | pci_read_config_byte(dev, 0x40, &c); | ||
396 | c |= 0x03; /* IDE: Chip Enable Bits */ | ||
397 | pci_write_config_byte(dev, 0x40, c); | ||
398 | |||
399 | /* | ||
400 | * Since only primary interface works, force the | ||
401 | * IDE function to standard primary IDE interrupt | ||
402 | * w/ 8259 offset | ||
403 | */ | ||
404 | dev->irq = 14; | ||
405 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * Force legacy USB interrupt routing | ||
410 | */ | ||
411 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
412 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { | ||
413 | dev->irq = 10; | ||
414 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); | ||
415 | } | ||
416 | |||
417 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
418 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { | ||
419 | dev->irq = 11; | ||
420 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); | ||
421 | } | ||
422 | } | ||
290 | #endif /* CONFIG_PCI */ | 423 | #endif /* CONFIG_PCI */ |
291 | 424 | ||
292 | TODC_ALLOC(); | 425 | TODC_ALLOC(); |
@@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void) | |||
328 | loops_per_jiffy = freq / HZ; | 461 | loops_per_jiffy = freq / HZ; |
329 | 462 | ||
330 | #ifdef CONFIG_PCI | 463 | #ifdef CONFIG_PCI |
464 | /* VIA IDE configuration */ | ||
465 | ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; | ||
466 | |||
331 | /* setup PCI host bridges */ | 467 | /* setup PCI host bridges */ |
332 | mpc85xx_setup_hose(); | 468 | mpc85xx_setup_hose(); |
333 | #endif | 469 | #endif |
@@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
459 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 595 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
460 | ppc_md.progress = gen550_progress; | 596 | ppc_md.progress = gen550_progress; |
461 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 597 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
598 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
599 | ppc_md.early_serial_map = mpc85xx_early_serial_map; | ||
600 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
462 | 601 | ||
463 | if (ppc_md.progress) | 602 | if (ppc_md.progress) |
464 | ppc_md.progress("mpc85xx_cds_init(): exit", 0); | 603 | ppc_md.progress("mpc85xx_cds_init(): exit", 0); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h index 7627d77504bd..12b292c6ae32 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h | |||
@@ -77,4 +77,7 @@ | |||
77 | 77 | ||
78 | #define MPC85XX_PCI2_IO_SIZE 0x01000000 | 78 | #define MPC85XX_PCI2_IO_SIZE 0x01000000 |
79 | 79 | ||
80 | #define NR_8259_INTS 16 | ||
81 | #define CPM_IRQ_OFFSET NR_8259_INTS | ||
82 | |||
80 | #endif /* __MACH_MPC85XX_CDS_H__ */ | 83 | #endif /* __MACH_MPC85XX_CDS_H__ */ |
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 9ab05e590c3e..7b9e1543e175 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
@@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
221 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 221 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
222 | ppc_md.progress = gen550_progress; | 222 | ppc_md.progress = gen550_progress; |
223 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 223 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
224 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
225 | ppc_md.early_serial_map = sbc8560_early_serial_map; | ||
226 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
224 | 227 | ||
225 | if (ppc_md.progress) | 228 | if (ppc_md.progress) |
226 | ppc_md.progress("sbc8560_init(): exit", 0); | 229 | ppc_md.progress("sbc8560_init(): exit", 0); |
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index f7fb2786cd50..937f46df711e 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c | |||
@@ -85,14 +85,11 @@ static int no_schedule; | |||
85 | static int has_cpu_l2lve; | 85 | static int has_cpu_l2lve; |
86 | 86 | ||
87 | 87 | ||
88 | #define PMAC_CPU_LOW_SPEED 1 | ||
89 | #define PMAC_CPU_HIGH_SPEED 0 | ||
90 | |||
91 | /* There are only two frequency states for each processor. Values | 88 | /* There are only two frequency states for each processor. Values |
92 | * are in kHz for the time being. | 89 | * are in kHz for the time being. |
93 | */ | 90 | */ |
94 | #define CPUFREQ_HIGH PMAC_CPU_HIGH_SPEED | 91 | #define CPUFREQ_HIGH 0 |
95 | #define CPUFREQ_LOW PMAC_CPU_LOW_SPEED | 92 | #define CPUFREQ_LOW 1 |
96 | 93 | ||
97 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | 94 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { |
98 | {CPUFREQ_HIGH, 0}, | 95 | {CPUFREQ_HIGH, 0}, |
@@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | |||
100 | {0, CPUFREQ_TABLE_END}, | 97 | {0, CPUFREQ_TABLE_END}, |
101 | }; | 98 | }; |
102 | 99 | ||
100 | static struct freq_attr* pmac_cpu_freqs_attr[] = { | ||
101 | &cpufreq_freq_attr_scaling_available_freqs, | ||
102 | NULL, | ||
103 | }; | ||
104 | |||
103 | static inline void local_delay(unsigned long ms) | 105 | static inline void local_delay(unsigned long ms) |
104 | { | 106 | { |
105 | if (no_schedule) | 107 | if (no_schedule) |
@@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
269 | #ifdef DEBUG_FREQ | 271 | #ifdef DEBUG_FREQ |
270 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 272 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); |
271 | #endif | 273 | #endif |
274 | pmu_suspend(); | ||
275 | |||
272 | /* Disable all interrupt sources on openpic */ | 276 | /* Disable all interrupt sources on openpic */ |
273 | pic_prio = openpic_get_priority(); | 277 | pic_prio = openpic_get_priority(); |
274 | openpic_set_priority(0xf); | 278 | openpic_set_priority(0xf); |
@@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
343 | debug_calc_bogomips(); | 347 | debug_calc_bogomips(); |
344 | #endif | 348 | #endif |
345 | 349 | ||
350 | pmu_resume(); | ||
351 | |||
346 | preempt_enable(); | 352 | preempt_enable(); |
347 | 353 | ||
348 | return 0; | 354 | return 0; |
@@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
355 | static unsigned long prev_l3cr; | 361 | static unsigned long prev_l3cr; |
356 | 362 | ||
357 | freqs.old = cur_freq; | 363 | freqs.old = cur_freq; |
358 | freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 364 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
359 | freqs.cpu = smp_processor_id(); | 365 | freqs.cpu = smp_processor_id(); |
360 | 366 | ||
361 | if (freqs.old == freqs.new) | 367 | if (freqs.old == freqs.new) |
@@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
363 | 369 | ||
364 | if (notify) | 370 | if (notify) |
365 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 371 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
366 | if (speed_mode == PMAC_CPU_LOW_SPEED && | 372 | if (speed_mode == CPUFREQ_LOW && |
367 | cpu_has_feature(CPU_FTR_L3CR)) { | 373 | cpu_has_feature(CPU_FTR_L3CR)) { |
368 | l3cr = _get_L3CR(); | 374 | l3cr = _get_L3CR(); |
369 | if (l3cr & L3CR_L3E) { | 375 | if (l3cr & L3CR_L3E) { |
@@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
371 | _set_L3CR(0); | 377 | _set_L3CR(0); |
372 | } | 378 | } |
373 | } | 379 | } |
374 | set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); | 380 | set_speed_proc(speed_mode == CPUFREQ_LOW); |
375 | if (speed_mode == PMAC_CPU_HIGH_SPEED && | 381 | if (speed_mode == CPUFREQ_HIGH && |
376 | cpu_has_feature(CPU_FTR_L3CR)) { | 382 | cpu_has_feature(CPU_FTR_L3CR)) { |
377 | l3cr = _get_L3CR(); | 383 | l3cr = _get_L3CR(); |
378 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) | 384 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) |
@@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
380 | } | 386 | } |
381 | if (notify) | 387 | if (notify) |
382 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 388 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
383 | cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 389 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
384 | 390 | ||
385 | return 0; | 391 | return 0; |
386 | } | 392 | } |
@@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
423 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 429 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
424 | policy->cur = cur_freq; | 430 | policy->cur = cur_freq; |
425 | 431 | ||
426 | return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]); | 432 | cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); |
433 | return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); | ||
427 | } | 434 | } |
428 | 435 | ||
429 | static u32 __pmac read_gpio(struct device_node *np) | 436 | static u32 __pmac read_gpio(struct device_node *np) |
@@ -457,7 +464,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) | |||
457 | no_schedule = 1; | 464 | no_schedule = 1; |
458 | sleep_freq = cur_freq; | 465 | sleep_freq = cur_freq; |
459 | if (cur_freq == low_freq) | 466 | if (cur_freq == low_freq) |
460 | do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0); | 467 | do_set_cpu_speed(CPUFREQ_HIGH, 0); |
461 | return 0; | 468 | return 0; |
462 | } | 469 | } |
463 | 470 | ||
@@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy) | |||
473 | * is that we force a switch to whatever it was, which is | 480 | * is that we force a switch to whatever it was, which is |
474 | * probably high speed due to our suspend() routine | 481 | * probably high speed due to our suspend() routine |
475 | */ | 482 | */ |
476 | do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED | 483 | do_set_cpu_speed(sleep_freq == low_freq ? |
477 | : PMAC_CPU_HIGH_SPEED, 0); | 484 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); |
478 | 485 | ||
479 | no_schedule = 0; | 486 | no_schedule = 0; |
480 | return 0; | 487 | return 0; |
@@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = { | |||
488 | .suspend = pmac_cpufreq_suspend, | 495 | .suspend = pmac_cpufreq_suspend, |
489 | .resume = pmac_cpufreq_resume, | 496 | .resume = pmac_cpufreq_resume, |
490 | .flags = CPUFREQ_PM_NO_WARN, | 497 | .flags = CPUFREQ_PM_NO_WARN, |
498 | .attr = pmac_cpu_freqs_attr, | ||
491 | .name = "powermac", | 499 | .name = "powermac", |
492 | .owner = THIS_MODULE, | 500 | .owner = THIS_MODULE, |
493 | }; | 501 | }; |
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h index cf5e5dd06d63..067d9a5aebc1 100644 --- a/arch/ppc/platforms/pq2ads.h +++ b/arch/ppc/platforms/pq2ads.h | |||
@@ -49,10 +49,10 @@ | |||
49 | /* PCI interrupt controller */ | 49 | /* PCI interrupt controller */ |
50 | #define PCI_INT_STAT_REG 0xF8200000 | 50 | #define PCI_INT_STAT_REG 0xF8200000 |
51 | #define PCI_INT_MASK_REG 0xF8200004 | 51 | #define PCI_INT_MASK_REG 0xF8200004 |
52 | #define PIRQA (NR_SIU_INTS + 0) | 52 | #define PIRQA (NR_CPM_INTS + 0) |
53 | #define PIRQB (NR_SIU_INTS + 1) | 53 | #define PIRQB (NR_CPM_INTS + 1) |
54 | #define PIRQC (NR_SIU_INTS + 2) | 54 | #define PIRQC (NR_CPM_INTS + 2) |
55 | #define PIRQD (NR_SIU_INTS + 3) | 55 | #define PIRQD (NR_CPM_INTS + 3) |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * PCI memory map definitions for MPC8266ADS-PCI. | 58 | * PCI memory map definitions for MPC8266ADS-PCI. |
@@ -68,28 +68,23 @@ | |||
68 | * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory | 68 | * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory |
69 | */ | 69 | */ |
70 | 70 | ||
71 | /* window for a PCI master to access MPC8266 memory */ | 71 | /* All the other PCI memory map definitions reside at syslib/m82xx_pci.h |
72 | #define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */ | 72 | Here we should redefine what is unique for this board */ |
73 | #define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ | 73 | #define M82xx_PCI_SLAVE_MEM_LOCAL 0x00000000 /* Local base */ |
74 | #define M82xx_PCI_SLAVE_MEM_BUS 0x00000000 /* PCI base */ | ||
75 | #define M82xx_PCI_SLAVE_MEM_SIZE 0x10000000 /* 256 Mb */ | ||
74 | 76 | ||
75 | /* window for the processor to access PCI memory with prefetching */ | 77 | #define M82xx_PCI_SLAVE_SEC_WND_SIZE ~(0x40000000 - 1U) /* 2 x 512Mb */ |
76 | #define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ | 78 | #define M82xx_PCI_SLAVE_SEC_WND_BASE 0x80000000 /* PCI Memory base */ |
77 | #define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */ | ||
78 | #define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */ | ||
79 | 79 | ||
80 | /* window for the processor to access PCI memory without prefetching */ | 80 | #if defined(CONFIG_ADS8272) |
81 | #define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */ | 81 | #define PCI_INT_TO_SIU SIU_INT_IRQ2 |
82 | #define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */ | 82 | #elif defined(CONFIG_PQ2FADS) |
83 | #define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */ | 83 | #define PCI_INT_TO_SIU SIU_INT_IRQ6 |
84 | #else | ||
85 | #warning PCI Bridge will be without interrupts support | ||
86 | #endif | ||
84 | 87 | ||
85 | /* window for the processor to access PCI I/O */ | ||
86 | #define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */ | ||
87 | #define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */ | ||
88 | #define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */ | ||
89 | |||
90 | #define _IO_BASE PCI_MSTR_IO_LOCAL | ||
91 | #define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL | ||
92 | #define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS | ||
93 | #endif /* CONFIG_PCI */ | 88 | #endif /* CONFIG_PCI */ |
94 | 89 | ||
95 | #endif /* __MACH_ADS8260_DEFS */ | 90 | #endif /* __MACH_ADS8260_DEFS */ |
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index dd418ea3426c..96acf85800d4 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile | |||
@@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx) += todc_time.o | |||
81 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ | 81 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ |
82 | todc_time.o | 82 | todc_time.o |
83 | obj-$(CONFIG_8260) += m8260_setup.o | 83 | obj-$(CONFIG_8260) += m8260_setup.o |
84 | obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o | 84 | obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o |
85 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o | 85 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o |
86 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o | 86 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o |
87 | ifeq ($(CONFIG_PPC_GEN550),y) | 87 | ifeq ($(CONFIG_PPC_GEN550),y) |
@@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o | |||
97 | obj-$(CONFIG_40x) += dcr.o | 97 | obj-$(CONFIG_40x) += dcr.o |
98 | obj-$(CONFIG_BOOKE) += dcr.o | 98 | obj-$(CONFIG_BOOKE) += dcr.o |
99 | obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ | 99 | obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ |
100 | ppc_sys.o mpc85xx_sys.o \ | 100 | ppc_sys.o i8259.o mpc85xx_sys.o \ |
101 | mpc85xx_devices.o | 101 | mpc85xx_devices.o |
102 | ifeq ($(CONFIG_85xx),y) | 102 | ifeq ($(CONFIG_85xx),y) |
103 | obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o | 103 | obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o |
diff --git a/arch/ppc/syslib/m8260_pci.c b/arch/ppc/syslib/m8260_pci.c deleted file mode 100644 index 057cc3f8ff37..000000000000 --- a/arch/ppc/syslib/m8260_pci.c +++ /dev/null | |||
@@ -1,193 +0,0 @@ | |||
1 | /* | ||
2 | * (C) Copyright 2003 | ||
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||
4 | * | ||
5 | * (C) Copyright 2004 Red Hat, Inc. | ||
6 | * | ||
7 | * See file CREDITS for list of people who contributed to this | ||
8 | * project. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation; either version 2 of | ||
13 | * the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
23 | * MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/delay.h> | ||
31 | |||
32 | #include <asm/byteorder.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/uaccess.h> | ||
36 | #include <asm/machdep.h> | ||
37 | #include <asm/pci-bridge.h> | ||
38 | #include <asm/immap_cpm2.h> | ||
39 | #include <asm/mpc8260.h> | ||
40 | |||
41 | #include "m8260_pci.h" | ||
42 | |||
43 | |||
44 | /* PCI bus configuration registers. | ||
45 | */ | ||
46 | |||
47 | static void __init m8260_setup_pci(struct pci_controller *hose) | ||
48 | { | ||
49 | volatile cpm2_map_t *immap = cpm2_immr; | ||
50 | unsigned long pocmr; | ||
51 | u16 tempShort; | ||
52 | |||
53 | #ifndef CONFIG_ATC /* already done in U-Boot */ | ||
54 | /* | ||
55 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | ||
56 | * and local bus for PCI (SIUMCR [LBPC]). | ||
57 | */ | ||
58 | immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000; | ||
59 | #endif | ||
60 | |||
61 | /* Make PCI lowest priority */ | ||
62 | /* Each 4 bits is a device bus request and the MS 4bits | ||
63 | is highest priority */ | ||
64 | /* Bus 4bit value | ||
65 | --- ---------- | ||
66 | CPM high 0b0000 | ||
67 | CPM middle 0b0001 | ||
68 | CPM low 0b0010 | ||
69 | PCI reguest 0b0011 | ||
70 | Reserved 0b0100 | ||
71 | Reserved 0b0101 | ||
72 | Internal Core 0b0110 | ||
73 | External Master 1 0b0111 | ||
74 | External Master 2 0b1000 | ||
75 | External Master 3 0b1001 | ||
76 | The rest are reserved */ | ||
77 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | ||
78 | |||
79 | /* Park bus on core while modifying PCI Bus accesses */ | ||
80 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6; | ||
81 | |||
82 | /* | ||
83 | * Set up master window that allows the CPU to access PCI space. This | ||
84 | * window is set up using the first SIU PCIBR registers. | ||
85 | */ | ||
86 | immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK; | ||
87 | immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE; | ||
88 | |||
89 | /* Disable machine check on no response or target abort */ | ||
90 | immap->im_pci.pci_emr = cpu_to_le32(0x1fe7); | ||
91 | /* Release PCI RST (by default the PCI RST signal is held low) */ | ||
92 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | ||
93 | |||
94 | /* give it some time */ | ||
95 | mdelay(1); | ||
96 | |||
97 | /* | ||
98 | * Set up master window that allows the CPU to access PCI Memory (prefetch) | ||
99 | * space. This window is set up using the first set of Outbound ATU registers. | ||
100 | */ | ||
101 | immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12); | ||
102 | immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12); | ||
103 | pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff; | ||
104 | immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN); | ||
105 | |||
106 | /* | ||
107 | * Set up master window that allows the CPU to access PCI Memory (non-prefetch) | ||
108 | * space. This window is set up using the second set of Outbound ATU registers. | ||
109 | */ | ||
110 | immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12); | ||
111 | immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12); | ||
112 | pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff; | ||
113 | immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE); | ||
114 | |||
115 | /* | ||
116 | * Set up master window that allows the CPU to access PCI IO space. This window | ||
117 | * is set up using the third set of Outbound ATU registers. | ||
118 | */ | ||
119 | immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12); | ||
120 | immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12); | ||
121 | pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff; | ||
122 | immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO); | ||
123 | |||
124 | /* | ||
125 | * Set up slave window that allows PCI masters to access MPC826x local memory. | ||
126 | * This window is set up using the first set of Inbound ATU registers | ||
127 | */ | ||
128 | |||
129 | immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12); | ||
130 | immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12); | ||
131 | pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff; | ||
132 | immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN); | ||
133 | |||
134 | /* See above for description - puts PCI request as highest priority */ | ||
135 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | ||
136 | |||
137 | /* Park the bus on the PCI */ | ||
138 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | ||
139 | |||
140 | /* Host mode - specify the bridge as a host-PCI bridge */ | ||
141 | early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST); | ||
142 | |||
143 | /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ | ||
144 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort); | ||
145 | early_write_config_word(hose, 0, 0, PCI_COMMAND, | ||
146 | tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | ||
147 | } | ||
148 | |||
149 | void __init m8260_find_bridges(void) | ||
150 | { | ||
151 | extern int pci_assign_all_busses; | ||
152 | struct pci_controller * hose; | ||
153 | |||
154 | pci_assign_all_busses = 1; | ||
155 | |||
156 | hose = pcibios_alloc_controller(); | ||
157 | |||
158 | if (!hose) | ||
159 | return; | ||
160 | |||
161 | ppc_md.pci_swizzle = common_swizzle; | ||
162 | |||
163 | hose->first_busno = 0; | ||
164 | hose->bus_offset = 0; | ||
165 | hose->last_busno = 0xff; | ||
166 | |||
167 | setup_m8260_indirect_pci(hose, | ||
168 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | ||
169 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | ||
170 | |||
171 | m8260_setup_pci(hose); | ||
172 | hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET; | ||
173 | |||
174 | hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE, | ||
175 | MPC826x_PCI_IO_SIZE); | ||
176 | isa_io_base = (unsigned long) hose->io_base_virt; | ||
177 | |||
178 | /* setup resources */ | ||
179 | pci_init_resource(&hose->mem_resources[0], | ||
180 | MPC826x_PCI_LOWER_MEM, | ||
181 | MPC826x_PCI_UPPER_MEM, | ||
182 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | ||
183 | |||
184 | pci_init_resource(&hose->mem_resources[1], | ||
185 | MPC826x_PCI_LOWER_MMIO, | ||
186 | MPC826x_PCI_UPPER_MMIO, | ||
187 | IORESOURCE_MEM, "PCI memory"); | ||
188 | |||
189 | pci_init_resource(&hose->io_resource, | ||
190 | MPC826x_PCI_LOWER_IO, | ||
191 | MPC826x_PCI_UPPER_IO, | ||
192 | IORESOURCE_IO, "PCI I/O"); | ||
193 | } | ||
diff --git a/arch/ppc/syslib/m8260_pci.h b/arch/ppc/syslib/m8260_pci.h deleted file mode 100644 index d1352120acd7..000000000000 --- a/arch/ppc/syslib/m8260_pci.h +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | |||
2 | #ifndef _PPC_KERNEL_M8260_PCI_H | ||
3 | #define _PPC_KERNEL_M8260_PCI_H | ||
4 | |||
5 | #include <asm/m8260_pci.h> | ||
6 | |||
7 | /* | ||
8 | * Local->PCI map (from CPU) controlled by | ||
9 | * MPC826x master window | ||
10 | * | ||
11 | * 0x80000000 - 0xBFFFFFFF Total CPU2PCI space PCIBR0 | ||
12 | * | ||
13 | * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) | ||
14 | * 0xA0000000 - 0xAFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) | ||
15 | * 0xB0000000 - 0xB0FFFFFF 32-bit PCI IO (Outbound ATU #3) | ||
16 | * | ||
17 | * PCI->Local map (from PCI) | ||
18 | * MPC826x slave window controlled by | ||
19 | * | ||
20 | * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * Slave window that allows PCI masters to access MPC826x local memory. | ||
25 | * This window is set up using the first set of Inbound ATU registers | ||
26 | */ | ||
27 | |||
28 | #ifndef MPC826x_PCI_SLAVE_MEM_LOCAL | ||
29 | #define MPC826x_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) | ||
30 | #define MPC826x_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) | ||
31 | #define MPC826x_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * This is the window that allows the CPU to access PCI address space. | ||
36 | * It will be setup with the SIU PCIBR0 register. All three PCI master | ||
37 | * windows, which allow the CPU to access PCI prefetch, non prefetch, | ||
38 | * and IO space (see below), must all fit within this window. | ||
39 | */ | ||
40 | #ifndef MPC826x_PCI_BASE | ||
41 | #define MPC826x_PCI_BASE 0x80000000 | ||
42 | #define MPC826x_PCI_MASK 0xc0000000 | ||
43 | #endif | ||
44 | |||
45 | #ifndef MPC826x_PCI_LOWER_MEM | ||
46 | #define MPC826x_PCI_LOWER_MEM 0x80000000 | ||
47 | #define MPC826x_PCI_UPPER_MEM 0x9fffffff | ||
48 | #define MPC826x_PCI_MEM_OFFSET 0x00000000 | ||
49 | #endif | ||
50 | |||
51 | #ifndef MPC826x_PCI_LOWER_MMIO | ||
52 | #define MPC826x_PCI_LOWER_MMIO 0xa0000000 | ||
53 | #define MPC826x_PCI_UPPER_MMIO 0xafffffff | ||
54 | #define MPC826x_PCI_MMIO_OFFSET 0x00000000 | ||
55 | #endif | ||
56 | |||
57 | #ifndef MPC826x_PCI_LOWER_IO | ||
58 | #define MPC826x_PCI_LOWER_IO 0x00000000 | ||
59 | #define MPC826x_PCI_UPPER_IO 0x00ffffff | ||
60 | #define MPC826x_PCI_IO_BASE 0xb0000000 | ||
61 | #define MPC826x_PCI_IO_SIZE 0x01000000 | ||
62 | #endif | ||
63 | |||
64 | #ifndef _IO_BASE | ||
65 | #define _IO_BASE isa_io_base | ||
66 | #endif | ||
67 | |||
68 | #ifdef CONFIG_8260_PCI9 | ||
69 | struct pci_controller; | ||
70 | extern void setup_m8260_indirect_pci(struct pci_controller* hose, | ||
71 | u32 cfg_addr, u32 cfg_data); | ||
72 | #else | ||
73 | #define setup_m8260_indirect_pci setup_indirect_pci | ||
74 | #endif | ||
75 | |||
76 | #endif /* _PPC_KERNEL_M8260_PCI_H */ | ||
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c index 9c0582d639e0..1dc7e4e1d491 100644 --- a/arch/ppc/syslib/m8260_pci_erratum9.c +++ b/arch/ppc/syslib/m8260_pci_erratum9.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/immap_cpm2.h> | 31 | #include <asm/immap_cpm2.h> |
32 | #include <asm/cpm2.h> | 32 | #include <asm/cpm2.h> |
33 | 33 | ||
34 | #include "m8260_pci.h" | 34 | #include "m82xx_pci.h" |
35 | 35 | ||
36 | #ifdef CONFIG_8260_PCI9 | 36 | #ifdef CONFIG_8260_PCI9 |
37 | /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ | 37 | /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ |
@@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le); | |||
248 | 248 | ||
249 | static inline int is_pci_mem(unsigned long addr) | 249 | static inline int is_pci_mem(unsigned long addr) |
250 | { | 250 | { |
251 | if (addr >= MPC826x_PCI_LOWER_MMIO && | 251 | if (addr >= M82xx_PCI_LOWER_MMIO && |
252 | addr <= MPC826x_PCI_UPPER_MMIO) | 252 | addr <= M82xx_PCI_UPPER_MMIO) |
253 | return 1; | 253 | return 1; |
254 | if (addr >= MPC826x_PCI_LOWER_MEM && | 254 | if (addr >= M82xx_PCI_LOWER_MEM && |
255 | addr <= MPC826x_PCI_UPPER_MEM) | 255 | addr <= M82xx_PCI_UPPER_MEM) |
256 | return 1; | 256 | return 1; |
257 | return 0; | 257 | return 0; |
258 | } | 258 | } |
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c index 23ea3f694de2..fda75d79050c 100644 --- a/arch/ppc/syslib/m8260_setup.c +++ b/arch/ppc/syslib/m8260_setup.c | |||
@@ -34,7 +34,8 @@ | |||
34 | unsigned char __res[sizeof(bd_t)]; | 34 | unsigned char __res[sizeof(bd_t)]; |
35 | 35 | ||
36 | extern void cpm2_reset(void); | 36 | extern void cpm2_reset(void); |
37 | extern void m8260_find_bridges(void); | 37 | extern void pq2_find_bridges(void); |
38 | extern void pq2pci_init_irq(void); | ||
38 | extern void idma_pci9_init(void); | 39 | extern void idma_pci9_init(void); |
39 | 40 | ||
40 | /* Place-holder for board-specific init */ | 41 | /* Place-holder for board-specific init */ |
@@ -56,7 +57,7 @@ m8260_setup_arch(void) | |||
56 | idma_pci9_init(); | 57 | idma_pci9_init(); |
57 | #endif | 58 | #endif |
58 | #ifdef CONFIG_PCI_8260 | 59 | #ifdef CONFIG_PCI_8260 |
59 | m8260_find_bridges(); | 60 | pq2_find_bridges(); |
60 | #endif | 61 | #endif |
61 | #ifdef CONFIG_BLK_DEV_INITRD | 62 | #ifdef CONFIG_BLK_DEV_INITRD |
62 | if (initrd_start) | 63 | if (initrd_start) |
@@ -173,6 +174,12 @@ m8260_init_IRQ(void) | |||
173 | * in case the boot rom changed something on us. | 174 | * in case the boot rom changed something on us. |
174 | */ | 175 | */ |
175 | cpm2_immr->im_intctl.ic_siprr = 0x05309770; | 176 | cpm2_immr->im_intctl.ic_siprr = 0x05309770; |
177 | |||
178 | #if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS)) | ||
179 | /* Initialize stuff for the 82xx CPLD IC and install demux */ | ||
180 | pq2pci_init_irq(); | ||
181 | #endif | ||
182 | |||
176 | } | 183 | } |
177 | 184 | ||
178 | /* | 185 | /* |
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c new file mode 100644 index 000000000000..5e7a7edcea74 --- /dev/null +++ b/arch/ppc/syslib/m82xx_pci.c | |||
@@ -0,0 +1,383 @@ | |||
1 | /* | ||
2 | * | ||
3 | * (C) Copyright 2003 | ||
4 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||
5 | * | ||
6 | * (C) Copyright 2004 Red Hat, Inc. | ||
7 | * | ||
8 | * 2005 (c) MontaVista Software, Inc. | ||
9 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
10 | * | ||
11 | * See file CREDITS for list of people who contributed to this | ||
12 | * project. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | */ | ||
29 | |||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/irq.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | |||
38 | #include <asm/byteorder.h> | ||
39 | #include <asm/io.h> | ||
40 | #include <asm/irq.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | #include <asm/machdep.h> | ||
43 | #include <asm/pci-bridge.h> | ||
44 | #include <asm/immap_cpm2.h> | ||
45 | #include <asm/mpc8260.h> | ||
46 | #include <asm/cpm2.h> | ||
47 | |||
48 | #include "m82xx_pci.h" | ||
49 | |||
50 | /* | ||
51 | * Interrupt routing | ||
52 | */ | ||
53 | |||
54 | static inline int | ||
55 | pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
56 | { | ||
57 | static char pci_irq_table[][4] = | ||
58 | /* | ||
59 | * PCI IDSEL/INTPIN->INTLINE | ||
60 | * A B C D | ||
61 | */ | ||
62 | { | ||
63 | { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */ | ||
64 | { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */ | ||
65 | { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */ | ||
66 | }; | ||
67 | |||
68 | const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4; | ||
69 | return PCI_IRQ_TABLE_LOOKUP; | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | pq2pci_mask_irq(unsigned int irq) | ||
74 | { | ||
75 | int bit = irq - NR_CPM_INTS; | ||
76 | |||
77 | *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit)); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | static void | ||
82 | pq2pci_unmask_irq(unsigned int irq) | ||
83 | { | ||
84 | int bit = irq - NR_CPM_INTS; | ||
85 | |||
86 | *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit)); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | static void | ||
91 | pq2pci_mask_and_ack(unsigned int irq) | ||
92 | { | ||
93 | int bit = irq - NR_CPM_INTS; | ||
94 | |||
95 | *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit)); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | static void | ||
100 | pq2pci_end_irq(unsigned int irq) | ||
101 | { | ||
102 | int bit = irq - NR_CPM_INTS; | ||
103 | |||
104 | *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit)); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | struct hw_interrupt_type pq2pci_ic = { | ||
109 | "PQ2 PCI", | ||
110 | NULL, | ||
111 | NULL, | ||
112 | pq2pci_unmask_irq, | ||
113 | pq2pci_mask_irq, | ||
114 | pq2pci_mask_and_ack, | ||
115 | pq2pci_end_irq, | ||
116 | 0 | ||
117 | }; | ||
118 | |||
119 | static irqreturn_t | ||
120 | pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs) | ||
121 | { | ||
122 | unsigned long stat, mask, pend; | ||
123 | int bit; | ||
124 | |||
125 | for(;;) { | ||
126 | stat = *(volatile unsigned long *) PCI_INT_STAT_REG; | ||
127 | mask = *(volatile unsigned long *) PCI_INT_MASK_REG; | ||
128 | pend = stat & ~mask & 0xf0000000; | ||
129 | if (!pend) | ||
130 | break; | ||
131 | for (bit = 0; pend != 0; ++bit, pend <<= 1) { | ||
132 | if (pend & 0x80000000) | ||
133 | __do_IRQ(NR_CPM_INTS + bit, regs); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | return IRQ_HANDLED; | ||
138 | } | ||
139 | |||
140 | static struct irqaction pq2pci_irqaction = { | ||
141 | .handler = pq2pci_irq_demux, | ||
142 | .flags = SA_INTERRUPT, | ||
143 | .mask = CPU_MASK_NONE, | ||
144 | .name = "PQ2 PCI cascade", | ||
145 | }; | ||
146 | |||
147 | |||
148 | void | ||
149 | pq2pci_init_irq(void) | ||
150 | { | ||
151 | int irq; | ||
152 | volatile cpm2_map_t *immap = cpm2_immr; | ||
153 | #if defined CONFIG_ADS8272 | ||
154 | /* configure chip select for PCI interrupt controller */ | ||
155 | immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801; | ||
156 | immap->im_memctl.memc_or3 = 0xffff8010; | ||
157 | #elif defined CONFIG_PQ2FADS | ||
158 | immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801; | ||
159 | immap->im_memctl.memc_or8 = 0xffff8010; | ||
160 | #endif | ||
161 | for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) | ||
162 | irq_desc[irq].handler = &pq2pci_ic; | ||
163 | |||
164 | /* make PCI IRQ level sensitive */ | ||
165 | immap->im_intctl.ic_siexr &= | ||
166 | ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1))); | ||
167 | |||
168 | /* mask all PCI interrupts */ | ||
169 | *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000; | ||
170 | |||
171 | /* install the demultiplexer for the PCI cascade interrupt */ | ||
172 | setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction); | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | static int | ||
177 | pq2pci_exclude_device(u_char bus, u_char devfn) | ||
178 | { | ||
179 | return PCIBIOS_SUCCESSFUL; | ||
180 | } | ||
181 | |||
182 | /* PCI bus configuration registers. | ||
183 | */ | ||
184 | static void | ||
185 | pq2ads_setup_pci(struct pci_controller *hose) | ||
186 | { | ||
187 | __u32 val; | ||
188 | volatile cpm2_map_t *immap = cpm2_immr; | ||
189 | bd_t* binfo = (bd_t*) __res; | ||
190 | u32 sccr = immap->im_clkrst.car_sccr; | ||
191 | uint pci_div,freq,time; | ||
192 | /* PCI int lowest prio */ | ||
193 | /* Each 4 bits is a device bus request and the MS 4bits | ||
194 | is highest priority */ | ||
195 | /* Bus 4bit value | ||
196 | --- ---------- | ||
197 | CPM high 0b0000 | ||
198 | CPM middle 0b0001 | ||
199 | CPM low 0b0010 | ||
200 | PCI reguest 0b0011 | ||
201 | Reserved 0b0100 | ||
202 | Reserved 0b0101 | ||
203 | Internal Core 0b0110 | ||
204 | External Master 1 0b0111 | ||
205 | External Master 2 0b1000 | ||
206 | External Master 3 0b1001 | ||
207 | The rest are reserved | ||
208 | */ | ||
209 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | ||
210 | /* park bus on core */ | ||
211 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE; | ||
212 | /* | ||
213 | * Set up master windows that allow the CPU to access PCI space. These | ||
214 | * windows are set up using the two SIU PCIBR registers. | ||
215 | */ | ||
216 | |||
217 | immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE; | ||
218 | immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE; | ||
219 | |||
220 | #ifdef M82xx_PCI_SEC_WND_SIZE | ||
221 | immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE; | ||
222 | immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE; | ||
223 | #endif | ||
224 | |||
225 | #if defined CONFIG_ADS8272 | ||
226 | immap->im_siu_conf.siu_82xx.sc_siumcr = | ||
227 | (immap->im_siu_conf.siu_82xx.sc_siumcr & | ||
228 | ~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE | | ||
229 | SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 | | ||
230 | SIUMCR_LBPC11 | SIUMCR_APPC11 | | ||
231 | SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) | | ||
232 | SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 | | ||
233 | SIUMCR_APPC10 | SIUMCR_CS10PC00 | | ||
234 | SIUMCR_BCTLC00 | SIUMCR_MMR11 ; | ||
235 | |||
236 | #elif defined CONFIG_PQ2FADS | ||
237 | /* | ||
238 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | ||
239 | * and local bus for PCI (SIUMCR [LBPC]). | ||
240 | */ | ||
241 | immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr & | ||
242 | ~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) | | ||
243 | SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10; | ||
244 | #endif | ||
245 | /* Enable PCI */ | ||
246 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | ||
247 | |||
248 | pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) * | ||
249 | ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1); | ||
250 | freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div)); | ||
251 | time = (int)666666/freq; | ||
252 | /* due to PCI Local Bus spec, some devices needs to wait such a long | ||
253 | time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */ | ||
254 | printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq, | ||
255 | (time==1) ? "0.5 seconds":"1 second" ); | ||
256 | |||
257 | { | ||
258 | int i; | ||
259 | for(i=0;i<(500*time);i++) | ||
260 | udelay(1000); | ||
261 | } | ||
262 | |||
263 | /* setup ATU registers */ | ||
264 | immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO | | ||
265 | ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT)); | ||
266 | immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT); | ||
267 | immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT); | ||
268 | |||
269 | /* Set-up non-prefetchable window */ | ||
270 | immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT)); | ||
271 | immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT); | ||
272 | immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT); | ||
273 | |||
274 | /* Set-up prefetchable window */ | ||
275 | immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN | | ||
276 | (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT)); | ||
277 | immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT); | ||
278 | immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT); | ||
279 | |||
280 | /* Inbound transactions from PCI memory space */ | ||
281 | immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN | | ||
282 | ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT)); | ||
283 | immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT); | ||
284 | immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT); | ||
285 | |||
286 | #if defined CONFIG_ADS8272 | ||
287 | /* PCI int highest prio */ | ||
288 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745; | ||
289 | #elif defined CONFIG_PQ2FADS | ||
290 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | ||
291 | #endif | ||
292 | /* park bus on PCI */ | ||
293 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | ||
294 | |||
295 | /* Enable bus mastering and inbound memory transactions */ | ||
296 | early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val); | ||
297 | val &= 0xffff0000; | ||
298 | val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER; | ||
299 | early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val); | ||
300 | |||
301 | } | ||
302 | |||
303 | void __init pq2_find_bridges(void) | ||
304 | { | ||
305 | extern int pci_assign_all_busses; | ||
306 | struct pci_controller * hose; | ||
307 | int host_bridge; | ||
308 | |||
309 | pci_assign_all_busses = 1; | ||
310 | |||
311 | hose = pcibios_alloc_controller(); | ||
312 | |||
313 | if (!hose) | ||
314 | return; | ||
315 | |||
316 | ppc_md.pci_swizzle = common_swizzle; | ||
317 | |||
318 | hose->first_busno = 0; | ||
319 | hose->bus_offset = 0; | ||
320 | hose->last_busno = 0xff; | ||
321 | |||
322 | #ifdef CONFIG_ADS8272 | ||
323 | hose->set_cfg_type = 1; | ||
324 | #endif | ||
325 | |||
326 | setup_m8260_indirect_pci(hose, | ||
327 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | ||
328 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | ||
329 | |||
330 | /* Make sure it is a supported bridge */ | ||
331 | early_read_config_dword(hose, | ||
332 | 0, | ||
333 | PCI_DEVFN(0,0), | ||
334 | PCI_VENDOR_ID, | ||
335 | &host_bridge); | ||
336 | switch (host_bridge) { | ||
337 | case PCI_DEVICE_ID_MPC8265: | ||
338 | break; | ||
339 | case PCI_DEVICE_ID_MPC8272: | ||
340 | break; | ||
341 | default: | ||
342 | printk("Attempting to use unrecognized host bridge ID" | ||
343 | " 0x%08x.\n", host_bridge); | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | pq2ads_setup_pci(hose); | ||
348 | |||
349 | hose->io_space.start = M82xx_PCI_LOWER_IO; | ||
350 | hose->io_space.end = M82xx_PCI_UPPER_IO; | ||
351 | hose->mem_space.start = M82xx_PCI_LOWER_MEM; | ||
352 | hose->mem_space.end = M82xx_PCI_UPPER_MMIO; | ||
353 | hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET; | ||
354 | |||
355 | isa_io_base = | ||
356 | (unsigned long) ioremap(M82xx_PCI_IO_BASE, | ||
357 | M82xx_PCI_IO_SIZE); | ||
358 | hose->io_base_virt = (void *) isa_io_base; | ||
359 | |||
360 | /* setup resources */ | ||
361 | pci_init_resource(&hose->mem_resources[0], | ||
362 | M82xx_PCI_LOWER_MEM, | ||
363 | M82xx_PCI_UPPER_MEM, | ||
364 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | ||
365 | |||
366 | pci_init_resource(&hose->mem_resources[1], | ||
367 | M82xx_PCI_LOWER_MMIO, | ||
368 | M82xx_PCI_UPPER_MMIO, | ||
369 | IORESOURCE_MEM, "PCI memory"); | ||
370 | |||
371 | pci_init_resource(&hose->io_resource, | ||
372 | M82xx_PCI_LOWER_IO, | ||
373 | M82xx_PCI_UPPER_IO, | ||
374 | IORESOURCE_IO | 1, "PCI I/O"); | ||
375 | |||
376 | ppc_md.pci_exclude_device = pq2pci_exclude_device; | ||
377 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | ||
378 | |||
379 | ppc_md.pci_map_irq = pq2pci_map_irq; | ||
380 | ppc_md.pcibios_fixup = NULL; | ||
381 | ppc_md.pcibios_fixup_bus = NULL; | ||
382 | |||
383 | } | ||
diff --git a/arch/ppc/syslib/m82xx_pci.h b/arch/ppc/syslib/m82xx_pci.h new file mode 100644 index 000000000000..924f73f8e595 --- /dev/null +++ b/arch/ppc/syslib/m82xx_pci.h | |||
@@ -0,0 +1,92 @@ | |||
1 | |||
2 | #ifndef _PPC_KERNEL_M82XX_PCI_H | ||
3 | #define _PPC_KERNEL_M82XX_PCI_H | ||
4 | |||
5 | #include <asm/m8260_pci.h> | ||
6 | /* | ||
7 | * Local->PCI map (from CPU) controlled by | ||
8 | * MPC826x master window | ||
9 | * | ||
10 | * 0xF6000000 - 0xF7FFFFFF IO space | ||
11 | * 0x80000000 - 0xBFFFFFFF CPU2PCI memory space PCIBR0 | ||
12 | * | ||
13 | * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) | ||
14 | * 0xA0000000 - 0xBFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) | ||
15 | * 0xF6000000 - 0xF7FFFFFF 32-bit PCI IO (Outbound ATU #3) | ||
16 | * | ||
17 | * PCI->Local map (from PCI) | ||
18 | * MPC826x slave window controlled by | ||
19 | * | ||
20 | * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * Slave window that allows PCI masters to access MPC826x local memory. | ||
25 | * This window is set up using the first set of Inbound ATU registers | ||
26 | */ | ||
27 | |||
28 | #ifndef M82xx_PCI_SLAVE_MEM_LOCAL | ||
29 | #define M82xx_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) | ||
30 | #define M82xx_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) | ||
31 | #define M82xx_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * This is the window that allows the CPU to access PCI address space. | ||
36 | * It will be setup with the SIU PCIBR0 register. All three PCI master | ||
37 | * windows, which allow the CPU to access PCI prefetch, non prefetch, | ||
38 | * and IO space (see below), must all fit within this window. | ||
39 | */ | ||
40 | |||
41 | #ifndef M82xx_PCI_LOWER_MEM | ||
42 | #define M82xx_PCI_LOWER_MEM 0x80000000 | ||
43 | #define M82xx_PCI_UPPER_MEM 0x9fffffff | ||
44 | #define M82xx_PCI_MEM_OFFSET 0x00000000 | ||
45 | #define M82xx_PCI_MEM_SIZE 0x20000000 | ||
46 | #endif | ||
47 | |||
48 | #ifndef M82xx_PCI_LOWER_MMIO | ||
49 | #define M82xx_PCI_LOWER_MMIO 0xa0000000 | ||
50 | #define M82xx_PCI_UPPER_MMIO 0xafffffff | ||
51 | #define M82xx_PCI_MMIO_OFFSET 0x00000000 | ||
52 | #define M82xx_PCI_MMIO_SIZE 0x20000000 | ||
53 | #endif | ||
54 | |||
55 | #ifndef M82xx_PCI_LOWER_IO | ||
56 | #define M82xx_PCI_LOWER_IO 0x00000000 | ||
57 | #define M82xx_PCI_UPPER_IO 0x01ffffff | ||
58 | #define M82xx_PCI_IO_BASE 0xf6000000 | ||
59 | #define M82xx_PCI_IO_SIZE 0x02000000 | ||
60 | #endif | ||
61 | |||
62 | #ifndef M82xx_PCI_PRIM_WND_SIZE | ||
63 | #define M82xx_PCI_PRIM_WND_SIZE ~(M82xx_PCI_IO_SIZE - 1U) | ||
64 | #define M82xx_PCI_PRIM_WND_BASE (M82xx_PCI_IO_BASE) | ||
65 | #endif | ||
66 | |||
67 | #ifndef M82xx_PCI_SEC_WND_SIZE | ||
68 | #define M82xx_PCI_SEC_WND_SIZE ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U) | ||
69 | #define M82xx_PCI_SEC_WND_BASE (M82xx_PCI_LOWER_MEM) | ||
70 | #endif | ||
71 | |||
72 | #ifndef POTA_ADDR_SHIFT | ||
73 | #define POTA_ADDR_SHIFT 12 | ||
74 | #endif | ||
75 | |||
76 | #ifndef PITA_ADDR_SHIFT | ||
77 | #define PITA_ADDR_SHIFT 12 | ||
78 | #endif | ||
79 | |||
80 | #ifndef _IO_BASE | ||
81 | #define _IO_BASE isa_io_base | ||
82 | #endif | ||
83 | |||
84 | #ifdef CONFIG_8260_PCI9 | ||
85 | struct pci_controller; | ||
86 | extern void setup_m8260_indirect_pci(struct pci_controller* hose, | ||
87 | u32 cfg_addr, u32 cfg_data); | ||
88 | #else | ||
89 | #define setup_m8260_indirect_pci setup_indirect_pci | ||
90 | #endif | ||
91 | |||
92 | #endif /* _PPC_KERNEL_M8260_PCI_H */ | ||
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 9d4ed68b5804..000ba47c67cb 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c | |||
@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void) | |||
275 | } | 275 | } |
276 | #endif | 276 | #endif |
277 | 277 | ||
278 | #if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM) | 278 | #if defined(CONFIG_EPIC_SERIAL_MODE) |
279 | static void openpic_reset(void) | 279 | static void openpic_reset(void) |
280 | { | 280 | { |
281 | openpic_setfield(&OpenPIC->Global.Global_Configuration0, | 281 | openpic_setfield(&OpenPIC->Global.Global_Configuration0, |
@@ -993,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev) | |||
993 | return 0; | 993 | return 0; |
994 | } | 994 | } |
995 | 995 | ||
996 | openpic_reset(); | ||
997 | |||
998 | /* OpenPIC sometimes seem to need some time to be fully back up... */ | 996 | /* OpenPIC sometimes seem to need some time to be fully back up... */ |
999 | do { | 997 | do { |
1000 | openpic_set_spurious(OPENPIC_VEC_SPURIOUS); | 998 | openpic_set_spurious(OPENPIC_VEC_SPURIOUS); |
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index c28f9d679484..843cf8873e60 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/mmu.h> | 29 | #include <asm/mmu.h> |
30 | #include <asm/ppc_sys.h> | 30 | #include <asm/ppc_sys.h> |
31 | #include <asm/kgdb.h> | 31 | #include <asm/kgdb.h> |
32 | #include <asm/delay.h> | ||
32 | 33 | ||
33 | #include <syslib/ppc83xx_setup.h> | 34 | #include <syslib/ppc83xx_setup.h> |
34 | 35 | ||
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void) | |||
117 | void | 118 | void |
118 | mpc83xx_restart(char *cmd) | 119 | mpc83xx_restart(char *cmd) |
119 | { | 120 | { |
121 | volatile unsigned char __iomem *reg; | ||
122 | unsigned char tmp; | ||
123 | |||
124 | reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); | ||
125 | |||
120 | local_irq_disable(); | 126 | local_irq_disable(); |
127 | |||
128 | /* | ||
129 | * Unlock the BCSR bits so a PRST will update the contents. | ||
130 | * Otherwise the reset asserts but doesn't clear. | ||
131 | */ | ||
132 | tmp = in_8(reg + BCSR_MISC_REG3_OFF); | ||
133 | tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */ | ||
134 | out_8(reg + BCSR_MISC_REG3_OFF, tmp); | ||
135 | |||
136 | /* | ||
137 | * Trigger a reset via a low->high transition of the | ||
138 | * PORESET bit. | ||
139 | */ | ||
140 | tmp = in_8(reg + BCSR_MISC_REG2_OFF); | ||
141 | tmp &= ~BCSR_MISC_REG2_PORESET; | ||
142 | out_8(reg + BCSR_MISC_REG2_OFF, tmp); | ||
143 | |||
144 | udelay(1); | ||
145 | |||
146 | tmp |= BCSR_MISC_REG2_PORESET; | ||
147 | out_8(reg + BCSR_MISC_REG2_OFF, tmp); | ||
148 | |||
121 | for(;;); | 149 | for(;;); |
122 | } | 150 | } |
123 | 151 | ||
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 152c3ef1312a..f3277f469e78 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c | |||
@@ -132,6 +132,12 @@ mpc85xx_halt(void) | |||
132 | } | 132 | } |
133 | 133 | ||
134 | #ifdef CONFIG_PCI | 134 | #ifdef CONFIG_PCI |
135 | |||
136 | #if defined(CONFIG_MPC8555_CDS) | ||
137 | extern void mpc85xx_cds_enable_via(struct pci_controller *hose); | ||
138 | extern void mpc85xx_cds_fixup_via(struct pci_controller *hose); | ||
139 | #endif | ||
140 | |||
135 | static void __init | 141 | static void __init |
136 | mpc85xx_setup_pci1(struct pci_controller *hose) | 142 | mpc85xx_setup_pci1(struct pci_controller *hose) |
137 | { | 143 | { |
@@ -302,8 +308,18 @@ mpc85xx_setup_hose(void) | |||
302 | 308 | ||
303 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | 309 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; |
304 | 310 | ||
311 | #if defined(CONFIG_MPC8555_CDS) | ||
312 | /* Pre pciauto_bus_scan VIA init */ | ||
313 | mpc85xx_cds_enable_via(hose_a); | ||
314 | #endif | ||
315 | |||
305 | hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); | 316 | hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); |
306 | 317 | ||
318 | #if defined(CONFIG_MPC8555_CDS) | ||
319 | /* Post pciauto_bus_scan VIA fixup */ | ||
320 | mpc85xx_cds_fixup_via(hose_a); | ||
321 | #endif | ||
322 | |||
307 | #ifdef CONFIG_85xx_PCI2 | 323 | #ifdef CONFIG_85xx_PCI2 |
308 | hose_b = pcibios_alloc_controller(); | 324 | hose_b = pcibios_alloc_controller(); |
309 | 325 | ||
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c index 2cee87137f2e..7f15136830f4 100644 --- a/arch/ppc/syslib/prom_init.c +++ b/arch/ppc/syslib/prom_init.c | |||
@@ -626,8 +626,18 @@ inspect_node(phandle node, struct device_node *dad, | |||
626 | l = call_prom("package-to-path", 3, 1, node, | 626 | l = call_prom("package-to-path", 3, 1, node, |
627 | mem_start, mem_end - mem_start); | 627 | mem_start, mem_end - mem_start); |
628 | if (l >= 0) { | 628 | if (l >= 0) { |
629 | char *p, *ep; | ||
630 | |||
629 | np->full_name = PTRUNRELOC((char *) mem_start); | 631 | np->full_name = PTRUNRELOC((char *) mem_start); |
630 | *(char *)(mem_start + l) = 0; | 632 | *(char *)(mem_start + l) = 0; |
633 | /* Fixup an Apple bug where they have bogus \0 chars in the | ||
634 | * middle of the path in some properties | ||
635 | */ | ||
636 | for (p = (char *)mem_start, ep = p + l; p < ep; p++) | ||
637 | if ((*p) == '\0') { | ||
638 | memmove(p, p+1, ep - p); | ||
639 | ep--; | ||
640 | } | ||
631 | mem_start = ALIGNUL(mem_start + l + 1); | 641 | mem_start = ALIGNUL(mem_start + l + 1); |
632 | } | 642 | } |
633 | 643 | ||
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index d3604056e1a9..b61572eb2a71 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S | |||
@@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
436 | REST_8GPRS(14, r1) | 436 | REST_8GPRS(14, r1) |
437 | REST_10GPRS(22, r1) | 437 | REST_10GPRS(22, r1) |
438 | 438 | ||
439 | #ifdef CONFIG_PPC_ISERIES | ||
440 | clrrdi r7,r1,THREAD_SHIFT /* get current_thread_info() */ | ||
441 | ld r7,TI_FLAGS(r7) /* Get run light flag */ | ||
442 | mfspr r9,CTRLF | ||
443 | srdi r7,r7,TIF_RUN_LIGHT | ||
444 | insrdi r9,r7,1,63 /* Insert run light into CTRL */ | ||
445 | mtspr CTRLT,r9 | ||
446 | #endif | ||
447 | |||
448 | /* convert old thread to its task_struct for return value */ | 439 | /* convert old thread to its task_struct for return value */ |
449 | addi r3,r3,-THREAD | 440 | addi r3,r3,-THREAD |
450 | ld r7,_NIP(r1) /* Return to _switch caller in new task */ | 441 | ld r7,_NIP(r1) /* Return to _switch caller in new task */ |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 92a744c31ab1..346dbf606b5d 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -626,10 +626,10 @@ system_reset_iSeries: | |||
626 | lhz r24,PACAPACAINDEX(r13) /* Get processor # */ | 626 | lhz r24,PACAPACAINDEX(r13) /* Get processor # */ |
627 | cmpwi 0,r24,0 /* Are we processor 0? */ | 627 | cmpwi 0,r24,0 /* Are we processor 0? */ |
628 | beq .__start_initialization_iSeries /* Start up the first processor */ | 628 | beq .__start_initialization_iSeries /* Start up the first processor */ |
629 | mfspr r4,CTRLF | 629 | mfspr r4,SPRN_CTRLF |
630 | li r5,RUNLATCH /* Turn off the run light */ | 630 | li r5,CTRL_RUNLATCH /* Turn off the run light */ |
631 | andc r4,r4,r5 | 631 | andc r4,r4,r5 |
632 | mtspr CTRLT,r4 | 632 | mtspr SPRN_CTRLT,r4 |
633 | 633 | ||
634 | 1: | 634 | 1: |
635 | HMT_LOW | 635 | HMT_LOW |
@@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary) | |||
2082 | mfspr r4, HID0 | 2082 | mfspr r4, HID0 |
2083 | ori r4, r4, 0x1 | 2083 | ori r4, r4, 0x1 |
2084 | mtspr HID0, r4 | 2084 | mtspr HID0, r4 |
2085 | mfspr r4, CTRLF | 2085 | mfspr r4, SPRN_CTRLF |
2086 | oris r4, r4, 0x40 | 2086 | oris r4, r4, 0x40 |
2087 | mtspr CTRLT, r4 | 2087 | mtspr SPRN_CTRLT, r4 |
2088 | blr | 2088 | blr |
2089 | #endif | 2089 | #endif |
2090 | 2090 | ||
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index da20120f2261..6d06eb550a3f 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
@@ -852,6 +852,28 @@ static int __init iSeries_src_init(void) | |||
852 | 852 | ||
853 | late_initcall(iSeries_src_init); | 853 | late_initcall(iSeries_src_init); |
854 | 854 | ||
855 | static int set_spread_lpevents(char *str) | ||
856 | { | ||
857 | unsigned long i; | ||
858 | unsigned long val = simple_strtoul(str, NULL, 0); | ||
859 | |||
860 | /* | ||
861 | * The parameter is the number of processors to share in processing | ||
862 | * lp events. | ||
863 | */ | ||
864 | if (( val > 0) && (val <= NR_CPUS)) { | ||
865 | for (i = 1; i < val; ++i) | ||
866 | paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; | ||
867 | |||
868 | printk("lpevent processing spread over %ld processors\n", val); | ||
869 | } else { | ||
870 | printk("invalid spread_lpevents %ld\n", val); | ||
871 | } | ||
872 | |||
873 | return 1; | ||
874 | } | ||
875 | __setup("spread_lpevents=", set_spread_lpevents); | ||
876 | |||
855 | void __init iSeries_early_setup(void) | 877 | void __init iSeries_early_setup(void) |
856 | { | 878 | { |
857 | iSeries_fixup_klimit(); | 879 | iSeries_fixup_klimit(); |
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 6abc621d3ba0..f24ce2b87200 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c | |||
@@ -75,13 +75,9 @@ static int iSeries_idle(void) | |||
75 | { | 75 | { |
76 | struct paca_struct *lpaca; | 76 | struct paca_struct *lpaca; |
77 | long oldval; | 77 | long oldval; |
78 | unsigned long CTRL; | ||
79 | 78 | ||
80 | /* ensure iSeries run light will be out when idle */ | 79 | /* ensure iSeries run light will be out when idle */ |
81 | clear_thread_flag(TIF_RUN_LIGHT); | 80 | ppc64_runlatch_off(); |
82 | CTRL = mfspr(CTRLF); | ||
83 | CTRL &= ~RUNLATCH; | ||
84 | mtspr(CTRLT, CTRL); | ||
85 | 81 | ||
86 | lpaca = get_paca(); | 82 | lpaca = get_paca(); |
87 | 83 | ||
@@ -111,7 +107,9 @@ static int iSeries_idle(void) | |||
111 | } | 107 | } |
112 | } | 108 | } |
113 | 109 | ||
110 | ppc64_runlatch_on(); | ||
114 | schedule(); | 111 | schedule(); |
112 | ppc64_runlatch_off(); | ||
115 | } | 113 | } |
116 | 114 | ||
117 | return 0; | 115 | return 0; |
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/ppc64/kernel/pSeries_reconfig.c index cb5443f2e49b..dc2a69d412a2 100644 --- a/arch/ppc64/kernel/pSeries_reconfig.c +++ b/arch/ppc64/kernel/pSeries_reconfig.c | |||
@@ -47,14 +47,6 @@ static void remove_node_proc_entries(struct device_node *np) | |||
47 | remove_proc_entry(pp->name, np->pde); | 47 | remove_proc_entry(pp->name, np->pde); |
48 | pp = pp->next; | 48 | pp = pp->next; |
49 | } | 49 | } |
50 | |||
51 | /* Assuming that symlinks have the same parent directory as | ||
52 | * np->pde. | ||
53 | */ | ||
54 | if (np->name_link) | ||
55 | remove_proc_entry(np->name_link->name, parent->pde); | ||
56 | if (np->addr_link) | ||
57 | remove_proc_entry(np->addr_link->name, parent->pde); | ||
58 | if (np->pde) | 50 | if (np->pde) |
59 | remove_proc_entry(np->pde->name, parent->pde); | 51 | remove_proc_entry(np->pde->name, parent->pde); |
60 | } | 52 | } |
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index 8b0686122738..cdfecbeb331f 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c | |||
@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
378 | childregs->gpr[1] = sp + sizeof(struct pt_regs); | 378 | childregs->gpr[1] = sp + sizeof(struct pt_regs); |
379 | p->thread.regs = NULL; /* no user register state */ | 379 | p->thread.regs = NULL; /* no user register state */ |
380 | clear_ti_thread_flag(p->thread_info, TIF_32BIT); | 380 | clear_ti_thread_flag(p->thread_info, TIF_32BIT); |
381 | #ifdef CONFIG_PPC_ISERIES | ||
382 | set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT); | ||
383 | #endif | ||
384 | } else { | 381 | } else { |
385 | childregs->gpr[1] = usp; | 382 | childregs->gpr[1] = usp; |
386 | p->thread.regs = childregs; | 383 | p->thread.regs = childregs; |
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 6f79b7b9b445..b7683abfbe6a 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c | |||
@@ -211,13 +211,23 @@ struct { | |||
211 | */ | 211 | */ |
212 | #define ADDR(x) (u32) ((unsigned long)(x) - offset) | 212 | #define ADDR(x) (u32) ((unsigned long)(x) - offset) |
213 | 213 | ||
214 | /* | ||
215 | * Error results ... some OF calls will return "-1" on error, some | ||
216 | * will return 0, some will return either. To simplify, here are | ||
217 | * macros to use with any ihandle or phandle return value to check if | ||
218 | * it is valid | ||
219 | */ | ||
220 | |||
221 | #define PROM_ERROR (-1u) | ||
222 | #define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) | ||
223 | #define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) | ||
224 | |||
225 | |||
214 | /* This is the one and *ONLY* place where we actually call open | 226 | /* This is the one and *ONLY* place where we actually call open |
215 | * firmware from, since we need to make sure we're running in 32b | 227 | * firmware from, since we need to make sure we're running in 32b |
216 | * mode when we do. We switch back to 64b mode upon return. | 228 | * mode when we do. We switch back to 64b mode upon return. |
217 | */ | 229 | */ |
218 | 230 | ||
219 | #define PROM_ERROR (-1) | ||
220 | |||
221 | static int __init call_prom(const char *service, int nargs, int nret, ...) | 231 | static int __init call_prom(const char *service, int nargs, int nret, ...) |
222 | { | 232 | { |
223 | int i; | 233 | int i; |
@@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void) | |||
587 | { | 597 | { |
588 | unsigned long offset = reloc_offset(); | 598 | unsigned long offset = reloc_offset(); |
589 | ihandle elfloader; | 599 | ihandle elfloader; |
590 | int ret; | ||
591 | 600 | ||
592 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); | 601 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); |
593 | if (elfloader == 0) { | 602 | if (elfloader == 0) { |
594 | prom_printf("couldn't open /packages/elf-loader\n"); | 603 | prom_printf("couldn't open /packages/elf-loader\n"); |
595 | return; | 604 | return; |
596 | } | 605 | } |
597 | ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), | 606 | call_prom("call-method", 3, 1, ADDR("process-elf-header"), |
598 | elfloader, ADDR(&fake_elf)); | 607 | elfloader, ADDR(&fake_elf)); |
599 | call_prom("close", 1, 0, elfloader); | 608 | call_prom("close", 1, 0, elfloader); |
600 | } | 609 | } |
@@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) | |||
646 | base = _ALIGN_UP(base + 0x100000, align)) { | 655 | base = _ALIGN_UP(base + 0x100000, align)) { |
647 | prom_debug(" trying: 0x%x\n\r", base); | 656 | prom_debug(" trying: 0x%x\n\r", base); |
648 | addr = (unsigned long)prom_claim(base, size, 0); | 657 | addr = (unsigned long)prom_claim(base, size, 0); |
649 | if ((int)addr != PROM_ERROR) | 658 | if (addr != PROM_ERROR) |
650 | break; | 659 | break; |
651 | addr = 0; | 660 | addr = 0; |
652 | if (align == 0) | 661 | if (align == 0) |
@@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align, | |||
708 | for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { | 717 | for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { |
709 | prom_debug(" trying: 0x%x\n\r", base); | 718 | prom_debug(" trying: 0x%x\n\r", base); |
710 | addr = (unsigned long)prom_claim(base, size, 0); | 719 | addr = (unsigned long)prom_claim(base, size, 0); |
711 | if ((int)addr != PROM_ERROR) | 720 | if (addr != PROM_ERROR) |
712 | break; | 721 | break; |
713 | addr = 0; | 722 | addr = 0; |
714 | } | 723 | } |
@@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void) | |||
902 | { | 911 | { |
903 | unsigned long offset = reloc_offset(); | 912 | unsigned long offset = reloc_offset(); |
904 | struct prom_t *_prom = PTRRELOC(&prom); | 913 | struct prom_t *_prom = PTRRELOC(&prom); |
905 | phandle prom_rtas, rtas_node; | 914 | phandle rtas_node; |
915 | ihandle rtas_inst; | ||
906 | u32 base, entry = 0; | 916 | u32 base, entry = 0; |
907 | u32 size = 0; | 917 | u32 size = 0; |
908 | 918 | ||
909 | prom_debug("prom_instantiate_rtas: start...\n"); | 919 | prom_debug("prom_instantiate_rtas: start...\n"); |
910 | 920 | ||
911 | prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 921 | rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
912 | prom_debug("prom_rtas: %x\n", prom_rtas); | 922 | prom_debug("rtas_node: %x\n", rtas_node); |
913 | if (prom_rtas == (phandle) -1) | 923 | if (!PHANDLE_VALID(rtas_node)) |
914 | return; | 924 | return; |
915 | 925 | ||
916 | prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size)); | 926 | prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); |
917 | if (size == 0) | 927 | if (size == 0) |
918 | return; | 928 | return; |
919 | 929 | ||
@@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void) | |||
922 | prom_printf("RTAS allocation failed !\n"); | 932 | prom_printf("RTAS allocation failed !\n"); |
923 | return; | 933 | return; |
924 | } | 934 | } |
925 | prom_printf("instantiating rtas at 0x%x", base); | ||
926 | 935 | ||
927 | rtas_node = call_prom("open", 1, 1, ADDR("/rtas")); | 936 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); |
928 | prom_printf("..."); | 937 | if (!IHANDLE_VALID(rtas_inst)) { |
938 | prom_printf("opening rtas package failed"); | ||
939 | return; | ||
940 | } | ||
941 | |||
942 | prom_printf("instantiating rtas at 0x%x ...", base); | ||
929 | 943 | ||
930 | if (call_prom("call-method", 3, 2, | 944 | if (call_prom("call-method", 3, 2, |
931 | ADDR("instantiate-rtas"), | 945 | ADDR("instantiate-rtas"), |
932 | rtas_node, base) != PROM_ERROR) { | 946 | rtas_inst, base) != PROM_ERROR) { |
933 | entry = (long)_prom->args.rets[1]; | 947 | entry = (long)_prom->args.rets[1]; |
934 | } | 948 | } |
935 | if (entry == 0) { | 949 | if (entry == 0) { |
@@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void) | |||
940 | 954 | ||
941 | reserve_mem(base, size); | 955 | reserve_mem(base, size); |
942 | 956 | ||
943 | prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base)); | 957 | prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); |
944 | prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry)); | 958 | prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); |
945 | 959 | ||
946 | prom_debug("rtas base = 0x%x\n", base); | 960 | prom_debug("rtas base = 0x%x\n", base); |
947 | prom_debug("rtas entry = 0x%x\n", entry); | 961 | prom_debug("rtas entry = 0x%x\n", entry); |
@@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void) | |||
1062 | 1076 | ||
1063 | prom_printf("opening PHB %s", path); | 1077 | prom_printf("opening PHB %s", path); |
1064 | phb_node = call_prom("open", 1, 1, path); | 1078 | phb_node = call_prom("open", 1, 1, path); |
1065 | if ( (long)phb_node <= 0) | 1079 | if (phb_node == 0) |
1066 | prom_printf("... failed\n"); | 1080 | prom_printf("... failed\n"); |
1067 | else | 1081 | else |
1068 | prom_printf("... done\n"); | 1082 | prom_printf("... done\n"); |
@@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp) | |||
1279 | 1293 | ||
1280 | /* get a handle for the stdout device */ | 1294 | /* get a handle for the stdout device */ |
1281 | _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); | 1295 | _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); |
1282 | if ((long)_prom->chosen <= 0) | 1296 | if (!PHANDLE_VALID(_prom->chosen)) |
1283 | prom_panic("cannot find chosen"); /* msg won't be printed :( */ | 1297 | prom_panic("cannot find chosen"); /* msg won't be printed :( */ |
1284 | 1298 | ||
1285 | /* get device tree root */ | 1299 | /* get device tree root */ |
1286 | _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); | 1300 | _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); |
1287 | if ((long)_prom->root <= 0) | 1301 | if (!PHANDLE_VALID(_prom->root)) |
1288 | prom_panic("cannot find device tree root"); /* msg won't be printed :( */ | 1302 | prom_panic("cannot find device tree root"); /* msg won't be printed :( */ |
1289 | } | 1303 | } |
1290 | 1304 | ||
@@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void) | |||
1356 | } | 1370 | } |
1357 | /* Default to pSeries. We need to know if we are running LPAR */ | 1371 | /* Default to pSeries. We need to know if we are running LPAR */ |
1358 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 1372 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
1359 | if (rtas != (phandle) -1) { | 1373 | if (PHANDLE_VALID(rtas)) { |
1360 | unsigned long x; | 1374 | int x = prom_getproplen(rtas, "ibm,hypertas-functions"); |
1361 | x = prom_getproplen(rtas, "ibm,hypertas-functions"); | ||
1362 | if (x != PROM_ERROR) { | 1375 | if (x != PROM_ERROR) { |
1363 | prom_printf("Hypertas detected, assuming LPAR !\n"); | 1376 | prom_printf("Hypertas detected, assuming LPAR !\n"); |
1364 | return PLATFORM_PSERIES_LPAR; | 1377 | return PLATFORM_PSERIES_LPAR; |
@@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void) | |||
1426 | * leave some room at the end of the path for appending extra | 1439 | * leave some room at the end of the path for appending extra |
1427 | * arguments | 1440 | * arguments |
1428 | */ | 1441 | */ |
1429 | if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0) | 1442 | if (call_prom("package-to-path", 3, 1, node, path, |
1443 | PROM_SCRATCH_SIZE-10) == PROM_ERROR) | ||
1430 | continue; | 1444 | continue; |
1431 | prom_printf("found display : %s, opening ... ", path); | 1445 | prom_printf("found display : %s, opening ... ", path); |
1432 | 1446 | ||
1433 | ih = call_prom("open", 1, 1, path); | 1447 | ih = call_prom("open", 1, 1, path); |
1434 | if (ih == (ihandle)0 || ih == (ihandle)-1) { | 1448 | if (ih == 0) { |
1435 | prom_printf("failed\n"); | 1449 | prom_printf("failed\n"); |
1436 | continue; | 1450 | continue; |
1437 | } | 1451 | } |
@@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str) | |||
1514 | return 0; | 1528 | return 0; |
1515 | } | 1529 | } |
1516 | 1530 | ||
1531 | /* | ||
1532 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
1533 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
1534 | */ | ||
1535 | #define MAX_PROPERTY_NAME 64 | ||
1536 | |||
1517 | static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | 1537 | static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, |
1518 | unsigned long *mem_end) | 1538 | unsigned long *mem_end) |
1519 | { | 1539 | { |
@@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
1527 | /* get and store all property names */ | 1547 | /* get and store all property names */ |
1528 | prev_name = RELOC(""); | 1548 | prev_name = RELOC(""); |
1529 | for (;;) { | 1549 | for (;;) { |
1530 | 1550 | int rc; | |
1531 | /* 32 is max len of name including nul. */ | 1551 | |
1532 | namep = make_room(mem_start, mem_end, 32, 1); | 1552 | /* 64 is max len of name including nul. */ |
1533 | if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { | 1553 | namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); |
1554 | rc = call_prom("nextprop", 3, 1, node, prev_name, namep); | ||
1555 | if (rc != 1) { | ||
1534 | /* No more nodes: unwind alloc */ | 1556 | /* No more nodes: unwind alloc */ |
1535 | *mem_start = (unsigned long)namep; | 1557 | *mem_start = (unsigned long)namep; |
1536 | break; | 1558 | break; |
@@ -1555,18 +1577,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
1555 | } | 1577 | } |
1556 | } | 1578 | } |
1557 | 1579 | ||
1558 | /* | ||
1559 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
1560 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
1561 | */ | ||
1562 | #define MAX_PROPERTY_NAME 64 | ||
1563 | |||
1564 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | 1580 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, |
1565 | unsigned long *mem_end) | 1581 | unsigned long *mem_end) |
1566 | { | 1582 | { |
1567 | int l, align; | 1583 | int l, align; |
1568 | phandle child; | 1584 | phandle child; |
1569 | char *namep, *prev_name, *sstart; | 1585 | char *namep, *prev_name, *sstart, *p, *ep; |
1570 | unsigned long soff; | 1586 | unsigned long soff; |
1571 | unsigned char *valp; | 1587 | unsigned char *valp; |
1572 | unsigned long offset = reloc_offset(); | 1588 | unsigned long offset = reloc_offset(); |
@@ -1588,6 +1604,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1588 | call_prom("package-to-path", 3, 1, node, namep, l); | 1604 | call_prom("package-to-path", 3, 1, node, namep, l); |
1589 | } | 1605 | } |
1590 | namep[l] = '\0'; | 1606 | namep[l] = '\0'; |
1607 | /* Fixup an Apple bug where they have bogus \0 chars in the | ||
1608 | * middle of the path in some properties | ||
1609 | */ | ||
1610 | for (p = namep, ep = namep + l; p < ep; p++) | ||
1611 | if (*p == '\0') { | ||
1612 | memmove(p, p+1, ep - p); | ||
1613 | ep--; l--; | ||
1614 | } | ||
1591 | *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); | 1615 | *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); |
1592 | } | 1616 | } |
1593 | 1617 | ||
@@ -1599,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1599 | prev_name = RELOC(""); | 1623 | prev_name = RELOC(""); |
1600 | sstart = (char *)RELOC(dt_string_start); | 1624 | sstart = (char *)RELOC(dt_string_start); |
1601 | for (;;) { | 1625 | for (;;) { |
1602 | if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0) | 1626 | int rc; |
1627 | |||
1628 | rc = call_prom("nextprop", 3, 1, node, prev_name, pname); | ||
1629 | if (rc != 1) | ||
1603 | break; | 1630 | break; |
1604 | 1631 | ||
1605 | /* find string offset */ | 1632 | /* find string offset */ |
@@ -1615,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1615 | l = call_prom("getproplen", 2, 1, node, pname); | 1642 | l = call_prom("getproplen", 2, 1, node, pname); |
1616 | 1643 | ||
1617 | /* sanity checks */ | 1644 | /* sanity checks */ |
1618 | if (l < 0) | 1645 | if (l == PROM_ERROR) |
1619 | continue; | 1646 | continue; |
1620 | if (l > MAX_PROPERTY_LENGTH) { | 1647 | if (l > MAX_PROPERTY_LENGTH) { |
1621 | prom_printf("WARNING: ignoring large property "); | 1648 | prom_printf("WARNING: ignoring large property "); |
@@ -1763,17 +1790,18 @@ static void __init fixup_device_tree(void) | |||
1763 | 1790 | ||
1764 | /* Some G5s have a missing interrupt definition, fix it up here */ | 1791 | /* Some G5s have a missing interrupt definition, fix it up here */ |
1765 | u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); | 1792 | u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); |
1766 | if ((long)u3 <= 0) | 1793 | if (!PHANDLE_VALID(u3)) |
1767 | return; | 1794 | return; |
1768 | i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); | 1795 | i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); |
1769 | if ((long)i2c <= 0) | 1796 | if (!PHANDLE_VALID(i2c)) |
1770 | return; | 1797 | return; |
1771 | mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); | 1798 | mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); |
1772 | if ((long)mpic <= 0) | 1799 | if (!PHANDLE_VALID(mpic)) |
1773 | return; | 1800 | return; |
1774 | 1801 | ||
1775 | /* check if proper rev of u3 */ | 1802 | /* check if proper rev of u3 */ |
1776 | if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0) | 1803 | if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) |
1804 | == PROM_ERROR) | ||
1777 | return; | 1805 | return; |
1778 | if (u3_rev != 0x35) | 1806 | if (u3_rev != 0x35) |
1779 | return; | 1807 | return; |
@@ -1881,6 +1909,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long | |||
1881 | &getprop_rval, sizeof(getprop_rval)); | 1909 | &getprop_rval, sizeof(getprop_rval)); |
1882 | 1910 | ||
1883 | /* | 1911 | /* |
1912 | * On pSeries, inform the firmware about our capabilities | ||
1913 | */ | ||
1914 | if (RELOC(of_platform) & PLATFORM_PSERIES) | ||
1915 | prom_send_capabilities(); | ||
1916 | |||
1917 | /* | ||
1884 | * On pSeries, copy the CPU hold code | 1918 | * On pSeries, copy the CPU hold code |
1885 | */ | 1919 | */ |
1886 | if (RELOC(of_platform) & PLATFORM_PSERIES) | 1920 | if (RELOC(of_platform) & PLATFORM_PSERIES) |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 21c57f539c29..dce198d39328 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -103,11 +103,6 @@ extern void unflatten_device_tree(void); | |||
103 | 103 | ||
104 | extern void smp_release_cpus(void); | 104 | extern void smp_release_cpus(void); |
105 | 105 | ||
106 | unsigned long decr_overclock = 1; | ||
107 | unsigned long decr_overclock_proc0 = 1; | ||
108 | unsigned long decr_overclock_set = 0; | ||
109 | unsigned long decr_overclock_proc0_set = 0; | ||
110 | |||
111 | int have_of = 1; | 106 | int have_of = 1; |
112 | int boot_cpuid = 0; | 107 | int boot_cpuid = 0; |
113 | int boot_cpuid_phys = 0; | 108 | int boot_cpuid_phys = 0; |
@@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg) | |||
1120 | printk("[dump]%04x %s\n", src, msg); | 1115 | printk("[dump]%04x %s\n", src, msg); |
1121 | } | 1116 | } |
1122 | 1117 | ||
1123 | int set_spread_lpevents( char * str ) | ||
1124 | { | ||
1125 | /* The parameter is the number of processors to share in processing lp events */ | ||
1126 | unsigned long i; | ||
1127 | unsigned long val = simple_strtoul( str, NULL, 0 ); | ||
1128 | if ( ( val > 0 ) && ( val <= NR_CPUS ) ) { | ||
1129 | for ( i=1; i<val; ++i ) | ||
1130 | paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; | ||
1131 | printk("lpevent processing spread over %ld processors\n", val); | ||
1132 | } | ||
1133 | else | ||
1134 | printk("invalid spreaqd_lpevents %ld\n", val); | ||
1135 | return 1; | ||
1136 | } | ||
1137 | |||
1138 | /* This should only be called on processor 0 during calibrate decr */ | 1118 | /* This should only be called on processor 0 during calibrate decr */ |
1139 | void setup_default_decr(void) | 1119 | void setup_default_decr(void) |
1140 | { | 1120 | { |
1141 | struct paca_struct *lpaca = get_paca(); | 1121 | struct paca_struct *lpaca = get_paca(); |
1142 | 1122 | ||
1143 | if ( decr_overclock_set && !decr_overclock_proc0_set ) | 1123 | lpaca->default_decr = tb_ticks_per_jiffy; |
1144 | decr_overclock_proc0 = decr_overclock; | ||
1145 | |||
1146 | lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0; | ||
1147 | lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; | 1124 | lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; |
1148 | } | 1125 | } |
1149 | 1126 | ||
1150 | int set_decr_overclock_proc0( char * str ) | ||
1151 | { | ||
1152 | unsigned long val = simple_strtoul( str, NULL, 0 ); | ||
1153 | if ( ( val >= 1 ) && ( val <= 48 ) ) { | ||
1154 | decr_overclock_proc0_set = 1; | ||
1155 | decr_overclock_proc0 = val; | ||
1156 | printk("proc 0 decrementer overclock factor of %ld\n", val); | ||
1157 | } | ||
1158 | else | ||
1159 | printk("invalid proc 0 decrementer overclock factor of %ld\n", val); | ||
1160 | return 1; | ||
1161 | } | ||
1162 | |||
1163 | int set_decr_overclock( char * str ) | ||
1164 | { | ||
1165 | unsigned long val = simple_strtoul( str, NULL, 0 ); | ||
1166 | if ( ( val >= 1 ) && ( val <= 48 ) ) { | ||
1167 | decr_overclock_set = 1; | ||
1168 | decr_overclock = val; | ||
1169 | printk("decrementer overclock factor of %ld\n", val); | ||
1170 | } | ||
1171 | else | ||
1172 | printk("invalid decrementer overclock factor of %ld\n", val); | ||
1173 | return 1; | ||
1174 | |||
1175 | } | ||
1176 | |||
1177 | __setup("spread_lpevents=", set_spread_lpevents ); | ||
1178 | __setup("decr_overclock_proc0=", set_decr_overclock_proc0 ); | ||
1179 | __setup("decr_overclock=", set_decr_overclock ); | ||
1180 | |||
1181 | #ifndef CONFIG_PPC_ISERIES | 1127 | #ifndef CONFIG_PPC_ISERIES |
1182 | /* | 1128 | /* |
1183 | * This function can be used by platforms to "find" legacy serial ports. | 1129 | * This function can be used by platforms to "find" legacy serial ports. |
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 3b906cd94037..9ef5d36d6b25 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c | |||
@@ -334,7 +334,6 @@ void smp_call_function_interrupt(void) | |||
334 | } | 334 | } |
335 | } | 335 | } |
336 | 336 | ||
337 | extern unsigned long decr_overclock; | ||
338 | extern struct gettimeofday_struct do_gtod; | 337 | extern struct gettimeofday_struct do_gtod; |
339 | 338 | ||
340 | struct thread_info *current_set[NR_CPUS]; | 339 | struct thread_info *current_set[NR_CPUS]; |
@@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu) | |||
491 | if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) | 490 | if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) |
492 | return -EINVAL; | 491 | return -EINVAL; |
493 | 492 | ||
494 | paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; | 493 | paca[cpu].default_decr = tb_ticks_per_jiffy; |
495 | 494 | ||
496 | if (!cpu_has_feature(CPU_FTR_SLB)) { | 495 | if (!cpu_has_feature(CPU_FTR_SLB)) { |
497 | void *tmp; | 496 | void *tmp; |
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index 0925694c3ce5..c8fa6569b2fd 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c | |||
@@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void) | |||
113 | #ifdef CONFIG_PPC_PSERIES | 113 | #ifdef CONFIG_PPC_PSERIES |
114 | unsigned long set, reset; | 114 | unsigned long set, reset; |
115 | int ret; | 115 | int ret; |
116 | unsigned int ctrl; | ||
117 | #endif /* CONFIG_PPC_PSERIES */ | 116 | #endif /* CONFIG_PPC_PSERIES */ |
118 | 117 | ||
119 | /* Only need to enable them once */ | 118 | /* Only need to enable them once */ |
@@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void) | |||
167 | * On SMT machines we have to set the run latch in the ctrl register | 166 | * On SMT machines we have to set the run latch in the ctrl register |
168 | * in order to make PMC6 spin. | 167 | * in order to make PMC6 spin. |
169 | */ | 168 | */ |
170 | if (cpu_has_feature(CPU_FTR_SMT)) { | 169 | if (cpu_has_feature(CPU_FTR_SMT)) |
171 | ctrl = mfspr(CTRLF); | 170 | ppc64_runlatch_on(); |
172 | ctrl |= RUNLATCH; | ||
173 | mtspr(CTRLT, ctrl); | ||
174 | } | ||
175 | #endif /* CONFIG_PPC_PSERIES */ | 171 | #endif /* CONFIG_PPC_PSERIES */ |
176 | } | 172 | } |
177 | 173 | ||
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 3d54745108c7..33364a7d2cd2 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
@@ -325,9 +325,7 @@ int timer_interrupt(struct pt_regs * regs) | |||
325 | 325 | ||
326 | irq_enter(); | 326 | irq_enter(); |
327 | 327 | ||
328 | #ifndef CONFIG_PPC_ISERIES | ||
329 | profile_tick(CPU_PROFILING, regs); | 328 | profile_tick(CPU_PROFILING, regs); |
330 | #endif | ||
331 | 329 | ||
332 | lpaca->lppaca.int_dword.fields.decr_int = 0; | 330 | lpaca->lppaca.int_dword.fields.decr_int = 0; |
333 | 331 | ||
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 33ca56c90da2..2803bc7c2c79 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c | |||
@@ -196,6 +196,34 @@ static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long | |||
196 | return NULL; | 196 | return NULL; |
197 | } | 197 | } |
198 | 198 | ||
199 | static int iommu_alloc_ctx(struct pci_iommu *iommu) | ||
200 | { | ||
201 | int lowest = iommu->ctx_lowest_free; | ||
202 | int sz = IOMMU_NUM_CTXS - lowest; | ||
203 | int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest); | ||
204 | |||
205 | if (unlikely(n == sz)) { | ||
206 | n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); | ||
207 | if (unlikely(n == lowest)) { | ||
208 | printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); | ||
209 | n = 0; | ||
210 | } | ||
211 | } | ||
212 | if (n) | ||
213 | __set_bit(n, iommu->ctx_bitmap); | ||
214 | |||
215 | return n; | ||
216 | } | ||
217 | |||
218 | static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) | ||
219 | { | ||
220 | if (likely(ctx)) { | ||
221 | __clear_bit(ctx, iommu->ctx_bitmap); | ||
222 | if (ctx < iommu->ctx_lowest_free) | ||
223 | iommu->ctx_lowest_free = ctx; | ||
224 | } | ||
225 | } | ||
226 | |||
199 | /* Allocate and map kernel buffer of size SIZE using consistent mode | 227 | /* Allocate and map kernel buffer of size SIZE using consistent mode |
200 | * DMA for PCI device PDEV. Return non-NULL cpu-side address if | 228 | * DMA for PCI device PDEV. Return non-NULL cpu-side address if |
201 | * successful and set *DMA_ADDRP to the PCI side dma address. | 229 | * successful and set *DMA_ADDRP to the PCI side dma address. |
@@ -236,7 +264,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad | |||
236 | npages = size >> IO_PAGE_SHIFT; | 264 | npages = size >> IO_PAGE_SHIFT; |
237 | ctx = 0; | 265 | ctx = 0; |
238 | if (iommu->iommu_ctxflush) | 266 | if (iommu->iommu_ctxflush) |
239 | ctx = iommu->iommu_cur_ctx++; | 267 | ctx = iommu_alloc_ctx(iommu); |
240 | first_page = __pa(first_page); | 268 | first_page = __pa(first_page); |
241 | while (npages--) { | 269 | while (npages--) { |
242 | iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | | 270 | iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | |
@@ -317,6 +345,8 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_ | |||
317 | } | 345 | } |
318 | } | 346 | } |
319 | 347 | ||
348 | iommu_free_ctx(iommu, ctx); | ||
349 | |||
320 | spin_unlock_irqrestore(&iommu->lock, flags); | 350 | spin_unlock_irqrestore(&iommu->lock, flags); |
321 | 351 | ||
322 | order = get_order(size); | 352 | order = get_order(size); |
@@ -360,7 +390,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct | |||
360 | base_paddr = __pa(oaddr & IO_PAGE_MASK); | 390 | base_paddr = __pa(oaddr & IO_PAGE_MASK); |
361 | ctx = 0; | 391 | ctx = 0; |
362 | if (iommu->iommu_ctxflush) | 392 | if (iommu->iommu_ctxflush) |
363 | ctx = iommu->iommu_cur_ctx++; | 393 | ctx = iommu_alloc_ctx(iommu); |
364 | if (strbuf->strbuf_enabled) | 394 | if (strbuf->strbuf_enabled) |
365 | iopte_protection = IOPTE_STREAMING(ctx); | 395 | iopte_protection = IOPTE_STREAMING(ctx); |
366 | else | 396 | else |
@@ -380,39 +410,53 @@ bad: | |||
380 | return PCI_DMA_ERROR_CODE; | 410 | return PCI_DMA_ERROR_CODE; |
381 | } | 411 | } |
382 | 412 | ||
383 | static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages) | 413 | static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction) |
384 | { | 414 | { |
385 | int limit; | 415 | int limit; |
386 | 416 | ||
387 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
388 | if (strbuf->strbuf_ctxflush && | 417 | if (strbuf->strbuf_ctxflush && |
389 | iommu->iommu_ctxflush) { | 418 | iommu->iommu_ctxflush) { |
390 | unsigned long matchreg, flushreg; | 419 | unsigned long matchreg, flushreg; |
420 | u64 val; | ||
391 | 421 | ||
392 | flushreg = strbuf->strbuf_ctxflush; | 422 | flushreg = strbuf->strbuf_ctxflush; |
393 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | 423 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); |
394 | 424 | ||
395 | limit = 100000; | ||
396 | pci_iommu_write(flushreg, ctx); | 425 | pci_iommu_write(flushreg, ctx); |
397 | for(;;) { | 426 | val = pci_iommu_read(matchreg); |
398 | if (((long)pci_iommu_read(matchreg)) >= 0L) | 427 | val &= 0xffff; |
399 | break; | 428 | if (!val) |
400 | limit--; | 429 | goto do_flush_sync; |
401 | if (!limit) | 430 | |
402 | break; | 431 | while (val) { |
403 | udelay(1); | 432 | if (val & 0x1) |
433 | pci_iommu_write(flushreg, ctx); | ||
434 | val >>= 1; | ||
404 | } | 435 | } |
405 | if (!limit) | 436 | val = pci_iommu_read(matchreg); |
437 | if (unlikely(val)) { | ||
406 | printk(KERN_WARNING "pci_strbuf_flush: ctx flush " | 438 | printk(KERN_WARNING "pci_strbuf_flush: ctx flush " |
407 | "timeout vaddr[%08x] ctx[%lx]\n", | 439 | "timeout matchreg[%lx] ctx[%lx]\n", |
408 | vaddr, ctx); | 440 | val, ctx); |
441 | goto do_page_flush; | ||
442 | } | ||
409 | } else { | 443 | } else { |
410 | unsigned long i; | 444 | unsigned long i; |
411 | 445 | ||
446 | do_page_flush: | ||
412 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | 447 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) |
413 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | 448 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); |
414 | } | 449 | } |
415 | 450 | ||
451 | do_flush_sync: | ||
452 | /* If the device could not have possibly put dirty data into | ||
453 | * the streaming cache, no flush-flag synchronization needs | ||
454 | * to be performed. | ||
455 | */ | ||
456 | if (direction == PCI_DMA_TODEVICE) | ||
457 | return; | ||
458 | |||
459 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
416 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | 460 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); |
417 | (void) pci_iommu_read(iommu->write_complete_reg); | 461 | (void) pci_iommu_read(iommu->write_complete_reg); |
418 | 462 | ||
@@ -466,7 +510,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
466 | 510 | ||
467 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 511 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
468 | if (strbuf->strbuf_enabled) | 512 | if (strbuf->strbuf_enabled) |
469 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 513 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
470 | 514 | ||
471 | /* Step 2: Clear out first TSB entry. */ | 515 | /* Step 2: Clear out first TSB entry. */ |
472 | iopte_make_dummy(iommu, base); | 516 | iopte_make_dummy(iommu, base); |
@@ -474,6 +518,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
474 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, | 518 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, |
475 | npages, ctx); | 519 | npages, ctx); |
476 | 520 | ||
521 | iommu_free_ctx(iommu, ctx); | ||
522 | |||
477 | spin_unlock_irqrestore(&iommu->lock, flags); | 523 | spin_unlock_irqrestore(&iommu->lock, flags); |
478 | } | 524 | } |
479 | 525 | ||
@@ -613,7 +659,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int | |||
613 | /* Step 4: Choose a context if necessary. */ | 659 | /* Step 4: Choose a context if necessary. */ |
614 | ctx = 0; | 660 | ctx = 0; |
615 | if (iommu->iommu_ctxflush) | 661 | if (iommu->iommu_ctxflush) |
616 | ctx = iommu->iommu_cur_ctx++; | 662 | ctx = iommu_alloc_ctx(iommu); |
617 | 663 | ||
618 | /* Step 5: Create the mappings. */ | 664 | /* Step 5: Create the mappings. */ |
619 | if (strbuf->strbuf_enabled) | 665 | if (strbuf->strbuf_enabled) |
@@ -678,7 +724,7 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
678 | 724 | ||
679 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 725 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
680 | if (strbuf->strbuf_enabled) | 726 | if (strbuf->strbuf_enabled) |
681 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 727 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
682 | 728 | ||
683 | /* Step 2: Clear out first TSB entry. */ | 729 | /* Step 2: Clear out first TSB entry. */ |
684 | iopte_make_dummy(iommu, base); | 730 | iopte_make_dummy(iommu, base); |
@@ -686,6 +732,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
686 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, | 732 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, |
687 | npages, ctx); | 733 | npages, ctx); |
688 | 734 | ||
735 | iommu_free_ctx(iommu, ctx); | ||
736 | |||
689 | spin_unlock_irqrestore(&iommu->lock, flags); | 737 | spin_unlock_irqrestore(&iommu->lock, flags); |
690 | } | 738 | } |
691 | 739 | ||
@@ -724,7 +772,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size | |||
724 | } | 772 | } |
725 | 773 | ||
726 | /* Step 2: Kick data out of streaming buffers. */ | 774 | /* Step 2: Kick data out of streaming buffers. */ |
727 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 775 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
728 | 776 | ||
729 | spin_unlock_irqrestore(&iommu->lock, flags); | 777 | spin_unlock_irqrestore(&iommu->lock, flags); |
730 | } | 778 | } |
@@ -768,7 +816,7 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i | |||
768 | i--; | 816 | i--; |
769 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) | 817 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) |
770 | - bus_addr) >> IO_PAGE_SHIFT; | 818 | - bus_addr) >> IO_PAGE_SHIFT; |
771 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 819 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
772 | 820 | ||
773 | spin_unlock_irqrestore(&iommu->lock, flags); | 821 | spin_unlock_irqrestore(&iommu->lock, flags); |
774 | } | 822 | } |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 3567fa879e1f..534320ef0db2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -1212,7 +1212,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p) | |||
1212 | 1212 | ||
1213 | /* Setup initial software IOMMU state. */ | 1213 | /* Setup initial software IOMMU state. */ |
1214 | spin_lock_init(&iommu->lock); | 1214 | spin_lock_init(&iommu->lock); |
1215 | iommu->iommu_cur_ctx = 0; | 1215 | iommu->ctx_lowest_free = 1; |
1216 | 1216 | ||
1217 | /* Register addresses. */ | 1217 | /* Register addresses. */ |
1218 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; | 1218 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 5525d1ec4af8..53d333b4a4e8 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -1265,7 +1265,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, | |||
1265 | 1265 | ||
1266 | /* Setup initial software IOMMU state. */ | 1266 | /* Setup initial software IOMMU state. */ |
1267 | spin_lock_init(&iommu->lock); | 1267 | spin_lock_init(&iommu->lock); |
1268 | iommu->iommu_cur_ctx = 0; | 1268 | iommu->ctx_lowest_free = 1; |
1269 | 1269 | ||
1270 | /* Register addresses. */ | 1270 | /* Register addresses. */ |
1271 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; | 1271 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e93fcadc3722..5753175b94e6 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -1753,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1753 | 1753 | ||
1754 | /* Setup initial software IOMMU state. */ | 1754 | /* Setup initial software IOMMU state. */ |
1755 | spin_lock_init(&iommu->lock); | 1755 | spin_lock_init(&iommu->lock); |
1756 | iommu->iommu_cur_ctx = 0; | 1756 | iommu->ctx_lowest_free = 1; |
1757 | 1757 | ||
1758 | /* Register addresses, SCHIZO has iommu ctx flushing. */ | 1758 | /* Register addresses, SCHIZO has iommu ctx flushing. */ |
1759 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; | 1759 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 76ea6455433f..89f5e019f24c 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -117,17 +117,25 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages | |||
117 | 117 | ||
118 | #define STRBUF_TAG_VALID 0x02UL | 118 | #define STRBUF_TAG_VALID 0x02UL |
119 | 119 | ||
120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) | 120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction) |
121 | { | 121 | { |
122 | unsigned long n; | 122 | unsigned long n; |
123 | int limit; | 123 | int limit; |
124 | 124 | ||
125 | iommu->strbuf_flushflag = 0UL; | ||
126 | n = npages; | 125 | n = npages; |
127 | while (n--) | 126 | while (n--) |
128 | upa_writeq(base + (n << IO_PAGE_SHIFT), | 127 | upa_writeq(base + (n << IO_PAGE_SHIFT), |
129 | iommu->strbuf_regs + STRBUF_PFLUSH); | 128 | iommu->strbuf_regs + STRBUF_PFLUSH); |
130 | 129 | ||
130 | /* If the device could not have possibly put dirty data into | ||
131 | * the streaming cache, no flush-flag synchronization needs | ||
132 | * to be performed. | ||
133 | */ | ||
134 | if (direction == SBUS_DMA_TODEVICE) | ||
135 | return; | ||
136 | |||
137 | iommu->strbuf_flushflag = 0UL; | ||
138 | |||
131 | /* Whoopee cushion! */ | 139 | /* Whoopee cushion! */ |
132 | upa_writeq(__pa(&iommu->strbuf_flushflag), | 140 | upa_writeq(__pa(&iommu->strbuf_flushflag), |
133 | iommu->strbuf_regs + STRBUF_FSYNC); | 141 | iommu->strbuf_regs + STRBUF_FSYNC); |
@@ -421,7 +429,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, | |||
421 | 429 | ||
422 | spin_lock_irqsave(&iommu->lock, flags); | 430 | spin_lock_irqsave(&iommu->lock, flags); |
423 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); | 431 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); |
424 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); | 432 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction); |
425 | spin_unlock_irqrestore(&iommu->lock, flags); | 433 | spin_unlock_irqrestore(&iommu->lock, flags); |
426 | } | 434 | } |
427 | 435 | ||
@@ -584,7 +592,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int | |||
584 | iommu = sdev->bus->iommu; | 592 | iommu = sdev->bus->iommu; |
585 | spin_lock_irqsave(&iommu->lock, flags); | 593 | spin_lock_irqsave(&iommu->lock, flags); |
586 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 594 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
587 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 595 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction); |
588 | spin_unlock_irqrestore(&iommu->lock, flags); | 596 | spin_unlock_irqrestore(&iommu->lock, flags); |
589 | } | 597 | } |
590 | 598 | ||
@@ -596,7 +604,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t | |||
596 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); | 604 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); |
597 | 605 | ||
598 | spin_lock_irqsave(&iommu->lock, flags); | 606 | spin_lock_irqsave(&iommu->lock, flags); |
599 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); | 607 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction); |
600 | spin_unlock_irqrestore(&iommu->lock, flags); | 608 | spin_unlock_irqrestore(&iommu->lock, flags); |
601 | } | 609 | } |
602 | 610 | ||
@@ -620,7 +628,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int | |||
620 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; | 628 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; |
621 | 629 | ||
622 | spin_lock_irqsave(&iommu->lock, flags); | 630 | spin_lock_irqsave(&iommu->lock, flags); |
623 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); | 631 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction); |
624 | spin_unlock_irqrestore(&iommu->lock, flags); | 632 | spin_unlock_irqrestore(&iommu->lock, flags); |
625 | } | 633 | } |
626 | 634 | ||
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index b89989de364d..bd41e4286d0d 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug | |||
@@ -2,10 +2,6 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | config FRAME_POINTER | ||
6 | bool | ||
7 | default y if DEBUG_INFO | ||
8 | |||
9 | config PT_PROXY | 5 | config PT_PROXY |
10 | bool "Enable ptrace proxy" | 6 | bool "Enable ptrace proxy" |
11 | depends on XTERM_CHAN && DEBUG_INFO && MODE_TT | 7 | depends on XTERM_CHAN && DEBUG_INFO && MODE_TT |
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index d43e9fab05a7..f9e22198e011 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
@@ -1,5 +1,10 @@ | |||
1 | /* Much of this ripped from hw_random.c */ | 1 | /* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */ |
2 | 2 | /* Much of this ripped from drivers/char/hw_random.c, see there for other | |
3 | * copyright. | ||
4 | * | ||
5 | * This software may be used and distributed according to the terms | ||
6 | * of the GNU General Public License, incorporated herein by reference. | ||
7 | */ | ||
3 | #include <linux/module.h> | 8 | #include <linux/module.h> |
4 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
5 | #include <linux/miscdevice.h> | 10 | #include <linux/miscdevice.h> |
@@ -12,8 +17,6 @@ | |||
12 | */ | 17 | */ |
13 | #define RNG_VERSION "1.0.0" | 18 | #define RNG_VERSION "1.0.0" |
14 | #define RNG_MODULE_NAME "random" | 19 | #define RNG_MODULE_NAME "random" |
15 | #define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION | ||
16 | #define PFX RNG_MODULE_NAME ": " | ||
17 | 20 | ||
18 | #define RNG_MISCDEV_MINOR 183 /* official */ | 21 | #define RNG_MISCDEV_MINOR 183 /* official */ |
19 | 22 | ||
@@ -98,7 +101,7 @@ static int __init rng_init (void) | |||
98 | 101 | ||
99 | err = misc_register (&rng_miscdev); | 102 | err = misc_register (&rng_miscdev); |
100 | if (err) { | 103 | if (err) { |
101 | printk (KERN_ERR PFX "misc device register failed\n"); | 104 | printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n"); |
102 | goto err_out_cleanup_hw; | 105 | goto err_out_cleanup_hw; |
103 | } | 106 | } |
104 | 107 | ||
@@ -120,3 +123,6 @@ static void __exit rng_cleanup (void) | |||
120 | 123 | ||
121 | module_init (rng_init); | 124 | module_init (rng_init); |
122 | module_exit (rng_cleanup); | 125 | module_exit (rng_cleanup); |
126 | |||
127 | MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver"); | ||
128 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index a2bac429f3d4..b32a77010fbe 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "init.h" | 22 | #include "init.h" |
23 | #include "irq_user.h" | 23 | #include "irq_user.h" |
24 | #include "mconsole_kern.h" | 24 | #include "mconsole_kern.h" |
25 | #include "2_5compat.h" | ||
26 | 25 | ||
27 | static int ssl_version = 1; | 26 | static int ssl_version = 1; |
28 | 27 | ||
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 361d0be342b3..afbe1e71ed83 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "irq_user.h" | 28 | #include "irq_user.h" |
29 | #include "mconsole_kern.h" | 29 | #include "mconsole_kern.h" |
30 | #include "init.h" | 30 | #include "init.h" |
31 | #include "2_5compat.h" | ||
32 | 31 | ||
33 | #define MAX_TTYS (16) | 32 | #define MAX_TTYS (16) |
34 | 33 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 88f956c34fed..2a7f6892c55c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include "irq_user.h" | 49 | #include "irq_user.h" |
50 | #include "irq_kern.h" | 50 | #include "irq_kern.h" |
51 | #include "ubd_user.h" | 51 | #include "ubd_user.h" |
52 | #include "2_5compat.h" | ||
53 | #include "os.h" | 52 | #include "os.h" |
54 | #include "mem.h" | 53 | #include "mem.h" |
55 | #include "mem_kern.h" | 54 | #include "mem_kern.h" |
@@ -440,9 +439,9 @@ static int udb_setup(char *str) | |||
440 | __setup("udb", udb_setup); | 439 | __setup("udb", udb_setup); |
441 | __uml_help(udb_setup, | 440 | __uml_help(udb_setup, |
442 | "udb\n" | 441 | "udb\n" |
443 | " This option is here solely to catch ubd -> udb typos, which can be\n\n" | 442 | " This option is here solely to catch ubd -> udb typos, which can be\n" |
444 | " to impossible to catch visually unless you specifically look for\n\n" | 443 | " to impossible to catch visually unless you specifically look for\n" |
445 | " them. The only result of any option starting with 'udb' is an error\n\n" | 444 | " them. The only result of any option starting with 'udb' is an error\n" |
446 | " in the boot output.\n\n" | 445 | " in the boot output.\n\n" |
447 | ); | 446 | ); |
448 | 447 | ||
diff --git a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h deleted file mode 100644 index abdb015a4d71..000000000000 --- a/arch/um/include/2_5compat.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __2_5_COMPAT_H__ | ||
7 | #define __2_5_COMPAT_H__ | ||
8 | |||
9 | #define INIT_HARDSECT(arr, maj, sizes) | ||
10 | |||
11 | #define SET_PRI(task) do ; while(0) | ||
12 | |||
13 | #endif | ||
14 | |||
15 | /* | ||
16 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
17 | * Emacs will notice this stuff at the end of the file and automatically | ||
18 | * adjust the settings for this buffer only. This must remain at the end | ||
19 | * of the file. | ||
20 | * --------------------------------------------------------------------------- | ||
21 | * Local variables: | ||
22 | * c-file-style: "linux" | ||
23 | * End: | ||
24 | */ | ||
diff --git a/arch/um/include/sysrq.h b/arch/um/include/sysrq.h index 2ce9423460b3..c8d332b56b98 100644 --- a/arch/um/include/sysrq.h +++ b/arch/um/include/sysrq.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __UM_SYSRQ_H | 1 | #ifndef __UM_SYSRQ_H |
2 | #define __UM_SYSRQ_H | 2 | #define __UM_SYSRQ_H |
3 | 3 | ||
4 | extern void show_trace(unsigned long *stack); | 4 | struct task_struct; |
5 | extern void show_trace(struct task_struct* task, unsigned long *stack); | ||
5 | 6 | ||
6 | #endif | 7 | #endif |
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c index 49ddabe69be7..efd222ffe20e 100644 --- a/arch/um/kernel/exec_kern.c +++ b/arch/um/kernel/exec_kern.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include "kern.h" | 16 | #include "kern.h" |
17 | #include "irq_user.h" | 17 | #include "irq_user.h" |
18 | #include "tlb.h" | 18 | #include "tlb.h" |
19 | #include "2_5compat.h" | ||
20 | #include "os.h" | 19 | #include "os.h" |
21 | #include "time_user.h" | 20 | #include "time_user.h" |
22 | #include "choose-mode.h" | 21 | #include "choose-mode.h" |
diff --git a/arch/um/kernel/initrd_kern.c b/arch/um/kernel/initrd_kern.c deleted file mode 100644 index fc568af468b9..000000000000 --- a/arch/um/kernel/initrd_kern.c +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include "linux/init.h" | ||
7 | #include "linux/bootmem.h" | ||
8 | #include "linux/initrd.h" | ||
9 | #include "asm/types.h" | ||
10 | #include "user_util.h" | ||
11 | #include "kern_util.h" | ||
12 | #include "initrd.h" | ||
13 | #include "init.h" | ||
14 | #include "os.h" | ||
15 | |||
16 | /* Changed by uml_initrd_setup, which is a setup */ | ||
17 | static char *initrd __initdata = NULL; | ||
18 | |||
19 | static int __init read_initrd(void) | ||
20 | { | ||
21 | void *area; | ||
22 | long long size; | ||
23 | int err; | ||
24 | |||
25 | if(initrd == NULL) return 0; | ||
26 | err = os_file_size(initrd, &size); | ||
27 | if(err) return 0; | ||
28 | area = alloc_bootmem(size); | ||
29 | if(area == NULL) return 0; | ||
30 | if(load_initrd(initrd, area, size) == -1) return 0; | ||
31 | initrd_start = (unsigned long) area; | ||
32 | initrd_end = initrd_start + size; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | __uml_postsetup(read_initrd); | ||
37 | |||
38 | static int __init uml_initrd_setup(char *line, int *add) | ||
39 | { | ||
40 | initrd = line; | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | __uml_setup("initrd=", uml_initrd_setup, | ||
45 | "initrd=<initrd image>\n" | ||
46 | " This is used to boot UML from an initrd image. The argument is the\n" | ||
47 | " name of the file containing the image.\n\n" | ||
48 | ); | ||
49 | |||
50 | /* | ||
51 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
52 | * Emacs will notice this stuff at the end of the file and automatically | ||
53 | * adjust the settings for this buffer only. This must remain at the end | ||
54 | * of the file. | ||
55 | * --------------------------------------------------------------------------- | ||
56 | * Local variables: | ||
57 | * c-file-style: "linux" | ||
58 | * End: | ||
59 | */ | ||
diff --git a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c deleted file mode 100644 index cb90681e151c..000000000000 --- a/arch/um/kernel/initrd_user.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <unistd.h> | ||
7 | #include <sys/types.h> | ||
8 | #include <sys/stat.h> | ||
9 | #include <errno.h> | ||
10 | |||
11 | #include "user_util.h" | ||
12 | #include "kern_util.h" | ||
13 | #include "user.h" | ||
14 | #include "initrd.h" | ||
15 | #include "os.h" | ||
16 | |||
17 | int load_initrd(char *filename, void *buf, int size) | ||
18 | { | ||
19 | int fd, n; | ||
20 | |||
21 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | ||
22 | if(fd < 0){ | ||
23 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | ||
24 | return(-1); | ||
25 | } | ||
26 | n = os_read_file(fd, buf, size); | ||
27 | if(n != size){ | ||
28 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | ||
29 | filename, -n); | ||
30 | return(-1); | ||
31 | } | ||
32 | |||
33 | os_close_file(fd); | ||
34 | return(0); | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
39 | * Emacs will notice this stuff at the end of the file and automatically | ||
40 | * adjust the settings for this buffer only. This must remain at the end | ||
41 | * of the file. | ||
42 | * --------------------------------------------------------------------------- | ||
43 | * Local variables: | ||
44 | * c-file-style: "linux" | ||
45 | * End: | ||
46 | */ | ||
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index a17c49703f9b..e42e6364ca13 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c | |||
@@ -71,7 +71,7 @@ static __init void do_uml_initcalls(void) | |||
71 | 71 | ||
72 | static void last_ditch_exit(int sig) | 72 | static void last_ditch_exit(int sig) |
73 | { | 73 | { |
74 | CHOOSE_MODE(kmalloc_ok = 0, (void) 0); | 74 | kmalloc_ok = 0; |
75 | signal(SIGINT, SIG_DFL); | 75 | signal(SIGINT, SIG_DFL); |
76 | signal(SIGTERM, SIG_DFL); | 76 | signal(SIGTERM, SIG_DFL); |
77 | signal(SIGHUP, SIG_DFL); | 77 | signal(SIGHUP, SIG_DFL); |
@@ -87,7 +87,7 @@ int main(int argc, char **argv, char **envp) | |||
87 | { | 87 | { |
88 | char **new_argv; | 88 | char **new_argv; |
89 | sigset_t mask; | 89 | sigset_t mask; |
90 | int ret, i; | 90 | int ret, i, err; |
91 | 91 | ||
92 | /* Enable all signals except SIGIO - in some environments, we can | 92 | /* Enable all signals except SIGIO - in some environments, we can |
93 | * enter with some signals blocked | 93 | * enter with some signals blocked |
@@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp) | |||
160 | */ | 160 | */ |
161 | change_sig(SIGPROF, 0); | 161 | change_sig(SIGPROF, 0); |
162 | 162 | ||
163 | /* Reboot */ | 163 | /* This signal stuff used to be in the reboot case. However, |
164 | if(ret){ | 164 | * sometimes a SIGVTALRM can come in when we're halting (reproducably |
165 | int err; | 165 | * when writing out gcov information, presumably because that takes |
166 | 166 | * some time) and cause a segfault. | |
167 | printf("\n"); | 167 | */ |
168 | 168 | ||
169 | /* stop timers and set SIG*ALRM to be ignored */ | 169 | /* stop timers and set SIG*ALRM to be ignored */ |
170 | disable_timer(); | 170 | disable_timer(); |
171 | 171 | ||
172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ | 172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ |
173 | err = deactivate_all_fds(); | 173 | err = deactivate_all_fds(); |
174 | if(err) | 174 | if(err) |
175 | printf("deactivate_all_fds failed, errno = %d\n", | 175 | printf("deactivate_all_fds failed, errno = %d\n", -err); |
176 | -err); | ||
177 | 176 | ||
178 | /* Let any pending signals fire now. This ensures | 177 | /* Let any pending signals fire now. This ensures |
179 | * that they won't be delivered after the exec, when | 178 | * that they won't be delivered after the exec, when |
180 | * they are definitely not expected. | 179 | * they are definitely not expected. |
181 | */ | 180 | */ |
182 | unblock_signals(); | 181 | unblock_signals(); |
183 | 182 | ||
183 | /* Reboot */ | ||
184 | if(ret){ | ||
185 | printf("\n"); | ||
184 | execvp(new_argv[0], new_argv); | 186 | execvp(new_argv[0], new_argv); |
185 | perror("Failed to exec kernel"); | 187 | perror("Failed to exec kernel"); |
186 | ret = 1; | 188 | ret = 1; |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index c1adf7ba3fd1..804c6bbdf67c 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include "tlb.h" | 43 | #include "tlb.h" |
44 | #include "frame_kern.h" | 44 | #include "frame_kern.h" |
45 | #include "sigcontext.h" | 45 | #include "sigcontext.h" |
46 | #include "2_5compat.h" | ||
47 | #include "os.h" | 46 | #include "os.h" |
48 | #include "mode.h" | 47 | #include "mode.h" |
49 | #include "mode_kern.h" | 48 | #include "mode_kern.h" |
@@ -55,18 +54,6 @@ | |||
55 | */ | 54 | */ |
56 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; | 55 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; |
57 | 56 | ||
58 | struct task_struct *get_task(int pid, int require) | ||
59 | { | ||
60 | struct task_struct *ret; | ||
61 | |||
62 | read_lock(&tasklist_lock); | ||
63 | ret = find_task_by_pid(pid); | ||
64 | read_unlock(&tasklist_lock); | ||
65 | |||
66 | if(require && (ret == NULL)) panic("get_task couldn't find a task\n"); | ||
67 | return(ret); | ||
68 | } | ||
69 | |||
70 | int external_pid(void *t) | 57 | int external_pid(void *t) |
71 | { | 58 | { |
72 | struct task_struct *task = t ? t : current; | 59 | struct task_struct *task = t ? t : current; |
@@ -189,7 +176,6 @@ void default_idle(void) | |||
189 | 176 | ||
190 | while(1){ | 177 | while(1){ |
191 | /* endless idle loop with no priority at all */ | 178 | /* endless idle loop with no priority at all */ |
192 | SET_PRI(current); | ||
193 | 179 | ||
194 | /* | 180 | /* |
195 | * although we are an idle CPU, we do not want to | 181 | * although we are an idle CPU, we do not want to |
@@ -212,11 +198,6 @@ int page_size(void) | |||
212 | return(PAGE_SIZE); | 198 | return(PAGE_SIZE); |
213 | } | 199 | } |
214 | 200 | ||
215 | unsigned long page_mask(void) | ||
216 | { | ||
217 | return(PAGE_MASK); | ||
218 | } | ||
219 | |||
220 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | 201 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, |
221 | pte_t *pte_out) | 202 | pte_t *pte_out) |
222 | { | 203 | { |
@@ -349,11 +330,6 @@ char *uml_strdup(char *string) | |||
349 | return(new); | 330 | return(new); |
350 | } | 331 | } |
351 | 332 | ||
352 | void *get_init_task(void) | ||
353 | { | ||
354 | return(&init_thread_union.thread_info.task); | ||
355 | } | ||
356 | |||
357 | int copy_to_user_proc(void __user *to, void *from, int size) | 333 | int copy_to_user_proc(void __user *to, void *from, int size) |
358 | { | 334 | { |
359 | return(copy_to_user(to, from, size)); | 335 | return(copy_to_user(to, from, size)); |
@@ -480,15 +456,3 @@ unsigned long arch_align_stack(unsigned long sp) | |||
480 | return sp & ~0xf; | 456 | return sp & ~0xf; |
481 | } | 457 | } |
482 | #endif | 458 | #endif |
483 | |||
484 | |||
485 | /* | ||
486 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
487 | * Emacs will notice this stuff at the end of the file and automatically | ||
488 | * adjust the settings for this buffer only. This must remain at the end | ||
489 | * of the file. | ||
490 | * --------------------------------------------------------------------------- | ||
491 | * Local variables: | ||
492 | * c-file-style: "linux" | ||
493 | * End: | ||
494 | */ | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 2925e15324de..71af4d503899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -322,11 +322,9 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
322 | UPT_SYSCALL_ARG2(regs), | 322 | UPT_SYSCALL_ARG2(regs), |
323 | UPT_SYSCALL_ARG3(regs), | 323 | UPT_SYSCALL_ARG3(regs), |
324 | UPT_SYSCALL_ARG4(regs)); | 324 | UPT_SYSCALL_ARG4(regs)); |
325 | else { | 325 | else audit_syscall_exit(current, |
326 | int res = UPT_SYSCALL_RET(regs); | 326 | AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), |
327 | audit_syscall_exit(current, AUDITSC_RESULT(res), | 327 | UPT_SYSCALL_RET(regs)); |
328 | res); | ||
329 | } | ||
330 | } | 328 | } |
331 | 329 | ||
332 | /* Fake a debug trap */ | 330 | /* Fake a debug trap */ |
@@ -356,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
356 | current->exit_code = 0; | 354 | current->exit_code = 0; |
357 | } | 355 | } |
358 | } | 356 | } |
359 | |||
360 | /* | ||
361 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
362 | * Emacs will notice this stuff at the end of the file and automatically | ||
363 | * adjust the settings for this buffer only. This must remain at the end | ||
364 | * of the file. | ||
365 | * --------------------------------------------------------------------------- | ||
366 | * Local variables: | ||
367 | * c-file-style: "linux" | ||
368 | * End: | ||
369 | */ | ||
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index e630438f9e73..f80850091e79 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/config.h" | ||
6 | #include "linux/sched.h" | 7 | #include "linux/sched.h" |
7 | #include "linux/kernel.h" | 8 | #include "linux/kernel.h" |
8 | #include "linux/module.h" | 9 | #include "linux/module.h" |
@@ -12,14 +13,14 @@ | |||
12 | #include "sysrq.h" | 13 | #include "sysrq.h" |
13 | #include "user_util.h" | 14 | #include "user_util.h" |
14 | 15 | ||
15 | void show_trace(unsigned long * stack) | 16 | /* Catch non-i386 SUBARCH's. */ |
17 | #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) | ||
18 | void show_trace(struct task_struct *task, unsigned long * stack) | ||
16 | { | 19 | { |
17 | /* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from | ||
18 | * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/ | ||
19 | unsigned long addr; | 20 | unsigned long addr; |
20 | 21 | ||
21 | if (!stack) { | 22 | if (!stack) { |
22 | stack = (unsigned long*) &stack; | 23 | stack = (unsigned long*) &stack; |
23 | WARN_ON(1); | 24 | WARN_ON(1); |
24 | } | 25 | } |
25 | 26 | ||
@@ -35,6 +36,7 @@ void show_trace(unsigned long * stack) | |||
35 | } | 36 | } |
36 | printk("\n"); | 37 | printk("\n"); |
37 | } | 38 | } |
39 | #endif | ||
38 | 40 | ||
39 | /* | 41 | /* |
40 | * stack dumps generator - this is used by arch-independent code. | 42 | * stack dumps generator - this is used by arch-independent code. |
@@ -44,7 +46,7 @@ void dump_stack(void) | |||
44 | { | 46 | { |
45 | unsigned long stack; | 47 | unsigned long stack; |
46 | 48 | ||
47 | show_trace(&stack); | 49 | show_trace(current, &stack); |
48 | } | 50 | } |
49 | EXPORT_SYMBOL(dump_stack); | 51 | EXPORT_SYMBOL(dump_stack); |
50 | 52 | ||
@@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
59 | int i; | 61 | int i; |
60 | 62 | ||
61 | if (esp == NULL) { | 63 | if (esp == NULL) { |
62 | if (task != current) { | 64 | if (task != current && task != NULL) { |
65 | /* XXX: Isn't this bogus? I.e. isn't this the | ||
66 | * *userspace* stack of this task? If not so, use this | ||
67 | * even when task == current (as in i386). | ||
68 | */ | ||
63 | esp = (unsigned long *) KSTK_ESP(task); | 69 | esp = (unsigned long *) KSTK_ESP(task); |
64 | /* Which one? No actual difference - just coding style.*/ | 70 | /* Which one? No actual difference - just coding style.*/ |
65 | //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); | 71 | //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); |
@@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
77 | printk("%08lx ", *stack++); | 83 | printk("%08lx ", *stack++); |
78 | } | 84 | } |
79 | 85 | ||
80 | show_trace(esp); | 86 | printk("Call Trace: \n"); |
87 | show_trace(current, esp); | ||
81 | } | 88 | } |
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 1de22d8a313a..c20aef120598 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "kern.h" | 23 | #include "kern.h" |
24 | #include "chan_kern.h" | 24 | #include "chan_kern.h" |
25 | #include "mconsole_kern.h" | 25 | #include "mconsole_kern.h" |
26 | #include "2_5compat.h" | ||
27 | #include "mem.h" | 26 | #include "mem.h" |
28 | #include "mem_kern.h" | 27 | #include "mem_kern.h" |
29 | 28 | ||
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index df810ca8fc12..776310fd5b8b 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
32 | unsigned long flags; | 32 | unsigned long flags; |
33 | int err, vtalrm, alrm, prof, cpu; | 33 | int err, vtalrm, alrm, prof, cpu; |
34 | char c; | 34 | char c; |
35 | /* jailing and SMP are incompatible, so this doesn't need to be | ||
36 | * made per-cpu | ||
37 | */ | ||
38 | static int reading; | ||
39 | 35 | ||
40 | from = prev; | 36 | from = prev; |
41 | to = next; | 37 | to = next; |
@@ -59,13 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
59 | c = 0; | 55 | c = 0; |
60 | set_current(to); | 56 | set_current(to); |
61 | 57 | ||
62 | reading = 0; | ||
63 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); | 58 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); |
64 | if(err != sizeof(c)) | 59 | if(err != sizeof(c)) |
65 | panic("write of switch_pipe failed, err = %d", -err); | 60 | panic("write of switch_pipe failed, err = %d", -err); |
66 | 61 | ||
67 | reading = 1; | 62 | if(from->thread.mode.tt.switch_pipe[0] == -1) |
68 | if(from->thread.mode.tt.switch_pipe[0] == -1) | ||
69 | os_kill_process(os_getpid(), 0); | 63 | os_kill_process(os_getpid(), 0); |
70 | 64 | ||
71 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); | 65 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 4d10ec372a67..418427107b29 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -111,12 +111,6 @@ struct seq_operations cpuinfo_op = { | |||
111 | .show = show_cpuinfo, | 111 | .show = show_cpuinfo, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | pte_t * __bad_pagetable(void) | ||
115 | { | ||
116 | panic("Someone should implement __bad_pagetable"); | ||
117 | return(NULL); | ||
118 | } | ||
119 | |||
120 | /* Set in linux_main */ | 114 | /* Set in linux_main */ |
121 | unsigned long host_task_size; | 115 | unsigned long host_task_size; |
122 | unsigned long task_size; | 116 | unsigned long task_size; |
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c index 281fc7b8ca00..e3706d15c4f5 100644 --- a/arch/um/sys-i386/sysrq.c +++ b/arch/um/sys-i386/sysrq.c | |||
@@ -3,12 +3,15 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/config.h" | ||
6 | #include "linux/kernel.h" | 7 | #include "linux/kernel.h" |
7 | #include "linux/smp.h" | 8 | #include "linux/smp.h" |
8 | #include "linux/sched.h" | 9 | #include "linux/sched.h" |
10 | #include "linux/kallsyms.h" | ||
9 | #include "asm/ptrace.h" | 11 | #include "asm/ptrace.h" |
10 | #include "sysrq.h" | 12 | #include "sysrq.h" |
11 | 13 | ||
14 | /* This is declared by <linux/sched.h> */ | ||
12 | void show_regs(struct pt_regs *regs) | 15 | void show_regs(struct pt_regs *regs) |
13 | { | 16 | { |
14 | printk("\n"); | 17 | printk("\n"); |
@@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs) | |||
31 | 0xffff & PT_REGS_DS(regs), | 34 | 0xffff & PT_REGS_DS(regs), |
32 | 0xffff & PT_REGS_ES(regs)); | 35 | 0xffff & PT_REGS_ES(regs)); |
33 | 36 | ||
34 | show_trace((unsigned long *) ®s); | 37 | show_trace(NULL, (unsigned long *) ®s); |
35 | } | 38 | } |
39 | |||
40 | /* Copied from i386. */ | ||
41 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | ||
42 | { | ||
43 | return p > (void *)tinfo && | ||
44 | p < (void *)tinfo + THREAD_SIZE - 3; | ||
45 | } | ||
46 | |||
47 | /* Adapted from i386 (we also print the address we read from). */ | ||
48 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | ||
49 | unsigned long *stack, unsigned long ebp) | ||
50 | { | ||
51 | unsigned long addr; | ||
52 | |||
53 | #ifdef CONFIG_FRAME_POINTER | ||
54 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | ||
55 | addr = *(unsigned long *)(ebp + 4); | ||
56 | printk("%08lx: [<%08lx>]", ebp + 4, addr); | ||
57 | print_symbol(" %s", addr); | ||
58 | printk("\n"); | ||
59 | ebp = *(unsigned long *)ebp; | ||
60 | } | ||
61 | #else | ||
62 | while (valid_stack_ptr(tinfo, stack)) { | ||
63 | addr = *stack; | ||
64 | if (__kernel_text_address(addr)) { | ||
65 | printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); | ||
66 | print_symbol(" %s", addr); | ||
67 | printk("\n"); | ||
68 | } | ||
69 | stack++; | ||
70 | } | ||
71 | #endif | ||
72 | return ebp; | ||
73 | } | ||
74 | |||
75 | void show_trace(struct task_struct* task, unsigned long * stack) | ||
76 | { | ||
77 | unsigned long ebp; | ||
78 | struct thread_info *context; | ||
79 | |||
80 | /* Turn this into BUG_ON if possible. */ | ||
81 | if (!stack) { | ||
82 | stack = (unsigned long*) &stack; | ||
83 | printk("show_trace: got NULL stack, implicit assumption task == current"); | ||
84 | WARN_ON(1); | ||
85 | } | ||
86 | |||
87 | if (!task) | ||
88 | task = current; | ||
89 | |||
90 | if (task != current) { | ||
91 | //ebp = (unsigned long) KSTK_EBP(task); | ||
92 | /* Which one? No actual difference - just coding style.*/ | ||
93 | ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs); | ||
94 | } else { | ||
95 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); | ||
96 | } | ||
97 | |||
98 | context = (struct thread_info *) | ||
99 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | ||
100 | print_context_stack(context, stack, ebp); | ||
101 | |||
102 | /*while (((long) stack & (THREAD_SIZE-1)) != 0) { | ||
103 | addr = *stack; | ||
104 | if (__kernel_text_address(addr)) { | ||
105 | printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); | ||
106 | print_symbol(" %s", addr); | ||
107 | printk("\n"); | ||
108 | } | ||
109 | stack++; | ||
110 | }*/ | ||
111 | printk("\n"); | ||
112 | } | ||
113 | |||
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c index 82d6e9335bb6..2f816f1a0ff4 100644 --- a/arch/um/sys-ppc/sysrq.c +++ b/arch/um/sys-ppc/sysrq.c | |||
@@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs) | |||
27 | 0xffff & regs->xds, 0xffff & regs->xes); | 27 | 0xffff & regs->xds, 0xffff & regs->xes); |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | show_trace(®s->gpr[1]); | 30 | show_trace(current, ®s->gpr[1]); |
31 | } | 31 | } |
32 | |||
33 | |||
34 | /* | ||
35 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
36 | * Emacs will notice this stuff at the end of the file and automatically | ||
37 | * adjust the settings for this buffer only. This must remain at the end | ||
38 | * of the file. | ||
39 | * --------------------------------------------------------------------------- | ||
40 | * Local variables: | ||
41 | * c-file-style: "linux" | ||
42 | * End: | ||
43 | */ | ||
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index d4a59657fb99..6f44f40204ed 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
@@ -133,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr) | |||
133 | 133 | ||
134 | #ifdef CONFIG_MODE_SKAS | 134 | #ifdef CONFIG_MODE_SKAS |
135 | 135 | ||
136 | /* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */ | ||
136 | static long arch_prctl_skas(int code, unsigned long addr) | 137 | static long arch_prctl_skas(int code, unsigned long addr) |
137 | { | 138 | { |
138 | long ret = 0; | 139 | long ret = 0; |
139 | 140 | ||
140 | switch(code){ | 141 | switch(code){ |
141 | case ARCH_SET_GS: | ||
142 | current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr; | ||
143 | break; | ||
144 | case ARCH_SET_FS: | 142 | case ARCH_SET_FS: |
145 | current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; | 143 | current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; |
146 | break; | 144 | break; |
145 | case ARCH_SET_GS: | ||
146 | current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr; | ||
147 | break; | ||
147 | case ARCH_GET_FS: | 148 | case ARCH_GET_FS: |
148 | ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr); | 149 | ret = put_user(current->thread.regs.regs.skas. |
150 | regs[FS_BASE / sizeof(unsigned long)], | ||
151 | (unsigned long __user *)addr); | ||
149 | break; | 152 | break; |
150 | case ARCH_GET_GS: | 153 | case ARCH_GET_GS: |
151 | ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \ | 154 | ret = put_user(current->thread.regs.regs.skas. |
152 | long)], &addr); | 155 | regs[GS_BASE / sizeof(unsigned long)], |
156 | (unsigned long __user *)addr); | ||
153 | break; | 157 | break; |
154 | default: | 158 | default: |
155 | ret = -EINVAL; | 159 | ret = -EINVAL; |
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c index ddf74691a610..d0a25af19a5b 100644 --- a/arch/um/sys-x86_64/sysrq.c +++ b/arch/um/sys-x86_64/sysrq.c | |||
@@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs) | |||
36 | void show_regs(struct pt_regs *regs) | 36 | void show_regs(struct pt_regs *regs) |
37 | { | 37 | { |
38 | __show_regs(regs); | 38 | __show_regs(regs); |
39 | show_trace((unsigned long *) ®s); | 39 | show_trace(current, (unsigned long *) ®s); |
40 | } | 40 | } |
41 | |||
42 | /* Emacs will notice this stuff at the end of the file and automatically | ||
43 | * adjust the settings for this buffer only. This must remain at the end | ||
44 | * of the file. | ||
45 | * --------------------------------------------------------------------------- | ||
46 | * Local variables: | ||
47 | * c-file-style: "linux" | ||
48 | * End: | ||
49 | */ | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 0f430d9d3632..289f448ac89c 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -305,6 +305,7 @@ config HPET_TIMER | |||
305 | 305 | ||
306 | config X86_PM_TIMER | 306 | config X86_PM_TIMER |
307 | bool "PM timer" | 307 | bool "PM timer" |
308 | depends on ACPI | ||
308 | default y | 309 | default y |
309 | help | 310 | help |
310 | Support the ACPI PM timer for time keeping. This is slow, | 311 | Support the ACPI PM timer for time keeping. This is slow, |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 80e9b498c443..afd87e64d0a8 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/desc.h> | 37 | #include <asm/desc.h> |
38 | #include <asm/proto.h> | 38 | #include <asm/proto.h> |
39 | #include <asm/mach_apic.h> | 39 | #include <asm/mach_apic.h> |
40 | #include <asm/acpi.h> | ||
40 | 41 | ||
41 | #define __apicdebuginit __init | 42 | #define __apicdebuginit __init |
42 | 43 | ||
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index f86d9db94bfc..61a63be6b294 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/pgalloc.h> | 30 | #include <asm/pgalloc.h> |
31 | #include <asm/io_apic.h> | 31 | #include <asm/io_apic.h> |
32 | #include <asm/proto.h> | 32 | #include <asm/proto.h> |
33 | #include <asm/acpi.h> | ||
33 | 34 | ||
34 | /* Have we found an MP table */ | 35 | /* Have we found an MP table */ |
35 | int smp_found_config; | 36 | int smp_found_config; |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 3fdcdba0fec5..429c0269dc4e 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/i387.h> | 29 | #include <asm/i387.h> |
30 | #include <asm/proto.h> | 30 | #include <asm/proto.h> |
31 | #include <asm/ia32_unistd.h> | ||
31 | 32 | ||
32 | /* #define DEBUG_SIG 1 */ | 33 | /* #define DEBUG_SIG 1 */ |
33 | 34 | ||
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 735b6767c8ed..fb8c809b4cd9 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -27,7 +27,9 @@ | |||
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
29 | #include <linux/acpi.h> | 29 | #include <linux/acpi.h> |
30 | #ifdef CONFIG_ACPI | ||
30 | #include <acpi/achware.h> /* for PM timer frequency */ | 31 | #include <acpi/achware.h> /* for PM timer frequency */ |
32 | #endif | ||
31 | #include <asm/8253pit.h> | 33 | #include <asm/8253pit.h> |
32 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
33 | #include <asm/vsyscall.h> | 35 | #include <asm/vsyscall.h> |
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index d1dcd8eae3c9..5b77188527a9 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile | |||
@@ -39,7 +39,8 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y) | |||
39 | fore_200e-objs += fore200e_pca_fw.o | 39 | fore_200e-objs += fore200e_pca_fw.o |
40 | # guess the target endianess to choose the right PCA-200E firmware image | 40 | # guess the target endianess to choose the right PCA-200E firmware image |
41 | ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) | 41 | ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) |
42 | CONFIG_ATM_FORE200E_PCA_FW = $(shell if test -n "`$(CC) -E -dM $(src)/../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo $(obj)/pca200e.bin; else echo $(obj)/pca200e_ecd.bin2; fi) | 42 | byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h |
43 | CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2) | ||
43 | endif | 44 | endif |
44 | endif | 45 | endif |
45 | 46 | ||
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 9e65bfb85ba3..5f702199543a 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
@@ -383,8 +383,7 @@ fore200e_shutdown(struct fore200e* fore200e) | |||
383 | switch(fore200e->state) { | 383 | switch(fore200e->state) { |
384 | 384 | ||
385 | case FORE200E_STATE_COMPLETE: | 385 | case FORE200E_STATE_COMPLETE: |
386 | if (fore200e->stats) | 386 | kfree(fore200e->stats); |
387 | kfree(fore200e->stats); | ||
388 | 387 | ||
389 | case FORE200E_STATE_IRQ: | 388 | case FORE200E_STATE_IRQ: |
390 | free_irq(fore200e->irq, fore200e->atm_dev); | 389 | free_irq(fore200e->irq, fore200e->atm_dev); |
@@ -963,8 +962,7 @@ fore200e_tx_irq(struct fore200e* fore200e) | |||
963 | entry, txq->tail, entry->vc_map, entry->skb); | 962 | entry, txq->tail, entry->vc_map, entry->skb); |
964 | 963 | ||
965 | /* free copy of misaligned data */ | 964 | /* free copy of misaligned data */ |
966 | if (entry->data) | 965 | kfree(entry->data); |
967 | kfree(entry->data); | ||
968 | 966 | ||
969 | /* remove DMA mapping */ | 967 | /* remove DMA mapping */ |
970 | fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, | 968 | fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, |
diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 3022c548a132..df2c83fd5496 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c | |||
@@ -412,8 +412,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) | |||
412 | init_one_failure: | 412 | init_one_failure: |
413 | if (atm_dev) | 413 | if (atm_dev) |
414 | atm_dev_deregister(atm_dev); | 414 | atm_dev_deregister(atm_dev); |
415 | if (he_dev) | 415 | kfree(he_dev); |
416 | kfree(he_dev); | ||
417 | pci_disable_device(pci_dev); | 416 | pci_disable_device(pci_dev); |
418 | return err; | 417 | return err; |
419 | } | 418 | } |
@@ -2534,8 +2533,7 @@ he_open(struct atm_vcc *vcc) | |||
2534 | open_failed: | 2533 | open_failed: |
2535 | 2534 | ||
2536 | if (err) { | 2535 | if (err) { |
2537 | if (he_vcc) | 2536 | kfree(he_vcc); |
2538 | kfree(he_vcc); | ||
2539 | clear_bit(ATM_VF_ADDR, &vcc->flags); | 2537 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
2540 | } | 2538 | } |
2541 | else | 2539 | else |
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 85bf5c8442b0..b2a7b754fd14 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c | |||
@@ -676,10 +676,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) | |||
676 | PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base); | 676 | PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base); |
677 | 677 | ||
678 | /* Initialize SCQ0, the only VBR SCQ used */ | 678 | /* Initialize SCQ0, the only VBR SCQ used */ |
679 | card->scq1 = (scq_info *) NULL; | 679 | card->scq1 = NULL; |
680 | card->scq2 = (scq_info *) NULL; | 680 | card->scq2 = NULL; |
681 | card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0); | 681 | card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0); |
682 | if (card->scq0 == (scq_info *) NULL) | 682 | if (card->scq0 == NULL) |
683 | { | 683 | { |
684 | printk("nicstar%d: can't get SCQ0.\n", i); | 684 | printk("nicstar%d: can't get SCQ0.\n", i); |
685 | error = 12; | 685 | error = 12; |
@@ -993,24 +993,24 @@ static scq_info *get_scq(int size, u32 scd) | |||
993 | int i; | 993 | int i; |
994 | 994 | ||
995 | if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) | 995 | if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) |
996 | return (scq_info *) NULL; | 996 | return NULL; |
997 | 997 | ||
998 | scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL); | 998 | scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL); |
999 | if (scq == (scq_info *) NULL) | 999 | if (scq == NULL) |
1000 | return (scq_info *) NULL; | 1000 | return NULL; |
1001 | scq->org = kmalloc(2 * size, GFP_KERNEL); | 1001 | scq->org = kmalloc(2 * size, GFP_KERNEL); |
1002 | if (scq->org == NULL) | 1002 | if (scq->org == NULL) |
1003 | { | 1003 | { |
1004 | kfree(scq); | 1004 | kfree(scq); |
1005 | return (scq_info *) NULL; | 1005 | return NULL; |
1006 | } | 1006 | } |
1007 | scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) * | 1007 | scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) * |
1008 | (size / NS_SCQE_SIZE), GFP_KERNEL); | 1008 | (size / NS_SCQE_SIZE), GFP_KERNEL); |
1009 | if (scq->skb == (struct sk_buff **) NULL) | 1009 | if (scq->skb == NULL) |
1010 | { | 1010 | { |
1011 | kfree(scq->org); | 1011 | kfree(scq->org); |
1012 | kfree(scq); | 1012 | kfree(scq); |
1013 | return (scq_info *) NULL; | 1013 | return NULL; |
1014 | } | 1014 | } |
1015 | scq->num_entries = size / NS_SCQE_SIZE; | 1015 | scq->num_entries = size / NS_SCQE_SIZE; |
1016 | scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size); | 1016 | scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size); |
@@ -1498,7 +1498,7 @@ static int ns_open(struct atm_vcc *vcc) | |||
1498 | vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; | 1498 | vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; |
1499 | 1499 | ||
1500 | scq = get_scq(CBR_SCQSIZE, vc->cbr_scd); | 1500 | scq = get_scq(CBR_SCQSIZE, vc->cbr_scd); |
1501 | if (scq == (scq_info *) NULL) | 1501 | if (scq == NULL) |
1502 | { | 1502 | { |
1503 | PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index); | 1503 | PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index); |
1504 | card->scd2vc[frscdi] = NULL; | 1504 | card->scd2vc[frscdi] = NULL; |
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 47a800519ad0..8d5e65cb9755 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c | |||
@@ -902,7 +902,7 @@ static void close_tx(struct atm_vcc *vcc) | |||
902 | zatm_dev->tx_bw += vcc->qos.txtp.min_pcr; | 902 | zatm_dev->tx_bw += vcc->qos.txtp.min_pcr; |
903 | dealloc_shaper(vcc->dev,zatm_vcc->shaper); | 903 | dealloc_shaper(vcc->dev,zatm_vcc->shaper); |
904 | } | 904 | } |
905 | if (zatm_vcc->ring) kfree(zatm_vcc->ring); | 905 | kfree(zatm_vcc->ring); |
906 | } | 906 | } |
907 | 907 | ||
908 | 908 | ||
@@ -1339,12 +1339,9 @@ static int __init zatm_start(struct atm_dev *dev) | |||
1339 | return 0; | 1339 | return 0; |
1340 | out: | 1340 | out: |
1341 | for (i = 0; i < NR_MBX; i++) | 1341 | for (i = 0; i < NR_MBX; i++) |
1342 | if (zatm_dev->mbx_start[i] != 0) | 1342 | kfree(zatm_dev->mbx_start[i]); |
1343 | kfree((void *) zatm_dev->mbx_start[i]); | 1343 | kfree(zatm_dev->rx_map); |
1344 | if (zatm_dev->rx_map != NULL) | 1344 | kfree(zatm_dev->tx_map); |
1345 | kfree(zatm_dev->rx_map); | ||
1346 | if (zatm_dev->tx_map != NULL) | ||
1347 | kfree(zatm_dev->tx_map); | ||
1348 | free_irq(zatm_dev->irq, dev); | 1345 | free_irq(zatm_dev->irq, dev); |
1349 | return error; | 1346 | return error; |
1350 | } | 1347 | } |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index ce42889f98fb..adc4dcc306f4 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -8,13 +8,12 @@ | |||
8 | * and is not licensed separately. See file COPYING for details. | 8 | * and is not licensed separately. See file COPYING for details. |
9 | * | 9 | * |
10 | * TODO (sorted by decreasing priority) | 10 | * TODO (sorted by decreasing priority) |
11 | * -- Kill first_open (Al Viro fixed the block layer now) | ||
11 | * -- Do resets with usb_device_reset (needs a thread context, use khubd) | 12 | * -- Do resets with usb_device_reset (needs a thread context, use khubd) |
12 | * -- set readonly flag for CDs, set removable flag for CF readers | 13 | * -- set readonly flag for CDs, set removable flag for CF readers |
13 | * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) | 14 | * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) |
14 | * -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...) | ||
15 | * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries | 15 | * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries |
16 | * -- verify the 13 conditions and do bulk resets | 16 | * -- verify the 13 conditions and do bulk resets |
17 | * -- normal pool of commands instead of cmdv[]? | ||
18 | * -- kill last_pipe and simply do two-state clearing on both pipes | 17 | * -- kill last_pipe and simply do two-state clearing on both pipes |
19 | * -- verify protocol (bulk) from USB descriptors (maybe...) | 18 | * -- verify protocol (bulk) from USB descriptors (maybe...) |
20 | * -- highmem and sg | 19 | * -- highmem and sg |
@@ -49,7 +48,14 @@ | |||
49 | #define US_SC_SCSI 0x06 /* Transparent */ | 48 | #define US_SC_SCSI 0x06 /* Transparent */ |
50 | 49 | ||
51 | /* | 50 | /* |
51 | * This many LUNs per USB device. | ||
52 | * Every one of them takes a host, see UB_MAX_HOSTS. | ||
52 | */ | 53 | */ |
54 | #define UB_MAX_LUNS 4 | ||
55 | |||
56 | /* | ||
57 | */ | ||
58 | |||
53 | #define UB_MINORS_PER_MAJOR 8 | 59 | #define UB_MINORS_PER_MAJOR 8 |
54 | 60 | ||
55 | #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ | 61 | #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ |
@@ -65,7 +71,7 @@ struct bulk_cb_wrap { | |||
65 | u32 Tag; /* unique per command id */ | 71 | u32 Tag; /* unique per command id */ |
66 | __le32 DataTransferLength; /* size of data */ | 72 | __le32 DataTransferLength; /* size of data */ |
67 | u8 Flags; /* direction in bit 0 */ | 73 | u8 Flags; /* direction in bit 0 */ |
68 | u8 Lun; /* LUN normally 0 */ | 74 | u8 Lun; /* LUN */ |
69 | u8 Length; /* of of the CDB */ | 75 | u8 Length; /* of of the CDB */ |
70 | u8 CDB[UB_MAX_CDB_SIZE]; /* max command */ | 76 | u8 CDB[UB_MAX_CDB_SIZE]; /* max command */ |
71 | }; | 77 | }; |
@@ -168,6 +174,7 @@ struct ub_scsi_cmd { | |||
168 | unsigned int len; /* Requested length */ | 174 | unsigned int len; /* Requested length */ |
169 | // struct scatterlist sgv[UB_MAX_REQ_SG]; | 175 | // struct scatterlist sgv[UB_MAX_REQ_SG]; |
170 | 176 | ||
177 | struct ub_lun *lun; | ||
171 | void (*done)(struct ub_dev *, struct ub_scsi_cmd *); | 178 | void (*done)(struct ub_dev *, struct ub_scsi_cmd *); |
172 | void *back; | 179 | void *back; |
173 | }; | 180 | }; |
@@ -252,25 +259,47 @@ struct ub_scsi_cmd_queue { | |||
252 | }; | 259 | }; |
253 | 260 | ||
254 | /* | 261 | /* |
255 | * The UB device instance. | 262 | * The block device instance (one per LUN). |
263 | */ | ||
264 | struct ub_lun { | ||
265 | struct ub_dev *udev; | ||
266 | struct list_head link; | ||
267 | struct gendisk *disk; | ||
268 | int id; /* Host index */ | ||
269 | int num; /* LUN number */ | ||
270 | char name[16]; | ||
271 | |||
272 | int changed; /* Media was changed */ | ||
273 | int removable; | ||
274 | int readonly; | ||
275 | int first_open; /* Kludge. See ub_bd_open. */ | ||
276 | |||
277 | /* Use Ingo's mempool if or when we have more than one command. */ | ||
278 | /* | ||
279 | * Currently we never need more than one command for the whole device. | ||
280 | * However, giving every LUN a command is a cheap and automatic way | ||
281 | * to enforce fairness between them. | ||
282 | */ | ||
283 | int cmda[1]; | ||
284 | struct ub_scsi_cmd cmdv[1]; | ||
285 | |||
286 | struct ub_capacity capacity; | ||
287 | }; | ||
288 | |||
289 | /* | ||
290 | * The USB device instance. | ||
256 | */ | 291 | */ |
257 | struct ub_dev { | 292 | struct ub_dev { |
258 | spinlock_t lock; | 293 | spinlock_t lock; |
259 | int id; /* Number among ub's */ | ||
260 | atomic_t poison; /* The USB device is disconnected */ | 294 | atomic_t poison; /* The USB device is disconnected */ |
261 | int openc; /* protected by ub_lock! */ | 295 | int openc; /* protected by ub_lock! */ |
262 | /* kref is too implicit for our taste */ | 296 | /* kref is too implicit for our taste */ |
263 | unsigned int tagcnt; | 297 | unsigned int tagcnt; |
264 | int changed; /* Media was changed */ | 298 | char name[12]; |
265 | int removable; | ||
266 | int readonly; | ||
267 | int first_open; /* Kludge. See ub_bd_open. */ | ||
268 | char name[8]; | ||
269 | struct usb_device *dev; | 299 | struct usb_device *dev; |
270 | struct usb_interface *intf; | 300 | struct usb_interface *intf; |
271 | 301 | ||
272 | struct ub_capacity capacity; | 302 | struct list_head luns; |
273 | struct gendisk *disk; | ||
274 | 303 | ||
275 | unsigned int send_bulk_pipe; /* cached pipe values */ | 304 | unsigned int send_bulk_pipe; /* cached pipe values */ |
276 | unsigned int recv_bulk_pipe; | 305 | unsigned int recv_bulk_pipe; |
@@ -279,10 +308,6 @@ struct ub_dev { | |||
279 | 308 | ||
280 | struct tasklet_struct tasklet; | 309 | struct tasklet_struct tasklet; |
281 | 310 | ||
282 | /* XXX Use Ingo's mempool (once we have more than one) */ | ||
283 | int cmda[1]; | ||
284 | struct ub_scsi_cmd cmdv[1]; | ||
285 | |||
286 | struct ub_scsi_cmd_queue cmd_queue; | 311 | struct ub_scsi_cmd_queue cmd_queue; |
287 | struct ub_scsi_cmd top_rqs_cmd; /* REQUEST SENSE */ | 312 | struct ub_scsi_cmd top_rqs_cmd; /* REQUEST SENSE */ |
288 | unsigned char top_sense[UB_SENSE_SIZE]; | 313 | unsigned char top_sense[UB_SENSE_SIZE]; |
@@ -301,9 +326,9 @@ struct ub_dev { | |||
301 | /* | 326 | /* |
302 | */ | 327 | */ |
303 | static void ub_cleanup(struct ub_dev *sc); | 328 | static void ub_cleanup(struct ub_dev *sc); |
304 | static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq); | 329 | static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq); |
305 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 330 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, |
306 | struct request *rq); | 331 | struct ub_scsi_cmd *cmd, struct request *rq); |
307 | static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 332 | static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, |
308 | struct request *rq); | 333 | struct request *rq); |
309 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 334 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
@@ -320,8 +345,10 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | |||
320 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 345 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, |
321 | int stalled_pipe); | 346 | int stalled_pipe); |
322 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); | 347 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); |
323 | static int ub_sync_tur(struct ub_dev *sc); | 348 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); |
324 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret); | 349 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, |
350 | struct ub_capacity *ret); | ||
351 | static int ub_probe_lun(struct ub_dev *sc, int lnum); | ||
325 | 352 | ||
326 | /* | 353 | /* |
327 | */ | 354 | */ |
@@ -342,6 +369,7 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids); | |||
342 | */ | 369 | */ |
343 | #define UB_MAX_HOSTS 26 | 370 | #define UB_MAX_HOSTS 26 |
344 | static char ub_hostv[UB_MAX_HOSTS]; | 371 | static char ub_hostv[UB_MAX_HOSTS]; |
372 | |||
345 | static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */ | 373 | static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */ |
346 | 374 | ||
347 | /* | 375 | /* |
@@ -406,6 +434,8 @@ static ssize_t ub_diag_show(struct device *dev, char *page) | |||
406 | { | 434 | { |
407 | struct usb_interface *intf; | 435 | struct usb_interface *intf; |
408 | struct ub_dev *sc; | 436 | struct ub_dev *sc; |
437 | struct list_head *p; | ||
438 | struct ub_lun *lun; | ||
409 | int cnt; | 439 | int cnt; |
410 | unsigned long flags; | 440 | unsigned long flags; |
411 | int nc, nh; | 441 | int nc, nh; |
@@ -421,9 +451,15 @@ static ssize_t ub_diag_show(struct device *dev, char *page) | |||
421 | spin_lock_irqsave(&sc->lock, flags); | 451 | spin_lock_irqsave(&sc->lock, flags); |
422 | 452 | ||
423 | cnt += sprintf(page + cnt, | 453 | cnt += sprintf(page + cnt, |
424 | "qlen %d qmax %d changed %d removable %d readonly %d\n", | 454 | "qlen %d qmax %d\n", |
425 | sc->cmd_queue.qlen, sc->cmd_queue.qmax, | 455 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); |
426 | sc->changed, sc->removable, sc->readonly); | 456 | |
457 | list_for_each (p, &sc->luns) { | ||
458 | lun = list_entry(p, struct ub_lun, link); | ||
459 | cnt += sprintf(page + cnt, | ||
460 | "lun %u changed %d removable %d readonly %d\n", | ||
461 | lun->num, lun->changed, lun->removable, lun->readonly); | ||
462 | } | ||
427 | 463 | ||
428 | if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0; | 464 | if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0; |
429 | for (j = 0; j < SCMD_TRACE_SZ; j++) { | 465 | for (j = 0; j < SCMD_TRACE_SZ; j++) { |
@@ -523,53 +559,63 @@ static void ub_put(struct ub_dev *sc) | |||
523 | */ | 559 | */ |
524 | static void ub_cleanup(struct ub_dev *sc) | 560 | static void ub_cleanup(struct ub_dev *sc) |
525 | { | 561 | { |
562 | struct list_head *p; | ||
563 | struct ub_lun *lun; | ||
526 | request_queue_t *q; | 564 | request_queue_t *q; |
527 | 565 | ||
528 | /* I don't think queue can be NULL. But... Stolen from sx8.c */ | 566 | while (!list_empty(&sc->luns)) { |
529 | if ((q = sc->disk->queue) != NULL) | 567 | p = sc->luns.next; |
530 | blk_cleanup_queue(q); | 568 | lun = list_entry(p, struct ub_lun, link); |
569 | list_del(p); | ||
531 | 570 | ||
532 | /* | 571 | /* I don't think queue can be NULL. But... Stolen from sx8.c */ |
533 | * If we zero disk->private_data BEFORE put_disk, we have to check | 572 | if ((q = lun->disk->queue) != NULL) |
534 | * for NULL all over the place in open, release, check_media and | 573 | blk_cleanup_queue(q); |
535 | * revalidate, because the block level semaphore is well inside the | 574 | /* |
536 | * put_disk. But we cannot zero after the call, because *disk is gone. | 575 | * If we zero disk->private_data BEFORE put_disk, we have |
537 | * The sd.c is blatantly racy in this area. | 576 | * to check for NULL all over the place in open, release, |
538 | */ | 577 | * check_media and revalidate, because the block level |
539 | /* disk->private_data = NULL; */ | 578 | * semaphore is well inside the put_disk. |
540 | put_disk(sc->disk); | 579 | * But we cannot zero after the call, because *disk is gone. |
541 | sc->disk = NULL; | 580 | * The sd.c is blatantly racy in this area. |
581 | */ | ||
582 | /* disk->private_data = NULL; */ | ||
583 | put_disk(lun->disk); | ||
584 | lun->disk = NULL; | ||
585 | |||
586 | ub_id_put(lun->id); | ||
587 | kfree(lun); | ||
588 | } | ||
542 | 589 | ||
543 | ub_id_put(sc->id); | ||
544 | kfree(sc); | 590 | kfree(sc); |
545 | } | 591 | } |
546 | 592 | ||
547 | /* | 593 | /* |
548 | * The "command allocator". | 594 | * The "command allocator". |
549 | */ | 595 | */ |
550 | static struct ub_scsi_cmd *ub_get_cmd(struct ub_dev *sc) | 596 | static struct ub_scsi_cmd *ub_get_cmd(struct ub_lun *lun) |
551 | { | 597 | { |
552 | struct ub_scsi_cmd *ret; | 598 | struct ub_scsi_cmd *ret; |
553 | 599 | ||
554 | if (sc->cmda[0]) | 600 | if (lun->cmda[0]) |
555 | return NULL; | 601 | return NULL; |
556 | ret = &sc->cmdv[0]; | 602 | ret = &lun->cmdv[0]; |
557 | sc->cmda[0] = 1; | 603 | lun->cmda[0] = 1; |
558 | return ret; | 604 | return ret; |
559 | } | 605 | } |
560 | 606 | ||
561 | static void ub_put_cmd(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 607 | static void ub_put_cmd(struct ub_lun *lun, struct ub_scsi_cmd *cmd) |
562 | { | 608 | { |
563 | if (cmd != &sc->cmdv[0]) { | 609 | if (cmd != &lun->cmdv[0]) { |
564 | printk(KERN_WARNING "%s: releasing a foreign cmd %p\n", | 610 | printk(KERN_WARNING "%s: releasing a foreign cmd %p\n", |
565 | sc->name, cmd); | 611 | lun->name, cmd); |
566 | return; | 612 | return; |
567 | } | 613 | } |
568 | if (!sc->cmda[0]) { | 614 | if (!lun->cmda[0]) { |
569 | printk(KERN_WARNING "%s: releasing a free cmd\n", sc->name); | 615 | printk(KERN_WARNING "%s: releasing a free cmd\n", lun->name); |
570 | return; | 616 | return; |
571 | } | 617 | } |
572 | sc->cmda[0] = 0; | 618 | lun->cmda[0] = 0; |
573 | } | 619 | } |
574 | 620 | ||
575 | /* | 621 | /* |
@@ -630,29 +676,30 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc) | |||
630 | 676 | ||
631 | static void ub_bd_rq_fn(request_queue_t *q) | 677 | static void ub_bd_rq_fn(request_queue_t *q) |
632 | { | 678 | { |
633 | struct ub_dev *sc = q->queuedata; | 679 | struct ub_lun *lun = q->queuedata; |
634 | struct request *rq; | 680 | struct request *rq; |
635 | 681 | ||
636 | while ((rq = elv_next_request(q)) != NULL) { | 682 | while ((rq = elv_next_request(q)) != NULL) { |
637 | if (ub_bd_rq_fn_1(sc, rq) != 0) { | 683 | if (ub_bd_rq_fn_1(lun, rq) != 0) { |
638 | blk_stop_queue(q); | 684 | blk_stop_queue(q); |
639 | break; | 685 | break; |
640 | } | 686 | } |
641 | } | 687 | } |
642 | } | 688 | } |
643 | 689 | ||
644 | static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) | 690 | static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) |
645 | { | 691 | { |
692 | struct ub_dev *sc = lun->udev; | ||
646 | struct ub_scsi_cmd *cmd; | 693 | struct ub_scsi_cmd *cmd; |
647 | int rc; | 694 | int rc; |
648 | 695 | ||
649 | if (atomic_read(&sc->poison) || sc->changed) { | 696 | if (atomic_read(&sc->poison) || lun->changed) { |
650 | blkdev_dequeue_request(rq); | 697 | blkdev_dequeue_request(rq); |
651 | ub_end_rq(rq, 0); | 698 | ub_end_rq(rq, 0); |
652 | return 0; | 699 | return 0; |
653 | } | 700 | } |
654 | 701 | ||
655 | if ((cmd = ub_get_cmd(sc)) == NULL) | 702 | if ((cmd = ub_get_cmd(lun)) == NULL) |
656 | return -1; | 703 | return -1; |
657 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); | 704 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); |
658 | 705 | ||
@@ -661,32 +708,30 @@ static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) | |||
661 | if (blk_pc_request(rq)) { | 708 | if (blk_pc_request(rq)) { |
662 | rc = ub_cmd_build_packet(sc, cmd, rq); | 709 | rc = ub_cmd_build_packet(sc, cmd, rq); |
663 | } else { | 710 | } else { |
664 | rc = ub_cmd_build_block(sc, cmd, rq); | 711 | rc = ub_cmd_build_block(sc, lun, cmd, rq); |
665 | } | 712 | } |
666 | if (rc != 0) { | 713 | if (rc != 0) { |
667 | ub_put_cmd(sc, cmd); | 714 | ub_put_cmd(lun, cmd); |
668 | ub_end_rq(rq, 0); | 715 | ub_end_rq(rq, 0); |
669 | blk_start_queue(sc->disk->queue); | ||
670 | return 0; | 716 | return 0; |
671 | } | 717 | } |
672 | |||
673 | cmd->state = UB_CMDST_INIT; | 718 | cmd->state = UB_CMDST_INIT; |
719 | cmd->lun = lun; | ||
674 | cmd->done = ub_rw_cmd_done; | 720 | cmd->done = ub_rw_cmd_done; |
675 | cmd->back = rq; | 721 | cmd->back = rq; |
676 | 722 | ||
677 | cmd->tag = sc->tagcnt++; | 723 | cmd->tag = sc->tagcnt++; |
678 | if ((rc = ub_submit_scsi(sc, cmd)) != 0) { | 724 | if ((rc = ub_submit_scsi(sc, cmd)) != 0) { |
679 | ub_put_cmd(sc, cmd); | 725 | ub_put_cmd(lun, cmd); |
680 | ub_end_rq(rq, 0); | 726 | ub_end_rq(rq, 0); |
681 | blk_start_queue(sc->disk->queue); | ||
682 | return 0; | 727 | return 0; |
683 | } | 728 | } |
684 | 729 | ||
685 | return 0; | 730 | return 0; |
686 | } | 731 | } |
687 | 732 | ||
688 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 733 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, |
689 | struct request *rq) | 734 | struct ub_scsi_cmd *cmd, struct request *rq) |
690 | { | 735 | { |
691 | int ub_dir; | 736 | int ub_dir; |
692 | #if 0 /* We use rq->buffer for now */ | 737 | #if 0 /* We use rq->buffer for now */ |
@@ -707,7 +752,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
707 | sg = &cmd->sgv[0]; | 752 | sg = &cmd->sgv[0]; |
708 | n_elem = blk_rq_map_sg(q, rq, sg); | 753 | n_elem = blk_rq_map_sg(q, rq, sg); |
709 | if (n_elem <= 0) { | 754 | if (n_elem <= 0) { |
710 | ub_put_cmd(sc, cmd); | 755 | ub_put_cmd(lun, cmd); |
711 | ub_end_rq(rq, 0); | 756 | ub_end_rq(rq, 0); |
712 | blk_start_queue(q); | 757 | blk_start_queue(q); |
713 | return 0; /* request with no s/g entries? */ | 758 | return 0; /* request with no s/g entries? */ |
@@ -716,7 +761,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
716 | if (n_elem != 1) { /* Paranoia */ | 761 | if (n_elem != 1) { /* Paranoia */ |
717 | printk(KERN_WARNING "%s: request with %d segments\n", | 762 | printk(KERN_WARNING "%s: request with %d segments\n", |
718 | sc->name, n_elem); | 763 | sc->name, n_elem); |
719 | ub_put_cmd(sc, cmd); | 764 | ub_put_cmd(lun, cmd); |
720 | ub_end_rq(rq, 0); | 765 | ub_end_rq(rq, 0); |
721 | blk_start_queue(q); | 766 | blk_start_queue(q); |
722 | return 0; | 767 | return 0; |
@@ -748,8 +793,8 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
748 | * The call to blk_queue_hardsect_size() guarantees that request | 793 | * The call to blk_queue_hardsect_size() guarantees that request |
749 | * is aligned, but it is given in terms of 512 byte units, always. | 794 | * is aligned, but it is given in terms of 512 byte units, always. |
750 | */ | 795 | */ |
751 | block = rq->sector >> sc->capacity.bshift; | 796 | block = rq->sector >> lun->capacity.bshift; |
752 | nblks = rq->nr_sectors >> sc->capacity.bshift; | 797 | nblks = rq->nr_sectors >> lun->capacity.bshift; |
753 | 798 | ||
754 | cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; | 799 | cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; |
755 | /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ | 800 | /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ |
@@ -803,7 +848,8 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
803 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 848 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) |
804 | { | 849 | { |
805 | struct request *rq = cmd->back; | 850 | struct request *rq = cmd->back; |
806 | struct gendisk *disk = sc->disk; | 851 | struct ub_lun *lun = cmd->lun; |
852 | struct gendisk *disk = lun->disk; | ||
807 | request_queue_t *q = disk->queue; | 853 | request_queue_t *q = disk->queue; |
808 | int uptodate; | 854 | int uptodate; |
809 | 855 | ||
@@ -818,7 +864,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
818 | else | 864 | else |
819 | uptodate = 0; | 865 | uptodate = 0; |
820 | 866 | ||
821 | ub_put_cmd(sc, cmd); | 867 | ub_put_cmd(lun, cmd); |
822 | ub_end_rq(rq, uptodate); | 868 | ub_end_rq(rq, uptodate); |
823 | blk_start_queue(q); | 869 | blk_start_queue(q); |
824 | } | 870 | } |
@@ -887,7 +933,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
887 | bcb->Tag = cmd->tag; /* Endianness is not important */ | 933 | bcb->Tag = cmd->tag; /* Endianness is not important */ |
888 | bcb->DataTransferLength = cpu_to_le32(cmd->len); | 934 | bcb->DataTransferLength = cpu_to_le32(cmd->len); |
889 | bcb->Flags = (cmd->dir == UB_DIR_READ) ? 0x80 : 0; | 935 | bcb->Flags = (cmd->dir == UB_DIR_READ) ? 0x80 : 0; |
890 | bcb->Lun = 0; /* No multi-LUN yet */ | 936 | bcb->Lun = (cmd->lun != NULL) ? cmd->lun->num : 0; |
891 | bcb->Length = cmd->cdb_len; | 937 | bcb->Length = cmd->cdb_len; |
892 | 938 | ||
893 | /* copy the command payload */ | 939 | /* copy the command payload */ |
@@ -1002,9 +1048,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1002 | * The control pipe clears itself - nothing to do. | 1048 | * The control pipe clears itself - nothing to do. |
1003 | * XXX Might try to reset the device here and retry. | 1049 | * XXX Might try to reset the device here and retry. |
1004 | */ | 1050 | */ |
1005 | printk(KERN_NOTICE "%s: " | 1051 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
1006 | "stall on control pipe for device %u\n", | 1052 | sc->name); |
1007 | sc->name, sc->dev->devnum); | ||
1008 | goto Bad_End; | 1053 | goto Bad_End; |
1009 | } | 1054 | } |
1010 | 1055 | ||
@@ -1025,9 +1070,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1025 | * The control pipe clears itself - nothing to do. | 1070 | * The control pipe clears itself - nothing to do. |
1026 | * XXX Might try to reset the device here and retry. | 1071 | * XXX Might try to reset the device here and retry. |
1027 | */ | 1072 | */ |
1028 | printk(KERN_NOTICE "%s: " | 1073 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
1029 | "stall on control pipe for device %u\n", | 1074 | sc->name); |
1030 | sc->name, sc->dev->devnum); | ||
1031 | goto Bad_End; | 1075 | goto Bad_End; |
1032 | } | 1076 | } |
1033 | 1077 | ||
@@ -1046,9 +1090,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1046 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); | 1090 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); |
1047 | if (rc != 0) { | 1091 | if (rc != 0) { |
1048 | printk(KERN_NOTICE "%s: " | 1092 | printk(KERN_NOTICE "%s: " |
1049 | "unable to submit clear for device %u" | 1093 | "unable to submit clear (%d)\n", |
1050 | " (code %d)\n", | 1094 | sc->name, rc); |
1051 | sc->name, sc->dev->devnum, rc); | ||
1052 | /* | 1095 | /* |
1053 | * This is typically ENOMEM or some other such shit. | 1096 | * This is typically ENOMEM or some other such shit. |
1054 | * Retrying is pointless. Just do Bad End on it... | 1097 | * Retrying is pointless. Just do Bad End on it... |
@@ -1107,9 +1150,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1107 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); | 1150 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); |
1108 | if (rc != 0) { | 1151 | if (rc != 0) { |
1109 | printk(KERN_NOTICE "%s: " | 1152 | printk(KERN_NOTICE "%s: " |
1110 | "unable to submit clear for device %u" | 1153 | "unable to submit clear (%d)\n", |
1111 | " (code %d)\n", | 1154 | sc->name, rc); |
1112 | sc->name, sc->dev->devnum, rc); | ||
1113 | /* | 1155 | /* |
1114 | * This is typically ENOMEM or some other such shit. | 1156 | * This is typically ENOMEM or some other such shit. |
1115 | * Retrying is pointless. Just do Bad End on it... | 1157 | * Retrying is pointless. Just do Bad End on it... |
@@ -1140,9 +1182,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1140 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); | 1182 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); |
1141 | if (rc != 0) { | 1183 | if (rc != 0) { |
1142 | printk(KERN_NOTICE "%s: " | 1184 | printk(KERN_NOTICE "%s: " |
1143 | "unable to submit clear for device %u" | 1185 | "unable to submit clear (%d)\n", |
1144 | " (code %d)\n", | 1186 | sc->name, rc); |
1145 | sc->name, sc->dev->devnum, rc); | ||
1146 | /* | 1187 | /* |
1147 | * This is typically ENOMEM or some other such shit. | 1188 | * This is typically ENOMEM or some other such shit. |
1148 | * Retrying is pointless. Just do Bad End on it... | 1189 | * Retrying is pointless. Just do Bad End on it... |
@@ -1164,9 +1205,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1164 | * encounter such a thing, try to read the CSW again. | 1205 | * encounter such a thing, try to read the CSW again. |
1165 | */ | 1206 | */ |
1166 | if (++cmd->stat_count >= 4) { | 1207 | if (++cmd->stat_count >= 4) { |
1167 | printk(KERN_NOTICE "%s: " | 1208 | printk(KERN_NOTICE "%s: unable to get CSW\n", |
1168 | "unable to get CSW on device %u\n", | 1209 | sc->name); |
1169 | sc->name, sc->dev->devnum); | ||
1170 | goto Bad_End; | 1210 | goto Bad_End; |
1171 | } | 1211 | } |
1172 | __ub_state_stat(sc, cmd); | 1212 | __ub_state_stat(sc, cmd); |
@@ -1207,10 +1247,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1207 | */ | 1247 | */ |
1208 | if (++cmd->stat_count >= 4) { | 1248 | if (++cmd->stat_count >= 4) { |
1209 | printk(KERN_NOTICE "%s: " | 1249 | printk(KERN_NOTICE "%s: " |
1210 | "tag mismatch orig 0x%x reply 0x%x " | 1250 | "tag mismatch orig 0x%x reply 0x%x\n", |
1211 | "on device %u\n", | 1251 | sc->name, cmd->tag, bcs->Tag); |
1212 | sc->name, cmd->tag, bcs->Tag, | ||
1213 | sc->dev->devnum); | ||
1214 | goto Bad_End; | 1252 | goto Bad_End; |
1215 | } | 1253 | } |
1216 | __ub_state_stat(sc, cmd); | 1254 | __ub_state_stat(sc, cmd); |
@@ -1244,8 +1282,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1244 | 1282 | ||
1245 | } else { | 1283 | } else { |
1246 | printk(KERN_WARNING "%s: " | 1284 | printk(KERN_WARNING "%s: " |
1247 | "wrong command state %d on device %u\n", | 1285 | "wrong command state %d\n", |
1248 | sc->name, cmd->state, sc->dev->devnum); | 1286 | sc->name, cmd->state); |
1249 | goto Bad_End; | 1287 | goto Bad_End; |
1250 | } | 1288 | } |
1251 | return; | 1289 | return; |
@@ -1288,7 +1326,6 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1288 | 1326 | ||
1289 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1327 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1290 | /* XXX Clear stalls */ | 1328 | /* XXX Clear stalls */ |
1291 | printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */ | ||
1292 | ub_complete(&sc->work_done); | 1329 | ub_complete(&sc->work_done); |
1293 | ub_state_done(sc, cmd, rc); | 1330 | ub_state_done(sc, cmd, rc); |
1294 | return; | 1331 | return; |
@@ -1333,6 +1370,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1333 | scmd->state = UB_CMDST_INIT; | 1370 | scmd->state = UB_CMDST_INIT; |
1334 | scmd->data = sc->top_sense; | 1371 | scmd->data = sc->top_sense; |
1335 | scmd->len = UB_SENSE_SIZE; | 1372 | scmd->len = UB_SENSE_SIZE; |
1373 | scmd->lun = cmd->lun; | ||
1336 | scmd->done = ub_top_sense_done; | 1374 | scmd->done = ub_top_sense_done; |
1337 | scmd->back = cmd; | 1375 | scmd->back = cmd; |
1338 | 1376 | ||
@@ -1411,14 +1449,14 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) | |||
1411 | } | 1449 | } |
1412 | if (cmd != scmd->back) { | 1450 | if (cmd != scmd->back) { |
1413 | printk(KERN_WARNING "%s: " | 1451 | printk(KERN_WARNING "%s: " |
1414 | "sense done for wrong command 0x%x on device %u\n", | 1452 | "sense done for wrong command 0x%x\n", |
1415 | sc->name, cmd->tag, sc->dev->devnum); | 1453 | sc->name, cmd->tag); |
1416 | return; | 1454 | return; |
1417 | } | 1455 | } |
1418 | if (cmd->state != UB_CMDST_SENSE) { | 1456 | if (cmd->state != UB_CMDST_SENSE) { |
1419 | printk(KERN_WARNING "%s: " | 1457 | printk(KERN_WARNING "%s: " |
1420 | "sense done with bad cmd state %d on device %u\n", | 1458 | "sense done with bad cmd state %d\n", |
1421 | sc->name, cmd->state, sc->dev->devnum); | 1459 | sc->name, cmd->state); |
1422 | return; | 1460 | return; |
1423 | } | 1461 | } |
1424 | 1462 | ||
@@ -1429,68 +1467,32 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) | |||
1429 | ub_scsi_urb_compl(sc, cmd); | 1467 | ub_scsi_urb_compl(sc, cmd); |
1430 | } | 1468 | } |
1431 | 1469 | ||
1432 | #if 0 | ||
1433 | /* Determine what the maximum LUN supported is */ | ||
1434 | int usb_stor_Bulk_max_lun(struct us_data *us) | ||
1435 | { | ||
1436 | int result; | ||
1437 | |||
1438 | /* issue the command */ | ||
1439 | result = usb_stor_control_msg(us, us->recv_ctrl_pipe, | ||
1440 | US_BULK_GET_MAX_LUN, | ||
1441 | USB_DIR_IN | USB_TYPE_CLASS | | ||
1442 | USB_RECIP_INTERFACE, | ||
1443 | 0, us->ifnum, us->iobuf, 1, HZ); | ||
1444 | |||
1445 | /* | ||
1446 | * Some devices (i.e. Iomega Zip100) need this -- apparently | ||
1447 | * the bulk pipes get STALLed when the GetMaxLUN request is | ||
1448 | * processed. This is, in theory, harmless to all other devices | ||
1449 | * (regardless of if they stall or not). | ||
1450 | */ | ||
1451 | if (result < 0) { | ||
1452 | usb_stor_clear_halt(us, us->recv_bulk_pipe); | ||
1453 | usb_stor_clear_halt(us, us->send_bulk_pipe); | ||
1454 | } | ||
1455 | |||
1456 | US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", | ||
1457 | result, us->iobuf[0]); | ||
1458 | |||
1459 | /* if we have a successful request, return the result */ | ||
1460 | if (result == 1) | ||
1461 | return us->iobuf[0]; | ||
1462 | |||
1463 | /* return the default -- no LUNs */ | ||
1464 | return 0; | ||
1465 | } | ||
1466 | #endif | ||
1467 | |||
1468 | /* | 1470 | /* |
1469 | * This is called from a process context. | 1471 | * This is called from a process context. |
1470 | */ | 1472 | */ |
1471 | static void ub_revalidate(struct ub_dev *sc) | 1473 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) |
1472 | { | 1474 | { |
1473 | 1475 | ||
1474 | sc->readonly = 0; /* XXX Query this from the device */ | 1476 | lun->readonly = 0; /* XXX Query this from the device */ |
1475 | 1477 | ||
1476 | sc->capacity.nsec = 0; | 1478 | lun->capacity.nsec = 0; |
1477 | sc->capacity.bsize = 512; | 1479 | lun->capacity.bsize = 512; |
1478 | sc->capacity.bshift = 0; | 1480 | lun->capacity.bshift = 0; |
1479 | 1481 | ||
1480 | if (ub_sync_tur(sc) != 0) | 1482 | if (ub_sync_tur(sc, lun) != 0) |
1481 | return; /* Not ready */ | 1483 | return; /* Not ready */ |
1482 | sc->changed = 0; | 1484 | lun->changed = 0; |
1483 | 1485 | ||
1484 | if (ub_sync_read_cap(sc, &sc->capacity) != 0) { | 1486 | if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { |
1485 | /* | 1487 | /* |
1486 | * The retry here means something is wrong, either with the | 1488 | * The retry here means something is wrong, either with the |
1487 | * device, with the transport, or with our code. | 1489 | * device, with the transport, or with our code. |
1488 | * We keep this because sd.c has retries for capacity. | 1490 | * We keep this because sd.c has retries for capacity. |
1489 | */ | 1491 | */ |
1490 | if (ub_sync_read_cap(sc, &sc->capacity) != 0) { | 1492 | if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { |
1491 | sc->capacity.nsec = 0; | 1493 | lun->capacity.nsec = 0; |
1492 | sc->capacity.bsize = 512; | 1494 | lun->capacity.bsize = 512; |
1493 | sc->capacity.bshift = 0; | 1495 | lun->capacity.bshift = 0; |
1494 | } | 1496 | } |
1495 | } | 1497 | } |
1496 | } | 1498 | } |
@@ -1503,12 +1505,15 @@ static void ub_revalidate(struct ub_dev *sc) | |||
1503 | static int ub_bd_open(struct inode *inode, struct file *filp) | 1505 | static int ub_bd_open(struct inode *inode, struct file *filp) |
1504 | { | 1506 | { |
1505 | struct gendisk *disk = inode->i_bdev->bd_disk; | 1507 | struct gendisk *disk = inode->i_bdev->bd_disk; |
1508 | struct ub_lun *lun; | ||
1506 | struct ub_dev *sc; | 1509 | struct ub_dev *sc; |
1507 | unsigned long flags; | 1510 | unsigned long flags; |
1508 | int rc; | 1511 | int rc; |
1509 | 1512 | ||
1510 | if ((sc = disk->private_data) == NULL) | 1513 | if ((lun = disk->private_data) == NULL) |
1511 | return -ENXIO; | 1514 | return -ENXIO; |
1515 | sc = lun->udev; | ||
1516 | |||
1512 | spin_lock_irqsave(&ub_lock, flags); | 1517 | spin_lock_irqsave(&ub_lock, flags); |
1513 | if (atomic_read(&sc->poison)) { | 1518 | if (atomic_read(&sc->poison)) { |
1514 | spin_unlock_irqrestore(&ub_lock, flags); | 1519 | spin_unlock_irqrestore(&ub_lock, flags); |
@@ -1529,15 +1534,15 @@ static int ub_bd_open(struct inode *inode, struct file *filp) | |||
1529 | * The bottom line is, Al Viro says that we should not allow | 1534 | * The bottom line is, Al Viro says that we should not allow |
1530 | * bdev->bd_invalidated to be set when doing add_disk no matter what. | 1535 | * bdev->bd_invalidated to be set when doing add_disk no matter what. |
1531 | */ | 1536 | */ |
1532 | if (sc->first_open) { | 1537 | if (lun->first_open) { |
1533 | if (sc->changed) { | 1538 | lun->first_open = 0; |
1534 | sc->first_open = 0; | 1539 | if (lun->changed) { |
1535 | rc = -ENOMEDIUM; | 1540 | rc = -ENOMEDIUM; |
1536 | goto err_open; | 1541 | goto err_open; |
1537 | } | 1542 | } |
1538 | } | 1543 | } |
1539 | 1544 | ||
1540 | if (sc->removable || sc->readonly) | 1545 | if (lun->removable || lun->readonly) |
1541 | check_disk_change(inode->i_bdev); | 1546 | check_disk_change(inode->i_bdev); |
1542 | 1547 | ||
1543 | /* | 1548 | /* |
@@ -1545,12 +1550,12 @@ static int ub_bd_open(struct inode *inode, struct file *filp) | |||
1545 | * under some pretty murky conditions (a failure of READ CAPACITY). | 1550 | * under some pretty murky conditions (a failure of READ CAPACITY). |
1546 | * We may need it one day. | 1551 | * We may need it one day. |
1547 | */ | 1552 | */ |
1548 | if (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) { | 1553 | if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) { |
1549 | rc = -ENOMEDIUM; | 1554 | rc = -ENOMEDIUM; |
1550 | goto err_open; | 1555 | goto err_open; |
1551 | } | 1556 | } |
1552 | 1557 | ||
1553 | if (sc->readonly && (filp->f_mode & FMODE_WRITE)) { | 1558 | if (lun->readonly && (filp->f_mode & FMODE_WRITE)) { |
1554 | rc = -EROFS; | 1559 | rc = -EROFS; |
1555 | goto err_open; | 1560 | goto err_open; |
1556 | } | 1561 | } |
@@ -1567,7 +1572,8 @@ err_open: | |||
1567 | static int ub_bd_release(struct inode *inode, struct file *filp) | 1572 | static int ub_bd_release(struct inode *inode, struct file *filp) |
1568 | { | 1573 | { |
1569 | struct gendisk *disk = inode->i_bdev->bd_disk; | 1574 | struct gendisk *disk = inode->i_bdev->bd_disk; |
1570 | struct ub_dev *sc = disk->private_data; | 1575 | struct ub_lun *lun = disk->private_data; |
1576 | struct ub_dev *sc = lun->udev; | ||
1571 | 1577 | ||
1572 | ub_put(sc); | 1578 | ub_put(sc); |
1573 | return 0; | 1579 | return 0; |
@@ -1597,20 +1603,14 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, | |||
1597 | */ | 1603 | */ |
1598 | static int ub_bd_revalidate(struct gendisk *disk) | 1604 | static int ub_bd_revalidate(struct gendisk *disk) |
1599 | { | 1605 | { |
1600 | struct ub_dev *sc = disk->private_data; | 1606 | struct ub_lun *lun = disk->private_data; |
1601 | 1607 | ||
1602 | ub_revalidate(sc); | 1608 | ub_revalidate(lun->udev, lun); |
1603 | /* This is pretty much a long term P3 */ | ||
1604 | if (!atomic_read(&sc->poison)) { /* Cover sc->dev */ | ||
1605 | printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", | ||
1606 | sc->name, sc->dev->devnum, | ||
1607 | sc->capacity.nsec, sc->capacity.bsize); | ||
1608 | } | ||
1609 | 1609 | ||
1610 | /* XXX Support sector size switching like in sr.c */ | 1610 | /* XXX Support sector size switching like in sr.c */ |
1611 | blk_queue_hardsect_size(disk->queue, sc->capacity.bsize); | 1611 | blk_queue_hardsect_size(disk->queue, lun->capacity.bsize); |
1612 | set_capacity(disk, sc->capacity.nsec); | 1612 | set_capacity(disk, lun->capacity.nsec); |
1613 | // set_disk_ro(sdkp->disk, sc->readonly); | 1613 | // set_disk_ro(sdkp->disk, lun->readonly); |
1614 | 1614 | ||
1615 | return 0; | 1615 | return 0; |
1616 | } | 1616 | } |
@@ -1626,9 +1626,9 @@ static int ub_bd_revalidate(struct gendisk *disk) | |||
1626 | */ | 1626 | */ |
1627 | static int ub_bd_media_changed(struct gendisk *disk) | 1627 | static int ub_bd_media_changed(struct gendisk *disk) |
1628 | { | 1628 | { |
1629 | struct ub_dev *sc = disk->private_data; | 1629 | struct ub_lun *lun = disk->private_data; |
1630 | 1630 | ||
1631 | if (!sc->removable) | 1631 | if (!lun->removable) |
1632 | return 0; | 1632 | return 0; |
1633 | 1633 | ||
1634 | /* | 1634 | /* |
@@ -1640,12 +1640,12 @@ static int ub_bd_media_changed(struct gendisk *disk) | |||
1640 | * will fail, then block layer discards the data. Since we never | 1640 | * will fail, then block layer discards the data. Since we never |
1641 | * spin drives up, such devices simply cannot be used with ub anyway. | 1641 | * spin drives up, such devices simply cannot be used with ub anyway. |
1642 | */ | 1642 | */ |
1643 | if (ub_sync_tur(sc) != 0) { | 1643 | if (ub_sync_tur(lun->udev, lun) != 0) { |
1644 | sc->changed = 1; | 1644 | lun->changed = 1; |
1645 | return 1; | 1645 | return 1; |
1646 | } | 1646 | } |
1647 | 1647 | ||
1648 | return sc->changed; | 1648 | return lun->changed; |
1649 | } | 1649 | } |
1650 | 1650 | ||
1651 | static struct block_device_operations ub_bd_fops = { | 1651 | static struct block_device_operations ub_bd_fops = { |
@@ -1669,7 +1669,7 @@ static void ub_probe_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1669 | /* | 1669 | /* |
1670 | * Test if the device has a check condition on it, synchronously. | 1670 | * Test if the device has a check condition on it, synchronously. |
1671 | */ | 1671 | */ |
1672 | static int ub_sync_tur(struct ub_dev *sc) | 1672 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) |
1673 | { | 1673 | { |
1674 | struct ub_scsi_cmd *cmd; | 1674 | struct ub_scsi_cmd *cmd; |
1675 | enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) }; | 1675 | enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) }; |
@@ -1688,6 +1688,7 @@ static int ub_sync_tur(struct ub_dev *sc) | |||
1688 | cmd->cdb_len = 6; | 1688 | cmd->cdb_len = 6; |
1689 | cmd->dir = UB_DIR_NONE; | 1689 | cmd->dir = UB_DIR_NONE; |
1690 | cmd->state = UB_CMDST_INIT; | 1690 | cmd->state = UB_CMDST_INIT; |
1691 | cmd->lun = lun; /* This may be NULL, but that's ok */ | ||
1691 | cmd->done = ub_probe_done; | 1692 | cmd->done = ub_probe_done; |
1692 | cmd->back = &compl; | 1693 | cmd->back = &compl; |
1693 | 1694 | ||
@@ -1718,7 +1719,8 @@ err_alloc: | |||
1718 | /* | 1719 | /* |
1719 | * Read the SCSI capacity synchronously (for probing). | 1720 | * Read the SCSI capacity synchronously (for probing). |
1720 | */ | 1721 | */ |
1721 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) | 1722 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, |
1723 | struct ub_capacity *ret) | ||
1722 | { | 1724 | { |
1723 | struct ub_scsi_cmd *cmd; | 1725 | struct ub_scsi_cmd *cmd; |
1724 | char *p; | 1726 | char *p; |
@@ -1743,6 +1745,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) | |||
1743 | cmd->state = UB_CMDST_INIT; | 1745 | cmd->state = UB_CMDST_INIT; |
1744 | cmd->data = p; | 1746 | cmd->data = p; |
1745 | cmd->len = 8; | 1747 | cmd->len = 8; |
1748 | cmd->lun = lun; | ||
1746 | cmd->done = ub_probe_done; | 1749 | cmd->done = ub_probe_done; |
1747 | cmd->back = &compl; | 1750 | cmd->back = &compl; |
1748 | 1751 | ||
@@ -1812,6 +1815,90 @@ static void ub_probe_timeout(unsigned long arg) | |||
1812 | } | 1815 | } |
1813 | 1816 | ||
1814 | /* | 1817 | /* |
1818 | * Get number of LUNs by the way of Bulk GetMaxLUN command. | ||
1819 | */ | ||
1820 | static int ub_sync_getmaxlun(struct ub_dev *sc) | ||
1821 | { | ||
1822 | int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber; | ||
1823 | unsigned char *p; | ||
1824 | enum { ALLOC_SIZE = 1 }; | ||
1825 | struct usb_ctrlrequest *cr; | ||
1826 | struct completion compl; | ||
1827 | struct timer_list timer; | ||
1828 | int nluns; | ||
1829 | int rc; | ||
1830 | |||
1831 | init_completion(&compl); | ||
1832 | |||
1833 | rc = -ENOMEM; | ||
1834 | if ((p = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL) | ||
1835 | goto err_alloc; | ||
1836 | *p = 55; | ||
1837 | |||
1838 | cr = &sc->work_cr; | ||
1839 | cr->bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; | ||
1840 | cr->bRequest = US_BULK_GET_MAX_LUN; | ||
1841 | cr->wValue = cpu_to_le16(0); | ||
1842 | cr->wIndex = cpu_to_le16(ifnum); | ||
1843 | cr->wLength = cpu_to_le16(1); | ||
1844 | |||
1845 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, | ||
1846 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); | ||
1847 | sc->work_urb.transfer_flags = 0; | ||
1848 | sc->work_urb.actual_length = 0; | ||
1849 | sc->work_urb.error_count = 0; | ||
1850 | sc->work_urb.status = 0; | ||
1851 | |||
1852 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { | ||
1853 | if (rc == -EPIPE) { | ||
1854 | printk("%s: Stall at GetMaxLUN, using 1 LUN\n", | ||
1855 | sc->name); /* P3 */ | ||
1856 | } else { | ||
1857 | printk(KERN_WARNING | ||
1858 | "%s: Unable to submit GetMaxLUN (%d)\n", | ||
1859 | sc->name, rc); | ||
1860 | } | ||
1861 | goto err_submit; | ||
1862 | } | ||
1863 | |||
1864 | init_timer(&timer); | ||
1865 | timer.function = ub_probe_timeout; | ||
1866 | timer.data = (unsigned long) &compl; | ||
1867 | timer.expires = jiffies + UB_CTRL_TIMEOUT; | ||
1868 | add_timer(&timer); | ||
1869 | |||
1870 | wait_for_completion(&compl); | ||
1871 | |||
1872 | del_timer_sync(&timer); | ||
1873 | usb_kill_urb(&sc->work_urb); | ||
1874 | |||
1875 | if (sc->work_urb.actual_length != 1) { | ||
1876 | printk("%s: GetMaxLUN returned %d bytes\n", sc->name, | ||
1877 | sc->work_urb.actual_length); /* P3 */ | ||
1878 | nluns = 0; | ||
1879 | } else { | ||
1880 | if ((nluns = *p) == 55) { | ||
1881 | nluns = 0; | ||
1882 | } else { | ||
1883 | /* GetMaxLUN returns the maximum LUN number */ | ||
1884 | nluns += 1; | ||
1885 | if (nluns > UB_MAX_LUNS) | ||
1886 | nluns = UB_MAX_LUNS; | ||
1887 | } | ||
1888 | printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name, | ||
1889 | *p, nluns); /* P3 */ | ||
1890 | } | ||
1891 | |||
1892 | kfree(p); | ||
1893 | return nluns; | ||
1894 | |||
1895 | err_submit: | ||
1896 | kfree(p); | ||
1897 | err_alloc: | ||
1898 | return rc; | ||
1899 | } | ||
1900 | |||
1901 | /* | ||
1815 | * Clear initial stalls. | 1902 | * Clear initial stalls. |
1816 | */ | 1903 | */ |
1817 | static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) | 1904 | static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) |
@@ -1897,8 +1984,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, | |||
1897 | } | 1984 | } |
1898 | 1985 | ||
1899 | if (ep_in == NULL || ep_out == NULL) { | 1986 | if (ep_in == NULL || ep_out == NULL) { |
1900 | printk(KERN_NOTICE "%s: device %u failed endpoint check\n", | 1987 | printk(KERN_NOTICE "%s: failed endpoint check\n", |
1901 | sc->name, sc->dev->devnum); | 1988 | sc->name); |
1902 | return -EIO; | 1989 | return -EIO; |
1903 | } | 1990 | } |
1904 | 1991 | ||
@@ -1921,8 +2008,7 @@ static int ub_probe(struct usb_interface *intf, | |||
1921 | const struct usb_device_id *dev_id) | 2008 | const struct usb_device_id *dev_id) |
1922 | { | 2009 | { |
1923 | struct ub_dev *sc; | 2010 | struct ub_dev *sc; |
1924 | request_queue_t *q; | 2011 | int nluns; |
1925 | struct gendisk *disk; | ||
1926 | int rc; | 2012 | int rc; |
1927 | int i; | 2013 | int i; |
1928 | 2014 | ||
@@ -1931,6 +2017,7 @@ static int ub_probe(struct usb_interface *intf, | |||
1931 | goto err_core; | 2017 | goto err_core; |
1932 | memset(sc, 0, sizeof(struct ub_dev)); | 2018 | memset(sc, 0, sizeof(struct ub_dev)); |
1933 | spin_lock_init(&sc->lock); | 2019 | spin_lock_init(&sc->lock); |
2020 | INIT_LIST_HEAD(&sc->luns); | ||
1934 | usb_init_urb(&sc->work_urb); | 2021 | usb_init_urb(&sc->work_urb); |
1935 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); | 2022 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); |
1936 | atomic_set(&sc->poison, 0); | 2023 | atomic_set(&sc->poison, 0); |
@@ -1942,19 +2029,16 @@ static int ub_probe(struct usb_interface *intf, | |||
1942 | ub_init_completion(&sc->work_done); | 2029 | ub_init_completion(&sc->work_done); |
1943 | sc->work_done.done = 1; /* A little yuk, but oh well... */ | 2030 | sc->work_done.done = 1; /* A little yuk, but oh well... */ |
1944 | 2031 | ||
1945 | rc = -ENOSR; | ||
1946 | if ((sc->id = ub_id_get()) == -1) | ||
1947 | goto err_id; | ||
1948 | snprintf(sc->name, 8, DRV_NAME "%c", sc->id + 'a'); | ||
1949 | |||
1950 | sc->dev = interface_to_usbdev(intf); | 2032 | sc->dev = interface_to_usbdev(intf); |
1951 | sc->intf = intf; | 2033 | sc->intf = intf; |
1952 | // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 2034 | // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; |
1953 | |||
1954 | usb_set_intfdata(intf, sc); | 2035 | usb_set_intfdata(intf, sc); |
1955 | usb_get_dev(sc->dev); | 2036 | usb_get_dev(sc->dev); |
1956 | // usb_get_intf(sc->intf); /* Do we need this? */ | 2037 | // usb_get_intf(sc->intf); /* Do we need this? */ |
1957 | 2038 | ||
2039 | snprintf(sc->name, 12, DRV_NAME "(%d.%d)", | ||
2040 | sc->dev->bus->busnum, sc->dev->devnum); | ||
2041 | |||
1958 | /* XXX Verify that we can handle the device (from descriptors) */ | 2042 | /* XXX Verify that we can handle the device (from descriptors) */ |
1959 | 2043 | ||
1960 | ub_get_pipes(sc, sc->dev, intf); | 2044 | ub_get_pipes(sc, sc->dev, intf); |
@@ -1992,35 +2076,88 @@ static int ub_probe(struct usb_interface *intf, | |||
1992 | * In any case it's not our business how revaliadation is implemented. | 2076 | * In any case it's not our business how revaliadation is implemented. |
1993 | */ | 2077 | */ |
1994 | for (i = 0; i < 3; i++) { /* Retries for benh's key */ | 2078 | for (i = 0; i < 3; i++) { /* Retries for benh's key */ |
1995 | if ((rc = ub_sync_tur(sc)) <= 0) break; | 2079 | if ((rc = ub_sync_tur(sc, NULL)) <= 0) break; |
1996 | if (rc != 0x6) break; | 2080 | if (rc != 0x6) break; |
1997 | msleep(10); | 2081 | msleep(10); |
1998 | } | 2082 | } |
1999 | 2083 | ||
2000 | sc->removable = 1; /* XXX Query this from the device */ | 2084 | nluns = 1; |
2001 | sc->changed = 1; /* ub_revalidate clears only */ | 2085 | for (i = 0; i < 3; i++) { |
2002 | sc->first_open = 1; | 2086 | if ((rc = ub_sync_getmaxlun(sc)) < 0) { |
2087 | /* | ||
2088 | * Some devices (i.e. Iomega Zip100) need this -- | ||
2089 | * apparently the bulk pipes get STALLed when the | ||
2090 | * GetMaxLUN request is processed. | ||
2091 | * XXX I have a ZIP-100, verify it does this. | ||
2092 | */ | ||
2093 | if (rc == -EPIPE) { | ||
2094 | ub_probe_clear_stall(sc, sc->recv_bulk_pipe); | ||
2095 | ub_probe_clear_stall(sc, sc->send_bulk_pipe); | ||
2096 | } | ||
2097 | break; | ||
2098 | } | ||
2099 | if (rc != 0) { | ||
2100 | nluns = rc; | ||
2101 | break; | ||
2102 | } | ||
2103 | mdelay(100); | ||
2104 | } | ||
2003 | 2105 | ||
2004 | ub_revalidate(sc); | 2106 | for (i = 0; i < nluns; i++) { |
2005 | /* This is pretty much a long term P3 */ | 2107 | ub_probe_lun(sc, i); |
2006 | printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", | 2108 | } |
2007 | sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize); | 2109 | return 0; |
2110 | |||
2111 | /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ | ||
2112 | err_diag: | ||
2113 | usb_set_intfdata(intf, NULL); | ||
2114 | // usb_put_intf(sc->intf); | ||
2115 | usb_put_dev(sc->dev); | ||
2116 | kfree(sc); | ||
2117 | err_core: | ||
2118 | return rc; | ||
2119 | } | ||
2120 | |||
2121 | static int ub_probe_lun(struct ub_dev *sc, int lnum) | ||
2122 | { | ||
2123 | struct ub_lun *lun; | ||
2124 | request_queue_t *q; | ||
2125 | struct gendisk *disk; | ||
2126 | int rc; | ||
2127 | |||
2128 | rc = -ENOMEM; | ||
2129 | if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL) | ||
2130 | goto err_alloc; | ||
2131 | memset(lun, 0, sizeof(struct ub_lun)); | ||
2132 | lun->num = lnum; | ||
2133 | |||
2134 | rc = -ENOSR; | ||
2135 | if ((lun->id = ub_id_get()) == -1) | ||
2136 | goto err_id; | ||
2137 | |||
2138 | lun->udev = sc; | ||
2139 | list_add(&lun->link, &sc->luns); | ||
2140 | |||
2141 | snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)", | ||
2142 | lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num); | ||
2143 | |||
2144 | lun->removable = 1; /* XXX Query this from the device */ | ||
2145 | lun->changed = 1; /* ub_revalidate clears only */ | ||
2146 | lun->first_open = 1; | ||
2147 | ub_revalidate(sc, lun); | ||
2008 | 2148 | ||
2009 | /* | ||
2010 | * Just one disk per sc currently, but maybe more. | ||
2011 | */ | ||
2012 | rc = -ENOMEM; | 2149 | rc = -ENOMEM; |
2013 | if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) | 2150 | if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) |
2014 | goto err_diskalloc; | 2151 | goto err_diskalloc; |
2015 | 2152 | ||
2016 | sc->disk = disk; | 2153 | lun->disk = disk; |
2017 | sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a'); | 2154 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); |
2018 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a'); | 2155 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); |
2019 | disk->major = UB_MAJOR; | 2156 | disk->major = UB_MAJOR; |
2020 | disk->first_minor = sc->id * UB_MINORS_PER_MAJOR; | 2157 | disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; |
2021 | disk->fops = &ub_bd_fops; | 2158 | disk->fops = &ub_bd_fops; |
2022 | disk->private_data = sc; | 2159 | disk->private_data = lun; |
2023 | disk->driverfs_dev = &intf->dev; | 2160 | disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ |
2024 | 2161 | ||
2025 | rc = -ENOMEM; | 2162 | rc = -ENOMEM; |
2026 | if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) | 2163 | if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) |
@@ -2028,28 +2165,17 @@ static int ub_probe(struct usb_interface *intf, | |||
2028 | 2165 | ||
2029 | disk->queue = q; | 2166 | disk->queue = q; |
2030 | 2167 | ||
2031 | // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | 2168 | blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); |
2032 | blk_queue_max_hw_segments(q, UB_MAX_REQ_SG); | 2169 | blk_queue_max_hw_segments(q, UB_MAX_REQ_SG); |
2033 | blk_queue_max_phys_segments(q, UB_MAX_REQ_SG); | 2170 | blk_queue_max_phys_segments(q, UB_MAX_REQ_SG); |
2034 | // blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); | 2171 | blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */ |
2035 | blk_queue_max_sectors(q, UB_MAX_SECTORS); | 2172 | blk_queue_max_sectors(q, UB_MAX_SECTORS); |
2036 | blk_queue_hardsect_size(q, sc->capacity.bsize); | 2173 | blk_queue_hardsect_size(q, lun->capacity.bsize); |
2037 | |||
2038 | /* | ||
2039 | * This is a serious infraction, caused by a deficiency in the | ||
2040 | * USB sg interface (usb_sg_wait()). We plan to remove this once | ||
2041 | * we get mileage on the driver and can justify a change to USB API. | ||
2042 | * See blk_queue_bounce_limit() to understand this part. | ||
2043 | * | ||
2044 | * XXX And I still need to be aware of the DMA mask in the HC. | ||
2045 | */ | ||
2046 | q->bounce_pfn = blk_max_low_pfn; | ||
2047 | q->bounce_gfp = GFP_NOIO; | ||
2048 | 2174 | ||
2049 | q->queuedata = sc; | 2175 | q->queuedata = lun; |
2050 | 2176 | ||
2051 | set_capacity(disk, sc->capacity.nsec); | 2177 | set_capacity(disk, lun->capacity.nsec); |
2052 | if (sc->removable) | 2178 | if (lun->removable) |
2053 | disk->flags |= GENHD_FL_REMOVABLE; | 2179 | disk->flags |= GENHD_FL_REMOVABLE; |
2054 | 2180 | ||
2055 | add_disk(disk); | 2181 | add_disk(disk); |
@@ -2059,22 +2185,20 @@ static int ub_probe(struct usb_interface *intf, | |||
2059 | err_blkqinit: | 2185 | err_blkqinit: |
2060 | put_disk(disk); | 2186 | put_disk(disk); |
2061 | err_diskalloc: | 2187 | err_diskalloc: |
2062 | device_remove_file(&sc->intf->dev, &dev_attr_diag); | 2188 | list_del(&lun->link); |
2063 | err_diag: | 2189 | ub_id_put(lun->id); |
2064 | usb_set_intfdata(intf, NULL); | ||
2065 | // usb_put_intf(sc->intf); | ||
2066 | usb_put_dev(sc->dev); | ||
2067 | ub_id_put(sc->id); | ||
2068 | err_id: | 2190 | err_id: |
2069 | kfree(sc); | 2191 | kfree(lun); |
2070 | err_core: | 2192 | err_alloc: |
2071 | return rc; | 2193 | return rc; |
2072 | } | 2194 | } |
2073 | 2195 | ||
2074 | static void ub_disconnect(struct usb_interface *intf) | 2196 | static void ub_disconnect(struct usb_interface *intf) |
2075 | { | 2197 | { |
2076 | struct ub_dev *sc = usb_get_intfdata(intf); | 2198 | struct ub_dev *sc = usb_get_intfdata(intf); |
2077 | struct gendisk *disk = sc->disk; | 2199 | struct list_head *p; |
2200 | struct ub_lun *lun; | ||
2201 | struct gendisk *disk; | ||
2078 | unsigned long flags; | 2202 | unsigned long flags; |
2079 | 2203 | ||
2080 | /* | 2204 | /* |
@@ -2124,14 +2248,18 @@ static void ub_disconnect(struct usb_interface *intf) | |||
2124 | /* | 2248 | /* |
2125 | * Unregister the upper layer. | 2249 | * Unregister the upper layer. |
2126 | */ | 2250 | */ |
2127 | if (disk->flags & GENHD_FL_UP) | 2251 | list_for_each (p, &sc->luns) { |
2128 | del_gendisk(disk); | 2252 | lun = list_entry(p, struct ub_lun, link); |
2129 | /* | 2253 | disk = lun->disk; |
2130 | * I wish I could do: | 2254 | if (disk->flags & GENHD_FL_UP) |
2131 | * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); | 2255 | del_gendisk(disk); |
2132 | * As it is, we rely on our internal poisoning and let | 2256 | /* |
2133 | * the upper levels to spin furiously failing all the I/O. | 2257 | * I wish I could do: |
2134 | */ | 2258 | * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); |
2259 | * As it is, we rely on our internal poisoning and let | ||
2260 | * the upper levels to spin furiously failing all the I/O. | ||
2261 | */ | ||
2262 | } | ||
2135 | 2263 | ||
2136 | /* | 2264 | /* |
2137 | * Taking a lock on a structure which is about to be freed | 2265 | * Taking a lock on a structure which is about to be freed |
@@ -2182,8 +2310,8 @@ static int __init ub_init(void) | |||
2182 | { | 2310 | { |
2183 | int rc; | 2311 | int rc; |
2184 | 2312 | ||
2185 | /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu\n", | 2313 | /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n", |
2186 | sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev)); | 2314 | sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun)); |
2187 | 2315 | ||
2188 | if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) | 2316 | if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) |
2189 | goto err_regblkdev; | 2317 | goto err_regblkdev; |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index fcca26c89bbc..38dd9ffbe8bc 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -488,6 +488,20 @@ static int viocd_packet(struct cdrom_device_info *cdi, | |||
488 | & (CDC_DVD_RAM | CDC_RAM)) != 0; | 488 | & (CDC_DVD_RAM | CDC_RAM)) != 0; |
489 | } | 489 | } |
490 | break; | 490 | break; |
491 | case GPCMD_GET_CONFIGURATION: | ||
492 | if (cgc->cmd[3] == CDF_RWRT) { | ||
493 | struct rwrt_feature_desc *rfd = (struct rwrt_feature_desc *)(cgc->buffer + sizeof(struct feature_header)); | ||
494 | |||
495 | if ((buflen >= | ||
496 | (sizeof(struct feature_header) + sizeof(*rfd))) && | ||
497 | (cdi->ops->capability & ~cdi->mask | ||
498 | & (CDC_DVD_RAM | CDC_RAM))) { | ||
499 | rfd->feature_code = cpu_to_be16(CDF_RWRT); | ||
500 | rfd->curr = 1; | ||
501 | ret = 0; | ||
502 | } | ||
503 | } | ||
504 | break; | ||
491 | default: | 505 | default: |
492 | if (cgc->sense) { | 506 | if (cgc->sense) { |
493 | /* indicate Unknown code */ | 507 | /* indicate Unknown code */ |
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 95882bb1950e..60c9be99c6d9 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -46,6 +46,10 @@ config CPU_FREQ_STAT_DETAILS | |||
46 | This will show detail CPU frequency translation table in sysfs file | 46 | This will show detail CPU frequency translation table in sysfs file |
47 | system | 47 | system |
48 | 48 | ||
49 | # Note that it is not currently possible to set the other governors (such as ondemand) | ||
50 | # as the default, since if they fail to initialise, cpufreq will be | ||
51 | # left in an undefined state. | ||
52 | |||
49 | choice | 53 | choice |
50 | prompt "Default CPUFreq governor" | 54 | prompt "Default CPUFreq governor" |
51 | default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 | 55 | default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 |
@@ -115,4 +119,24 @@ config CPU_FREQ_GOV_ONDEMAND | |||
115 | 119 | ||
116 | If in doubt, say N. | 120 | If in doubt, say N. |
117 | 121 | ||
122 | config CPU_FREQ_GOV_CONSERVATIVE | ||
123 | tristate "'conservative' cpufreq governor" | ||
124 | depends on CPU_FREQ | ||
125 | help | ||
126 | 'conservative' - this driver is rather similar to the 'ondemand' | ||
127 | governor both in its source code and its purpose, the difference is | ||
128 | its optimisation for better suitability in a battery powered | ||
129 | environment. The frequency is gracefully increased and decreased | ||
130 | rather than jumping to 100% when speed is required. | ||
131 | |||
132 | If you have a desktop machine then you should really be considering | ||
133 | the 'ondemand' governor instead, however if you are using a laptop, | ||
134 | PDA or even an AMD64 based computer (due to the unacceptable | ||
135 | step-by-step latency issues between the minimum and maximum frequency | ||
136 | transitions in the CPU) you will probably want to use this governor. | ||
137 | |||
138 | For details, take a look at linux/Documentation/cpu-freq. | ||
139 | |||
140 | If in doubt, say N. | ||
141 | |||
118 | endif # CPU_FREQ | 142 | endif # CPU_FREQ |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 67b16e5a41a7..71fc3b4173f1 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o | |||
8 | obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o | 8 | obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o |
9 | obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o | 9 | obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o |
10 | obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o | 10 | obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o |
11 | obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o | ||
11 | 12 | ||
12 | # CPUfreq cross-arch helpers | 13 | # CPUfreq cross-arch helpers |
13 | obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o | 14 | obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8e561313d094..03b5fb2ddcf4 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -258,7 +258,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | |||
258 | (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && | 258 | (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && |
259 | (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) | 259 | (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) |
260 | { | 260 | { |
261 | printk(KERN_WARNING "Warning: CPU frequency is %u, " | 261 | dprintk(KERN_WARNING "Warning: CPU frequency is %u, " |
262 | "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); | 262 | "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); |
263 | freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; | 263 | freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; |
264 | } | 264 | } |
@@ -814,7 +814,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne | |||
814 | { | 814 | { |
815 | struct cpufreq_freqs freqs; | 815 | struct cpufreq_freqs freqs; |
816 | 816 | ||
817 | printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " | 817 | dprintk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " |
818 | "core thinks of %u, is %u kHz.\n", old_freq, new_freq); | 818 | "core thinks of %u, is %u kHz.\n", old_freq, new_freq); |
819 | 819 | ||
820 | freqs.cpu = cpu; | 820 | freqs.cpu = cpu; |
@@ -923,7 +923,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, u32 state) | |||
923 | struct cpufreq_freqs freqs; | 923 | struct cpufreq_freqs freqs; |
924 | 924 | ||
925 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | 925 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
926 | printk(KERN_DEBUG "Warning: CPU frequency is %u, " | 926 | dprintk(KERN_DEBUG "Warning: CPU frequency is %u, " |
927 | "cpufreq assumed %u kHz.\n", | 927 | "cpufreq assumed %u kHz.\n", |
928 | cur_freq, cpu_policy->cur); | 928 | cur_freq, cpu_policy->cur); |
929 | 929 | ||
@@ -1004,7 +1004,7 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
1004 | struct cpufreq_freqs freqs; | 1004 | struct cpufreq_freqs freqs; |
1005 | 1005 | ||
1006 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | 1006 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
1007 | printk(KERN_WARNING "Warning: CPU frequency" | 1007 | dprintk(KERN_WARNING "Warning: CPU frequency" |
1008 | "is %u, cpufreq assumed %u kHz.\n", | 1008 | "is %u, cpufreq assumed %u kHz.\n", |
1009 | cur_freq, cpu_policy->cur); | 1009 | cur_freq, cpu_policy->cur); |
1010 | 1010 | ||
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c new file mode 100644 index 000000000000..e1df376e709e --- /dev/null +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -0,0 +1,586 @@ | |||
1 | /* | ||
2 | * drivers/cpufreq/cpufreq_conservative.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Russell King | ||
5 | * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>. | ||
6 | * Jun Nakajima <jun.nakajima@intel.com> | ||
7 | * (C) 2004 Alexander Clouter <alex-kernel@digriz.org.uk> | ||
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 version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/ctype.h> | ||
20 | #include <linux/cpufreq.h> | ||
21 | #include <linux/sysctl.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/sysfs.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/kmod.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/kernel_stat.h> | ||
30 | #include <linux/percpu.h> | ||
31 | |||
32 | /* | ||
33 | * dbs is used in this file as a shortform for demandbased switching | ||
34 | * It helps to keep variable names smaller, simpler | ||
35 | */ | ||
36 | |||
37 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | ||
38 | #define MIN_FREQUENCY_UP_THRESHOLD (0) | ||
39 | #define MAX_FREQUENCY_UP_THRESHOLD (100) | ||
40 | |||
41 | #define DEF_FREQUENCY_DOWN_THRESHOLD (20) | ||
42 | #define MIN_FREQUENCY_DOWN_THRESHOLD (0) | ||
43 | #define MAX_FREQUENCY_DOWN_THRESHOLD (100) | ||
44 | |||
45 | /* | ||
46 | * The polling frequency of this governor depends on the capability of | ||
47 | * the processor. Default polling frequency is 1000 times the transition | ||
48 | * latency of the processor. The governor will work on any processor with | ||
49 | * transition latency <= 10mS, using appropriate sampling | ||
50 | * rate. | ||
51 | * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) | ||
52 | * this governor will not work. | ||
53 | * All times here are in uS. | ||
54 | */ | ||
55 | static unsigned int def_sampling_rate; | ||
56 | #define MIN_SAMPLING_RATE (def_sampling_rate / 2) | ||
57 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | ||
58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (100000) | ||
59 | #define DEF_SAMPLING_DOWN_FACTOR (5) | ||
60 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | ||
61 | |||
62 | static void do_dbs_timer(void *data); | ||
63 | |||
64 | struct cpu_dbs_info_s { | ||
65 | struct cpufreq_policy *cur_policy; | ||
66 | unsigned int prev_cpu_idle_up; | ||
67 | unsigned int prev_cpu_idle_down; | ||
68 | unsigned int enable; | ||
69 | }; | ||
70 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | ||
71 | |||
72 | static unsigned int dbs_enable; /* number of CPUs using this policy */ | ||
73 | |||
74 | static DECLARE_MUTEX (dbs_sem); | ||
75 | static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); | ||
76 | |||
77 | struct dbs_tuners { | ||
78 | unsigned int sampling_rate; | ||
79 | unsigned int sampling_down_factor; | ||
80 | unsigned int up_threshold; | ||
81 | unsigned int down_threshold; | ||
82 | unsigned int ignore_nice; | ||
83 | unsigned int freq_step; | ||
84 | }; | ||
85 | |||
86 | static struct dbs_tuners dbs_tuners_ins = { | ||
87 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | ||
88 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, | ||
89 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | ||
90 | }; | ||
91 | |||
92 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | ||
93 | { | ||
94 | return kstat_cpu(cpu).cpustat.idle + | ||
95 | kstat_cpu(cpu).cpustat.iowait + | ||
96 | ( !dbs_tuners_ins.ignore_nice ? | ||
97 | kstat_cpu(cpu).cpustat.nice : | ||
98 | 0); | ||
99 | } | ||
100 | |||
101 | /************************** sysfs interface ************************/ | ||
102 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | ||
103 | { | ||
104 | return sprintf (buf, "%u\n", MAX_SAMPLING_RATE); | ||
105 | } | ||
106 | |||
107 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) | ||
108 | { | ||
109 | return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); | ||
110 | } | ||
111 | |||
112 | #define define_one_ro(_name) \ | ||
113 | static struct freq_attr _name = \ | ||
114 | __ATTR(_name, 0444, show_##_name, NULL) | ||
115 | |||
116 | define_one_ro(sampling_rate_max); | ||
117 | define_one_ro(sampling_rate_min); | ||
118 | |||
119 | /* cpufreq_conservative Governor Tunables */ | ||
120 | #define show_one(file_name, object) \ | ||
121 | static ssize_t show_##file_name \ | ||
122 | (struct cpufreq_policy *unused, char *buf) \ | ||
123 | { \ | ||
124 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | ||
125 | } | ||
126 | show_one(sampling_rate, sampling_rate); | ||
127 | show_one(sampling_down_factor, sampling_down_factor); | ||
128 | show_one(up_threshold, up_threshold); | ||
129 | show_one(down_threshold, down_threshold); | ||
130 | show_one(ignore_nice, ignore_nice); | ||
131 | show_one(freq_step, freq_step); | ||
132 | |||
133 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | ||
134 | const char *buf, size_t count) | ||
135 | { | ||
136 | unsigned int input; | ||
137 | int ret; | ||
138 | ret = sscanf (buf, "%u", &input); | ||
139 | if (ret != 1 ) | ||
140 | return -EINVAL; | ||
141 | |||
142 | down(&dbs_sem); | ||
143 | dbs_tuners_ins.sampling_down_factor = input; | ||
144 | up(&dbs_sem); | ||
145 | |||
146 | return count; | ||
147 | } | ||
148 | |||
149 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | ||
150 | const char *buf, size_t count) | ||
151 | { | ||
152 | unsigned int input; | ||
153 | int ret; | ||
154 | ret = sscanf (buf, "%u", &input); | ||
155 | |||
156 | down(&dbs_sem); | ||
157 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { | ||
158 | up(&dbs_sem); | ||
159 | return -EINVAL; | ||
160 | } | ||
161 | |||
162 | dbs_tuners_ins.sampling_rate = input; | ||
163 | up(&dbs_sem); | ||
164 | |||
165 | return count; | ||
166 | } | ||
167 | |||
168 | static ssize_t store_up_threshold(struct cpufreq_policy *unused, | ||
169 | const char *buf, size_t count) | ||
170 | { | ||
171 | unsigned int input; | ||
172 | int ret; | ||
173 | ret = sscanf (buf, "%u", &input); | ||
174 | |||
175 | down(&dbs_sem); | ||
176 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | ||
177 | input < MIN_FREQUENCY_UP_THRESHOLD || | ||
178 | input <= dbs_tuners_ins.down_threshold) { | ||
179 | up(&dbs_sem); | ||
180 | return -EINVAL; | ||
181 | } | ||
182 | |||
183 | dbs_tuners_ins.up_threshold = input; | ||
184 | up(&dbs_sem); | ||
185 | |||
186 | return count; | ||
187 | } | ||
188 | |||
189 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, | ||
190 | const char *buf, size_t count) | ||
191 | { | ||
192 | unsigned int input; | ||
193 | int ret; | ||
194 | ret = sscanf (buf, "%u", &input); | ||
195 | |||
196 | down(&dbs_sem); | ||
197 | if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || | ||
198 | input < MIN_FREQUENCY_DOWN_THRESHOLD || | ||
199 | input >= dbs_tuners_ins.up_threshold) { | ||
200 | up(&dbs_sem); | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | dbs_tuners_ins.down_threshold = input; | ||
205 | up(&dbs_sem); | ||
206 | |||
207 | return count; | ||
208 | } | ||
209 | |||
210 | static ssize_t store_ignore_nice(struct cpufreq_policy *policy, | ||
211 | const char *buf, size_t count) | ||
212 | { | ||
213 | unsigned int input; | ||
214 | int ret; | ||
215 | |||
216 | unsigned int j; | ||
217 | |||
218 | ret = sscanf (buf, "%u", &input); | ||
219 | if ( ret != 1 ) | ||
220 | return -EINVAL; | ||
221 | |||
222 | if ( input > 1 ) | ||
223 | input = 1; | ||
224 | |||
225 | down(&dbs_sem); | ||
226 | if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ | ||
227 | up(&dbs_sem); | ||
228 | return count; | ||
229 | } | ||
230 | dbs_tuners_ins.ignore_nice = input; | ||
231 | |||
232 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ | ||
233 | for_each_online_cpu(j) { | ||
234 | struct cpu_dbs_info_s *j_dbs_info; | ||
235 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
236 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | ||
237 | j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; | ||
238 | } | ||
239 | up(&dbs_sem); | ||
240 | |||
241 | return count; | ||
242 | } | ||
243 | |||
244 | static ssize_t store_freq_step(struct cpufreq_policy *policy, | ||
245 | const char *buf, size_t count) | ||
246 | { | ||
247 | unsigned int input; | ||
248 | int ret; | ||
249 | |||
250 | ret = sscanf (buf, "%u", &input); | ||
251 | |||
252 | if ( ret != 1 ) | ||
253 | return -EINVAL; | ||
254 | |||
255 | if ( input > 100 ) | ||
256 | input = 100; | ||
257 | |||
258 | /* no need to test here if freq_step is zero as the user might actually | ||
259 | * want this, they would be crazy though :) */ | ||
260 | down(&dbs_sem); | ||
261 | dbs_tuners_ins.freq_step = input; | ||
262 | up(&dbs_sem); | ||
263 | |||
264 | return count; | ||
265 | } | ||
266 | |||
267 | #define define_one_rw(_name) \ | ||
268 | static struct freq_attr _name = \ | ||
269 | __ATTR(_name, 0644, show_##_name, store_##_name) | ||
270 | |||
271 | define_one_rw(sampling_rate); | ||
272 | define_one_rw(sampling_down_factor); | ||
273 | define_one_rw(up_threshold); | ||
274 | define_one_rw(down_threshold); | ||
275 | define_one_rw(ignore_nice); | ||
276 | define_one_rw(freq_step); | ||
277 | |||
278 | static struct attribute * dbs_attributes[] = { | ||
279 | &sampling_rate_max.attr, | ||
280 | &sampling_rate_min.attr, | ||
281 | &sampling_rate.attr, | ||
282 | &sampling_down_factor.attr, | ||
283 | &up_threshold.attr, | ||
284 | &down_threshold.attr, | ||
285 | &ignore_nice.attr, | ||
286 | &freq_step.attr, | ||
287 | NULL | ||
288 | }; | ||
289 | |||
290 | static struct attribute_group dbs_attr_group = { | ||
291 | .attrs = dbs_attributes, | ||
292 | .name = "conservative", | ||
293 | }; | ||
294 | |||
295 | /************************** sysfs end ************************/ | ||
296 | |||
297 | static void dbs_check_cpu(int cpu) | ||
298 | { | ||
299 | unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; | ||
300 | unsigned int freq_step; | ||
301 | unsigned int freq_down_sampling_rate; | ||
302 | static int down_skip[NR_CPUS]; | ||
303 | static int requested_freq[NR_CPUS]; | ||
304 | static unsigned short init_flag = 0; | ||
305 | struct cpu_dbs_info_s *this_dbs_info; | ||
306 | struct cpu_dbs_info_s *dbs_info; | ||
307 | |||
308 | struct cpufreq_policy *policy; | ||
309 | unsigned int j; | ||
310 | |||
311 | this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
312 | if (!this_dbs_info->enable) | ||
313 | return; | ||
314 | |||
315 | policy = this_dbs_info->cur_policy; | ||
316 | |||
317 | if ( init_flag == 0 ) { | ||
318 | for ( /* NULL */; init_flag < NR_CPUS; init_flag++ ) { | ||
319 | dbs_info = &per_cpu(cpu_dbs_info, init_flag); | ||
320 | requested_freq[cpu] = dbs_info->cur_policy->cur; | ||
321 | } | ||
322 | init_flag = 1; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * The default safe range is 20% to 80% | ||
327 | * Every sampling_rate, we check | ||
328 | * - If current idle time is less than 20%, then we try to | ||
329 | * increase frequency | ||
330 | * Every sampling_rate*sampling_down_factor, we check | ||
331 | * - If current idle time is more than 80%, then we try to | ||
332 | * decrease frequency | ||
333 | * | ||
334 | * Any frequency increase takes it to the maximum frequency. | ||
335 | * Frequency reduction happens at minimum steps of | ||
336 | * 5% (default) of max_frequency | ||
337 | */ | ||
338 | |||
339 | /* Check for frequency increase */ | ||
340 | |||
341 | idle_ticks = UINT_MAX; | ||
342 | for_each_cpu_mask(j, policy->cpus) { | ||
343 | unsigned int tmp_idle_ticks, total_idle_ticks; | ||
344 | struct cpu_dbs_info_s *j_dbs_info; | ||
345 | |||
346 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
347 | /* Check for frequency increase */ | ||
348 | total_idle_ticks = get_cpu_idle_time(j); | ||
349 | tmp_idle_ticks = total_idle_ticks - | ||
350 | j_dbs_info->prev_cpu_idle_up; | ||
351 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; | ||
352 | |||
353 | if (tmp_idle_ticks < idle_ticks) | ||
354 | idle_ticks = tmp_idle_ticks; | ||
355 | } | ||
356 | |||
357 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
358 | idle_ticks *= 100; | ||
359 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * | ||
360 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | ||
361 | |||
362 | if (idle_ticks < up_idle_ticks) { | ||
363 | down_skip[cpu] = 0; | ||
364 | for_each_cpu_mask(j, policy->cpus) { | ||
365 | struct cpu_dbs_info_s *j_dbs_info; | ||
366 | |||
367 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
368 | j_dbs_info->prev_cpu_idle_down = | ||
369 | j_dbs_info->prev_cpu_idle_up; | ||
370 | } | ||
371 | /* if we are already at full speed then break out early */ | ||
372 | if (requested_freq[cpu] == policy->max) | ||
373 | return; | ||
374 | |||
375 | freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; | ||
376 | |||
377 | /* max freq cannot be less than 100. But who knows.... */ | ||
378 | if (unlikely(freq_step == 0)) | ||
379 | freq_step = 5; | ||
380 | |||
381 | requested_freq[cpu] += freq_step; | ||
382 | if (requested_freq[cpu] > policy->max) | ||
383 | requested_freq[cpu] = policy->max; | ||
384 | |||
385 | __cpufreq_driver_target(policy, requested_freq[cpu], | ||
386 | CPUFREQ_RELATION_H); | ||
387 | return; | ||
388 | } | ||
389 | |||
390 | /* Check for frequency decrease */ | ||
391 | down_skip[cpu]++; | ||
392 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) | ||
393 | return; | ||
394 | |||
395 | idle_ticks = UINT_MAX; | ||
396 | for_each_cpu_mask(j, policy->cpus) { | ||
397 | unsigned int tmp_idle_ticks, total_idle_ticks; | ||
398 | struct cpu_dbs_info_s *j_dbs_info; | ||
399 | |||
400 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
401 | total_idle_ticks = j_dbs_info->prev_cpu_idle_up; | ||
402 | tmp_idle_ticks = total_idle_ticks - | ||
403 | j_dbs_info->prev_cpu_idle_down; | ||
404 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
405 | |||
406 | if (tmp_idle_ticks < idle_ticks) | ||
407 | idle_ticks = tmp_idle_ticks; | ||
408 | } | ||
409 | |||
410 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
411 | idle_ticks *= 100; | ||
412 | down_skip[cpu] = 0; | ||
413 | |||
414 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * | ||
415 | dbs_tuners_ins.sampling_down_factor; | ||
416 | down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * | ||
417 | usecs_to_jiffies(freq_down_sampling_rate); | ||
418 | |||
419 | if (idle_ticks > down_idle_ticks) { | ||
420 | /* if we are already at the lowest speed then break out early | ||
421 | * or if we 'cannot' reduce the speed as the user might want | ||
422 | * freq_step to be zero */ | ||
423 | if (requested_freq[cpu] == policy->min | ||
424 | || dbs_tuners_ins.freq_step == 0) | ||
425 | return; | ||
426 | |||
427 | freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; | ||
428 | |||
429 | /* max freq cannot be less than 100. But who knows.... */ | ||
430 | if (unlikely(freq_step == 0)) | ||
431 | freq_step = 5; | ||
432 | |||
433 | requested_freq[cpu] -= freq_step; | ||
434 | if (requested_freq[cpu] < policy->min) | ||
435 | requested_freq[cpu] = policy->min; | ||
436 | |||
437 | __cpufreq_driver_target(policy, | ||
438 | requested_freq[cpu], | ||
439 | CPUFREQ_RELATION_H); | ||
440 | return; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | static void do_dbs_timer(void *data) | ||
445 | { | ||
446 | int i; | ||
447 | down(&dbs_sem); | ||
448 | for_each_online_cpu(i) | ||
449 | dbs_check_cpu(i); | ||
450 | schedule_delayed_work(&dbs_work, | ||
451 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
452 | up(&dbs_sem); | ||
453 | } | ||
454 | |||
455 | static inline void dbs_timer_init(void) | ||
456 | { | ||
457 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | ||
458 | schedule_delayed_work(&dbs_work, | ||
459 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
460 | return; | ||
461 | } | ||
462 | |||
463 | static inline void dbs_timer_exit(void) | ||
464 | { | ||
465 | cancel_delayed_work(&dbs_work); | ||
466 | return; | ||
467 | } | ||
468 | |||
469 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | ||
470 | unsigned int event) | ||
471 | { | ||
472 | unsigned int cpu = policy->cpu; | ||
473 | struct cpu_dbs_info_s *this_dbs_info; | ||
474 | unsigned int j; | ||
475 | |||
476 | this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
477 | |||
478 | switch (event) { | ||
479 | case CPUFREQ_GOV_START: | ||
480 | if ((!cpu_online(cpu)) || | ||
481 | (!policy->cur)) | ||
482 | return -EINVAL; | ||
483 | |||
484 | if (policy->cpuinfo.transition_latency > | ||
485 | (TRANSITION_LATENCY_LIMIT * 1000)) | ||
486 | return -EINVAL; | ||
487 | if (this_dbs_info->enable) /* Already enabled */ | ||
488 | break; | ||
489 | |||
490 | down(&dbs_sem); | ||
491 | for_each_cpu_mask(j, policy->cpus) { | ||
492 | struct cpu_dbs_info_s *j_dbs_info; | ||
493 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
494 | j_dbs_info->cur_policy = policy; | ||
495 | |||
496 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | ||
497 | j_dbs_info->prev_cpu_idle_down | ||
498 | = j_dbs_info->prev_cpu_idle_up; | ||
499 | } | ||
500 | this_dbs_info->enable = 1; | ||
501 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | ||
502 | dbs_enable++; | ||
503 | /* | ||
504 | * Start the timerschedule work, when this governor | ||
505 | * is used for first time | ||
506 | */ | ||
507 | if (dbs_enable == 1) { | ||
508 | unsigned int latency; | ||
509 | /* policy latency is in nS. Convert it to uS first */ | ||
510 | |||
511 | latency = policy->cpuinfo.transition_latency; | ||
512 | if (latency < 1000) | ||
513 | latency = 1000; | ||
514 | |||
515 | def_sampling_rate = (latency / 1000) * | ||
516 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; | ||
517 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | ||
518 | dbs_tuners_ins.ignore_nice = 0; | ||
519 | dbs_tuners_ins.freq_step = 5; | ||
520 | |||
521 | dbs_timer_init(); | ||
522 | } | ||
523 | |||
524 | up(&dbs_sem); | ||
525 | break; | ||
526 | |||
527 | case CPUFREQ_GOV_STOP: | ||
528 | down(&dbs_sem); | ||
529 | this_dbs_info->enable = 0; | ||
530 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | ||
531 | dbs_enable--; | ||
532 | /* | ||
533 | * Stop the timerschedule work, when this governor | ||
534 | * is used for first time | ||
535 | */ | ||
536 | if (dbs_enable == 0) | ||
537 | dbs_timer_exit(); | ||
538 | |||
539 | up(&dbs_sem); | ||
540 | |||
541 | break; | ||
542 | |||
543 | case CPUFREQ_GOV_LIMITS: | ||
544 | down(&dbs_sem); | ||
545 | if (policy->max < this_dbs_info->cur_policy->cur) | ||
546 | __cpufreq_driver_target( | ||
547 | this_dbs_info->cur_policy, | ||
548 | policy->max, CPUFREQ_RELATION_H); | ||
549 | else if (policy->min > this_dbs_info->cur_policy->cur) | ||
550 | __cpufreq_driver_target( | ||
551 | this_dbs_info->cur_policy, | ||
552 | policy->min, CPUFREQ_RELATION_L); | ||
553 | up(&dbs_sem); | ||
554 | break; | ||
555 | } | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static struct cpufreq_governor cpufreq_gov_dbs = { | ||
560 | .name = "conservative", | ||
561 | .governor = cpufreq_governor_dbs, | ||
562 | .owner = THIS_MODULE, | ||
563 | }; | ||
564 | |||
565 | static int __init cpufreq_gov_dbs_init(void) | ||
566 | { | ||
567 | return cpufreq_register_governor(&cpufreq_gov_dbs); | ||
568 | } | ||
569 | |||
570 | static void __exit cpufreq_gov_dbs_exit(void) | ||
571 | { | ||
572 | /* Make sure that the scheduled work is indeed not running */ | ||
573 | flush_scheduled_work(); | ||
574 | |||
575 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | ||
576 | } | ||
577 | |||
578 | |||
579 | MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>"); | ||
580 | MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for " | ||
581 | "Low Latency Frequency Transition capable processors " | ||
582 | "optimised for use in a battery environment"); | ||
583 | MODULE_LICENSE ("GPL"); | ||
584 | |||
585 | module_init(cpufreq_gov_dbs_init); | ||
586 | module_exit(cpufreq_gov_dbs_exit); | ||
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 8d83a21c6477..c1fc9c62bb51 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -34,13 +34,9 @@ | |||
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | 36 | #define DEF_FREQUENCY_UP_THRESHOLD (80) |
37 | #define MIN_FREQUENCY_UP_THRESHOLD (0) | 37 | #define MIN_FREQUENCY_UP_THRESHOLD (11) |
38 | #define MAX_FREQUENCY_UP_THRESHOLD (100) | 38 | #define MAX_FREQUENCY_UP_THRESHOLD (100) |
39 | 39 | ||
40 | #define DEF_FREQUENCY_DOWN_THRESHOLD (20) | ||
41 | #define MIN_FREQUENCY_DOWN_THRESHOLD (0) | ||
42 | #define MAX_FREQUENCY_DOWN_THRESHOLD (100) | ||
43 | |||
44 | /* | 40 | /* |
45 | * The polling frequency of this governor depends on the capability of | 41 | * The polling frequency of this governor depends on the capability of |
46 | * the processor. Default polling frequency is 1000 times the transition | 42 | * the processor. Default polling frequency is 1000 times the transition |
@@ -55,9 +51,9 @@ static unsigned int def_sampling_rate; | |||
55 | #define MIN_SAMPLING_RATE (def_sampling_rate / 2) | 51 | #define MIN_SAMPLING_RATE (def_sampling_rate / 2) |
56 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 52 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) |
57 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 53 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) |
58 | #define DEF_SAMPLING_DOWN_FACTOR (10) | 54 | #define DEF_SAMPLING_DOWN_FACTOR (1) |
55 | #define MAX_SAMPLING_DOWN_FACTOR (10) | ||
59 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 56 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) |
60 | #define sampling_rate_in_HZ(x) (((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000))) | ||
61 | 57 | ||
62 | static void do_dbs_timer(void *data); | 58 | static void do_dbs_timer(void *data); |
63 | 59 | ||
@@ -78,15 +74,23 @@ struct dbs_tuners { | |||
78 | unsigned int sampling_rate; | 74 | unsigned int sampling_rate; |
79 | unsigned int sampling_down_factor; | 75 | unsigned int sampling_down_factor; |
80 | unsigned int up_threshold; | 76 | unsigned int up_threshold; |
81 | unsigned int down_threshold; | 77 | unsigned int ignore_nice; |
82 | }; | 78 | }; |
83 | 79 | ||
84 | static struct dbs_tuners dbs_tuners_ins = { | 80 | static struct dbs_tuners dbs_tuners_ins = { |
85 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 81 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
86 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, | ||
87 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | 82 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, |
88 | }; | 83 | }; |
89 | 84 | ||
85 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | ||
86 | { | ||
87 | return kstat_cpu(cpu).cpustat.idle + | ||
88 | kstat_cpu(cpu).cpustat.iowait + | ||
89 | ( !dbs_tuners_ins.ignore_nice ? | ||
90 | kstat_cpu(cpu).cpustat.nice : | ||
91 | 0); | ||
92 | } | ||
93 | |||
90 | /************************** sysfs interface ************************/ | 94 | /************************** sysfs interface ************************/ |
91 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | 95 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) |
92 | { | 96 | { |
@@ -115,7 +119,7 @@ static ssize_t show_##file_name \ | |||
115 | show_one(sampling_rate, sampling_rate); | 119 | show_one(sampling_rate, sampling_rate); |
116 | show_one(sampling_down_factor, sampling_down_factor); | 120 | show_one(sampling_down_factor, sampling_down_factor); |
117 | show_one(up_threshold, up_threshold); | 121 | show_one(up_threshold, up_threshold); |
118 | show_one(down_threshold, down_threshold); | 122 | show_one(ignore_nice, ignore_nice); |
119 | 123 | ||
120 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | 124 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, |
121 | const char *buf, size_t count) | 125 | const char *buf, size_t count) |
@@ -126,6 +130,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | |||
126 | if (ret != 1 ) | 130 | if (ret != 1 ) |
127 | return -EINVAL; | 131 | return -EINVAL; |
128 | 132 | ||
133 | if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1) | ||
134 | return -EINVAL; | ||
135 | |||
129 | down(&dbs_sem); | 136 | down(&dbs_sem); |
130 | dbs_tuners_ins.sampling_down_factor = input; | 137 | dbs_tuners_ins.sampling_down_factor = input; |
131 | up(&dbs_sem); | 138 | up(&dbs_sem); |
@@ -161,8 +168,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
161 | 168 | ||
162 | down(&dbs_sem); | 169 | down(&dbs_sem); |
163 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | 170 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || |
164 | input < MIN_FREQUENCY_UP_THRESHOLD || | 171 | input < MIN_FREQUENCY_UP_THRESHOLD) { |
165 | input <= dbs_tuners_ins.down_threshold) { | ||
166 | up(&dbs_sem); | 172 | up(&dbs_sem); |
167 | return -EINVAL; | 173 | return -EINVAL; |
168 | } | 174 | } |
@@ -173,22 +179,35 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
173 | return count; | 179 | return count; |
174 | } | 180 | } |
175 | 181 | ||
176 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, | 182 | static ssize_t store_ignore_nice(struct cpufreq_policy *policy, |
177 | const char *buf, size_t count) | 183 | const char *buf, size_t count) |
178 | { | 184 | { |
179 | unsigned int input; | 185 | unsigned int input; |
180 | int ret; | 186 | int ret; |
187 | |||
188 | unsigned int j; | ||
189 | |||
181 | ret = sscanf (buf, "%u", &input); | 190 | ret = sscanf (buf, "%u", &input); |
191 | if ( ret != 1 ) | ||
192 | return -EINVAL; | ||
182 | 193 | ||
194 | if ( input > 1 ) | ||
195 | input = 1; | ||
196 | |||
183 | down(&dbs_sem); | 197 | down(&dbs_sem); |
184 | if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || | 198 | if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ |
185 | input < MIN_FREQUENCY_DOWN_THRESHOLD || | ||
186 | input >= dbs_tuners_ins.up_threshold) { | ||
187 | up(&dbs_sem); | 199 | up(&dbs_sem); |
188 | return -EINVAL; | 200 | return count; |
189 | } | 201 | } |
202 | dbs_tuners_ins.ignore_nice = input; | ||
190 | 203 | ||
191 | dbs_tuners_ins.down_threshold = input; | 204 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ |
205 | for_each_online_cpu(j) { | ||
206 | struct cpu_dbs_info_s *j_dbs_info; | ||
207 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
208 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | ||
209 | j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; | ||
210 | } | ||
192 | up(&dbs_sem); | 211 | up(&dbs_sem); |
193 | 212 | ||
194 | return count; | 213 | return count; |
@@ -201,7 +220,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name) | |||
201 | define_one_rw(sampling_rate); | 220 | define_one_rw(sampling_rate); |
202 | define_one_rw(sampling_down_factor); | 221 | define_one_rw(sampling_down_factor); |
203 | define_one_rw(up_threshold); | 222 | define_one_rw(up_threshold); |
204 | define_one_rw(down_threshold); | 223 | define_one_rw(ignore_nice); |
205 | 224 | ||
206 | static struct attribute * dbs_attributes[] = { | 225 | static struct attribute * dbs_attributes[] = { |
207 | &sampling_rate_max.attr, | 226 | &sampling_rate_max.attr, |
@@ -209,7 +228,7 @@ static struct attribute * dbs_attributes[] = { | |||
209 | &sampling_rate.attr, | 228 | &sampling_rate.attr, |
210 | &sampling_down_factor.attr, | 229 | &sampling_down_factor.attr, |
211 | &up_threshold.attr, | 230 | &up_threshold.attr, |
212 | &down_threshold.attr, | 231 | &ignore_nice.attr, |
213 | NULL | 232 | NULL |
214 | }; | 233 | }; |
215 | 234 | ||
@@ -222,9 +241,8 @@ static struct attribute_group dbs_attr_group = { | |||
222 | 241 | ||
223 | static void dbs_check_cpu(int cpu) | 242 | static void dbs_check_cpu(int cpu) |
224 | { | 243 | { |
225 | unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; | 244 | unsigned int idle_ticks, up_idle_ticks, total_ticks; |
226 | unsigned int total_idle_ticks; | 245 | unsigned int freq_next; |
227 | unsigned int freq_down_step; | ||
228 | unsigned int freq_down_sampling_rate; | 246 | unsigned int freq_down_sampling_rate; |
229 | static int down_skip[NR_CPUS]; | 247 | static int down_skip[NR_CPUS]; |
230 | struct cpu_dbs_info_s *this_dbs_info; | 248 | struct cpu_dbs_info_s *this_dbs_info; |
@@ -238,38 +256,25 @@ static void dbs_check_cpu(int cpu) | |||
238 | 256 | ||
239 | policy = this_dbs_info->cur_policy; | 257 | policy = this_dbs_info->cur_policy; |
240 | /* | 258 | /* |
241 | * The default safe range is 20% to 80% | 259 | * Every sampling_rate, we check, if current idle time is less |
242 | * Every sampling_rate, we check | 260 | * than 20% (default), then we try to increase frequency |
243 | * - If current idle time is less than 20%, then we try to | 261 | * Every sampling_rate*sampling_down_factor, we look for a the lowest |
244 | * increase frequency | 262 | * frequency which can sustain the load while keeping idle time over |
245 | * Every sampling_rate*sampling_down_factor, we check | 263 | * 30%. If such a frequency exist, we try to decrease to this frequency. |
246 | * - If current idle time is more than 80%, then we try to | ||
247 | * decrease frequency | ||
248 | * | 264 | * |
249 | * Any frequency increase takes it to the maximum frequency. | 265 | * Any frequency increase takes it to the maximum frequency. |
250 | * Frequency reduction happens at minimum steps of | 266 | * Frequency reduction happens at minimum steps of |
251 | * 5% of max_frequency | 267 | * 5% (default) of current frequency |
252 | */ | 268 | */ |
253 | 269 | ||
254 | /* Check for frequency increase */ | 270 | /* Check for frequency increase */ |
255 | total_idle_ticks = kstat_cpu(cpu).cpustat.idle + | 271 | idle_ticks = UINT_MAX; |
256 | kstat_cpu(cpu).cpustat.iowait; | ||
257 | idle_ticks = total_idle_ticks - | ||
258 | this_dbs_info->prev_cpu_idle_up; | ||
259 | this_dbs_info->prev_cpu_idle_up = total_idle_ticks; | ||
260 | |||
261 | |||
262 | for_each_cpu_mask(j, policy->cpus) { | 272 | for_each_cpu_mask(j, policy->cpus) { |
263 | unsigned int tmp_idle_ticks; | 273 | unsigned int tmp_idle_ticks, total_idle_ticks; |
264 | struct cpu_dbs_info_s *j_dbs_info; | 274 | struct cpu_dbs_info_s *j_dbs_info; |
265 | 275 | ||
266 | if (j == cpu) | ||
267 | continue; | ||
268 | |||
269 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 276 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
270 | /* Check for frequency increase */ | 277 | total_idle_ticks = get_cpu_idle_time(j); |
271 | total_idle_ticks = kstat_cpu(j).cpustat.idle + | ||
272 | kstat_cpu(j).cpustat.iowait; | ||
273 | tmp_idle_ticks = total_idle_ticks - | 278 | tmp_idle_ticks = total_idle_ticks - |
274 | j_dbs_info->prev_cpu_idle_up; | 279 | j_dbs_info->prev_cpu_idle_up; |
275 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; | 280 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; |
@@ -281,13 +286,23 @@ static void dbs_check_cpu(int cpu) | |||
281 | /* Scale idle ticks by 100 and compare with up and down ticks */ | 286 | /* Scale idle ticks by 100 and compare with up and down ticks */ |
282 | idle_ticks *= 100; | 287 | idle_ticks *= 100; |
283 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * | 288 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * |
284 | sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate); | 289 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
285 | 290 | ||
286 | if (idle_ticks < up_idle_ticks) { | 291 | if (idle_ticks < up_idle_ticks) { |
292 | down_skip[cpu] = 0; | ||
293 | for_each_cpu_mask(j, policy->cpus) { | ||
294 | struct cpu_dbs_info_s *j_dbs_info; | ||
295 | |||
296 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
297 | j_dbs_info->prev_cpu_idle_down = | ||
298 | j_dbs_info->prev_cpu_idle_up; | ||
299 | } | ||
300 | /* if we are already at full speed then break out early */ | ||
301 | if (policy->cur == policy->max) | ||
302 | return; | ||
303 | |||
287 | __cpufreq_driver_target(policy, policy->max, | 304 | __cpufreq_driver_target(policy, policy->max, |
288 | CPUFREQ_RELATION_H); | 305 | CPUFREQ_RELATION_H); |
289 | down_skip[cpu] = 0; | ||
290 | this_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
291 | return; | 306 | return; |
292 | } | 307 | } |
293 | 308 | ||
@@ -296,23 +311,14 @@ static void dbs_check_cpu(int cpu) | |||
296 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) | 311 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) |
297 | return; | 312 | return; |
298 | 313 | ||
299 | total_idle_ticks = kstat_cpu(cpu).cpustat.idle + | 314 | idle_ticks = UINT_MAX; |
300 | kstat_cpu(cpu).cpustat.iowait; | ||
301 | idle_ticks = total_idle_ticks - | ||
302 | this_dbs_info->prev_cpu_idle_down; | ||
303 | this_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
304 | |||
305 | for_each_cpu_mask(j, policy->cpus) { | 315 | for_each_cpu_mask(j, policy->cpus) { |
306 | unsigned int tmp_idle_ticks; | 316 | unsigned int tmp_idle_ticks, total_idle_ticks; |
307 | struct cpu_dbs_info_s *j_dbs_info; | 317 | struct cpu_dbs_info_s *j_dbs_info; |
308 | 318 | ||
309 | if (j == cpu) | ||
310 | continue; | ||
311 | |||
312 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 319 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
313 | /* Check for frequency increase */ | 320 | /* Check for frequency decrease */ |
314 | total_idle_ticks = kstat_cpu(j).cpustat.idle + | 321 | total_idle_ticks = j_dbs_info->prev_cpu_idle_up; |
315 | kstat_cpu(j).cpustat.iowait; | ||
316 | tmp_idle_ticks = total_idle_ticks - | 322 | tmp_idle_ticks = total_idle_ticks - |
317 | j_dbs_info->prev_cpu_idle_down; | 323 | j_dbs_info->prev_cpu_idle_down; |
318 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; | 324 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; |
@@ -321,38 +327,37 @@ static void dbs_check_cpu(int cpu) | |||
321 | idle_ticks = tmp_idle_ticks; | 327 | idle_ticks = tmp_idle_ticks; |
322 | } | 328 | } |
323 | 329 | ||
324 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
325 | idle_ticks *= 100; | ||
326 | down_skip[cpu] = 0; | 330 | down_skip[cpu] = 0; |
331 | /* if we cannot reduce the frequency anymore, break out early */ | ||
332 | if (policy->cur == policy->min) | ||
333 | return; | ||
327 | 334 | ||
335 | /* Compute how many ticks there are between two measurements */ | ||
328 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * | 336 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * |
329 | dbs_tuners_ins.sampling_down_factor; | 337 | dbs_tuners_ins.sampling_down_factor; |
330 | down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * | 338 | total_ticks = usecs_to_jiffies(freq_down_sampling_rate); |
331 | sampling_rate_in_HZ(freq_down_sampling_rate); | ||
332 | 339 | ||
333 | if (idle_ticks > down_idle_ticks ) { | 340 | /* |
334 | freq_down_step = (5 * policy->max) / 100; | 341 | * The optimal frequency is the frequency that is the lowest that |
335 | 342 | * can support the current CPU usage without triggering the up | |
336 | /* max freq cannot be less than 100. But who knows.... */ | 343 | * policy. To be safe, we focus 10 points under the threshold. |
337 | if (unlikely(freq_down_step == 0)) | 344 | */ |
338 | freq_down_step = 5; | 345 | freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks; |
346 | freq_next = (freq_next * policy->cur) / | ||
347 | (dbs_tuners_ins.up_threshold - 10); | ||
339 | 348 | ||
340 | __cpufreq_driver_target(policy, | 349 | if (freq_next <= ((policy->cur * 95) / 100)) |
341 | policy->cur - freq_down_step, | 350 | __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); |
342 | CPUFREQ_RELATION_H); | ||
343 | return; | ||
344 | } | ||
345 | } | 351 | } |
346 | 352 | ||
347 | static void do_dbs_timer(void *data) | 353 | static void do_dbs_timer(void *data) |
348 | { | 354 | { |
349 | int i; | 355 | int i; |
350 | down(&dbs_sem); | 356 | down(&dbs_sem); |
351 | for (i = 0; i < NR_CPUS; i++) | 357 | for_each_online_cpu(i) |
352 | if (cpu_online(i)) | 358 | dbs_check_cpu(i); |
353 | dbs_check_cpu(i); | ||
354 | schedule_delayed_work(&dbs_work, | 359 | schedule_delayed_work(&dbs_work, |
355 | sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate)); | 360 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
356 | up(&dbs_sem); | 361 | up(&dbs_sem); |
357 | } | 362 | } |
358 | 363 | ||
@@ -360,7 +365,7 @@ static inline void dbs_timer_init(void) | |||
360 | { | 365 | { |
361 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | 366 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); |
362 | schedule_delayed_work(&dbs_work, | 367 | schedule_delayed_work(&dbs_work, |
363 | sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate)); | 368 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
364 | return; | 369 | return; |
365 | } | 370 | } |
366 | 371 | ||
@@ -397,12 +402,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
397 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 402 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
398 | j_dbs_info->cur_policy = policy; | 403 | j_dbs_info->cur_policy = policy; |
399 | 404 | ||
400 | j_dbs_info->prev_cpu_idle_up = | 405 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); |
401 | kstat_cpu(j).cpustat.idle + | 406 | j_dbs_info->prev_cpu_idle_down |
402 | kstat_cpu(j).cpustat.iowait; | 407 | = j_dbs_info->prev_cpu_idle_up; |
403 | j_dbs_info->prev_cpu_idle_down = | ||
404 | kstat_cpu(j).cpustat.idle + | ||
405 | kstat_cpu(j).cpustat.iowait; | ||
406 | } | 408 | } |
407 | this_dbs_info->enable = 1; | 409 | this_dbs_info->enable = 1; |
408 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | 410 | sysfs_create_group(&policy->kobj, &dbs_attr_group); |
@@ -422,6 +424,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
422 | def_sampling_rate = (latency / 1000) * | 424 | def_sampling_rate = (latency / 1000) * |
423 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; | 425 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; |
424 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 426 | dbs_tuners_ins.sampling_rate = def_sampling_rate; |
427 | dbs_tuners_ins.ignore_nice = 0; | ||
425 | 428 | ||
426 | dbs_timer_init(); | 429 | dbs_timer_init(); |
427 | } | 430 | } |
@@ -461,12 +464,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
461 | return 0; | 464 | return 0; |
462 | } | 465 | } |
463 | 466 | ||
464 | struct cpufreq_governor cpufreq_gov_dbs = { | 467 | static struct cpufreq_governor cpufreq_gov_dbs = { |
465 | .name = "ondemand", | 468 | .name = "ondemand", |
466 | .governor = cpufreq_governor_dbs, | 469 | .governor = cpufreq_governor_dbs, |
467 | .owner = THIS_MODULE, | 470 | .owner = THIS_MODULE, |
468 | }; | 471 | }; |
469 | EXPORT_SYMBOL(cpufreq_gov_dbs); | ||
470 | 472 | ||
471 | static int __init cpufreq_gov_dbs_init(void) | 473 | static int __init cpufreq_gov_dbs_init(void) |
472 | { | 474 | { |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 2084593937c6..741b6b191e6a 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/percpu.h> | 19 | #include <linux/percpu.h> |
20 | #include <linux/kobject.h> | 20 | #include <linux/kobject.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <asm/cputime.h> | ||
22 | 23 | ||
23 | static spinlock_t cpufreq_stats_lock; | 24 | static spinlock_t cpufreq_stats_lock; |
24 | 25 | ||
@@ -29,20 +30,14 @@ static struct freq_attr _attr_##_name = {\ | |||
29 | .show = _show,\ | 30 | .show = _show,\ |
30 | }; | 31 | }; |
31 | 32 | ||
32 | static unsigned long | ||
33 | delta_time(unsigned long old, unsigned long new) | ||
34 | { | ||
35 | return (old > new) ? (old - new): (new + ~old + 1); | ||
36 | } | ||
37 | |||
38 | struct cpufreq_stats { | 33 | struct cpufreq_stats { |
39 | unsigned int cpu; | 34 | unsigned int cpu; |
40 | unsigned int total_trans; | 35 | unsigned int total_trans; |
41 | unsigned long long last_time; | 36 | unsigned long long last_time; |
42 | unsigned int max_state; | 37 | unsigned int max_state; |
43 | unsigned int state_num; | 38 | unsigned int state_num; |
44 | unsigned int last_index; | 39 | unsigned int last_index; |
45 | unsigned long long *time_in_state; | 40 | cputime64_t *time_in_state; |
46 | unsigned int *freq_table; | 41 | unsigned int *freq_table; |
47 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 42 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
48 | unsigned int *trans_table; | 43 | unsigned int *trans_table; |
@@ -60,12 +55,16 @@ static int | |||
60 | cpufreq_stats_update (unsigned int cpu) | 55 | cpufreq_stats_update (unsigned int cpu) |
61 | { | 56 | { |
62 | struct cpufreq_stats *stat; | 57 | struct cpufreq_stats *stat; |
58 | unsigned long long cur_time; | ||
59 | |||
60 | cur_time = get_jiffies_64(); | ||
63 | spin_lock(&cpufreq_stats_lock); | 61 | spin_lock(&cpufreq_stats_lock); |
64 | stat = cpufreq_stats_table[cpu]; | 62 | stat = cpufreq_stats_table[cpu]; |
65 | if (stat->time_in_state) | 63 | if (stat->time_in_state) |
66 | stat->time_in_state[stat->last_index] += | 64 | stat->time_in_state[stat->last_index] = |
67 | delta_time(stat->last_time, jiffies); | 65 | cputime64_add(stat->time_in_state[stat->last_index], |
68 | stat->last_time = jiffies; | 66 | cputime_sub(cur_time, stat->last_time)); |
67 | stat->last_time = cur_time; | ||
69 | spin_unlock(&cpufreq_stats_lock); | 68 | spin_unlock(&cpufreq_stats_lock); |
70 | return 0; | 69 | return 0; |
71 | } | 70 | } |
@@ -90,8 +89,8 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf) | |||
90 | return 0; | 89 | return 0; |
91 | cpufreq_stats_update(stat->cpu); | 90 | cpufreq_stats_update(stat->cpu); |
92 | for (i = 0; i < stat->state_num; i++) { | 91 | for (i = 0; i < stat->state_num; i++) { |
93 | len += sprintf(buf + len, "%u %llu\n", | 92 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], |
94 | stat->freq_table[i], stat->time_in_state[i]); | 93 | (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i])); |
95 | } | 94 | } |
96 | return len; | 95 | return len; |
97 | } | 96 | } |
@@ -107,16 +106,30 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) | |||
107 | if(!stat) | 106 | if(!stat) |
108 | return 0; | 107 | return 0; |
109 | cpufreq_stats_update(stat->cpu); | 108 | cpufreq_stats_update(stat->cpu); |
109 | len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); | ||
110 | len += snprintf(buf + len, PAGE_SIZE - len, " : "); | ||
111 | for (i = 0; i < stat->state_num; i++) { | ||
112 | if (len >= PAGE_SIZE) | ||
113 | break; | ||
114 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", | ||
115 | stat->freq_table[i]); | ||
116 | } | ||
117 | if (len >= PAGE_SIZE) | ||
118 | return len; | ||
119 | |||
120 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | ||
121 | |||
110 | for (i = 0; i < stat->state_num; i++) { | 122 | for (i = 0; i < stat->state_num; i++) { |
111 | if (len >= PAGE_SIZE) | 123 | if (len >= PAGE_SIZE) |
112 | break; | 124 | break; |
113 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t", | 125 | |
126 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", | ||
114 | stat->freq_table[i]); | 127 | stat->freq_table[i]); |
115 | 128 | ||
116 | for (j = 0; j < stat->state_num; j++) { | 129 | for (j = 0; j < stat->state_num; j++) { |
117 | if (len >= PAGE_SIZE) | 130 | if (len >= PAGE_SIZE) |
118 | break; | 131 | break; |
119 | len += snprintf(buf + len, PAGE_SIZE - len, "%u\t", | 132 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", |
120 | stat->trans_table[i*stat->max_state+j]); | 133 | stat->trans_table[i*stat->max_state+j]); |
121 | } | 134 | } |
122 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 135 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
@@ -197,7 +210,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, | |||
197 | count++; | 210 | count++; |
198 | } | 211 | } |
199 | 212 | ||
200 | alloc_size = count * sizeof(int) + count * sizeof(long long); | 213 | alloc_size = count * sizeof(int) + count * sizeof(cputime64_t); |
201 | 214 | ||
202 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 215 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
203 | alloc_size += count * count * sizeof(int); | 216 | alloc_size += count * count * sizeof(int); |
@@ -224,7 +237,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, | |||
224 | } | 237 | } |
225 | stat->state_num = j; | 238 | stat->state_num = j; |
226 | spin_lock(&cpufreq_stats_lock); | 239 | spin_lock(&cpufreq_stats_lock); |
227 | stat->last_time = jiffies; | 240 | stat->last_time = get_jiffies_64(); |
228 | stat->last_index = freq_table_get_index(stat, policy->cur); | 241 | stat->last_index = freq_table_get_index(stat, policy->cur); |
229 | spin_unlock(&cpufreq_stats_lock); | 242 | spin_unlock(&cpufreq_stats_lock); |
230 | cpufreq_cpu_put(data); | 243 | cpufreq_cpu_put(data); |
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 6d5df6c2efa2..df1b721154d2 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/config.h> | ||
14 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
15 | #include <linux/console.h> | 16 | #include <linux/console.h> |
16 | #include <linux/efi.h> | 17 | #include <linux/efi.h> |
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 35710818fe47..fdd881aee618 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge | 2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Patrick Mochel | 4 | * Copyright (C) 2004 Patrick Mochel |
5 | * 2005 Rudolf Marek <r.marek@sh.cvut.cz> | ||
5 | * | 6 | * |
6 | * The 1563 southbridge is deceptively similar to the 1533, with a | 7 | * The 1563 southbridge is deceptively similar to the 1533, with a |
7 | * few notable exceptions. One of those happens to be the fact they | 8 | * few notable exceptions. One of those happens to be the fact they |
@@ -57,10 +58,11 @@ | |||
57 | #define HST_CNTL2_BLOCK 0x05 | 58 | #define HST_CNTL2_BLOCK 0x05 |
58 | 59 | ||
59 | 60 | ||
61 | #define HST_CNTL2_SIZEMASK 0x38 | ||
60 | 62 | ||
61 | static unsigned short ali1563_smba; | 63 | static unsigned short ali1563_smba; |
62 | 64 | ||
63 | static int ali1563_transaction(struct i2c_adapter * a) | 65 | static int ali1563_transaction(struct i2c_adapter * a, int size) |
64 | { | 66 | { |
65 | u32 data; | 67 | u32 data; |
66 | int timeout; | 68 | int timeout; |
@@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
73 | 75 | ||
74 | data = inb_p(SMB_HST_STS); | 76 | data = inb_p(SMB_HST_STS); |
75 | if (data & HST_STS_BAD) { | 77 | if (data & HST_STS_BAD) { |
76 | dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); | 78 | dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); |
77 | outb_p(data | HST_STS_BAD,SMB_HST_STS); | 79 | outb_p(data | HST_STS_BAD,SMB_HST_STS); |
78 | data = inb_p(SMB_HST_STS); | 80 | data = inb_p(SMB_HST_STS); |
79 | if (data & HST_STS_BAD) | 81 | if (data & HST_STS_BAD) |
@@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
94 | 96 | ||
95 | if (timeout && !(data & HST_STS_BAD)) | 97 | if (timeout && !(data & HST_STS_BAD)) |
96 | return 0; | 98 | return 0; |
97 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | ||
98 | timeout ? "Timeout " : "", | ||
99 | data & HST_STS_FAIL ? "Transaction Failed " : "", | ||
100 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | ||
101 | data & HST_STS_DEVERR ? "Device Error " : "", | ||
102 | !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); | ||
103 | 99 | ||
104 | if (!(data & HST_STS_DONE)) | 100 | if (!timeout) { |
101 | dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n"); | ||
105 | /* Issue 'kill' to host controller */ | 102 | /* Issue 'kill' to host controller */ |
106 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); | 103 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); |
107 | else | 104 | data = inb_p(SMB_HST_STS); |
108 | /* Issue timeout to reset all devices on bus */ | 105 | } |
106 | |||
107 | /* device error - no response, ignore the autodetection case */ | ||
108 | if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { | ||
109 | dev_err(&a->dev, "Device error!\n"); | ||
110 | } | ||
111 | |||
112 | /* bus collision */ | ||
113 | if (data & HST_STS_BUSERR) { | ||
114 | dev_err(&a->dev, "Bus collision!\n"); | ||
115 | /* Issue timeout, hoping it helps */ | ||
109 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); | 116 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); |
117 | } | ||
118 | |||
119 | if (data & HST_STS_FAIL) { | ||
120 | dev_err(&a->dev, "Cleaning fail after KILL!\n"); | ||
121 | outb_p(0x0,SMB_HST_CNTL2); | ||
122 | } | ||
123 | |||
110 | return -1; | 124 | return -1; |
111 | } | 125 | } |
112 | 126 | ||
@@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a) | |||
149 | 163 | ||
150 | if (timeout && !(data & HST_STS_BAD)) | 164 | if (timeout && !(data & HST_STS_BAD)) |
151 | return 0; | 165 | return 0; |
152 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | 166 | dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", |
153 | timeout ? "Timeout " : "", | 167 | timeout ? "Timeout " : "", |
154 | data & HST_STS_FAIL ? "Transaction Failed " : "", | 168 | data & HST_STS_FAIL ? "Transaction Failed " : "", |
155 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | 169 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", |
@@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
242 | } | 256 | } |
243 | 257 | ||
244 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); | 258 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); |
245 | outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2); | 259 | outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); |
246 | 260 | ||
247 | /* Write the command register */ | 261 | /* Write the command register */ |
262 | |||
248 | switch(size) { | 263 | switch(size) { |
249 | case HST_CNTL2_BYTE: | 264 | case HST_CNTL2_BYTE: |
250 | if (rw== I2C_SMBUS_WRITE) | 265 | if (rw== I2C_SMBUS_WRITE) |
251 | outb_p(cmd, SMB_HST_CMD); | 266 | /* Beware it uses DAT0 register and not CMD! */ |
267 | outb_p(cmd, SMB_HST_DAT0); | ||
252 | break; | 268 | break; |
253 | case HST_CNTL2_BYTE_DATA: | 269 | case HST_CNTL2_BYTE_DATA: |
254 | outb_p(cmd, SMB_HST_CMD); | 270 | outb_p(cmd, SMB_HST_CMD); |
@@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
268 | goto Done; | 284 | goto Done; |
269 | } | 285 | } |
270 | 286 | ||
271 | if ((error = ali1563_transaction(a))) | 287 | if ((error = ali1563_transaction(a, size))) |
272 | goto Done; | 288 | goto Done; |
273 | 289 | ||
274 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) | 290 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 78e3e7b24d7d..39f3e9101ed4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -1936,7 +1936,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
1936 | * NOTE! The "len" and "addr" checks should possibly have | 1936 | * NOTE! The "len" and "addr" checks should possibly have |
1937 | * separate masks. | 1937 | * separate masks. |
1938 | */ | 1938 | */ |
1939 | if ((rq->data_len & mask) || (addr & mask)) | 1939 | if ((rq->data_len & 15) || (addr & mask)) |
1940 | info->dma = 0; | 1940 | info->dma = 0; |
1941 | } | 1941 | } |
1942 | 1942 | ||
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 47225e324356..4e0f13d1d060 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -72,6 +72,7 @@ static struct amd_ide_chip { | |||
72 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, | 72 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, |
73 | { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, | 73 | { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, |
74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, | 74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, |
75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, | ||
75 | { 0 } | 76 | { 0 } |
76 | }; | 77 | }; |
77 | 78 | ||
@@ -487,6 +488,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { | |||
487 | /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), | 488 | /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), |
488 | /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), | 489 | /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), |
489 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), | 490 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), |
491 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), | ||
490 | }; | 492 | }; |
491 | 493 | ||
492 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 494 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
@@ -521,6 +523,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { | |||
521 | #endif | 523 | #endif |
522 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, | 524 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, |
523 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, | 525 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, |
526 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, | ||
524 | { 0, }, | 527 | { 0, }, |
525 | }; | 528 | }; |
526 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); | 529 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); |
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig index 6282f460aba0..1d93f5092904 100644 --- a/drivers/input/gameport/Kconfig +++ b/drivers/input/gameport/Kconfig | |||
@@ -68,23 +68,3 @@ config GAMEPORT_CS461X | |||
68 | depends on PCI | 68 | depends on PCI |
69 | 69 | ||
70 | endif | 70 | endif |
71 | |||
72 | # Yes, SOUND_GAMEPORT looks a bit odd. Yes, it ends up being turned on | ||
73 | # in every .config. Please don't touch it. It is here to handle an | ||
74 | # unusual dependency between GAMEPORT and sound drivers. | ||
75 | # | ||
76 | # Some sound drivers call gameport functions. If GAMEPORT is | ||
77 | # not selected, empty stubs are provided for the functions and all is | ||
78 | # well. | ||
79 | # If GAMEPORT is built in, everything is fine. | ||
80 | # If GAMEPORT is a module, however, it would need to be loaded for the | ||
81 | # sound driver to be able to link properly. Therefore, the sound | ||
82 | # driver must be a module as well in that case. Since there's no way | ||
83 | # to express that directly in Kconfig, we use SOUND_GAMEPORT to | ||
84 | # express it. SOUND_GAMEPORT boils down to "if GAMEPORT is 'm', | ||
85 | # anything that depends on SOUND_GAMEPORT must be 'm' as well. if | ||
86 | # GAMEPORT is 'y' or 'n', it can be anything". | ||
87 | config SOUND_GAMEPORT | ||
88 | tristate | ||
89 | default m if GAMEPORT=m | ||
90 | default y | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 7d7527f8b02d..627d343dfba1 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -422,7 +422,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct | |||
422 | joydev->nkey++; | 422 | joydev->nkey++; |
423 | } | 423 | } |
424 | 424 | ||
425 | for (i = 0; i < BTN_JOYSTICK - BTN_MISC + 1; i++) | 425 | for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++) |
426 | if (test_bit(i + BTN_MISC, dev->keybit)) { | 426 | if (test_bit(i + BTN_MISC, dev->keybit)) { |
427 | joydev->keymap[i] = joydev->nkey; | 427 | joydev->keymap[i] = joydev->nkey; |
428 | joydev->keypam[joydev->nkey] = i + BTN_MISC; | 428 | joydev->keypam[joydev->nkey] = i + BTN_MISC; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 79c332f16fc7..af0446c6de82 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -171,9 +171,9 @@ static struct { | |||
171 | unsigned char set2; | 171 | unsigned char set2; |
172 | } atkbd_scroll_keys[] = { | 172 | } atkbd_scroll_keys[] = { |
173 | { ATKBD_SCR_1, 0xc5 }, | 173 | { ATKBD_SCR_1, 0xc5 }, |
174 | { ATKBD_SCR_2, 0xa9 }, | 174 | { ATKBD_SCR_2, 0x9d }, |
175 | { ATKBD_SCR_4, 0xb6 }, | 175 | { ATKBD_SCR_4, 0xa4 }, |
176 | { ATKBD_SCR_8, 0xa7 }, | 176 | { ATKBD_SCR_8, 0x9b }, |
177 | { ATKBD_SCR_CLICK, 0xe0 }, | 177 | { ATKBD_SCR_CLICK, 0xe0 }, |
178 | { ATKBD_SCR_LEFT, 0xcb }, | 178 | { ATKBD_SCR_LEFT, 0xcb }, |
179 | { ATKBD_SCR_RIGHT, 0xd2 }, | 179 | { ATKBD_SCR_RIGHT, 0xd2 }, |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cd8509549eac..019034b21a0b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -518,13 +518,16 @@ static int psmouse_probe(struct psmouse *psmouse) | |||
518 | /* | 518 | /* |
519 | * First, we check if it's a mouse. It should send 0x00 or 0x03 | 519 | * First, we check if it's a mouse. It should send 0x00 or 0x03 |
520 | * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. | 520 | * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. |
521 | * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and subsequent | ||
522 | * ID queries, probably due to a firmware bug. | ||
521 | */ | 523 | */ |
522 | 524 | ||
523 | param[0] = 0xa5; | 525 | param[0] = 0xa5; |
524 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) | 526 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) |
525 | return -1; | 527 | return -1; |
526 | 528 | ||
527 | if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) | 529 | if (param[0] != 0x00 && param[0] != 0x03 && |
530 | param[0] != 0x04 && param[0] != 0xff) | ||
528 | return -1; | 531 | return -1; |
529 | 532 | ||
530 | /* | 533 | /* |
@@ -972,7 +975,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | |||
972 | return -EINVAL; | 975 | return -EINVAL; |
973 | 976 | ||
974 | if (!strncmp(val, "any", 3)) { | 977 | if (!strncmp(val, "any", 3)) { |
975 | *((unsigned int *)kp->arg) = -1UL; | 978 | *((unsigned int *)kp->arg) = -1U; |
976 | return 0; | 979 | return 0; |
977 | } | 980 | } |
978 | 981 | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 69832f8fb720..36c721227b68 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -143,39 +143,6 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
143 | return -1; | 143 | return -1; |
144 | } | 144 | } |
145 | 145 | ||
146 | static void print_ident(struct synaptics_data *priv) | ||
147 | { | ||
148 | printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity)); | ||
149 | printk(KERN_INFO " Firmware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity), | ||
150 | SYN_ID_MINOR(priv->identity)); | ||
151 | if (SYN_MODEL_ROT180(priv->model_id)) | ||
152 | printk(KERN_INFO " 180 degree mounted touchpad\n"); | ||
153 | if (SYN_MODEL_PORTRAIT(priv->model_id)) | ||
154 | printk(KERN_INFO " portrait touchpad\n"); | ||
155 | printk(KERN_INFO " Sensor: %ld\n", SYN_MODEL_SENSOR(priv->model_id)); | ||
156 | if (SYN_MODEL_NEWABS(priv->model_id)) | ||
157 | printk(KERN_INFO " new absolute packet format\n"); | ||
158 | if (SYN_MODEL_PEN(priv->model_id)) | ||
159 | printk(KERN_INFO " pen detection\n"); | ||
160 | |||
161 | if (SYN_CAP_EXTENDED(priv->capabilities)) { | ||
162 | printk(KERN_INFO " Touchpad has extended capability bits\n"); | ||
163 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | ||
164 | printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n", | ||
165 | (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))); | ||
166 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | ||
167 | printk(KERN_INFO " -> middle button\n"); | ||
168 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) | ||
169 | printk(KERN_INFO " -> four buttons\n"); | ||
170 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) | ||
171 | printk(KERN_INFO " -> multifinger detection\n"); | ||
172 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | ||
173 | printk(KERN_INFO " -> palm detection\n"); | ||
174 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) | ||
175 | printk(KERN_INFO " -> pass-through port\n"); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static int synaptics_query_hardware(struct psmouse *psmouse) | 146 | static int synaptics_query_hardware(struct psmouse *psmouse) |
180 | { | 147 | { |
181 | int retries = 0; | 148 | int retries = 0; |
@@ -666,7 +633,11 @@ int synaptics_init(struct psmouse *psmouse) | |||
666 | 633 | ||
667 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 634 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
668 | 635 | ||
669 | print_ident(priv); | 636 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", |
637 | SYN_ID_MODEL(priv->identity), | ||
638 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | ||
639 | priv->model_id, priv->capabilities, priv->ext_cap); | ||
640 | |||
670 | set_input_params(&psmouse->dev, priv); | 641 | set_input_params(&psmouse->dev, priv); |
671 | 642 | ||
672 | psmouse->protocol_handler = synaptics_process_byte; | 643 | psmouse->protocol_handler = synaptics_process_byte; |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 564974ce5793..96fb9870834a 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -101,6 +101,7 @@ struct mousedev_list { | |||
101 | unsigned char ready, buffer, bufsiz; | 101 | unsigned char ready, buffer, bufsiz; |
102 | unsigned char imexseq, impsseq; | 102 | unsigned char imexseq, impsseq; |
103 | enum mousedev_emul mode; | 103 | enum mousedev_emul mode; |
104 | unsigned long last_buttons; | ||
104 | }; | 105 | }; |
105 | 106 | ||
106 | #define MOUSEDEV_SEQ_LEN 6 | 107 | #define MOUSEDEV_SEQ_LEN 6 |
@@ -224,7 +225,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h | |||
224 | spin_lock_irqsave(&list->packet_lock, flags); | 225 | spin_lock_irqsave(&list->packet_lock, flags); |
225 | 226 | ||
226 | p = &list->packets[list->head]; | 227 | p = &list->packets[list->head]; |
227 | if (list->ready && p->buttons != packet->buttons) { | 228 | if (list->ready && p->buttons != mousedev->packet.buttons) { |
228 | unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; | 229 | unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; |
229 | if (new_head != list->tail) { | 230 | if (new_head != list->tail) { |
230 | p = &list->packets[list->head = new_head]; | 231 | p = &list->packets[list->head = new_head]; |
@@ -249,10 +250,13 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h | |||
249 | p->dz += packet->dz; | 250 | p->dz += packet->dz; |
250 | p->buttons = mousedev->packet.buttons; | 251 | p->buttons = mousedev->packet.buttons; |
251 | 252 | ||
252 | list->ready = 1; | 253 | if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons) |
254 | list->ready = 1; | ||
253 | 255 | ||
254 | spin_unlock_irqrestore(&list->packet_lock, flags); | 256 | spin_unlock_irqrestore(&list->packet_lock, flags); |
255 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 257 | |
258 | if (list->ready) | ||
259 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | ||
256 | } | 260 | } |
257 | 261 | ||
258 | wake_up_interruptible(&mousedev->wait); | 262 | wake_up_interruptible(&mousedev->wait); |
@@ -477,9 +481,10 @@ static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) | |||
477 | } | 481 | } |
478 | 482 | ||
479 | if (!p->dx && !p->dy && !p->dz) { | 483 | if (!p->dx && !p->dy && !p->dz) { |
480 | if (list->tail == list->head) | 484 | if (list->tail == list->head) { |
481 | list->ready = 0; | 485 | list->ready = 0; |
482 | else | 486 | list->last_buttons = p->buttons; |
487 | } else | ||
483 | list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; | 488 | list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; |
484 | } | 489 | } |
485 | 490 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index f64867808fea..0487ecbb8a49 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -88,9 +88,11 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
88 | }; | 88 | }; |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Some Fujitsu notebooks are ahving trouble with touhcpads if | 91 | * Some Fujitsu notebooks are having trouble with touchpads if |
92 | * active multiplexing mode is activated. Luckily they don't have | 92 | * active multiplexing mode is activated. Luckily they don't have |
93 | * external PS/2 ports so we can safely disable it. | 93 | * external PS/2 ports so we can safely disable it. |
94 | * ... apparently some Toshibas don't like MUX mode either and | ||
95 | * die horrible death on reboot. | ||
94 | */ | 96 | */ |
95 | static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | 97 | static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { |
96 | { | 98 | { |
@@ -115,12 +117,26 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
115 | }, | 117 | }, |
116 | }, | 118 | }, |
117 | { | 119 | { |
120 | .ident = "Fujitsu Lifebook S6230", | ||
121 | .matches = { | ||
122 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
123 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), | ||
124 | }, | ||
125 | }, | ||
126 | { | ||
118 | .ident = "Fujitsu T70H", | 127 | .ident = "Fujitsu T70H", |
119 | .matches = { | 128 | .matches = { |
120 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 129 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
121 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), | 130 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), |
122 | }, | 131 | }, |
123 | }, | 132 | }, |
133 | { | ||
134 | .ident = "Toshiba P10", | ||
135 | .matches = { | ||
136 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
137 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), | ||
138 | }, | ||
139 | }, | ||
124 | { } | 140 | { } |
125 | }; | 141 | }; |
126 | 142 | ||
@@ -215,11 +231,15 @@ static struct pnp_driver i8042_pnp_aux_driver = { | |||
215 | 231 | ||
216 | static void i8042_pnp_exit(void) | 232 | static void i8042_pnp_exit(void) |
217 | { | 233 | { |
218 | if (i8042_pnp_kbd_registered) | 234 | if (i8042_pnp_kbd_registered) { |
235 | i8042_pnp_kbd_registered = 0; | ||
219 | pnp_unregister_driver(&i8042_pnp_kbd_driver); | 236 | pnp_unregister_driver(&i8042_pnp_kbd_driver); |
237 | } | ||
220 | 238 | ||
221 | if (i8042_pnp_aux_registered) | 239 | if (i8042_pnp_aux_registered) { |
240 | i8042_pnp_aux_registered = 0; | ||
222 | pnp_unregister_driver(&i8042_pnp_aux_driver); | 241 | pnp_unregister_driver(&i8042_pnp_aux_driver); |
242 | } | ||
223 | } | 243 | } |
224 | 244 | ||
225 | static int i8042_pnp_init(void) | 245 | static int i8042_pnp_init(void) |
@@ -227,7 +247,7 @@ static int i8042_pnp_init(void) | |||
227 | int result_kbd, result_aux; | 247 | int result_kbd, result_aux; |
228 | 248 | ||
229 | if (i8042_nopnp) { | 249 | if (i8042_nopnp) { |
230 | printk("i8042: PNP detection disabled\n"); | 250 | printk(KERN_INFO "i8042: PNP detection disabled\n"); |
231 | return 0; | 251 | return 0; |
232 | } | 252 | } |
233 | 253 | ||
@@ -241,7 +261,7 @@ static int i8042_pnp_init(void) | |||
241 | #if defined(__ia64__) | 261 | #if defined(__ia64__) |
242 | return -ENODEV; | 262 | return -ENODEV; |
243 | #else | 263 | #else |
244 | printk(KERN_WARNING "PNP: No PS/2 controller found. Probing ports directly.\n"); | 264 | printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); |
245 | return 0; | 265 | return 0; |
246 | #endif | 266 | #endif |
247 | } | 267 | } |
@@ -265,7 +285,7 @@ static int i8042_pnp_init(void) | |||
265 | i8042_pnp_kbd_irq = i8042_kbd_irq; | 285 | i8042_pnp_kbd_irq = i8042_kbd_irq; |
266 | } | 286 | } |
267 | 287 | ||
268 | if (result_aux > 0 && !i8042_pnp_aux_irq) { | 288 | if (!i8042_pnp_aux_irq) { |
269 | printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq); | 289 | printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq); |
270 | i8042_pnp_aux_irq = i8042_aux_irq; | 290 | i8042_pnp_aux_irq = i8042_aux_irq; |
271 | } | 291 | } |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 8e63e464d361..5900de3c3f4f 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -698,6 +698,26 @@ static void i8042_timer_func(unsigned long data) | |||
698 | i8042_interrupt(0, NULL, NULL); | 698 | i8042_interrupt(0, NULL, NULL); |
699 | } | 699 | } |
700 | 700 | ||
701 | static int i8042_ctl_test(void) | ||
702 | { | ||
703 | unsigned char param; | ||
704 | |||
705 | if (!i8042_reset) | ||
706 | return 0; | ||
707 | |||
708 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | ||
709 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | ||
710 | return -1; | ||
711 | } | ||
712 | |||
713 | if (param != I8042_RET_CTL_TEST) { | ||
714 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | ||
715 | param, I8042_RET_CTL_TEST); | ||
716 | return -1; | ||
717 | } | ||
718 | |||
719 | return 0; | ||
720 | } | ||
701 | 721 | ||
702 | /* | 722 | /* |
703 | * i8042_controller init initializes the i8042 controller, and, | 723 | * i8042_controller init initializes the i8042 controller, and, |
@@ -719,21 +739,8 @@ static int i8042_controller_init(void) | |||
719 | return -1; | 739 | return -1; |
720 | } | 740 | } |
721 | 741 | ||
722 | if (i8042_reset) { | 742 | if (i8042_ctl_test()) |
723 | 743 | return -1; | |
724 | unsigned char param; | ||
725 | |||
726 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | ||
727 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | ||
728 | return -1; | ||
729 | } | ||
730 | |||
731 | if (param != I8042_RET_CTL_TEST) { | ||
732 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | ||
733 | param, I8042_RET_CTL_TEST); | ||
734 | return -1; | ||
735 | } | ||
736 | } | ||
737 | 744 | ||
738 | /* | 745 | /* |
739 | * Save the CTR for restoral on unload / reboot. | 746 | * Save the CTR for restoral on unload / reboot. |
@@ -802,15 +809,11 @@ static int i8042_controller_init(void) | |||
802 | */ | 809 | */ |
803 | static void i8042_controller_reset(void) | 810 | static void i8042_controller_reset(void) |
804 | { | 811 | { |
805 | unsigned char param; | ||
806 | |||
807 | /* | 812 | /* |
808 | * Reset the controller if requested. | 813 | * Reset the controller if requested. |
809 | */ | 814 | */ |
810 | 815 | ||
811 | if (i8042_reset) | 816 | i8042_ctl_test(); |
812 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) | ||
813 | printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n"); | ||
814 | 817 | ||
815 | /* | 818 | /* |
816 | * Disable MUX mode if present. | 819 | * Disable MUX mode if present. |
@@ -922,8 +925,11 @@ static int i8042_resume(struct device *dev, u32 level) | |||
922 | if (level != RESUME_ENABLE) | 925 | if (level != RESUME_ENABLE) |
923 | return 0; | 926 | return 0; |
924 | 927 | ||
925 | if (i8042_controller_init()) { | 928 | if (i8042_ctl_test()) |
926 | printk(KERN_ERR "i8042: resume failed\n"); | 929 | return -1; |
930 | |||
931 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | ||
932 | printk(KERN_ERR "i8042: Can't write CTR\n"); | ||
927 | return -1; | 933 | return -1; |
928 | } | 934 | } |
929 | 935 | ||
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index c9d0a153671c..53a27e43dd23 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
@@ -68,8 +68,7 @@ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) | |||
68 | 68 | ||
69 | if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || | 69 | if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || |
70 | (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { | 70 | (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { |
71 | gunze->data[10] = 0; | 71 | printk(KERN_WARNING "gunze.c: bad packet: >%.*s<\n", GUNZE_MAX_LENGTH, gunze->data); |
72 | printk(KERN_WARNING "gunze.c: bad packet: >%s<\n", gunze->data); | ||
73 | return; | 72 | return; |
74 | } | 73 | } |
75 | 74 | ||
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index e654aa5eecd4..bb9f4044c74d 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -2421,7 +2421,7 @@ pmac_wakeup_devices(void) | |||
2421 | 2421 | ||
2422 | /* Re-enable local CPU interrupts */ | 2422 | /* Re-enable local CPU interrupts */ |
2423 | local_irq_enable(); | 2423 | local_irq_enable(); |
2424 | mdelay(100); | 2424 | mdelay(10); |
2425 | preempt_enable(); | 2425 | preempt_enable(); |
2426 | 2426 | ||
2427 | /* Re-enable clock spreading on some machines */ | 2427 | /* Re-enable clock spreading on some machines */ |
@@ -2549,7 +2549,9 @@ powerbook_sleep_Core99(void) | |||
2549 | return ret; | 2549 | return ret; |
2550 | } | 2550 | } |
2551 | 2551 | ||
2552 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 2552 | /* Stop environment and ADB interrupts */ |
2553 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); | ||
2554 | pmu_wait_complete(&req); | ||
2553 | 2555 | ||
2554 | /* Tell PMU what events will wake us up */ | 2556 | /* Tell PMU what events will wake us up */ |
2555 | pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, | 2557 | pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, |
@@ -2611,8 +2613,6 @@ powerbook_sleep_Core99(void) | |||
2611 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); | 2613 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); |
2612 | pmu_wait_complete(&req); | 2614 | pmu_wait_complete(&req); |
2613 | 2615 | ||
2614 | printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); | ||
2615 | |||
2616 | pmac_wakeup_devices(); | 2616 | pmac_wakeup_devices(); |
2617 | 2617 | ||
2618 | return 0; | 2618 | return 0; |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index d047e349d706..1339912c308b 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -906,22 +906,12 @@ static int dst_tone_power_cmd(struct dst_state* state) | |||
906 | if (state->dst_type == DST_TYPE_IS_TERR) | 906 | if (state->dst_type == DST_TYPE_IS_TERR) |
907 | return 0; | 907 | return 0; |
908 | 908 | ||
909 | if (state->voltage == SEC_VOLTAGE_OFF) | 909 | paket[4] = state->tx_tuna[4]; |
910 | paket[4] = 0; | 910 | paket[2] = state->tx_tuna[2]; |
911 | else | 911 | paket[3] = state->tx_tuna[3]; |
912 | paket[4] = 1; | ||
913 | |||
914 | if (state->tone == SEC_TONE_ON) | ||
915 | paket[2] = 0x02; | ||
916 | else | ||
917 | paket[2] = 0; | ||
918 | if (state->minicmd == SEC_MINI_A) | ||
919 | paket[3] = 0x02; | ||
920 | else | ||
921 | paket[3] = 0; | ||
922 | |||
923 | paket[7] = dst_check_sum (paket, 7); | 912 | paket[7] = dst_check_sum (paket, 7); |
924 | dst_command(state, paket, 8); | 913 | dst_command(state, paket, 8); |
914 | |||
925 | return 0; | 915 | return 0; |
926 | } | 916 | } |
927 | 917 | ||
@@ -980,7 +970,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | |||
980 | 970 | ||
981 | static int dst_write_tuna(struct dvb_frontend* fe) | 971 | static int dst_write_tuna(struct dvb_frontend* fe) |
982 | { | 972 | { |
983 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 973 | struct dst_state* state = fe->demodulator_priv; |
984 | int retval; | 974 | int retval; |
985 | u8 reply; | 975 | u8 reply; |
986 | 976 | ||
@@ -1048,10 +1038,10 @@ static int dst_write_tuna(struct dvb_frontend* fe) | |||
1048 | 1038 | ||
1049 | static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | 1039 | static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) |
1050 | { | 1040 | { |
1051 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1041 | struct dst_state* state = fe->demodulator_priv; |
1052 | u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; | 1042 | u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; |
1053 | 1043 | ||
1054 | if (state->dst_type == DST_TYPE_IS_TERR) | 1044 | if (state->dst_type != DST_TYPE_IS_SAT) |
1055 | return 0; | 1045 | return 0; |
1056 | 1046 | ||
1057 | if (cmd->msg_len == 0 || cmd->msg_len > 4) | 1047 | if (cmd->msg_len == 0 || cmd->msg_len > 4) |
@@ -1064,39 +1054,32 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* | |||
1064 | 1054 | ||
1065 | static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 1055 | static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
1066 | { | 1056 | { |
1067 | u8 *val; | ||
1068 | int need_cmd; | 1057 | int need_cmd; |
1069 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1058 | struct dst_state* state = fe->demodulator_priv; |
1070 | 1059 | ||
1071 | state->voltage = voltage; | 1060 | state->voltage = voltage; |
1072 | 1061 | ||
1073 | if (state->dst_type == DST_TYPE_IS_TERR) | 1062 | if (state->dst_type != DST_TYPE_IS_SAT) |
1074 | return 0; | 1063 | return 0; |
1075 | 1064 | ||
1076 | need_cmd = 0; | 1065 | need_cmd = 0; |
1077 | val = &state->tx_tuna[0]; | ||
1078 | val[8] &= ~0x40; | ||
1079 | switch (voltage) { | 1066 | switch (voltage) { |
1080 | case SEC_VOLTAGE_13: | 1067 | case SEC_VOLTAGE_13: |
1081 | if ((state->diseq_flags & HAS_POWER) == 0) | 1068 | case SEC_VOLTAGE_18: |
1082 | need_cmd = 1; | 1069 | if ((state->diseq_flags & HAS_POWER) == 0) |
1083 | state->diseq_flags |= HAS_POWER; | 1070 | need_cmd = 1; |
1084 | break; | 1071 | state->diseq_flags |= HAS_POWER; |
1072 | state->tx_tuna[4] = 0x01; | ||
1073 | break; | ||
1085 | 1074 | ||
1086 | case SEC_VOLTAGE_18: | 1075 | case SEC_VOLTAGE_OFF: |
1087 | if ((state->diseq_flags & HAS_POWER) == 0) | ||
1088 | need_cmd = 1; | 1076 | need_cmd = 1; |
1089 | state->diseq_flags |= HAS_POWER; | 1077 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); |
1090 | val[8] |= 0x40; | 1078 | state->tx_tuna[4] = 0x00; |
1091 | break; | 1079 | break; |
1092 | |||
1093 | case SEC_VOLTAGE_OFF: | ||
1094 | need_cmd = 1; | ||
1095 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); | ||
1096 | break; | ||
1097 | 1080 | ||
1098 | default: | 1081 | default: |
1099 | return -EINVAL; | 1082 | return -EINVAL; |
1100 | } | 1083 | } |
1101 | if (need_cmd) | 1084 | if (need_cmd) |
1102 | dst_tone_power_cmd(state); | 1085 | dst_tone_power_cmd(state); |
@@ -1106,37 +1089,56 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | |||
1106 | 1089 | ||
1107 | static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 1090 | static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
1108 | { | 1091 | { |
1109 | u8 *val; | 1092 | struct dst_state* state = fe->demodulator_priv; |
1110 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | ||
1111 | 1093 | ||
1112 | state->tone = tone; | 1094 | state->tone = tone; |
1113 | 1095 | ||
1114 | if (state->dst_type == DST_TYPE_IS_TERR) | 1096 | if (state->dst_type != DST_TYPE_IS_SAT) |
1115 | return 0; | 1097 | return 0; |
1116 | 1098 | ||
1117 | val = &state->tx_tuna[0]; | 1099 | switch (tone) { |
1100 | case SEC_TONE_OFF: | ||
1101 | state->tx_tuna[2] = 0xff; | ||
1102 | break; | ||
1118 | 1103 | ||
1119 | val[8] &= ~0x1; | 1104 | case SEC_TONE_ON: |
1105 | state->tx_tuna[2] = 0x02; | ||
1106 | break; | ||
1120 | 1107 | ||
1121 | switch (tone) { | 1108 | default: |
1122 | case SEC_TONE_OFF: | 1109 | return -EINVAL; |
1123 | break; | 1110 | } |
1111 | dst_tone_power_cmd(state); | ||
1124 | 1112 | ||
1125 | case SEC_TONE_ON: | 1113 | return 0; |
1126 | val[8] |= 1; | 1114 | } |
1127 | break; | ||
1128 | 1115 | ||
1129 | default: | 1116 | static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) |
1130 | return -EINVAL; | 1117 | { |
1118 | struct dst_state *state = fe->demodulator_priv; | ||
1119 | |||
1120 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
1121 | return 0; | ||
1122 | |||
1123 | state->minicmd = minicmd; | ||
1124 | |||
1125 | switch (minicmd) { | ||
1126 | case SEC_MINI_A: | ||
1127 | state->tx_tuna[3] = 0x02; | ||
1128 | break; | ||
1129 | case SEC_MINI_B: | ||
1130 | state->tx_tuna[3] = 0xff; | ||
1131 | break; | ||
1131 | } | 1132 | } |
1132 | dst_tone_power_cmd(state); | 1133 | dst_tone_power_cmd(state); |
1133 | 1134 | ||
1134 | return 0; | 1135 | return 0; |
1135 | } | 1136 | } |
1136 | 1137 | ||
1138 | |||
1137 | static int dst_init(struct dvb_frontend* fe) | 1139 | static int dst_init(struct dvb_frontend* fe) |
1138 | { | 1140 | { |
1139 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1141 | struct dst_state* state = fe->demodulator_priv; |
1140 | static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; | 1142 | static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; |
1141 | static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; | 1143 | static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; |
1142 | static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; | 1144 | static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; |
@@ -1168,7 +1170,7 @@ static int dst_init(struct dvb_frontend* fe) | |||
1168 | 1170 | ||
1169 | static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) | 1171 | static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) |
1170 | { | 1172 | { |
1171 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1173 | struct dst_state* state = fe->demodulator_priv; |
1172 | 1174 | ||
1173 | *status = 0; | 1175 | *status = 0; |
1174 | if (state->diseq_flags & HAS_LOCK) { | 1176 | if (state->diseq_flags & HAS_LOCK) { |
@@ -1182,7 +1184,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
1182 | 1184 | ||
1183 | static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 1185 | static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
1184 | { | 1186 | { |
1185 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1187 | struct dst_state* state = fe->demodulator_priv; |
1186 | 1188 | ||
1187 | dst_get_signal(state); | 1189 | dst_get_signal(state); |
1188 | *strength = state->decode_strength; | 1190 | *strength = state->decode_strength; |
@@ -1192,7 +1194,7 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
1192 | 1194 | ||
1193 | static int dst_read_snr(struct dvb_frontend* fe, u16* snr) | 1195 | static int dst_read_snr(struct dvb_frontend* fe, u16* snr) |
1194 | { | 1196 | { |
1195 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1197 | struct dst_state* state = fe->demodulator_priv; |
1196 | 1198 | ||
1197 | dst_get_signal(state); | 1199 | dst_get_signal(state); |
1198 | *snr = state->decode_snr; | 1200 | *snr = state->decode_snr; |
@@ -1202,7 +1204,7 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr) | |||
1202 | 1204 | ||
1203 | static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 1205 | static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
1204 | { | 1206 | { |
1205 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1207 | struct dst_state* state = fe->demodulator_priv; |
1206 | 1208 | ||
1207 | dst_set_freq(state, p->frequency); | 1209 | dst_set_freq(state, p->frequency); |
1208 | if (verbose > 4) | 1210 | if (verbose > 4) |
@@ -1228,7 +1230,7 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
1228 | 1230 | ||
1229 | static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 1231 | static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
1230 | { | 1232 | { |
1231 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1233 | struct dst_state* state = fe->demodulator_priv; |
1232 | 1234 | ||
1233 | p->frequency = state->decode_freq; | 1235 | p->frequency = state->decode_freq; |
1234 | p->inversion = state->inversion; | 1236 | p->inversion = state->inversion; |
@@ -1248,7 +1250,7 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
1248 | 1250 | ||
1249 | static void dst_release(struct dvb_frontend* fe) | 1251 | static void dst_release(struct dvb_frontend* fe) |
1250 | { | 1252 | { |
1251 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1253 | struct dst_state* state = fe->demodulator_priv; |
1252 | kfree(state); | 1254 | kfree(state); |
1253 | } | 1255 | } |
1254 | 1256 | ||
@@ -1346,7 +1348,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1346 | .read_signal_strength = dst_read_signal_strength, | 1348 | .read_signal_strength = dst_read_signal_strength, |
1347 | .read_snr = dst_read_snr, | 1349 | .read_snr = dst_read_snr, |
1348 | 1350 | ||
1349 | .diseqc_send_burst = dst_set_tone, | 1351 | .diseqc_send_burst = dst_send_burst, |
1350 | .diseqc_send_master_cmd = dst_set_diseqc, | 1352 | .diseqc_send_master_cmd = dst_set_diseqc, |
1351 | .set_voltage = dst_set_voltage, | 1353 | .set_voltage = dst_set_voltage, |
1352 | .set_tone = dst_set_tone, | 1354 | .set_tone = dst_set_tone, |
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index d639cb8dc461..72cdf19e1be1 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | #include <linux/config.h> | 55 | #include <linux/config.h> |
56 | #include <linux/module.h> | 56 | #include <linux/module.h> |
57 | #include <linux/moduleparam.h> | ||
57 | #include <linux/kernel.h> | 58 | #include <linux/kernel.h> |
58 | #include <linux/compiler.h> | 59 | #include <linux/compiler.h> |
59 | #include <linux/netdevice.h> | 60 | #include <linux/netdevice.h> |
@@ -91,16 +92,17 @@ KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE | |||
91 | 92 | ||
92 | MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>"); | 93 | MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>"); |
93 | MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver"); | 94 | MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver"); |
95 | MODULE_VERSION(DRV_VERSION); | ||
94 | MODULE_LICENSE("GPL"); | 96 | MODULE_LICENSE("GPL"); |
95 | 97 | ||
96 | static int debug = -1; | 98 | static int debug = -1; |
97 | MODULE_PARM (debug, "i"); | 99 | module_param(debug, int, 0); |
98 | MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number"); | 100 | MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number"); |
99 | 101 | ||
100 | /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). | 102 | /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). |
101 | The RTL chips use a 64 element hash table based on the Ethernet CRC. */ | 103 | The RTL chips use a 64 element hash table based on the Ethernet CRC. */ |
102 | static int multicast_filter_limit = 32; | 104 | static int multicast_filter_limit = 32; |
103 | MODULE_PARM (multicast_filter_limit, "i"); | 105 | module_param(multicast_filter_limit, int, 0); |
104 | MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses"); | 106 | MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses"); |
105 | 107 | ||
106 | #define PFX DRV_NAME ": " | 108 | #define PFX DRV_NAME ": " |
@@ -186,6 +188,9 @@ enum { | |||
186 | RingEnd = (1 << 30), /* End of descriptor ring */ | 188 | RingEnd = (1 << 30), /* End of descriptor ring */ |
187 | FirstFrag = (1 << 29), /* First segment of a packet */ | 189 | FirstFrag = (1 << 29), /* First segment of a packet */ |
188 | LastFrag = (1 << 28), /* Final segment of a packet */ | 190 | LastFrag = (1 << 28), /* Final segment of a packet */ |
191 | LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ | ||
192 | MSSShift = 16, /* MSS value position */ | ||
193 | MSSMask = 0xfff, /* MSS value: 11 bits */ | ||
189 | TxError = (1 << 23), /* Tx error summary */ | 194 | TxError = (1 << 23), /* Tx error summary */ |
190 | RxError = (1 << 20), /* Rx error summary */ | 195 | RxError = (1 << 20), /* Rx error summary */ |
191 | IPCS = (1 << 18), /* Calculate IP checksum */ | 196 | IPCS = (1 << 18), /* Calculate IP checksum */ |
@@ -312,7 +317,7 @@ struct cp_desc { | |||
312 | struct ring_info { | 317 | struct ring_info { |
313 | struct sk_buff *skb; | 318 | struct sk_buff *skb; |
314 | dma_addr_t mapping; | 319 | dma_addr_t mapping; |
315 | unsigned frag; | 320 | u32 len; |
316 | }; | 321 | }; |
317 | 322 | ||
318 | struct cp_dma_stats { | 323 | struct cp_dma_stats { |
@@ -394,6 +399,9 @@ struct cp_private { | |||
394 | static void __cp_set_rx_mode (struct net_device *dev); | 399 | static void __cp_set_rx_mode (struct net_device *dev); |
395 | static void cp_tx (struct cp_private *cp); | 400 | static void cp_tx (struct cp_private *cp); |
396 | static void cp_clean_rings (struct cp_private *cp); | 401 | static void cp_clean_rings (struct cp_private *cp); |
402 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
403 | static void cp_poll_controller(struct net_device *dev); | ||
404 | #endif | ||
397 | 405 | ||
398 | static struct pci_device_id cp_pci_tbl[] = { | 406 | static struct pci_device_id cp_pci_tbl[] = { |
399 | { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, | 407 | { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, |
@@ -688,6 +696,19 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | |||
688 | return IRQ_HANDLED; | 696 | return IRQ_HANDLED; |
689 | } | 697 | } |
690 | 698 | ||
699 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
700 | /* | ||
701 | * Polling receive - used by netconsole and other diagnostic tools | ||
702 | * to allow network i/o with interrupts disabled. | ||
703 | */ | ||
704 | static void cp_poll_controller(struct net_device *dev) | ||
705 | { | ||
706 | disable_irq(dev->irq); | ||
707 | cp_interrupt(dev->irq, dev, NULL); | ||
708 | enable_irq(dev->irq); | ||
709 | } | ||
710 | #endif | ||
711 | |||
691 | static void cp_tx (struct cp_private *cp) | 712 | static void cp_tx (struct cp_private *cp) |
692 | { | 713 | { |
693 | unsigned tx_head = cp->tx_head; | 714 | unsigned tx_head = cp->tx_head; |
@@ -707,7 +728,7 @@ static void cp_tx (struct cp_private *cp) | |||
707 | BUG(); | 728 | BUG(); |
708 | 729 | ||
709 | pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, | 730 | pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, |
710 | skb->len, PCI_DMA_TODEVICE); | 731 | cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); |
711 | 732 | ||
712 | if (status & LastFrag) { | 733 | if (status & LastFrag) { |
713 | if (status & (TxError | TxFIFOUnder)) { | 734 | if (status & (TxError | TxFIFOUnder)) { |
@@ -749,10 +770,11 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
749 | { | 770 | { |
750 | struct cp_private *cp = netdev_priv(dev); | 771 | struct cp_private *cp = netdev_priv(dev); |
751 | unsigned entry; | 772 | unsigned entry; |
752 | u32 eor; | 773 | u32 eor, flags; |
753 | #if CP_VLAN_TAG_USED | 774 | #if CP_VLAN_TAG_USED |
754 | u32 vlan_tag = 0; | 775 | u32 vlan_tag = 0; |
755 | #endif | 776 | #endif |
777 | int mss = 0; | ||
756 | 778 | ||
757 | spin_lock_irq(&cp->lock); | 779 | spin_lock_irq(&cp->lock); |
758 | 780 | ||
@@ -772,6 +794,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
772 | 794 | ||
773 | entry = cp->tx_head; | 795 | entry = cp->tx_head; |
774 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; | 796 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; |
797 | if (dev->features & NETIF_F_TSO) | ||
798 | mss = skb_shinfo(skb)->tso_size; | ||
799 | |||
775 | if (skb_shinfo(skb)->nr_frags == 0) { | 800 | if (skb_shinfo(skb)->nr_frags == 0) { |
776 | struct cp_desc *txd = &cp->tx_ring[entry]; | 801 | struct cp_desc *txd = &cp->tx_ring[entry]; |
777 | u32 len; | 802 | u32 len; |
@@ -783,26 +808,26 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
783 | txd->addr = cpu_to_le64(mapping); | 808 | txd->addr = cpu_to_le64(mapping); |
784 | wmb(); | 809 | wmb(); |
785 | 810 | ||
786 | if (skb->ip_summed == CHECKSUM_HW) { | 811 | flags = eor | len | DescOwn | FirstFrag | LastFrag; |
812 | |||
813 | if (mss) | ||
814 | flags |= LargeSend | ((mss & MSSMask) << MSSShift); | ||
815 | else if (skb->ip_summed == CHECKSUM_HW) { | ||
787 | const struct iphdr *ip = skb->nh.iph; | 816 | const struct iphdr *ip = skb->nh.iph; |
788 | if (ip->protocol == IPPROTO_TCP) | 817 | if (ip->protocol == IPPROTO_TCP) |
789 | txd->opts1 = cpu_to_le32(eor | len | DescOwn | | 818 | flags |= IPCS | TCPCS; |
790 | FirstFrag | LastFrag | | ||
791 | IPCS | TCPCS); | ||
792 | else if (ip->protocol == IPPROTO_UDP) | 819 | else if (ip->protocol == IPPROTO_UDP) |
793 | txd->opts1 = cpu_to_le32(eor | len | DescOwn | | 820 | flags |= IPCS | UDPCS; |
794 | FirstFrag | LastFrag | | ||
795 | IPCS | UDPCS); | ||
796 | else | 821 | else |
797 | BUG(); | 822 | WARN_ON(1); /* we need a WARN() */ |
798 | } else | 823 | } |
799 | txd->opts1 = cpu_to_le32(eor | len | DescOwn | | 824 | |
800 | FirstFrag | LastFrag); | 825 | txd->opts1 = cpu_to_le32(flags); |
801 | wmb(); | 826 | wmb(); |
802 | 827 | ||
803 | cp->tx_skb[entry].skb = skb; | 828 | cp->tx_skb[entry].skb = skb; |
804 | cp->tx_skb[entry].mapping = mapping; | 829 | cp->tx_skb[entry].mapping = mapping; |
805 | cp->tx_skb[entry].frag = 0; | 830 | cp->tx_skb[entry].len = len; |
806 | entry = NEXT_TX(entry); | 831 | entry = NEXT_TX(entry); |
807 | } else { | 832 | } else { |
808 | struct cp_desc *txd; | 833 | struct cp_desc *txd; |
@@ -820,7 +845,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
820 | first_len, PCI_DMA_TODEVICE); | 845 | first_len, PCI_DMA_TODEVICE); |
821 | cp->tx_skb[entry].skb = skb; | 846 | cp->tx_skb[entry].skb = skb; |
822 | cp->tx_skb[entry].mapping = first_mapping; | 847 | cp->tx_skb[entry].mapping = first_mapping; |
823 | cp->tx_skb[entry].frag = 1; | 848 | cp->tx_skb[entry].len = first_len; |
824 | entry = NEXT_TX(entry); | 849 | entry = NEXT_TX(entry); |
825 | 850 | ||
826 | for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { | 851 | for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { |
@@ -836,16 +861,19 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
836 | len, PCI_DMA_TODEVICE); | 861 | len, PCI_DMA_TODEVICE); |
837 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; | 862 | eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; |
838 | 863 | ||
839 | if (skb->ip_summed == CHECKSUM_HW) { | 864 | ctrl = eor | len | DescOwn; |
840 | ctrl = eor | len | DescOwn | IPCS; | 865 | |
866 | if (mss) | ||
867 | ctrl |= LargeSend | | ||
868 | ((mss & MSSMask) << MSSShift); | ||
869 | else if (skb->ip_summed == CHECKSUM_HW) { | ||
841 | if (ip->protocol == IPPROTO_TCP) | 870 | if (ip->protocol == IPPROTO_TCP) |
842 | ctrl |= TCPCS; | 871 | ctrl |= IPCS | TCPCS; |
843 | else if (ip->protocol == IPPROTO_UDP) | 872 | else if (ip->protocol == IPPROTO_UDP) |
844 | ctrl |= UDPCS; | 873 | ctrl |= IPCS | UDPCS; |
845 | else | 874 | else |
846 | BUG(); | 875 | BUG(); |
847 | } else | 876 | } |
848 | ctrl = eor | len | DescOwn; | ||
849 | 877 | ||
850 | if (frag == skb_shinfo(skb)->nr_frags - 1) | 878 | if (frag == skb_shinfo(skb)->nr_frags - 1) |
851 | ctrl |= LastFrag; | 879 | ctrl |= LastFrag; |
@@ -860,7 +888,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
860 | 888 | ||
861 | cp->tx_skb[entry].skb = skb; | 889 | cp->tx_skb[entry].skb = skb; |
862 | cp->tx_skb[entry].mapping = mapping; | 890 | cp->tx_skb[entry].mapping = mapping; |
863 | cp->tx_skb[entry].frag = frag + 2; | 891 | cp->tx_skb[entry].len = len; |
864 | entry = NEXT_TX(entry); | 892 | entry = NEXT_TX(entry); |
865 | } | 893 | } |
866 | 894 | ||
@@ -1074,7 +1102,6 @@ static int cp_refill_rx (struct cp_private *cp) | |||
1074 | cp->rx_skb[i].mapping = pci_map_single(cp->pdev, | 1102 | cp->rx_skb[i].mapping = pci_map_single(cp->pdev, |
1075 | skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1103 | skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1076 | cp->rx_skb[i].skb = skb; | 1104 | cp->rx_skb[i].skb = skb; |
1077 | cp->rx_skb[i].frag = 0; | ||
1078 | 1105 | ||
1079 | cp->rx_ring[i].opts2 = 0; | 1106 | cp->rx_ring[i].opts2 = 0; |
1080 | cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping); | 1107 | cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping); |
@@ -1126,9 +1153,6 @@ static void cp_clean_rings (struct cp_private *cp) | |||
1126 | { | 1153 | { |
1127 | unsigned i; | 1154 | unsigned i; |
1128 | 1155 | ||
1129 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); | ||
1130 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); | ||
1131 | |||
1132 | for (i = 0; i < CP_RX_RING_SIZE; i++) { | 1156 | for (i = 0; i < CP_RX_RING_SIZE; i++) { |
1133 | if (cp->rx_skb[i].skb) { | 1157 | if (cp->rx_skb[i].skb) { |
1134 | pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping, | 1158 | pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping, |
@@ -1140,13 +1164,18 @@ static void cp_clean_rings (struct cp_private *cp) | |||
1140 | for (i = 0; i < CP_TX_RING_SIZE; i++) { | 1164 | for (i = 0; i < CP_TX_RING_SIZE; i++) { |
1141 | if (cp->tx_skb[i].skb) { | 1165 | if (cp->tx_skb[i].skb) { |
1142 | struct sk_buff *skb = cp->tx_skb[i].skb; | 1166 | struct sk_buff *skb = cp->tx_skb[i].skb; |
1167 | |||
1143 | pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping, | 1168 | pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping, |
1144 | skb->len, PCI_DMA_TODEVICE); | 1169 | cp->tx_skb[i].len, PCI_DMA_TODEVICE); |
1145 | dev_kfree_skb(skb); | 1170 | if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag) |
1171 | dev_kfree_skb(skb); | ||
1146 | cp->net_stats.tx_dropped++; | 1172 | cp->net_stats.tx_dropped++; |
1147 | } | 1173 | } |
1148 | } | 1174 | } |
1149 | 1175 | ||
1176 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); | ||
1177 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); | ||
1178 | |||
1150 | memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE); | 1179 | memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE); |
1151 | memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE); | 1180 | memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE); |
1152 | } | 1181 | } |
@@ -1538,6 +1567,8 @@ static struct ethtool_ops cp_ethtool_ops = { | |||
1538 | .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ | 1567 | .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ |
1539 | .get_sg = ethtool_op_get_sg, | 1568 | .get_sg = ethtool_op_get_sg, |
1540 | .set_sg = ethtool_op_set_sg, | 1569 | .set_sg = ethtool_op_set_sg, |
1570 | .get_tso = ethtool_op_get_tso, | ||
1571 | .set_tso = ethtool_op_set_tso, | ||
1541 | .get_regs = cp_get_regs, | 1572 | .get_regs = cp_get_regs, |
1542 | .get_wol = cp_get_wol, | 1573 | .get_wol = cp_get_wol, |
1543 | .set_wol = cp_set_wol, | 1574 | .set_wol = cp_set_wol, |
@@ -1749,6 +1780,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1749 | dev->get_stats = cp_get_stats; | 1780 | dev->get_stats = cp_get_stats; |
1750 | dev->do_ioctl = cp_ioctl; | 1781 | dev->do_ioctl = cp_ioctl; |
1751 | dev->poll = cp_rx_poll; | 1782 | dev->poll = cp_rx_poll; |
1783 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1784 | dev->poll_controller = cp_poll_controller; | ||
1785 | #endif | ||
1752 | dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ | 1786 | dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ |
1753 | #ifdef BROKEN | 1787 | #ifdef BROKEN |
1754 | dev->change_mtu = cp_change_mtu; | 1788 | dev->change_mtu = cp_change_mtu; |
@@ -1768,6 +1802,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1768 | if (pci_using_dac) | 1802 | if (pci_using_dac) |
1769 | dev->features |= NETIF_F_HIGHDMA; | 1803 | dev->features |= NETIF_F_HIGHDMA; |
1770 | 1804 | ||
1805 | #if 0 /* disabled by default until verified */ | ||
1806 | dev->features |= NETIF_F_TSO; | ||
1807 | #endif | ||
1808 | |||
1771 | dev->irq = pdev->irq; | 1809 | dev->irq = pdev->irq; |
1772 | 1810 | ||
1773 | rc = register_netdev(dev); | 1811 | rc = register_netdev(dev); |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index d4bd20c21a1f..047202c4d9a8 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -569,7 +569,7 @@ struct rtl_extra_stats { | |||
569 | }; | 569 | }; |
570 | 570 | ||
571 | struct rtl8139_private { | 571 | struct rtl8139_private { |
572 | void *mmio_addr; | 572 | void __iomem *mmio_addr; |
573 | int drv_flags; | 573 | int drv_flags; |
574 | struct pci_dev *pci_dev; | 574 | struct pci_dev *pci_dev; |
575 | u32 msg_enable; | 575 | u32 msg_enable; |
@@ -614,7 +614,7 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered mu | |||
614 | MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps"); | 614 | MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps"); |
615 | MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)"); | 615 | MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)"); |
616 | 616 | ||
617 | static int read_eeprom (void *ioaddr, int location, int addr_len); | 617 | static int read_eeprom (void __iomem *ioaddr, int location, int addr_len); |
618 | static int rtl8139_open (struct net_device *dev); | 618 | static int rtl8139_open (struct net_device *dev); |
619 | static int mdio_read (struct net_device *dev, int phy_id, int location); | 619 | static int mdio_read (struct net_device *dev, int phy_id, int location); |
620 | static void mdio_write (struct net_device *dev, int phy_id, int location, | 620 | static void mdio_write (struct net_device *dev, int phy_id, int location, |
@@ -638,46 +638,20 @@ static void __set_rx_mode (struct net_device *dev); | |||
638 | static void rtl8139_hw_start (struct net_device *dev); | 638 | static void rtl8139_hw_start (struct net_device *dev); |
639 | static struct ethtool_ops rtl8139_ethtool_ops; | 639 | static struct ethtool_ops rtl8139_ethtool_ops; |
640 | 640 | ||
641 | #ifdef USE_IO_OPS | ||
642 | |||
643 | #define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg)) | ||
644 | #define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg)) | ||
645 | #define RTL_R32(reg) ((unsigned long) inl (((unsigned long)ioaddr) + (reg))) | ||
646 | #define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg)) | ||
647 | #define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg)) | ||
648 | #define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg)) | ||
649 | #define RTL_W8_F RTL_W8 | ||
650 | #define RTL_W16_F RTL_W16 | ||
651 | #define RTL_W32_F RTL_W32 | ||
652 | #undef readb | ||
653 | #undef readw | ||
654 | #undef readl | ||
655 | #undef writeb | ||
656 | #undef writew | ||
657 | #undef writel | ||
658 | #define readb(addr) inb((unsigned long)(addr)) | ||
659 | #define readw(addr) inw((unsigned long)(addr)) | ||
660 | #define readl(addr) inl((unsigned long)(addr)) | ||
661 | #define writeb(val,addr) outb((val),(unsigned long)(addr)) | ||
662 | #define writew(val,addr) outw((val),(unsigned long)(addr)) | ||
663 | #define writel(val,addr) outl((val),(unsigned long)(addr)) | ||
664 | |||
665 | #else | ||
666 | |||
667 | /* write MMIO register, with flush */ | 641 | /* write MMIO register, with flush */ |
668 | /* Flush avoids rtl8139 bug w/ posted MMIO writes */ | 642 | /* Flush avoids rtl8139 bug w/ posted MMIO writes */ |
669 | #define RTL_W8_F(reg, val8) do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0) | 643 | #define RTL_W8_F(reg, val8) do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0) |
670 | #define RTL_W16_F(reg, val16) do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0) | 644 | #define RTL_W16_F(reg, val16) do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0) |
671 | #define RTL_W32_F(reg, val32) do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0) | 645 | #define RTL_W32_F(reg, val32) do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0) |
672 | 646 | ||
673 | 647 | ||
674 | #define MMIO_FLUSH_AUDIT_COMPLETE 1 | 648 | #define MMIO_FLUSH_AUDIT_COMPLETE 1 |
675 | #if MMIO_FLUSH_AUDIT_COMPLETE | 649 | #if MMIO_FLUSH_AUDIT_COMPLETE |
676 | 650 | ||
677 | /* write MMIO register */ | 651 | /* write MMIO register */ |
678 | #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) | 652 | #define RTL_W8(reg, val8) iowrite8 ((val8), ioaddr + (reg)) |
679 | #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) | 653 | #define RTL_W16(reg, val16) iowrite16 ((val16), ioaddr + (reg)) |
680 | #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) | 654 | #define RTL_W32(reg, val32) iowrite32 ((val32), ioaddr + (reg)) |
681 | 655 | ||
682 | #else | 656 | #else |
683 | 657 | ||
@@ -689,11 +663,9 @@ static struct ethtool_ops rtl8139_ethtool_ops; | |||
689 | #endif /* MMIO_FLUSH_AUDIT_COMPLETE */ | 663 | #endif /* MMIO_FLUSH_AUDIT_COMPLETE */ |
690 | 664 | ||
691 | /* read MMIO register */ | 665 | /* read MMIO register */ |
692 | #define RTL_R8(reg) readb (ioaddr + (reg)) | 666 | #define RTL_R8(reg) ioread8 (ioaddr + (reg)) |
693 | #define RTL_R16(reg) readw (ioaddr + (reg)) | 667 | #define RTL_R16(reg) ioread16 (ioaddr + (reg)) |
694 | #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) | 668 | #define RTL_R32(reg) ((unsigned long) ioread32 (ioaddr + (reg))) |
695 | |||
696 | #endif /* USE_IO_OPS */ | ||
697 | 669 | ||
698 | 670 | ||
699 | static const u16 rtl8139_intr_mask = | 671 | static const u16 rtl8139_intr_mask = |
@@ -740,10 +712,13 @@ static void __rtl8139_cleanup_dev (struct net_device *dev) | |||
740 | assert (tp->pci_dev != NULL); | 712 | assert (tp->pci_dev != NULL); |
741 | pdev = tp->pci_dev; | 713 | pdev = tp->pci_dev; |
742 | 714 | ||
743 | #ifndef USE_IO_OPS | 715 | #ifdef USE_IO_OPS |
716 | if (tp->mmio_addr) | ||
717 | ioport_unmap (tp->mmio_addr); | ||
718 | #else | ||
744 | if (tp->mmio_addr) | 719 | if (tp->mmio_addr) |
745 | iounmap (tp->mmio_addr); | 720 | pci_iounmap (pdev, tp->mmio_addr); |
746 | #endif /* !USE_IO_OPS */ | 721 | #endif /* USE_IO_OPS */ |
747 | 722 | ||
748 | /* it's ok to call this even if we have no regions to free */ | 723 | /* it's ok to call this even if we have no regions to free */ |
749 | pci_release_regions (pdev); | 724 | pci_release_regions (pdev); |
@@ -753,7 +728,7 @@ static void __rtl8139_cleanup_dev (struct net_device *dev) | |||
753 | } | 728 | } |
754 | 729 | ||
755 | 730 | ||
756 | static void rtl8139_chip_reset (void *ioaddr) | 731 | static void rtl8139_chip_reset (void __iomem *ioaddr) |
757 | { | 732 | { |
758 | int i; | 733 | int i; |
759 | 734 | ||
@@ -773,7 +748,7 @@ static void rtl8139_chip_reset (void *ioaddr) | |||
773 | static int __devinit rtl8139_init_board (struct pci_dev *pdev, | 748 | static int __devinit rtl8139_init_board (struct pci_dev *pdev, |
774 | struct net_device **dev_out) | 749 | struct net_device **dev_out) |
775 | { | 750 | { |
776 | void *ioaddr; | 751 | void __iomem *ioaddr; |
777 | struct net_device *dev; | 752 | struct net_device *dev; |
778 | struct rtl8139_private *tp; | 753 | struct rtl8139_private *tp; |
779 | u8 tmp8; | 754 | u8 tmp8; |
@@ -855,13 +830,18 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, | |||
855 | pci_set_master (pdev); | 830 | pci_set_master (pdev); |
856 | 831 | ||
857 | #ifdef USE_IO_OPS | 832 | #ifdef USE_IO_OPS |
858 | ioaddr = (void *) pio_start; | 833 | ioaddr = ioport_map(pio_start, pio_len); |
834 | if (!ioaddr) { | ||
835 | printk (KERN_ERR PFX "%s: cannot map PIO, aborting\n", pci_name(pdev)); | ||
836 | rc = -EIO; | ||
837 | goto err_out; | ||
838 | } | ||
859 | dev->base_addr = pio_start; | 839 | dev->base_addr = pio_start; |
860 | tp->mmio_addr = ioaddr; | 840 | tp->mmio_addr = ioaddr; |
861 | tp->regs_len = pio_len; | 841 | tp->regs_len = pio_len; |
862 | #else | 842 | #else |
863 | /* ioremap MMIO region */ | 843 | /* ioremap MMIO region */ |
864 | ioaddr = ioremap (mmio_start, mmio_len); | 844 | ioaddr = pci_iomap(pdev, 1, 0); |
865 | if (ioaddr == NULL) { | 845 | if (ioaddr == NULL) { |
866 | printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev)); | 846 | printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev)); |
867 | rc = -EIO; | 847 | rc = -EIO; |
@@ -947,7 +927,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, | |||
947 | struct net_device *dev = NULL; | 927 | struct net_device *dev = NULL; |
948 | struct rtl8139_private *tp; | 928 | struct rtl8139_private *tp; |
949 | int i, addr_len, option; | 929 | int i, addr_len, option; |
950 | void *ioaddr; | 930 | void __iomem *ioaddr; |
951 | static int board_idx = -1; | 931 | static int board_idx = -1; |
952 | u8 pci_rev; | 932 | u8 pci_rev; |
953 | 933 | ||
@@ -1147,47 +1127,46 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev) | |||
1147 | No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. | 1127 | No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. |
1148 | */ | 1128 | */ |
1149 | 1129 | ||
1150 | #define eeprom_delay() readl(ee_addr) | 1130 | #define eeprom_delay() RTL_R32(Cfg9346) |
1151 | 1131 | ||
1152 | /* The EEPROM commands include the alway-set leading bit. */ | 1132 | /* The EEPROM commands include the alway-set leading bit. */ |
1153 | #define EE_WRITE_CMD (5) | 1133 | #define EE_WRITE_CMD (5) |
1154 | #define EE_READ_CMD (6) | 1134 | #define EE_READ_CMD (6) |
1155 | #define EE_ERASE_CMD (7) | 1135 | #define EE_ERASE_CMD (7) |
1156 | 1136 | ||
1157 | static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) | 1137 | static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_len) |
1158 | { | 1138 | { |
1159 | int i; | 1139 | int i; |
1160 | unsigned retval = 0; | 1140 | unsigned retval = 0; |
1161 | void *ee_addr = ioaddr + Cfg9346; | ||
1162 | int read_cmd = location | (EE_READ_CMD << addr_len); | 1141 | int read_cmd = location | (EE_READ_CMD << addr_len); |
1163 | 1142 | ||
1164 | writeb (EE_ENB & ~EE_CS, ee_addr); | 1143 | RTL_W8 (Cfg9346, EE_ENB & ~EE_CS); |
1165 | writeb (EE_ENB, ee_addr); | 1144 | RTL_W8 (Cfg9346, EE_ENB); |
1166 | eeprom_delay (); | 1145 | eeprom_delay (); |
1167 | 1146 | ||
1168 | /* Shift the read command bits out. */ | 1147 | /* Shift the read command bits out. */ |
1169 | for (i = 4 + addr_len; i >= 0; i--) { | 1148 | for (i = 4 + addr_len; i >= 0; i--) { |
1170 | int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; | 1149 | int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; |
1171 | writeb (EE_ENB | dataval, ee_addr); | 1150 | RTL_W8 (Cfg9346, EE_ENB | dataval); |
1172 | eeprom_delay (); | 1151 | eeprom_delay (); |
1173 | writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); | 1152 | RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK); |
1174 | eeprom_delay (); | 1153 | eeprom_delay (); |
1175 | } | 1154 | } |
1176 | writeb (EE_ENB, ee_addr); | 1155 | RTL_W8 (Cfg9346, EE_ENB); |
1177 | eeprom_delay (); | 1156 | eeprom_delay (); |
1178 | 1157 | ||
1179 | for (i = 16; i > 0; i--) { | 1158 | for (i = 16; i > 0; i--) { |
1180 | writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); | 1159 | RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK); |
1181 | eeprom_delay (); | 1160 | eeprom_delay (); |
1182 | retval = | 1161 | retval = |
1183 | (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 : | 1162 | (retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 : |
1184 | 0); | 1163 | 0); |
1185 | writeb (EE_ENB, ee_addr); | 1164 | RTL_W8 (Cfg9346, EE_ENB); |
1186 | eeprom_delay (); | 1165 | eeprom_delay (); |
1187 | } | 1166 | } |
1188 | 1167 | ||
1189 | /* Terminate the EEPROM access. */ | 1168 | /* Terminate the EEPROM access. */ |
1190 | writeb (~EE_CS, ee_addr); | 1169 | RTL_W8 (Cfg9346, ~EE_CS); |
1191 | eeprom_delay (); | 1170 | eeprom_delay (); |
1192 | 1171 | ||
1193 | return retval; | 1172 | return retval; |
@@ -1206,7 +1185,7 @@ static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) | |||
1206 | #define MDIO_WRITE0 (MDIO_DIR) | 1185 | #define MDIO_WRITE0 (MDIO_DIR) |
1207 | #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT) | 1186 | #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT) |
1208 | 1187 | ||
1209 | #define mdio_delay(mdio_addr) readb(mdio_addr) | 1188 | #define mdio_delay() RTL_R8(Config4) |
1210 | 1189 | ||
1211 | 1190 | ||
1212 | static char mii_2_8139_map[8] = { | 1191 | static char mii_2_8139_map[8] = { |
@@ -1223,15 +1202,15 @@ static char mii_2_8139_map[8] = { | |||
1223 | 1202 | ||
1224 | #ifdef CONFIG_8139TOO_8129 | 1203 | #ifdef CONFIG_8139TOO_8129 |
1225 | /* Syncronize the MII management interface by shifting 32 one bits out. */ | 1204 | /* Syncronize the MII management interface by shifting 32 one bits out. */ |
1226 | static void mdio_sync (void *mdio_addr) | 1205 | static void mdio_sync (void __iomem *ioaddr) |
1227 | { | 1206 | { |
1228 | int i; | 1207 | int i; |
1229 | 1208 | ||
1230 | for (i = 32; i >= 0; i--) { | 1209 | for (i = 32; i >= 0; i--) { |
1231 | writeb (MDIO_WRITE1, mdio_addr); | 1210 | RTL_W8 (Config4, MDIO_WRITE1); |
1232 | mdio_delay (mdio_addr); | 1211 | mdio_delay (); |
1233 | writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr); | 1212 | RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK); |
1234 | mdio_delay (mdio_addr); | 1213 | mdio_delay (); |
1235 | } | 1214 | } |
1236 | } | 1215 | } |
1237 | #endif | 1216 | #endif |
@@ -1241,35 +1220,36 @@ static int mdio_read (struct net_device *dev, int phy_id, int location) | |||
1241 | struct rtl8139_private *tp = netdev_priv(dev); | 1220 | struct rtl8139_private *tp = netdev_priv(dev); |
1242 | int retval = 0; | 1221 | int retval = 0; |
1243 | #ifdef CONFIG_8139TOO_8129 | 1222 | #ifdef CONFIG_8139TOO_8129 |
1244 | void *mdio_addr = tp->mmio_addr + Config4; | 1223 | void __iomem *ioaddr = tp->mmio_addr; |
1245 | int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; | 1224 | int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; |
1246 | int i; | 1225 | int i; |
1247 | #endif | 1226 | #endif |
1248 | 1227 | ||
1249 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ | 1228 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ |
1229 | void __iomem *ioaddr = tp->mmio_addr; | ||
1250 | return location < 8 && mii_2_8139_map[location] ? | 1230 | return location < 8 && mii_2_8139_map[location] ? |
1251 | readw (tp->mmio_addr + mii_2_8139_map[location]) : 0; | 1231 | RTL_R16 (mii_2_8139_map[location]) : 0; |
1252 | } | 1232 | } |
1253 | 1233 | ||
1254 | #ifdef CONFIG_8139TOO_8129 | 1234 | #ifdef CONFIG_8139TOO_8129 |
1255 | mdio_sync (mdio_addr); | 1235 | mdio_sync (ioaddr); |
1256 | /* Shift the read command bits out. */ | 1236 | /* Shift the read command bits out. */ |
1257 | for (i = 15; i >= 0; i--) { | 1237 | for (i = 15; i >= 0; i--) { |
1258 | int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0; | 1238 | int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0; |
1259 | 1239 | ||
1260 | writeb (MDIO_DIR | dataval, mdio_addr); | 1240 | RTL_W8 (Config4, MDIO_DIR | dataval); |
1261 | mdio_delay (mdio_addr); | 1241 | mdio_delay (); |
1262 | writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr); | 1242 | RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK); |
1263 | mdio_delay (mdio_addr); | 1243 | mdio_delay (); |
1264 | } | 1244 | } |
1265 | 1245 | ||
1266 | /* Read the two transition, 16 data, and wire-idle bits. */ | 1246 | /* Read the two transition, 16 data, and wire-idle bits. */ |
1267 | for (i = 19; i > 0; i--) { | 1247 | for (i = 19; i > 0; i--) { |
1268 | writeb (0, mdio_addr); | 1248 | RTL_W8 (Config4, 0); |
1269 | mdio_delay (mdio_addr); | 1249 | mdio_delay (); |
1270 | retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0); | 1250 | retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0); |
1271 | writeb (MDIO_CLK, mdio_addr); | 1251 | RTL_W8 (Config4, MDIO_CLK); |
1272 | mdio_delay (mdio_addr); | 1252 | mdio_delay (); |
1273 | } | 1253 | } |
1274 | #endif | 1254 | #endif |
1275 | 1255 | ||
@@ -1282,13 +1262,13 @@ static void mdio_write (struct net_device *dev, int phy_id, int location, | |||
1282 | { | 1262 | { |
1283 | struct rtl8139_private *tp = netdev_priv(dev); | 1263 | struct rtl8139_private *tp = netdev_priv(dev); |
1284 | #ifdef CONFIG_8139TOO_8129 | 1264 | #ifdef CONFIG_8139TOO_8129 |
1285 | void *mdio_addr = tp->mmio_addr + Config4; | 1265 | void __iomem *ioaddr = tp->mmio_addr; |
1286 | int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value; | 1266 | int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value; |
1287 | int i; | 1267 | int i; |
1288 | #endif | 1268 | #endif |
1289 | 1269 | ||
1290 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ | 1270 | if (phy_id > 31) { /* Really a 8139. Use internal registers. */ |
1291 | void *ioaddr = tp->mmio_addr; | 1271 | void __iomem *ioaddr = tp->mmio_addr; |
1292 | if (location == 0) { | 1272 | if (location == 0) { |
1293 | RTL_W8 (Cfg9346, Cfg9346_Unlock); | 1273 | RTL_W8 (Cfg9346, Cfg9346_Unlock); |
1294 | RTL_W16 (BasicModeCtrl, value); | 1274 | RTL_W16 (BasicModeCtrl, value); |
@@ -1299,23 +1279,23 @@ static void mdio_write (struct net_device *dev, int phy_id, int location, | |||
1299 | } | 1279 | } |
1300 | 1280 | ||
1301 | #ifdef CONFIG_8139TOO_8129 | 1281 | #ifdef CONFIG_8139TOO_8129 |
1302 | mdio_sync (mdio_addr); | 1282 | mdio_sync (ioaddr); |
1303 | 1283 | ||
1304 | /* Shift the command bits out. */ | 1284 | /* Shift the command bits out. */ |
1305 | for (i = 31; i >= 0; i--) { | 1285 | for (i = 31; i >= 0; i--) { |
1306 | int dataval = | 1286 | int dataval = |
1307 | (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; | 1287 | (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; |
1308 | writeb (dataval, mdio_addr); | 1288 | RTL_W8 (Config4, dataval); |
1309 | mdio_delay (mdio_addr); | 1289 | mdio_delay (); |
1310 | writeb (dataval | MDIO_CLK, mdio_addr); | 1290 | RTL_W8 (Config4, dataval | MDIO_CLK); |
1311 | mdio_delay (mdio_addr); | 1291 | mdio_delay (); |
1312 | } | 1292 | } |
1313 | /* Clear out extra bits. */ | 1293 | /* Clear out extra bits. */ |
1314 | for (i = 2; i > 0; i--) { | 1294 | for (i = 2; i > 0; i--) { |
1315 | writeb (0, mdio_addr); | 1295 | RTL_W8 (Config4, 0); |
1316 | mdio_delay (mdio_addr); | 1296 | mdio_delay (); |
1317 | writeb (MDIO_CLK, mdio_addr); | 1297 | RTL_W8 (Config4, MDIO_CLK); |
1318 | mdio_delay (mdio_addr); | 1298 | mdio_delay (); |
1319 | } | 1299 | } |
1320 | #endif | 1300 | #endif |
1321 | } | 1301 | } |
@@ -1325,7 +1305,7 @@ static int rtl8139_open (struct net_device *dev) | |||
1325 | { | 1305 | { |
1326 | struct rtl8139_private *tp = netdev_priv(dev); | 1306 | struct rtl8139_private *tp = netdev_priv(dev); |
1327 | int retval; | 1307 | int retval; |
1328 | void *ioaddr = tp->mmio_addr; | 1308 | void __iomem *ioaddr = tp->mmio_addr; |
1329 | 1309 | ||
1330 | retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); | 1310 | retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); |
1331 | if (retval) | 1311 | if (retval) |
@@ -1382,7 +1362,7 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media) | |||
1382 | static void rtl8139_hw_start (struct net_device *dev) | 1362 | static void rtl8139_hw_start (struct net_device *dev) |
1383 | { | 1363 | { |
1384 | struct rtl8139_private *tp = netdev_priv(dev); | 1364 | struct rtl8139_private *tp = netdev_priv(dev); |
1385 | void *ioaddr = tp->mmio_addr; | 1365 | void __iomem *ioaddr = tp->mmio_addr; |
1386 | u32 i; | 1366 | u32 i; |
1387 | u8 tmp; | 1367 | u8 tmp; |
1388 | 1368 | ||
@@ -1484,7 +1464,7 @@ static void rtl8139_tune_twister (struct net_device *dev, | |||
1484 | struct rtl8139_private *tp) | 1464 | struct rtl8139_private *tp) |
1485 | { | 1465 | { |
1486 | int linkcase; | 1466 | int linkcase; |
1487 | void *ioaddr = tp->mmio_addr; | 1467 | void __iomem *ioaddr = tp->mmio_addr; |
1488 | 1468 | ||
1489 | /* This is a complicated state machine to configure the "twister" for | 1469 | /* This is a complicated state machine to configure the "twister" for |
1490 | impedance/echos based on the cable length. | 1470 | impedance/echos based on the cable length. |
@@ -1568,7 +1548,7 @@ static void rtl8139_tune_twister (struct net_device *dev, | |||
1568 | 1548 | ||
1569 | static inline void rtl8139_thread_iter (struct net_device *dev, | 1549 | static inline void rtl8139_thread_iter (struct net_device *dev, |
1570 | struct rtl8139_private *tp, | 1550 | struct rtl8139_private *tp, |
1571 | void *ioaddr) | 1551 | void __iomem *ioaddr) |
1572 | { | 1552 | { |
1573 | int mii_lpa; | 1553 | int mii_lpa; |
1574 | 1554 | ||
@@ -1676,7 +1656,7 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | |||
1676 | static void rtl8139_tx_timeout (struct net_device *dev) | 1656 | static void rtl8139_tx_timeout (struct net_device *dev) |
1677 | { | 1657 | { |
1678 | struct rtl8139_private *tp = netdev_priv(dev); | 1658 | struct rtl8139_private *tp = netdev_priv(dev); |
1679 | void *ioaddr = tp->mmio_addr; | 1659 | void __iomem *ioaddr = tp->mmio_addr; |
1680 | int i; | 1660 | int i; |
1681 | u8 tmp8; | 1661 | u8 tmp8; |
1682 | unsigned long flags; | 1662 | unsigned long flags; |
@@ -1721,7 +1701,7 @@ static void rtl8139_tx_timeout (struct net_device *dev) | |||
1721 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | 1701 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) |
1722 | { | 1702 | { |
1723 | struct rtl8139_private *tp = netdev_priv(dev); | 1703 | struct rtl8139_private *tp = netdev_priv(dev); |
1724 | void *ioaddr = tp->mmio_addr; | 1704 | void __iomem *ioaddr = tp->mmio_addr; |
1725 | unsigned int entry; | 1705 | unsigned int entry; |
1726 | unsigned int len = skb->len; | 1706 | unsigned int len = skb->len; |
1727 | 1707 | ||
@@ -1763,7 +1743,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
1763 | 1743 | ||
1764 | static void rtl8139_tx_interrupt (struct net_device *dev, | 1744 | static void rtl8139_tx_interrupt (struct net_device *dev, |
1765 | struct rtl8139_private *tp, | 1745 | struct rtl8139_private *tp, |
1766 | void *ioaddr) | 1746 | void __iomem *ioaddr) |
1767 | { | 1747 | { |
1768 | unsigned long dirty_tx, tx_left; | 1748 | unsigned long dirty_tx, tx_left; |
1769 | 1749 | ||
@@ -1833,7 +1813,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev, | |||
1833 | 1813 | ||
1834 | /* TODO: clean this up! Rx reset need not be this intensive */ | 1814 | /* TODO: clean this up! Rx reset need not be this intensive */ |
1835 | static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, | 1815 | static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, |
1836 | struct rtl8139_private *tp, void *ioaddr) | 1816 | struct rtl8139_private *tp, void __iomem *ioaddr) |
1837 | { | 1817 | { |
1838 | u8 tmp8; | 1818 | u8 tmp8; |
1839 | #ifdef CONFIG_8139_OLD_RX_RESET | 1819 | #ifdef CONFIG_8139_OLD_RX_RESET |
@@ -1930,7 +1910,7 @@ static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring, | |||
1930 | 1910 | ||
1931 | static void rtl8139_isr_ack(struct rtl8139_private *tp) | 1911 | static void rtl8139_isr_ack(struct rtl8139_private *tp) |
1932 | { | 1912 | { |
1933 | void *ioaddr = tp->mmio_addr; | 1913 | void __iomem *ioaddr = tp->mmio_addr; |
1934 | u16 status; | 1914 | u16 status; |
1935 | 1915 | ||
1936 | status = RTL_R16 (IntrStatus) & RxAckBits; | 1916 | status = RTL_R16 (IntrStatus) & RxAckBits; |
@@ -1949,7 +1929,7 @@ static void rtl8139_isr_ack(struct rtl8139_private *tp) | |||
1949 | static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp, | 1929 | static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp, |
1950 | int budget) | 1930 | int budget) |
1951 | { | 1931 | { |
1952 | void *ioaddr = tp->mmio_addr; | 1932 | void __iomem *ioaddr = tp->mmio_addr; |
1953 | int received = 0; | 1933 | int received = 0; |
1954 | unsigned char *rx_ring = tp->rx_ring; | 1934 | unsigned char *rx_ring = tp->rx_ring; |
1955 | unsigned int cur_rx = tp->cur_rx; | 1935 | unsigned int cur_rx = tp->cur_rx; |
@@ -2087,7 +2067,7 @@ out: | |||
2087 | 2067 | ||
2088 | static void rtl8139_weird_interrupt (struct net_device *dev, | 2068 | static void rtl8139_weird_interrupt (struct net_device *dev, |
2089 | struct rtl8139_private *tp, | 2069 | struct rtl8139_private *tp, |
2090 | void *ioaddr, | 2070 | void __iomem *ioaddr, |
2091 | int status, int link_changed) | 2071 | int status, int link_changed) |
2092 | { | 2072 | { |
2093 | DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n", | 2073 | DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n", |
@@ -2127,7 +2107,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev, | |||
2127 | static int rtl8139_poll(struct net_device *dev, int *budget) | 2107 | static int rtl8139_poll(struct net_device *dev, int *budget) |
2128 | { | 2108 | { |
2129 | struct rtl8139_private *tp = netdev_priv(dev); | 2109 | struct rtl8139_private *tp = netdev_priv(dev); |
2130 | void *ioaddr = tp->mmio_addr; | 2110 | void __iomem *ioaddr = tp->mmio_addr; |
2131 | int orig_budget = min(*budget, dev->quota); | 2111 | int orig_budget = min(*budget, dev->quota); |
2132 | int done = 1; | 2112 | int done = 1; |
2133 | 2113 | ||
@@ -2165,7 +2145,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, | |||
2165 | { | 2145 | { |
2166 | struct net_device *dev = (struct net_device *) dev_instance; | 2146 | struct net_device *dev = (struct net_device *) dev_instance; |
2167 | struct rtl8139_private *tp = netdev_priv(dev); | 2147 | struct rtl8139_private *tp = netdev_priv(dev); |
2168 | void *ioaddr = tp->mmio_addr; | 2148 | void __iomem *ioaddr = tp->mmio_addr; |
2169 | u16 status, ackstat; | 2149 | u16 status, ackstat; |
2170 | int link_changed = 0; /* avoid bogus "uninit" warning */ | 2150 | int link_changed = 0; /* avoid bogus "uninit" warning */ |
2171 | int handled = 0; | 2151 | int handled = 0; |
@@ -2241,7 +2221,7 @@ static void rtl8139_poll_controller(struct net_device *dev) | |||
2241 | static int rtl8139_close (struct net_device *dev) | 2221 | static int rtl8139_close (struct net_device *dev) |
2242 | { | 2222 | { |
2243 | struct rtl8139_private *tp = netdev_priv(dev); | 2223 | struct rtl8139_private *tp = netdev_priv(dev); |
2244 | void *ioaddr = tp->mmio_addr; | 2224 | void __iomem *ioaddr = tp->mmio_addr; |
2245 | int ret = 0; | 2225 | int ret = 0; |
2246 | unsigned long flags; | 2226 | unsigned long flags; |
2247 | 2227 | ||
@@ -2304,7 +2284,7 @@ static int rtl8139_close (struct net_device *dev) | |||
2304 | static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2284 | static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2305 | { | 2285 | { |
2306 | struct rtl8139_private *np = netdev_priv(dev); | 2286 | struct rtl8139_private *np = netdev_priv(dev); |
2307 | void *ioaddr = np->mmio_addr; | 2287 | void __iomem *ioaddr = np->mmio_addr; |
2308 | 2288 | ||
2309 | spin_lock_irq(&np->lock); | 2289 | spin_lock_irq(&np->lock); |
2310 | if (rtl_chip_info[np->chipset].flags & HasLWake) { | 2290 | if (rtl_chip_info[np->chipset].flags & HasLWake) { |
@@ -2338,7 +2318,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2338 | static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2318 | static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2339 | { | 2319 | { |
2340 | struct rtl8139_private *np = netdev_priv(dev); | 2320 | struct rtl8139_private *np = netdev_priv(dev); |
2341 | void *ioaddr = np->mmio_addr; | 2321 | void __iomem *ioaddr = np->mmio_addr; |
2342 | u32 support; | 2322 | u32 support; |
2343 | u8 cfg3, cfg5; | 2323 | u8 cfg3, cfg5; |
2344 | 2324 | ||
@@ -2506,7 +2486,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2506 | static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) | 2486 | static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) |
2507 | { | 2487 | { |
2508 | struct rtl8139_private *tp = netdev_priv(dev); | 2488 | struct rtl8139_private *tp = netdev_priv(dev); |
2509 | void *ioaddr = tp->mmio_addr; | 2489 | void __iomem *ioaddr = tp->mmio_addr; |
2510 | unsigned long flags; | 2490 | unsigned long flags; |
2511 | 2491 | ||
2512 | if (netif_running(dev)) { | 2492 | if (netif_running(dev)) { |
@@ -2525,7 +2505,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) | |||
2525 | static void __set_rx_mode (struct net_device *dev) | 2505 | static void __set_rx_mode (struct net_device *dev) |
2526 | { | 2506 | { |
2527 | struct rtl8139_private *tp = netdev_priv(dev); | 2507 | struct rtl8139_private *tp = netdev_priv(dev); |
2528 | void *ioaddr = tp->mmio_addr; | 2508 | void __iomem *ioaddr = tp->mmio_addr; |
2529 | u32 mc_filter[2]; /* Multicast hash filter */ | 2509 | u32 mc_filter[2]; /* Multicast hash filter */ |
2530 | int i, rx_mode; | 2510 | int i, rx_mode; |
2531 | u32 tmp; | 2511 | u32 tmp; |
@@ -2586,7 +2566,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state) | |||
2586 | { | 2566 | { |
2587 | struct net_device *dev = pci_get_drvdata (pdev); | 2567 | struct net_device *dev = pci_get_drvdata (pdev); |
2588 | struct rtl8139_private *tp = netdev_priv(dev); | 2568 | struct rtl8139_private *tp = netdev_priv(dev); |
2589 | void *ioaddr = tp->mmio_addr; | 2569 | void __iomem *ioaddr = tp->mmio_addr; |
2590 | unsigned long flags; | 2570 | unsigned long flags; |
2591 | 2571 | ||
2592 | pci_save_state (pdev); | 2572 | pci_save_state (pdev); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f08e01b2fd19..cebee528f3c7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -824,6 +824,18 @@ config SMC9194 | |||
824 | <file:Documentation/networking/net-modules.txt>. The module | 824 | <file:Documentation/networking/net-modules.txt>. The module |
825 | will be called smc9194. | 825 | will be called smc9194. |
826 | 826 | ||
827 | config DM9000 | ||
828 | tristate "DM9000 support" | ||
829 | depends on ARM && NET_ETHERNET | ||
830 | select CRC32 | ||
831 | select MII | ||
832 | ---help--- | ||
833 | Support for DM9000 chipset. | ||
834 | |||
835 | To compile this driver as a module, choose M here and read | ||
836 | <file:Documentation/networking/net-modules.txt>. The module will be | ||
837 | called dm9000. | ||
838 | |||
827 | config NET_VENDOR_RACAL | 839 | config NET_VENDOR_RACAL |
828 | bool "Racal-Interlan (Micom) NI cards" | 840 | bool "Racal-Interlan (Micom) NI cards" |
829 | depends on NET_ETHERNET && ISA | 841 | depends on NET_ETHERNET && ISA |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 30c7567001fe..0d97be0c77d4 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -180,6 +180,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o | |||
180 | obj-$(CONFIG_IBMVETH) += ibmveth.o | 180 | obj-$(CONFIG_IBMVETH) += ibmveth.o |
181 | obj-$(CONFIG_S2IO) += s2io.o | 181 | obj-$(CONFIG_S2IO) += s2io.o |
182 | obj-$(CONFIG_SMC91X) += smc91x.o | 182 | obj-$(CONFIG_SMC91X) += smc91x.o |
183 | obj-$(CONFIG_DM9000) += dm9000.o | ||
183 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ | 184 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ |
184 | 185 | ||
185 | obj-$(CONFIG_ARM) += arm/ | 186 | obj-$(CONFIG_ARM) += arm/ |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c new file mode 100644 index 000000000000..f4ba0ffb8637 --- /dev/null +++ b/drivers/net/dm9000.c | |||
@@ -0,0 +1,1219 @@ | |||
1 | /* | ||
2 | * dm9000.c: Version 1.2 03/18/2003 | ||
3 | * | ||
4 | * A Davicom DM9000 ISA NIC fast Ethernet driver for Linux. | ||
5 | * Copyright (C) 1997 Sten Wang | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (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 | * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. | ||
18 | * | ||
19 | * V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match | ||
20 | * 06/22/2001 Support DM9801 progrmming | ||
21 | * E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000 | ||
22 | * E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200 | ||
23 | * R17 = (R17 & 0xfff0) | NF + 3 | ||
24 | * E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200 | ||
25 | * R17 = (R17 & 0xfff0) | NF | ||
26 | * | ||
27 | * v1.00 modify by simon 2001.9.5 | ||
28 | * change for kernel 2.4.x | ||
29 | * | ||
30 | * v1.1 11/09/2001 fix force mode bug | ||
31 | * | ||
32 | * v1.2 03/18/2003 Weilun Huang <weilun_huang@davicom.com.tw>: | ||
33 | * Fixed phy reset. | ||
34 | * Added tx/rx 32 bit mode. | ||
35 | * Cleaned up for kernel merge. | ||
36 | * | ||
37 | * 03/03/2004 Sascha Hauer <s.hauer@pengutronix.de> | ||
38 | * Port to 2.6 kernel | ||
39 | * | ||
40 | * 24-Sep-2004 Ben Dooks <ben@simtec.co.uk> | ||
41 | * Cleanup of code to remove ifdefs | ||
42 | * Allowed platform device data to influence access width | ||
43 | * Reformatting areas of code | ||
44 | * | ||
45 | * 17-Mar-2005 Sascha Hauer <s.hauer@pengutronix.de> | ||
46 | * * removed 2.4 style module parameters | ||
47 | * * removed removed unused stat counter and fixed | ||
48 | * net_device_stats | ||
49 | * * introduced tx_timeout function | ||
50 | * * reworked locking | ||
51 | */ | ||
52 | |||
53 | #include <linux/module.h> | ||
54 | #include <linux/ioport.h> | ||
55 | #include <linux/netdevice.h> | ||
56 | #include <linux/etherdevice.h> | ||
57 | #include <linux/init.h> | ||
58 | #include <linux/skbuff.h> | ||
59 | #include <linux/version.h> | ||
60 | #include <linux/spinlock.h> | ||
61 | #include <linux/crc32.h> | ||
62 | #include <linux/mii.h> | ||
63 | #include <linux/dm9000.h> | ||
64 | #include <linux/delay.h> | ||
65 | |||
66 | #include <asm/delay.h> | ||
67 | #include <asm/irq.h> | ||
68 | #include <asm/io.h> | ||
69 | |||
70 | #include "dm9000.h" | ||
71 | |||
72 | /* Board/System/Debug information/definition ---------------- */ | ||
73 | |||
74 | #define DM9000_PHY 0x40 /* PHY address 0x01 */ | ||
75 | |||
76 | #define TRUE 1 | ||
77 | #define FALSE 0 | ||
78 | |||
79 | #define CARDNAME "dm9000" | ||
80 | #define PFX CARDNAME ": " | ||
81 | |||
82 | #define DM9000_TIMER_WUT jiffies+(HZ*2) /* timer wakeup time : 2 second */ | ||
83 | |||
84 | #define DM9000_DEBUG 0 | ||
85 | |||
86 | #if DM9000_DEBUG > 2 | ||
87 | #define PRINTK3(args...) printk(CARDNAME ": " args) | ||
88 | #else | ||
89 | #define PRINTK3(args...) do { } while(0) | ||
90 | #endif | ||
91 | |||
92 | #if DM9000_DEBUG > 1 | ||
93 | #define PRINTK2(args...) printk(CARDNAME ": " args) | ||
94 | #else | ||
95 | #define PRINTK2(args...) do { } while(0) | ||
96 | #endif | ||
97 | |||
98 | #if DM9000_DEBUG > 0 | ||
99 | #define PRINTK1(args...) printk(CARDNAME ": " args) | ||
100 | #define PRINTK(args...) printk(CARDNAME ": " args) | ||
101 | #else | ||
102 | #define PRINTK1(args...) do { } while(0) | ||
103 | #define PRINTK(args...) printk(KERN_DEBUG args) | ||
104 | #endif | ||
105 | |||
106 | /* | ||
107 | * Transmit timeout, default 5 seconds. | ||
108 | */ | ||
109 | static int watchdog = 5000; | ||
110 | module_param(watchdog, int, 0400); | ||
111 | MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); | ||
112 | |||
113 | /* Structure/enum declaration ------------------------------- */ | ||
114 | typedef struct board_info { | ||
115 | |||
116 | void __iomem *io_addr; /* Register I/O base address */ | ||
117 | void __iomem *io_data; /* Data I/O address */ | ||
118 | u16 irq; /* IRQ */ | ||
119 | |||
120 | u16 tx_pkt_cnt; | ||
121 | u16 queue_pkt_len; | ||
122 | u16 queue_start_addr; | ||
123 | u16 dbug_cnt; | ||
124 | u8 io_mode; /* 0:word, 2:byte */ | ||
125 | u8 phy_addr; | ||
126 | |||
127 | void (*inblk)(void __iomem *port, void *data, int length); | ||
128 | void (*outblk)(void __iomem *port, void *data, int length); | ||
129 | void (*dumpblk)(void __iomem *port, int length); | ||
130 | |||
131 | struct resource *addr_res; /* resources found */ | ||
132 | struct resource *data_res; | ||
133 | struct resource *addr_req; /* resources requested */ | ||
134 | struct resource *data_req; | ||
135 | struct resource *irq_res; | ||
136 | |||
137 | struct timer_list timer; | ||
138 | struct net_device_stats stats; | ||
139 | unsigned char srom[128]; | ||
140 | spinlock_t lock; | ||
141 | |||
142 | struct mii_if_info mii; | ||
143 | u32 msg_enable; | ||
144 | } board_info_t; | ||
145 | |||
146 | /* function declaration ------------------------------------- */ | ||
147 | static int dm9000_probe(struct device *); | ||
148 | static int dm9000_open(struct net_device *); | ||
149 | static int dm9000_start_xmit(struct sk_buff *, struct net_device *); | ||
150 | static int dm9000_stop(struct net_device *); | ||
151 | static int dm9000_do_ioctl(struct net_device *, struct ifreq *, int); | ||
152 | |||
153 | |||
154 | static void dm9000_timer(unsigned long); | ||
155 | static void dm9000_init_dm9000(struct net_device *); | ||
156 | |||
157 | static struct net_device_stats *dm9000_get_stats(struct net_device *); | ||
158 | |||
159 | static irqreturn_t dm9000_interrupt(int, void *, struct pt_regs *); | ||
160 | |||
161 | static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg); | ||
162 | static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, | ||
163 | int value); | ||
164 | static u16 read_srom_word(board_info_t *, int); | ||
165 | static void dm9000_rx(struct net_device *); | ||
166 | static void dm9000_hash_table(struct net_device *); | ||
167 | |||
168 | //#define DM9000_PROGRAM_EEPROM | ||
169 | #ifdef DM9000_PROGRAM_EEPROM | ||
170 | static void program_eeprom(board_info_t * db); | ||
171 | #endif | ||
172 | /* DM9000 network board routine ---------------------------- */ | ||
173 | |||
174 | static void | ||
175 | dm9000_reset(board_info_t * db) | ||
176 | { | ||
177 | PRINTK1("dm9000x: resetting\n"); | ||
178 | /* RESET device */ | ||
179 | writeb(DM9000_NCR, db->io_addr); | ||
180 | udelay(200); | ||
181 | writeb(NCR_RST, db->io_data); | ||
182 | udelay(200); | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * Read a byte from I/O port | ||
187 | */ | ||
188 | static u8 | ||
189 | ior(board_info_t * db, int reg) | ||
190 | { | ||
191 | writeb(reg, db->io_addr); | ||
192 | return readb(db->io_data); | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Write a byte to I/O port | ||
197 | */ | ||
198 | |||
199 | static void | ||
200 | iow(board_info_t * db, int reg, int value) | ||
201 | { | ||
202 | writeb(reg, db->io_addr); | ||
203 | writeb(value, db->io_data); | ||
204 | } | ||
205 | |||
206 | /* routines for sending block to chip */ | ||
207 | |||
208 | static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count) | ||
209 | { | ||
210 | writesb(reg, data, count); | ||
211 | } | ||
212 | |||
213 | static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count) | ||
214 | { | ||
215 | writesw(reg, data, (count+1) >> 1); | ||
216 | } | ||
217 | |||
218 | static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count) | ||
219 | { | ||
220 | writesl(reg, data, (count+3) >> 2); | ||
221 | } | ||
222 | |||
223 | /* input block from chip to memory */ | ||
224 | |||
225 | static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count) | ||
226 | { | ||
227 | readsb(reg, data, count+1); | ||
228 | } | ||
229 | |||
230 | |||
231 | static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count) | ||
232 | { | ||
233 | readsw(reg, data, (count+1) >> 1); | ||
234 | } | ||
235 | |||
236 | static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count) | ||
237 | { | ||
238 | readsl(reg, data, (count+3) >> 2); | ||
239 | } | ||
240 | |||
241 | /* dump block from chip to null */ | ||
242 | |||
243 | static void dm9000_dumpblk_8bit(void __iomem *reg, int count) | ||
244 | { | ||
245 | int i; | ||
246 | int tmp; | ||
247 | |||
248 | for (i = 0; i < count; i++) | ||
249 | tmp = readb(reg); | ||
250 | } | ||
251 | |||
252 | static void dm9000_dumpblk_16bit(void __iomem *reg, int count) | ||
253 | { | ||
254 | int i; | ||
255 | int tmp; | ||
256 | |||
257 | count = (count + 1) >> 1; | ||
258 | |||
259 | for (i = 0; i < count; i++) | ||
260 | tmp = readw(reg); | ||
261 | } | ||
262 | |||
263 | static void dm9000_dumpblk_32bit(void __iomem *reg, int count) | ||
264 | { | ||
265 | int i; | ||
266 | int tmp; | ||
267 | |||
268 | count = (count + 3) >> 2; | ||
269 | |||
270 | for (i = 0; i < count; i++) | ||
271 | tmp = readl(reg); | ||
272 | } | ||
273 | |||
274 | /* dm9000_set_io | ||
275 | * | ||
276 | * select the specified set of io routines to use with the | ||
277 | * device | ||
278 | */ | ||
279 | |||
280 | static void dm9000_set_io(struct board_info *db, int byte_width) | ||
281 | { | ||
282 | /* use the size of the data resource to work out what IO | ||
283 | * routines we want to use | ||
284 | */ | ||
285 | |||
286 | switch (byte_width) { | ||
287 | case 1: | ||
288 | db->dumpblk = dm9000_dumpblk_8bit; | ||
289 | db->outblk = dm9000_outblk_8bit; | ||
290 | db->inblk = dm9000_inblk_8bit; | ||
291 | break; | ||
292 | |||
293 | case 2: | ||
294 | db->dumpblk = dm9000_dumpblk_16bit; | ||
295 | db->outblk = dm9000_outblk_16bit; | ||
296 | db->inblk = dm9000_inblk_16bit; | ||
297 | break; | ||
298 | |||
299 | case 3: | ||
300 | printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n"); | ||
301 | db->dumpblk = dm9000_dumpblk_16bit; | ||
302 | db->outblk = dm9000_outblk_16bit; | ||
303 | db->inblk = dm9000_inblk_16bit; | ||
304 | break; | ||
305 | |||
306 | case 4: | ||
307 | default: | ||
308 | db->dumpblk = dm9000_dumpblk_32bit; | ||
309 | db->outblk = dm9000_outblk_32bit; | ||
310 | db->inblk = dm9000_inblk_32bit; | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | |||
316 | /* Our watchdog timed out. Called by the networking layer */ | ||
317 | static void dm9000_timeout(struct net_device *dev) | ||
318 | { | ||
319 | board_info_t *db = (board_info_t *) dev->priv; | ||
320 | u8 reg_save; | ||
321 | unsigned long flags; | ||
322 | |||
323 | /* Save previous register address */ | ||
324 | reg_save = readb(db->io_addr); | ||
325 | spin_lock_irqsave(db->lock,flags); | ||
326 | |||
327 | netif_stop_queue(dev); | ||
328 | dm9000_reset(db); | ||
329 | dm9000_init_dm9000(dev); | ||
330 | /* We can accept TX packets again */ | ||
331 | dev->trans_start = jiffies; | ||
332 | netif_wake_queue(dev); | ||
333 | |||
334 | /* Restore previous register address */ | ||
335 | writeb(reg_save, db->io_addr); | ||
336 | spin_unlock_irqrestore(db->lock,flags); | ||
337 | } | ||
338 | |||
339 | |||
340 | /* dm9000_release_board | ||
341 | * | ||
342 | * release a board, and any mapped resources | ||
343 | */ | ||
344 | |||
345 | static void | ||
346 | dm9000_release_board(struct platform_device *pdev, struct board_info *db) | ||
347 | { | ||
348 | if (db->data_res == NULL) { | ||
349 | if (db->addr_res != NULL) | ||
350 | release_mem_region((unsigned long)db->io_addr, 4); | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* unmap our resources */ | ||
355 | |||
356 | iounmap(db->io_addr); | ||
357 | iounmap(db->io_data); | ||
358 | |||
359 | /* release the resources */ | ||
360 | |||
361 | if (db->data_req != NULL) { | ||
362 | release_resource(db->data_req); | ||
363 | kfree(db->data_req); | ||
364 | } | ||
365 | |||
366 | if (db->addr_res != NULL) { | ||
367 | release_resource(db->data_req); | ||
368 | kfree(db->addr_req); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | #define res_size(_r) (((_r)->end - (_r)->start) + 1) | ||
373 | |||
374 | /* | ||
375 | * Search DM9000 board, allocate space and register it | ||
376 | */ | ||
377 | static int | ||
378 | dm9000_probe(struct device *dev) | ||
379 | { | ||
380 | struct platform_device *pdev = to_platform_device(dev); | ||
381 | struct dm9000_plat_data *pdata = pdev->dev.platform_data; | ||
382 | struct board_info *db; /* Point a board information structure */ | ||
383 | struct net_device *ndev; | ||
384 | unsigned long base; | ||
385 | int ret = 0; | ||
386 | int iosize; | ||
387 | int i; | ||
388 | u32 id_val; | ||
389 | |||
390 | printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); | ||
391 | |||
392 | /* Init network device */ | ||
393 | ndev = alloc_etherdev(sizeof (struct board_info)); | ||
394 | if (!ndev) { | ||
395 | printk("%s: could not allocate device.\n", CARDNAME); | ||
396 | return -ENOMEM; | ||
397 | } | ||
398 | |||
399 | SET_MODULE_OWNER(ndev); | ||
400 | SET_NETDEV_DEV(ndev, dev); | ||
401 | |||
402 | PRINTK2("dm9000_probe()"); | ||
403 | |||
404 | /* setup board info structure */ | ||
405 | db = (struct board_info *) ndev->priv; | ||
406 | memset(db, 0, sizeof (*db)); | ||
407 | |||
408 | if (pdev->num_resources < 2) { | ||
409 | ret = -ENODEV; | ||
410 | goto out; | ||
411 | } | ||
412 | |||
413 | switch (pdev->num_resources) { | ||
414 | case 2: | ||
415 | base = pdev->resource[0].start; | ||
416 | |||
417 | if (!request_mem_region(base, 4, ndev->name)) { | ||
418 | ret = -EBUSY; | ||
419 | goto out; | ||
420 | } | ||
421 | |||
422 | ndev->base_addr = base; | ||
423 | ndev->irq = pdev->resource[1].start; | ||
424 | db->io_addr = (void *)base; | ||
425 | db->io_data = (void *)(base + 4); | ||
426 | |||
427 | break; | ||
428 | |||
429 | case 3: | ||
430 | db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
431 | db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
432 | db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
433 | |||
434 | if (db->addr_res == NULL || db->data_res == NULL) { | ||
435 | printk(KERN_ERR PFX "insufficient resources\n"); | ||
436 | ret = -ENOENT; | ||
437 | goto out; | ||
438 | } | ||
439 | |||
440 | i = res_size(db->addr_res); | ||
441 | db->addr_req = request_mem_region(db->addr_res->start, i, | ||
442 | pdev->name); | ||
443 | |||
444 | if (db->addr_req == NULL) { | ||
445 | printk(KERN_ERR PFX "cannot claim address reg area\n"); | ||
446 | ret = -EIO; | ||
447 | goto out; | ||
448 | } | ||
449 | |||
450 | db->io_addr = ioremap(db->addr_res->start, i); | ||
451 | |||
452 | if (db->io_addr == NULL) { | ||
453 | printk(KERN_ERR "failed to ioremap address reg\n"); | ||
454 | ret = -EINVAL; | ||
455 | goto out; | ||
456 | } | ||
457 | |||
458 | iosize = res_size(db->data_res); | ||
459 | db->data_req = request_mem_region(db->data_res->start, iosize, | ||
460 | pdev->name); | ||
461 | |||
462 | if (db->data_req == NULL) { | ||
463 | printk(KERN_ERR PFX "cannot claim data reg area\n"); | ||
464 | ret = -EIO; | ||
465 | goto out; | ||
466 | } | ||
467 | |||
468 | db->io_data = ioremap(db->data_res->start, iosize); | ||
469 | |||
470 | if (db->io_data == NULL) { | ||
471 | printk(KERN_ERR "failed to ioremap data reg\n"); | ||
472 | ret = -EINVAL; | ||
473 | goto out; | ||
474 | } | ||
475 | |||
476 | /* fill in parameters for net-dev structure */ | ||
477 | |||
478 | ndev->base_addr = (unsigned long)db->io_addr; | ||
479 | ndev->irq = db->irq_res->start; | ||
480 | |||
481 | /* ensure at least we have a default set of IO routines */ | ||
482 | dm9000_set_io(db, iosize); | ||
483 | |||
484 | } | ||
485 | |||
486 | /* check to see if anything is being over-ridden */ | ||
487 | if (pdata != NULL) { | ||
488 | /* check to see if the driver wants to over-ride the | ||
489 | * default IO width */ | ||
490 | |||
491 | if (pdata->flags & DM9000_PLATF_8BITONLY) | ||
492 | dm9000_set_io(db, 1); | ||
493 | |||
494 | if (pdata->flags & DM9000_PLATF_16BITONLY) | ||
495 | dm9000_set_io(db, 2); | ||
496 | |||
497 | if (pdata->flags & DM9000_PLATF_32BITONLY) | ||
498 | dm9000_set_io(db, 4); | ||
499 | |||
500 | /* check to see if there are any IO routine | ||
501 | * over-rides */ | ||
502 | |||
503 | if (pdata->inblk != NULL) | ||
504 | db->inblk = pdata->inblk; | ||
505 | |||
506 | if (pdata->outblk != NULL) | ||
507 | db->outblk = pdata->outblk; | ||
508 | |||
509 | if (pdata->dumpblk != NULL) | ||
510 | db->dumpblk = pdata->dumpblk; | ||
511 | } | ||
512 | |||
513 | dm9000_reset(db); | ||
514 | |||
515 | /* try two times, DM9000 sometimes gets the first read wrong */ | ||
516 | for (i = 0; i < 2; i++) { | ||
517 | id_val = ior(db, DM9000_VIDL); | ||
518 | id_val |= (u32)ior(db, DM9000_VIDH) << 8; | ||
519 | id_val |= (u32)ior(db, DM9000_PIDL) << 16; | ||
520 | id_val |= (u32)ior(db, DM9000_PIDH) << 24; | ||
521 | |||
522 | if (id_val == DM9000_ID) | ||
523 | break; | ||
524 | printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val); | ||
525 | } | ||
526 | |||
527 | if (id_val != DM9000_ID) { | ||
528 | printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val); | ||
529 | goto release; | ||
530 | } | ||
531 | |||
532 | /* from this point we assume that we have found a DM9000 */ | ||
533 | |||
534 | /* driver system function */ | ||
535 | ether_setup(ndev); | ||
536 | |||
537 | ndev->open = &dm9000_open; | ||
538 | ndev->hard_start_xmit = &dm9000_start_xmit; | ||
539 | ndev->tx_timeout = &dm9000_timeout; | ||
540 | ndev->watchdog_timeo = msecs_to_jiffies(watchdog); | ||
541 | ndev->stop = &dm9000_stop; | ||
542 | ndev->get_stats = &dm9000_get_stats; | ||
543 | ndev->set_multicast_list = &dm9000_hash_table; | ||
544 | ndev->do_ioctl = &dm9000_do_ioctl; | ||
545 | |||
546 | #ifdef DM9000_PROGRAM_EEPROM | ||
547 | program_eeprom(db); | ||
548 | #endif | ||
549 | db->msg_enable = NETIF_MSG_LINK; | ||
550 | db->mii.phy_id_mask = 0x1f; | ||
551 | db->mii.reg_num_mask = 0x1f; | ||
552 | db->mii.force_media = 0; | ||
553 | db->mii.full_duplex = 0; | ||
554 | db->mii.dev = ndev; | ||
555 | db->mii.mdio_read = dm9000_phy_read; | ||
556 | db->mii.mdio_write = dm9000_phy_write; | ||
557 | |||
558 | /* Read SROM content */ | ||
559 | for (i = 0; i < 64; i++) | ||
560 | ((u16 *) db->srom)[i] = read_srom_word(db, i); | ||
561 | |||
562 | /* Set Node Address */ | ||
563 | for (i = 0; i < 6; i++) | ||
564 | ndev->dev_addr[i] = db->srom[i]; | ||
565 | |||
566 | if (!is_valid_ether_addr(ndev->dev_addr)) | ||
567 | printk("%s: Invalid ethernet MAC address. Please " | ||
568 | "set using ifconfig\n", ndev->name); | ||
569 | |||
570 | dev_set_drvdata(dev, ndev); | ||
571 | ret = register_netdev(ndev); | ||
572 | |||
573 | if (ret == 0) { | ||
574 | printk("%s: dm9000 at %p,%p IRQ %d MAC: ", | ||
575 | ndev->name, db->io_addr, db->io_data, ndev->irq); | ||
576 | for (i = 0; i < 5; i++) | ||
577 | printk("%02x:", ndev->dev_addr[i]); | ||
578 | printk("%02x\n", ndev->dev_addr[5]); | ||
579 | } | ||
580 | return 0; | ||
581 | |||
582 | release: | ||
583 | out: | ||
584 | printk("%s: not found (%d).\n", CARDNAME, ret); | ||
585 | |||
586 | dm9000_release_board(pdev, db); | ||
587 | kfree(ndev); | ||
588 | |||
589 | return ret; | ||
590 | } | ||
591 | |||
592 | /* | ||
593 | * Open the interface. | ||
594 | * The interface is opened whenever "ifconfig" actives it. | ||
595 | */ | ||
596 | static int | ||
597 | dm9000_open(struct net_device *dev) | ||
598 | { | ||
599 | board_info_t *db = (board_info_t *) dev->priv; | ||
600 | |||
601 | PRINTK2("entering dm9000_open\n"); | ||
602 | |||
603 | if (request_irq(dev->irq, &dm9000_interrupt, SA_SHIRQ, dev->name, dev)) | ||
604 | return -EAGAIN; | ||
605 | |||
606 | /* Initialize DM9000 board */ | ||
607 | dm9000_reset(db); | ||
608 | dm9000_init_dm9000(dev); | ||
609 | |||
610 | /* Init driver variable */ | ||
611 | db->dbug_cnt = 0; | ||
612 | |||
613 | /* set and active a timer process */ | ||
614 | init_timer(&db->timer); | ||
615 | db->timer.expires = DM9000_TIMER_WUT * 2; | ||
616 | db->timer.data = (unsigned long) dev; | ||
617 | db->timer.function = &dm9000_timer; | ||
618 | add_timer(&db->timer); | ||
619 | |||
620 | mii_check_media(&db->mii, netif_msg_link(db), 1); | ||
621 | netif_start_queue(dev); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | /* | ||
627 | * Initilize dm9000 board | ||
628 | */ | ||
629 | static void | ||
630 | dm9000_init_dm9000(struct net_device *dev) | ||
631 | { | ||
632 | board_info_t *db = (board_info_t *) dev->priv; | ||
633 | |||
634 | PRINTK1("entering %s\n",__FUNCTION__); | ||
635 | |||
636 | /* I/O mode */ | ||
637 | db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ | ||
638 | |||
639 | /* GPIO0 on pre-activate PHY */ | ||
640 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ | ||
641 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ | ||
642 | iow(db, DM9000_GPR, 0); /* Enable PHY */ | ||
643 | |||
644 | /* Program operating register */ | ||
645 | iow(db, DM9000_TCR, 0); /* TX Polling clear */ | ||
646 | iow(db, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */ | ||
647 | iow(db, DM9000_FCR, 0xff); /* Flow Control */ | ||
648 | iow(db, DM9000_SMCR, 0); /* Special Mode */ | ||
649 | /* clear TX status */ | ||
650 | iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); | ||
651 | iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */ | ||
652 | |||
653 | /* Set address filter table */ | ||
654 | dm9000_hash_table(dev); | ||
655 | |||
656 | /* Activate DM9000 */ | ||
657 | iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); | ||
658 | /* Enable TX/RX interrupt mask */ | ||
659 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | ||
660 | |||
661 | /* Init Driver variable */ | ||
662 | db->tx_pkt_cnt = 0; | ||
663 | db->queue_pkt_len = 0; | ||
664 | dev->trans_start = 0; | ||
665 | spin_lock_init(&db->lock); | ||
666 | } | ||
667 | |||
668 | /* | ||
669 | * Hardware start transmission. | ||
670 | * Send a packet to media from the upper layer. | ||
671 | */ | ||
672 | static int | ||
673 | dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
674 | { | ||
675 | board_info_t *db = (board_info_t *) dev->priv; | ||
676 | |||
677 | PRINTK3("dm9000_start_xmit\n"); | ||
678 | |||
679 | if (db->tx_pkt_cnt > 1) | ||
680 | return 1; | ||
681 | |||
682 | netif_stop_queue(dev); | ||
683 | |||
684 | /* Disable all interrupts */ | ||
685 | iow(db, DM9000_IMR, IMR_PAR); | ||
686 | |||
687 | /* Move data to DM9000 TX RAM */ | ||
688 | writeb(DM9000_MWCMD, db->io_addr); | ||
689 | |||
690 | (db->outblk)(db->io_data, skb->data, skb->len); | ||
691 | db->stats.tx_bytes += skb->len; | ||
692 | |||
693 | /* TX control: First packet immediately send, second packet queue */ | ||
694 | if (db->tx_pkt_cnt == 0) { | ||
695 | |||
696 | /* First Packet */ | ||
697 | db->tx_pkt_cnt++; | ||
698 | |||
699 | /* Set TX length to DM9000 */ | ||
700 | iow(db, DM9000_TXPLL, skb->len & 0xff); | ||
701 | iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff); | ||
702 | |||
703 | /* Issue TX polling command */ | ||
704 | iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ | ||
705 | |||
706 | dev->trans_start = jiffies; /* save the time stamp */ | ||
707 | |||
708 | } else { | ||
709 | /* Second packet */ | ||
710 | db->tx_pkt_cnt++; | ||
711 | db->queue_pkt_len = skb->len; | ||
712 | } | ||
713 | |||
714 | /* free this SKB */ | ||
715 | dev_kfree_skb(skb); | ||
716 | |||
717 | /* Re-enable resource check */ | ||
718 | if (db->tx_pkt_cnt == 1) | ||
719 | netif_wake_queue(dev); | ||
720 | |||
721 | /* Re-enable interrupt */ | ||
722 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static void | ||
728 | dm9000_shutdown(struct net_device *dev) | ||
729 | { | ||
730 | board_info_t *db = (board_info_t *) dev->priv; | ||
731 | |||
732 | /* RESET device */ | ||
733 | dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ | ||
734 | iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */ | ||
735 | iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */ | ||
736 | iow(db, DM9000_RCR, 0x00); /* Disable RX */ | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * Stop the interface. | ||
741 | * The interface is stopped when it is brought. | ||
742 | */ | ||
743 | static int | ||
744 | dm9000_stop(struct net_device *ndev) | ||
745 | { | ||
746 | board_info_t *db = (board_info_t *) ndev->priv; | ||
747 | |||
748 | PRINTK1("entering %s\n",__FUNCTION__); | ||
749 | |||
750 | /* deleted timer */ | ||
751 | del_timer(&db->timer); | ||
752 | |||
753 | netif_stop_queue(ndev); | ||
754 | netif_carrier_off(ndev); | ||
755 | |||
756 | /* free interrupt */ | ||
757 | free_irq(ndev->irq, ndev); | ||
758 | |||
759 | dm9000_shutdown(ndev); | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | /* | ||
765 | * DM9000 interrupt handler | ||
766 | * receive the packet to upper layer, free the transmitted packet | ||
767 | */ | ||
768 | |||
769 | void | ||
770 | dm9000_tx_done(struct net_device *dev, board_info_t * db) | ||
771 | { | ||
772 | int tx_status = ior(db, DM9000_NSR); /* Got TX status */ | ||
773 | |||
774 | if (tx_status & (NSR_TX2END | NSR_TX1END)) { | ||
775 | /* One packet sent complete */ | ||
776 | db->tx_pkt_cnt--; | ||
777 | db->stats.tx_packets++; | ||
778 | |||
779 | /* Queue packet check & send */ | ||
780 | if (db->tx_pkt_cnt > 0) { | ||
781 | iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff); | ||
782 | iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff); | ||
783 | iow(db, DM9000_TCR, TCR_TXREQ); | ||
784 | dev->trans_start = jiffies; | ||
785 | } | ||
786 | netif_wake_queue(dev); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | static irqreturn_t | ||
791 | dm9000_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
792 | { | ||
793 | struct net_device *dev = dev_id; | ||
794 | board_info_t *db; | ||
795 | int int_status; | ||
796 | u8 reg_save; | ||
797 | |||
798 | PRINTK3("entering %s\n",__FUNCTION__); | ||
799 | |||
800 | if (!dev) { | ||
801 | PRINTK1("dm9000_interrupt() without DEVICE arg\n"); | ||
802 | return IRQ_HANDLED; | ||
803 | } | ||
804 | |||
805 | /* A real interrupt coming */ | ||
806 | db = (board_info_t *) dev->priv; | ||
807 | spin_lock(&db->lock); | ||
808 | |||
809 | /* Save previous register address */ | ||
810 | reg_save = readb(db->io_addr); | ||
811 | |||
812 | /* Disable all interrupts */ | ||
813 | iow(db, DM9000_IMR, IMR_PAR); | ||
814 | |||
815 | /* Got DM9000 interrupt status */ | ||
816 | int_status = ior(db, DM9000_ISR); /* Got ISR */ | ||
817 | iow(db, DM9000_ISR, int_status); /* Clear ISR status */ | ||
818 | |||
819 | /* Received the coming packet */ | ||
820 | if (int_status & ISR_PRS) | ||
821 | dm9000_rx(dev); | ||
822 | |||
823 | /* Trnasmit Interrupt check */ | ||
824 | if (int_status & ISR_PTS) | ||
825 | dm9000_tx_done(dev, db); | ||
826 | |||
827 | /* Re-enable interrupt mask */ | ||
828 | iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); | ||
829 | |||
830 | /* Restore previous register address */ | ||
831 | writeb(reg_save, db->io_addr); | ||
832 | |||
833 | spin_unlock(&db->lock); | ||
834 | |||
835 | return IRQ_HANDLED; | ||
836 | } | ||
837 | |||
838 | /* | ||
839 | * Get statistics from driver. | ||
840 | */ | ||
841 | static struct net_device_stats * | ||
842 | dm9000_get_stats(struct net_device *dev) | ||
843 | { | ||
844 | board_info_t *db = (board_info_t *) dev->priv; | ||
845 | return &db->stats; | ||
846 | } | ||
847 | |||
848 | /* | ||
849 | * Process the upper socket ioctl command | ||
850 | */ | ||
851 | static int | ||
852 | dm9000_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
853 | { | ||
854 | PRINTK1("entering %s\n",__FUNCTION__); | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * A periodic timer routine | ||
860 | * Dynamic media sense, allocated Rx buffer... | ||
861 | */ | ||
862 | static void | ||
863 | dm9000_timer(unsigned long data) | ||
864 | { | ||
865 | struct net_device *dev = (struct net_device *) data; | ||
866 | board_info_t *db = (board_info_t *) dev->priv; | ||
867 | u8 reg_save; | ||
868 | unsigned long flags; | ||
869 | |||
870 | PRINTK3("dm9000_timer()\n"); | ||
871 | |||
872 | spin_lock_irqsave(db->lock,flags); | ||
873 | /* Save previous register address */ | ||
874 | reg_save = readb(db->io_addr); | ||
875 | |||
876 | mii_check_media(&db->mii, netif_msg_link(db), 0); | ||
877 | |||
878 | /* Restore previous register address */ | ||
879 | writeb(reg_save, db->io_addr); | ||
880 | spin_unlock_irqrestore(db->lock,flags); | ||
881 | |||
882 | /* Set timer again */ | ||
883 | db->timer.expires = DM9000_TIMER_WUT; | ||
884 | add_timer(&db->timer); | ||
885 | } | ||
886 | |||
887 | struct dm9000_rxhdr { | ||
888 | u16 RxStatus; | ||
889 | u16 RxLen; | ||
890 | } __attribute__((__packed__)); | ||
891 | |||
892 | /* | ||
893 | * Received a packet and pass to upper layer | ||
894 | */ | ||
895 | static void | ||
896 | dm9000_rx(struct net_device *dev) | ||
897 | { | ||
898 | board_info_t *db = (board_info_t *) dev->priv; | ||
899 | struct dm9000_rxhdr rxhdr; | ||
900 | struct sk_buff *skb; | ||
901 | u8 rxbyte, *rdptr; | ||
902 | int GoodPacket; | ||
903 | int RxLen; | ||
904 | |||
905 | /* Check packet ready or not */ | ||
906 | do { | ||
907 | ior(db, DM9000_MRCMDX); /* Dummy read */ | ||
908 | |||
909 | /* Get most updated data */ | ||
910 | rxbyte = readb(db->io_data); | ||
911 | |||
912 | /* Status check: this byte must be 0 or 1 */ | ||
913 | if (rxbyte > DM9000_PKT_RDY) { | ||
914 | printk("status check failed: %d\n", rxbyte); | ||
915 | iow(db, DM9000_RCR, 0x00); /* Stop Device */ | ||
916 | iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */ | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | if (rxbyte != DM9000_PKT_RDY) | ||
921 | return; | ||
922 | |||
923 | /* A packet ready now & Get status/length */ | ||
924 | GoodPacket = TRUE; | ||
925 | writeb(DM9000_MRCMD, db->io_addr); | ||
926 | |||
927 | (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr)); | ||
928 | |||
929 | RxLen = rxhdr.RxLen; | ||
930 | |||
931 | /* Packet Status check */ | ||
932 | if (RxLen < 0x40) { | ||
933 | GoodPacket = FALSE; | ||
934 | PRINTK1("Bad Packet received (runt)\n"); | ||
935 | } | ||
936 | |||
937 | if (RxLen > DM9000_PKT_MAX) { | ||
938 | PRINTK1("RST: RX Len:%x\n", RxLen); | ||
939 | } | ||
940 | |||
941 | if (rxhdr.RxStatus & 0xbf00) { | ||
942 | GoodPacket = FALSE; | ||
943 | if (rxhdr.RxStatus & 0x100) { | ||
944 | PRINTK1("fifo error\n"); | ||
945 | db->stats.rx_fifo_errors++; | ||
946 | } | ||
947 | if (rxhdr.RxStatus & 0x200) { | ||
948 | PRINTK1("crc error\n"); | ||
949 | db->stats.rx_crc_errors++; | ||
950 | } | ||
951 | if (rxhdr.RxStatus & 0x8000) { | ||
952 | PRINTK1("length error\n"); | ||
953 | db->stats.rx_length_errors++; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | /* Move data from DM9000 */ | ||
958 | if (GoodPacket | ||
959 | && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) { | ||
960 | skb->dev = dev; | ||
961 | skb_reserve(skb, 2); | ||
962 | rdptr = (u8 *) skb_put(skb, RxLen - 4); | ||
963 | |||
964 | /* Read received packet from RX SRAM */ | ||
965 | |||
966 | (db->inblk)(db->io_data, rdptr, RxLen); | ||
967 | db->stats.rx_bytes += RxLen; | ||
968 | |||
969 | /* Pass to upper layer */ | ||
970 | skb->protocol = eth_type_trans(skb, dev); | ||
971 | netif_rx(skb); | ||
972 | db->stats.rx_packets++; | ||
973 | |||
974 | } else { | ||
975 | /* need to dump the packet's data */ | ||
976 | |||
977 | (db->dumpblk)(db->io_data, RxLen); | ||
978 | } | ||
979 | } while (rxbyte == DM9000_PKT_RDY); | ||
980 | } | ||
981 | |||
982 | /* | ||
983 | * Read a word data from SROM | ||
984 | */ | ||
985 | static u16 | ||
986 | read_srom_word(board_info_t * db, int offset) | ||
987 | { | ||
988 | iow(db, DM9000_EPAR, offset); | ||
989 | iow(db, DM9000_EPCR, EPCR_ERPRR); | ||
990 | mdelay(8); /* according to the datasheet 200us should be enough, | ||
991 | but it doesn't work */ | ||
992 | iow(db, DM9000_EPCR, 0x0); | ||
993 | return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) << 8)); | ||
994 | } | ||
995 | |||
996 | #ifdef DM9000_PROGRAM_EEPROM | ||
997 | /* | ||
998 | * Write a word data to SROM | ||
999 | */ | ||
1000 | static void | ||
1001 | write_srom_word(board_info_t * db, int offset, u16 val) | ||
1002 | { | ||
1003 | iow(db, DM9000_EPAR, offset); | ||
1004 | iow(db, DM9000_EPDRH, ((val >> 8) & 0xff)); | ||
1005 | iow(db, DM9000_EPDRL, (val & 0xff)); | ||
1006 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); | ||
1007 | mdelay(8); /* same shit */ | ||
1008 | iow(db, DM9000_EPCR, 0); | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Only for development: | ||
1013 | * Here we write static data to the eeprom in case | ||
1014 | * we don't have valid content on a new board | ||
1015 | */ | ||
1016 | static void | ||
1017 | program_eeprom(board_info_t * db) | ||
1018 | { | ||
1019 | u16 eeprom[] = { 0x0c00, 0x007f, 0x1300, /* MAC Address */ | ||
1020 | 0x0000, /* Autoload: accept nothing */ | ||
1021 | 0x0a46, 0x9000, /* Vendor / Product ID */ | ||
1022 | 0x0000, /* pin control */ | ||
1023 | 0x0000, | ||
1024 | }; /* Wake-up mode control */ | ||
1025 | int i; | ||
1026 | for (i = 0; i < 8; i++) | ||
1027 | write_srom_word(db, i, eeprom[i]); | ||
1028 | } | ||
1029 | #endif | ||
1030 | |||
1031 | |||
1032 | /* | ||
1033 | * Calculate the CRC valude of the Rx packet | ||
1034 | * flag = 1 : return the reverse CRC (for the received packet CRC) | ||
1035 | * 0 : return the normal CRC (for Hash Table index) | ||
1036 | */ | ||
1037 | |||
1038 | static unsigned long | ||
1039 | cal_CRC(unsigned char *Data, unsigned int Len, u8 flag) | ||
1040 | { | ||
1041 | |||
1042 | u32 crc = ether_crc_le(Len, Data); | ||
1043 | |||
1044 | if (flag) | ||
1045 | return ~crc; | ||
1046 | |||
1047 | return crc; | ||
1048 | } | ||
1049 | |||
1050 | /* | ||
1051 | * Set DM9000 multicast address | ||
1052 | */ | ||
1053 | static void | ||
1054 | dm9000_hash_table(struct net_device *dev) | ||
1055 | { | ||
1056 | board_info_t *db = (board_info_t *) dev->priv; | ||
1057 | struct dev_mc_list *mcptr = dev->mc_list; | ||
1058 | int mc_cnt = dev->mc_count; | ||
1059 | u32 hash_val; | ||
1060 | u16 i, oft, hash_table[4]; | ||
1061 | unsigned long flags; | ||
1062 | |||
1063 | PRINTK2("dm9000_hash_table()\n"); | ||
1064 | |||
1065 | spin_lock_irqsave(&db->lock,flags); | ||
1066 | |||
1067 | for (i = 0, oft = 0x10; i < 6; i++, oft++) | ||
1068 | iow(db, oft, dev->dev_addr[i]); | ||
1069 | |||
1070 | /* Clear Hash Table */ | ||
1071 | for (i = 0; i < 4; i++) | ||
1072 | hash_table[i] = 0x0; | ||
1073 | |||
1074 | /* broadcast address */ | ||
1075 | hash_table[3] = 0x8000; | ||
1076 | |||
1077 | /* the multicast address in Hash Table : 64 bits */ | ||
1078 | for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { | ||
1079 | hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; | ||
1080 | hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); | ||
1081 | } | ||
1082 | |||
1083 | /* Write the hash table to MAC MD table */ | ||
1084 | for (i = 0, oft = 0x16; i < 4; i++) { | ||
1085 | iow(db, oft++, hash_table[i] & 0xff); | ||
1086 | iow(db, oft++, (hash_table[i] >> 8) & 0xff); | ||
1087 | } | ||
1088 | |||
1089 | spin_unlock_irqrestore(&db->lock,flags); | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | /* | ||
1094 | * Read a word from phyxcer | ||
1095 | */ | ||
1096 | static int | ||
1097 | dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) | ||
1098 | { | ||
1099 | board_info_t *db = (board_info_t *) dev->priv; | ||
1100 | unsigned long flags; | ||
1101 | int ret; | ||
1102 | |||
1103 | spin_lock_irqsave(&db->lock,flags); | ||
1104 | /* Fill the phyxcer register into REG_0C */ | ||
1105 | iow(db, DM9000_EPAR, DM9000_PHY | reg); | ||
1106 | |||
1107 | iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */ | ||
1108 | udelay(100); /* Wait read complete */ | ||
1109 | iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ | ||
1110 | |||
1111 | /* The read data keeps on REG_0D & REG_0E */ | ||
1112 | ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); | ||
1113 | |||
1114 | spin_unlock_irqrestore(&db->lock,flags); | ||
1115 | |||
1116 | return ret; | ||
1117 | } | ||
1118 | |||
1119 | /* | ||
1120 | * Write a word to phyxcer | ||
1121 | */ | ||
1122 | static void | ||
1123 | dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) | ||
1124 | { | ||
1125 | board_info_t *db = (board_info_t *) dev->priv; | ||
1126 | unsigned long flags; | ||
1127 | |||
1128 | spin_lock_irqsave(&db->lock,flags); | ||
1129 | |||
1130 | /* Fill the phyxcer register into REG_0C */ | ||
1131 | iow(db, DM9000_EPAR, DM9000_PHY | reg); | ||
1132 | |||
1133 | /* Fill the written data into REG_0D & REG_0E */ | ||
1134 | iow(db, DM9000_EPDRL, (value & 0xff)); | ||
1135 | iow(db, DM9000_EPDRH, ((value >> 8) & 0xff)); | ||
1136 | |||
1137 | iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */ | ||
1138 | udelay(500); /* Wait write complete */ | ||
1139 | iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ | ||
1140 | |||
1141 | spin_unlock_irqrestore(&db->lock,flags); | ||
1142 | } | ||
1143 | |||
1144 | static int | ||
1145 | dm9000_drv_suspend(struct device *dev, u32 state, u32 level) | ||
1146 | { | ||
1147 | struct net_device *ndev = dev_get_drvdata(dev); | ||
1148 | |||
1149 | if (ndev && level == SUSPEND_DISABLE) { | ||
1150 | if (netif_running(ndev)) { | ||
1151 | netif_device_detach(ndev); | ||
1152 | dm9000_shutdown(ndev); | ||
1153 | } | ||
1154 | } | ||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | static int | ||
1159 | dm9000_drv_resume(struct device *dev, u32 level) | ||
1160 | { | ||
1161 | struct net_device *ndev = dev_get_drvdata(dev); | ||
1162 | board_info_t *db = (board_info_t *) ndev->priv; | ||
1163 | |||
1164 | if (ndev && level == RESUME_ENABLE) { | ||
1165 | |||
1166 | if (netif_running(ndev)) { | ||
1167 | dm9000_reset(db); | ||
1168 | dm9000_init_dm9000(ndev); | ||
1169 | |||
1170 | netif_device_attach(ndev); | ||
1171 | } | ||
1172 | } | ||
1173 | return 0; | ||
1174 | } | ||
1175 | |||
1176 | static int | ||
1177 | dm9000_drv_remove(struct device *dev) | ||
1178 | { | ||
1179 | struct platform_device *pdev = to_platform_device(dev); | ||
1180 | struct net_device *ndev = dev_get_drvdata(dev); | ||
1181 | |||
1182 | dev_set_drvdata(dev, NULL); | ||
1183 | |||
1184 | unregister_netdev(ndev); | ||
1185 | dm9000_release_board(pdev, (board_info_t *) ndev->priv); | ||
1186 | kfree(ndev); /* free device structure */ | ||
1187 | |||
1188 | PRINTK1("clean_module() exit\n"); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static struct device_driver dm9000_driver = { | ||
1194 | .name = "dm9000", | ||
1195 | .bus = &platform_bus_type, | ||
1196 | .probe = dm9000_probe, | ||
1197 | .remove = dm9000_drv_remove, | ||
1198 | .suspend = dm9000_drv_suspend, | ||
1199 | .resume = dm9000_drv_resume, | ||
1200 | }; | ||
1201 | |||
1202 | static int __init | ||
1203 | dm9000_init(void) | ||
1204 | { | ||
1205 | return driver_register(&dm9000_driver); /* search board and register */ | ||
1206 | } | ||
1207 | |||
1208 | static void __exit | ||
1209 | dm9000_cleanup(void) | ||
1210 | { | ||
1211 | driver_unregister(&dm9000_driver); | ||
1212 | } | ||
1213 | |||
1214 | module_init(dm9000_init); | ||
1215 | module_exit(dm9000_cleanup); | ||
1216 | |||
1217 | MODULE_AUTHOR("Sascha Hauer, Ben Dooks"); | ||
1218 | MODULE_DESCRIPTION("Davicom DM9000 network driver"); | ||
1219 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h new file mode 100644 index 000000000000..82cad360bafc --- /dev/null +++ b/drivers/net/dm9000.h | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * dm9000 Ethernet | ||
3 | */ | ||
4 | |||
5 | #ifndef _DM9000X_H_ | ||
6 | #define _DM9000X_H_ | ||
7 | |||
8 | #define DM9000_ID 0x90000A46 | ||
9 | |||
10 | /* although the registers are 16 bit, they are 32-bit aligned. | ||
11 | */ | ||
12 | |||
13 | #define DM9000_NCR 0x00 | ||
14 | #define DM9000_NSR 0x01 | ||
15 | #define DM9000_TCR 0x02 | ||
16 | #define DM9000_TSR1 0x03 | ||
17 | #define DM9000_TSR2 0x04 | ||
18 | #define DM9000_RCR 0x05 | ||
19 | #define DM9000_RSR 0x06 | ||
20 | #define DM9000_ROCR 0x07 | ||
21 | #define DM9000_BPTR 0x08 | ||
22 | #define DM9000_FCTR 0x09 | ||
23 | #define DM9000_FCR 0x0A | ||
24 | #define DM9000_EPCR 0x0B | ||
25 | #define DM9000_EPAR 0x0C | ||
26 | #define DM9000_EPDRL 0x0D | ||
27 | #define DM9000_EPDRH 0x0E | ||
28 | #define DM9000_WCR 0x0F | ||
29 | |||
30 | #define DM9000_PAR 0x10 | ||
31 | #define DM9000_MAR 0x16 | ||
32 | |||
33 | #define DM9000_GPCR 0x1e | ||
34 | #define DM9000_GPR 0x1f | ||
35 | #define DM9000_TRPAL 0x22 | ||
36 | #define DM9000_TRPAH 0x23 | ||
37 | #define DM9000_RWPAL 0x24 | ||
38 | #define DM9000_RWPAH 0x25 | ||
39 | |||
40 | #define DM9000_VIDL 0x28 | ||
41 | #define DM9000_VIDH 0x29 | ||
42 | #define DM9000_PIDL 0x2A | ||
43 | #define DM9000_PIDH 0x2B | ||
44 | |||
45 | #define DM9000_CHIPR 0x2C | ||
46 | #define DM9000_SMCR 0x2F | ||
47 | |||
48 | #define DM9000_MRCMDX 0xF0 | ||
49 | #define DM9000_MRCMD 0xF2 | ||
50 | #define DM9000_MRRL 0xF4 | ||
51 | #define DM9000_MRRH 0xF5 | ||
52 | #define DM9000_MWCMDX 0xF6 | ||
53 | #define DM9000_MWCMD 0xF8 | ||
54 | #define DM9000_MWRL 0xFA | ||
55 | #define DM9000_MWRH 0xFB | ||
56 | #define DM9000_TXPLL 0xFC | ||
57 | #define DM9000_TXPLH 0xFD | ||
58 | #define DM9000_ISR 0xFE | ||
59 | #define DM9000_IMR 0xFF | ||
60 | |||
61 | #define NCR_EXT_PHY (1<<7) | ||
62 | #define NCR_WAKEEN (1<<6) | ||
63 | #define NCR_FCOL (1<<4) | ||
64 | #define NCR_FDX (1<<3) | ||
65 | #define NCR_LBK (3<<1) | ||
66 | #define NCR_RST (1<<0) | ||
67 | |||
68 | #define NSR_SPEED (1<<7) | ||
69 | #define NSR_LINKST (1<<6) | ||
70 | #define NSR_WAKEST (1<<5) | ||
71 | #define NSR_TX2END (1<<3) | ||
72 | #define NSR_TX1END (1<<2) | ||
73 | #define NSR_RXOV (1<<1) | ||
74 | |||
75 | #define TCR_TJDIS (1<<6) | ||
76 | #define TCR_EXCECM (1<<5) | ||
77 | #define TCR_PAD_DIS2 (1<<4) | ||
78 | #define TCR_CRC_DIS2 (1<<3) | ||
79 | #define TCR_PAD_DIS1 (1<<2) | ||
80 | #define TCR_CRC_DIS1 (1<<1) | ||
81 | #define TCR_TXREQ (1<<0) | ||
82 | |||
83 | #define TSR_TJTO (1<<7) | ||
84 | #define TSR_LC (1<<6) | ||
85 | #define TSR_NC (1<<5) | ||
86 | #define TSR_LCOL (1<<4) | ||
87 | #define TSR_COL (1<<3) | ||
88 | #define TSR_EC (1<<2) | ||
89 | |||
90 | #define RCR_WTDIS (1<<6) | ||
91 | #define RCR_DIS_LONG (1<<5) | ||
92 | #define RCR_DIS_CRC (1<<4) | ||
93 | #define RCR_ALL (1<<3) | ||
94 | #define RCR_RUNT (1<<2) | ||
95 | #define RCR_PRMSC (1<<1) | ||
96 | #define RCR_RXEN (1<<0) | ||
97 | |||
98 | #define RSR_RF (1<<7) | ||
99 | #define RSR_MF (1<<6) | ||
100 | #define RSR_LCS (1<<5) | ||
101 | #define RSR_RWTO (1<<4) | ||
102 | #define RSR_PLE (1<<3) | ||
103 | #define RSR_AE (1<<2) | ||
104 | #define RSR_CE (1<<1) | ||
105 | #define RSR_FOE (1<<0) | ||
106 | |||
107 | #define FCTR_HWOT(ot) (( ot & 0xf ) << 4 ) | ||
108 | #define FCTR_LWOT(ot) ( ot & 0xf ) | ||
109 | |||
110 | #define IMR_PAR (1<<7) | ||
111 | #define IMR_ROOM (1<<3) | ||
112 | #define IMR_ROM (1<<2) | ||
113 | #define IMR_PTM (1<<1) | ||
114 | #define IMR_PRM (1<<0) | ||
115 | |||
116 | #define ISR_ROOS (1<<3) | ||
117 | #define ISR_ROS (1<<2) | ||
118 | #define ISR_PTS (1<<1) | ||
119 | #define ISR_PRS (1<<0) | ||
120 | #define ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS) | ||
121 | |||
122 | #define EPCR_REEP (1<<5) | ||
123 | #define EPCR_WEP (1<<4) | ||
124 | #define EPCR_EPOS (1<<3) | ||
125 | #define EPCR_ERPRR (1<<2) | ||
126 | #define EPCR_ERPRW (1<<1) | ||
127 | #define EPCR_ERRE (1<<0) | ||
128 | |||
129 | #define GPCR_GEP_CNTL (1<<0) | ||
130 | |||
131 | #define DM9000_PKT_RDY 0x01 /* Packet ready to receive */ | ||
132 | #define DM9000_PKT_MAX 1536 /* Received packet max size */ | ||
133 | |||
134 | #endif /* _DM9000X_H_ */ | ||
135 | |||
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 1c563f905a59..a7f15d9f13e5 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -374,29 +374,6 @@ static inline void do_kiss_params(struct baycom_state *bc, | |||
374 | } | 374 | } |
375 | 375 | ||
376 | /* --------------------------------------------------------------------- */ | 376 | /* --------------------------------------------------------------------- */ |
377 | /* | ||
378 | * high performance HDLC encoder | ||
379 | * yes, it's ugly, but generates pretty good code | ||
380 | */ | ||
381 | |||
382 | #define ENCODEITERA(j) \ | ||
383 | ({ \ | ||
384 | if (!(notbitstream & (0x1f0 << j))) \ | ||
385 | goto stuff##j; \ | ||
386 | encodeend##j: ; \ | ||
387 | }) | ||
388 | |||
389 | #define ENCODEITERB(j) \ | ||
390 | ({ \ | ||
391 | stuff##j: \ | ||
392 | bitstream &= ~(0x100 << j); \ | ||
393 | bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \ | ||
394 | ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \ | ||
395 | numbit++; \ | ||
396 | notbitstream = ~bitstream; \ | ||
397 | goto encodeend##j; \ | ||
398 | }) | ||
399 | |||
400 | 377 | ||
401 | static void encode_hdlc(struct baycom_state *bc) | 378 | static void encode_hdlc(struct baycom_state *bc) |
402 | { | 379 | { |
@@ -405,6 +382,7 @@ static void encode_hdlc(struct baycom_state *bc) | |||
405 | int pkt_len; | 382 | int pkt_len; |
406 | unsigned bitstream, notbitstream, bitbuf, numbit, crc; | 383 | unsigned bitstream, notbitstream, bitbuf, numbit, crc; |
407 | unsigned char crcarr[2]; | 384 | unsigned char crcarr[2]; |
385 | int j; | ||
408 | 386 | ||
409 | if (bc->hdlctx.bufcnt > 0) | 387 | if (bc->hdlctx.bufcnt > 0) |
410 | return; | 388 | return; |
@@ -429,24 +407,14 @@ static void encode_hdlc(struct baycom_state *bc) | |||
429 | pkt_len--; | 407 | pkt_len--; |
430 | if (!pkt_len) | 408 | if (!pkt_len) |
431 | bp = crcarr; | 409 | bp = crcarr; |
432 | ENCODEITERA(0); | 410 | for (j = 0; j < 8; j++) |
433 | ENCODEITERA(1); | 411 | if (unlikely(!(notbitstream & (0x1f0 << j)))) { |
434 | ENCODEITERA(2); | 412 | bitstream &= ~(0x100 << j); |
435 | ENCODEITERA(3); | 413 | bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | |
436 | ENCODEITERA(4); | 414 | ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); |
437 | ENCODEITERA(5); | 415 | numbit++; |
438 | ENCODEITERA(6); | 416 | notbitstream = ~bitstream; |
439 | ENCODEITERA(7); | 417 | } |
440 | goto enditer; | ||
441 | ENCODEITERB(0); | ||
442 | ENCODEITERB(1); | ||
443 | ENCODEITERB(2); | ||
444 | ENCODEITERB(3); | ||
445 | ENCODEITERB(4); | ||
446 | ENCODEITERB(5); | ||
447 | ENCODEITERB(6); | ||
448 | ENCODEITERB(7); | ||
449 | enditer: | ||
450 | numbit += 8; | 418 | numbit += 8; |
451 | while (numbit >= 8) { | 419 | while (numbit >= 8) { |
452 | *wp++ = bitbuf; | 420 | *wp++ = bitbuf; |
@@ -610,37 +578,6 @@ static void do_rxpacket(struct net_device *dev) | |||
610 | bc->stats.rx_packets++; | 578 | bc->stats.rx_packets++; |
611 | } | 579 | } |
612 | 580 | ||
613 | #define DECODEITERA(j) \ | ||
614 | ({ \ | ||
615 | if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \ | ||
616 | goto flgabrt##j; \ | ||
617 | if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \ | ||
618 | goto stuff##j; \ | ||
619 | enditer##j: ; \ | ||
620 | }) | ||
621 | |||
622 | #define DECODEITERB(j) \ | ||
623 | ({ \ | ||
624 | flgabrt##j: \ | ||
625 | if (!(notbitstream & (0x1fc << j))) { /* abort received */ \ | ||
626 | state = 0; \ | ||
627 | goto enditer##j; \ | ||
628 | } \ | ||
629 | if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \ | ||
630 | goto enditer##j; \ | ||
631 | if (state) \ | ||
632 | do_rxpacket(dev); \ | ||
633 | bc->hdlcrx.bufcnt = 0; \ | ||
634 | bc->hdlcrx.bufptr = bc->hdlcrx.buf; \ | ||
635 | state = 1; \ | ||
636 | numbits = 7-j; \ | ||
637 | goto enditer##j; \ | ||
638 | stuff##j: \ | ||
639 | numbits--; \ | ||
640 | bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \ | ||
641 | goto enditer##j; \ | ||
642 | }) | ||
643 | |||
644 | static int receive(struct net_device *dev, int cnt) | 581 | static int receive(struct net_device *dev, int cnt) |
645 | { | 582 | { |
646 | struct baycom_state *bc = netdev_priv(dev); | 583 | struct baycom_state *bc = netdev_priv(dev); |
@@ -649,6 +586,7 @@ static int receive(struct net_device *dev, int cnt) | |||
649 | unsigned char tmp[128]; | 586 | unsigned char tmp[128]; |
650 | unsigned char *cp; | 587 | unsigned char *cp; |
651 | int cnt2, ret = 0; | 588 | int cnt2, ret = 0; |
589 | int j; | ||
652 | 590 | ||
653 | numbits = bc->hdlcrx.numbits; | 591 | numbits = bc->hdlcrx.numbits; |
654 | state = bc->hdlcrx.state; | 592 | state = bc->hdlcrx.state; |
@@ -669,24 +607,32 @@ static int receive(struct net_device *dev, int cnt) | |||
669 | bitbuf |= (*cp) << 8; | 607 | bitbuf |= (*cp) << 8; |
670 | numbits += 8; | 608 | numbits += 8; |
671 | notbitstream = ~bitstream; | 609 | notbitstream = ~bitstream; |
672 | DECODEITERA(0); | 610 | for (j = 0; j < 8; j++) { |
673 | DECODEITERA(1); | 611 | |
674 | DECODEITERA(2); | 612 | /* flag or abort */ |
675 | DECODEITERA(3); | 613 | if (unlikely(!(notbitstream & (0x0fc << j)))) { |
676 | DECODEITERA(4); | 614 | |
677 | DECODEITERA(5); | 615 | /* abort received */ |
678 | DECODEITERA(6); | 616 | if (!(notbitstream & (0x1fc << j))) |
679 | DECODEITERA(7); | 617 | state = 0; |
680 | goto enddec; | 618 | |
681 | DECODEITERB(0); | 619 | /* not flag received */ |
682 | DECODEITERB(1); | 620 | else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) { |
683 | DECODEITERB(2); | 621 | if (state) |
684 | DECODEITERB(3); | 622 | do_rxpacket(dev); |
685 | DECODEITERB(4); | 623 | bc->hdlcrx.bufcnt = 0; |
686 | DECODEITERB(5); | 624 | bc->hdlcrx.bufptr = bc->hdlcrx.buf; |
687 | DECODEITERB(6); | 625 | state = 1; |
688 | DECODEITERB(7); | 626 | numbits = 7-j; |
689 | enddec: | 627 | } |
628 | } | ||
629 | |||
630 | /* stuffed bit */ | ||
631 | else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) { | ||
632 | numbits--; | ||
633 | bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); | ||
634 | } | ||
635 | } | ||
690 | while (state && numbits >= 8) { | 636 | while (state && numbits >= 8) { |
691 | if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { | 637 | if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { |
692 | state = 0; | 638 | state = 0; |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 3b377f6cd4a0..ad4b58af6b76 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1217,36 +1217,43 @@ ppp_push(struct ppp *ppp) | |||
1217 | */ | 1217 | */ |
1218 | static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | 1218 | static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) |
1219 | { | 1219 | { |
1220 | int nch, len, fragsize; | 1220 | int len, fragsize; |
1221 | int i, bits, hdrlen, mtu; | 1221 | int i, bits, hdrlen, mtu; |
1222 | int flen, fnb; | 1222 | int flen; |
1223 | int navail, nfree; | ||
1224 | int nbigger; | ||
1223 | unsigned char *p, *q; | 1225 | unsigned char *p, *q; |
1224 | struct list_head *list; | 1226 | struct list_head *list; |
1225 | struct channel *pch; | 1227 | struct channel *pch; |
1226 | struct sk_buff *frag; | 1228 | struct sk_buff *frag; |
1227 | struct ppp_channel *chan; | 1229 | struct ppp_channel *chan; |
1228 | 1230 | ||
1229 | nch = 0; | 1231 | nfree = 0; /* # channels which have no packet already queued */ |
1232 | navail = 0; /* total # of usable channels (not deregistered) */ | ||
1230 | hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; | 1233 | hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; |
1234 | i = 0; | ||
1231 | list = &ppp->channels; | 1235 | list = &ppp->channels; |
1232 | while ((list = list->next) != &ppp->channels) { | 1236 | while ((list = list->next) != &ppp->channels) { |
1233 | pch = list_entry(list, struct channel, clist); | 1237 | pch = list_entry(list, struct channel, clist); |
1234 | nch += pch->avail = (skb_queue_len(&pch->file.xq) == 0); | 1238 | navail += pch->avail = (pch->chan != NULL); |
1235 | /* | 1239 | if (pch->avail) { |
1236 | * If a channel hasn't had a fragment yet, it has to get | 1240 | if (skb_queue_len(&pch->file.xq) == 0 |
1237 | * one before we send any fragments on later channels. | 1241 | || !pch->had_frag) { |
1238 | * If it can't take a fragment now, don't give any | 1242 | pch->avail = 2; |
1239 | * to subsequent channels. | 1243 | ++nfree; |
1240 | */ | ||
1241 | if (!pch->had_frag && !pch->avail) { | ||
1242 | while ((list = list->next) != &ppp->channels) { | ||
1243 | pch = list_entry(list, struct channel, clist); | ||
1244 | pch->avail = 0; | ||
1245 | } | 1244 | } |
1246 | break; | 1245 | if (!pch->had_frag && i < ppp->nxchan) |
1246 | ppp->nxchan = i; | ||
1247 | } | 1247 | } |
1248 | ++i; | ||
1248 | } | 1249 | } |
1249 | if (nch == 0) | 1250 | |
1251 | /* | ||
1252 | * Don't start sending this packet unless at least half of | ||
1253 | * the channels are free. This gives much better TCP | ||
1254 | * performance if we have a lot of channels. | ||
1255 | */ | ||
1256 | if (nfree == 0 || nfree < navail / 2) | ||
1250 | return 0; /* can't take now, leave it in xmit_pending */ | 1257 | return 0; /* can't take now, leave it in xmit_pending */ |
1251 | 1258 | ||
1252 | /* Do protocol field compression (XXX this should be optional) */ | 1259 | /* Do protocol field compression (XXX this should be optional) */ |
@@ -1257,14 +1264,19 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1257 | --len; | 1264 | --len; |
1258 | } | 1265 | } |
1259 | 1266 | ||
1260 | /* decide on fragment size */ | 1267 | /* |
1268 | * Decide on fragment size. | ||
1269 | * We create a fragment for each free channel regardless of | ||
1270 | * how small they are (i.e. even 0 length) in order to minimize | ||
1271 | * the time that it will take to detect when a channel drops | ||
1272 | * a fragment. | ||
1273 | */ | ||
1261 | fragsize = len; | 1274 | fragsize = len; |
1262 | if (nch > 1) { | 1275 | if (nfree > 1) |
1263 | int maxch = ROUNDUP(len, MIN_FRAG_SIZE); | 1276 | fragsize = ROUNDUP(fragsize, nfree); |
1264 | if (nch > maxch) | 1277 | /* nbigger channels get fragsize bytes, the rest get fragsize-1, |
1265 | nch = maxch; | 1278 | except if nbigger==0, then they all get fragsize. */ |
1266 | fragsize = ROUNDUP(fragsize, nch); | 1279 | nbigger = len % nfree; |
1267 | } | ||
1268 | 1280 | ||
1269 | /* skip to the channel after the one we last used | 1281 | /* skip to the channel after the one we last used |
1270 | and start at that one */ | 1282 | and start at that one */ |
@@ -1278,7 +1290,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1278 | 1290 | ||
1279 | /* create a fragment for each channel */ | 1291 | /* create a fragment for each channel */ |
1280 | bits = B; | 1292 | bits = B; |
1281 | do { | 1293 | while (nfree > 0 || len > 0) { |
1282 | list = list->next; | 1294 | list = list->next; |
1283 | if (list == &ppp->channels) { | 1295 | if (list == &ppp->channels) { |
1284 | i = 0; | 1296 | i = 0; |
@@ -1289,61 +1301,92 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1289 | if (!pch->avail) | 1301 | if (!pch->avail) |
1290 | continue; | 1302 | continue; |
1291 | 1303 | ||
1304 | /* | ||
1305 | * Skip this channel if it has a fragment pending already and | ||
1306 | * we haven't given a fragment to all of the free channels. | ||
1307 | */ | ||
1308 | if (pch->avail == 1) { | ||
1309 | if (nfree > 0) | ||
1310 | continue; | ||
1311 | } else { | ||
1312 | --nfree; | ||
1313 | pch->avail = 1; | ||
1314 | } | ||
1315 | |||
1292 | /* check the channel's mtu and whether it is still attached. */ | 1316 | /* check the channel's mtu and whether it is still attached. */ |
1293 | spin_lock_bh(&pch->downl); | 1317 | spin_lock_bh(&pch->downl); |
1294 | if (pch->chan == 0 || (mtu = pch->chan->mtu) < hdrlen) { | 1318 | if (pch->chan == NULL) { |
1295 | /* can't use this channel */ | 1319 | /* can't use this channel, it's being deregistered */ |
1296 | spin_unlock_bh(&pch->downl); | 1320 | spin_unlock_bh(&pch->downl); |
1297 | pch->avail = 0; | 1321 | pch->avail = 0; |
1298 | if (--nch == 0) | 1322 | if (--navail == 0) |
1299 | break; | 1323 | break; |
1300 | continue; | 1324 | continue; |
1301 | } | 1325 | } |
1302 | 1326 | ||
1303 | /* | 1327 | /* |
1304 | * We have to create multiple fragments for this channel | 1328 | * Create a fragment for this channel of |
1305 | * if fragsize is greater than the channel's mtu. | 1329 | * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes. |
1330 | * If mtu+2-hdrlen < 4, that is a ridiculously small | ||
1331 | * MTU, so we use mtu = 2 + hdrlen. | ||
1306 | */ | 1332 | */ |
1307 | if (fragsize > len) | 1333 | if (fragsize > len) |
1308 | fragsize = len; | 1334 | fragsize = len; |
1309 | for (flen = fragsize; flen > 0; flen -= fnb) { | 1335 | flen = fragsize; |
1310 | fnb = flen; | 1336 | mtu = pch->chan->mtu + 2 - hdrlen; |
1311 | if (fnb > mtu + 2 - hdrlen) | 1337 | if (mtu < 4) |
1312 | fnb = mtu + 2 - hdrlen; | 1338 | mtu = 4; |
1313 | if (fnb >= len) | 1339 | if (flen > mtu) |
1314 | bits |= E; | 1340 | flen = mtu; |
1315 | frag = alloc_skb(fnb + hdrlen, GFP_ATOMIC); | 1341 | if (flen == len && nfree == 0) |
1316 | if (frag == 0) | 1342 | bits |= E; |
1317 | goto noskb; | 1343 | frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC); |
1318 | q = skb_put(frag, fnb + hdrlen); | 1344 | if (frag == 0) |
1319 | /* make the MP header */ | 1345 | goto noskb; |
1320 | q[0] = PPP_MP >> 8; | 1346 | q = skb_put(frag, flen + hdrlen); |
1321 | q[1] = PPP_MP; | 1347 | |
1322 | if (ppp->flags & SC_MP_XSHORTSEQ) { | 1348 | /* make the MP header */ |
1323 | q[2] = bits + ((ppp->nxseq >> 8) & 0xf); | 1349 | q[0] = PPP_MP >> 8; |
1324 | q[3] = ppp->nxseq; | 1350 | q[1] = PPP_MP; |
1325 | } else { | 1351 | if (ppp->flags & SC_MP_XSHORTSEQ) { |
1326 | q[2] = bits; | 1352 | q[2] = bits + ((ppp->nxseq >> 8) & 0xf); |
1327 | q[3] = ppp->nxseq >> 16; | 1353 | q[3] = ppp->nxseq; |
1328 | q[4] = ppp->nxseq >> 8; | 1354 | } else { |
1329 | q[5] = ppp->nxseq; | 1355 | q[2] = bits; |
1330 | } | 1356 | q[3] = ppp->nxseq >> 16; |
1331 | 1357 | q[4] = ppp->nxseq >> 8; | |
1332 | /* copy the data in */ | 1358 | q[5] = ppp->nxseq; |
1333 | memcpy(q + hdrlen, p, fnb); | ||
1334 | |||
1335 | /* try to send it down the channel */ | ||
1336 | chan = pch->chan; | ||
1337 | if (!chan->ops->start_xmit(chan, frag)) | ||
1338 | skb_queue_tail(&pch->file.xq, frag); | ||
1339 | pch->had_frag = 1; | ||
1340 | p += fnb; | ||
1341 | len -= fnb; | ||
1342 | ++ppp->nxseq; | ||
1343 | bits = 0; | ||
1344 | } | 1359 | } |
1360 | |||
1361 | /* | ||
1362 | * Copy the data in. | ||
1363 | * Unfortunately there is a bug in older versions of | ||
1364 | * the Linux PPP multilink reconstruction code where it | ||
1365 | * drops 0-length fragments. Therefore we make sure the | ||
1366 | * fragment has at least one byte of data. Any bytes | ||
1367 | * we add in this situation will end up as padding on the | ||
1368 | * end of the reconstructed packet. | ||
1369 | */ | ||
1370 | if (flen == 0) | ||
1371 | *skb_put(frag, 1) = 0; | ||
1372 | else | ||
1373 | memcpy(q + hdrlen, p, flen); | ||
1374 | |||
1375 | /* try to send it down the channel */ | ||
1376 | chan = pch->chan; | ||
1377 | if (skb_queue_len(&pch->file.xq) | ||
1378 | || !chan->ops->start_xmit(chan, frag)) | ||
1379 | skb_queue_tail(&pch->file.xq, frag); | ||
1380 | pch->had_frag = 1; | ||
1381 | p += flen; | ||
1382 | len -= flen; | ||
1383 | ++ppp->nxseq; | ||
1384 | bits = 0; | ||
1345 | spin_unlock_bh(&pch->downl); | 1385 | spin_unlock_bh(&pch->downl); |
1346 | } while (len > 0); | 1386 | |
1387 | if (--nbigger == 0 && fragsize > 0) | ||
1388 | --fragsize; | ||
1389 | } | ||
1347 | ppp->nxchan = i; | 1390 | ppp->nxchan = i; |
1348 | 1391 | ||
1349 | return 1; | 1392 | return 1; |
@@ -1422,7 +1465,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) | |||
1422 | kfree_skb(skb); | 1465 | kfree_skb(skb); |
1423 | return; | 1466 | return; |
1424 | } | 1467 | } |
1425 | 1468 | ||
1426 | proto = PPP_PROTO(skb); | 1469 | proto = PPP_PROTO(skb); |
1427 | read_lock_bh(&pch->upl); | 1470 | read_lock_bh(&pch->upl); |
1428 | if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) { | 1471 | if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) { |
@@ -1691,7 +1734,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1691 | struct list_head *l; | 1734 | struct list_head *l; |
1692 | int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; | 1735 | int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; |
1693 | 1736 | ||
1694 | if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0) | 1737 | if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0) |
1695 | goto err; /* no good, throw it away */ | 1738 | goto err; /* no good, throw it away */ |
1696 | 1739 | ||
1697 | /* Decode sequence number and begin/end bits */ | 1740 | /* Decode sequence number and begin/end bits */ |
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index e68cf5fb4920..20edeb345792 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c | |||
@@ -100,35 +100,8 @@ static int sh_debug; /* Debug flag */ | |||
100 | 100 | ||
101 | #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" | 101 | #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" |
102 | 102 | ||
103 | /* | ||
104 | * Locking | ||
105 | */ | ||
106 | |||
107 | static int shaper_lock(struct shaper *sh) | ||
108 | { | ||
109 | /* | ||
110 | * Lock in an interrupt must fail | ||
111 | */ | ||
112 | while (test_and_set_bit(0, &sh->locked)) | ||
113 | { | ||
114 | if (!in_interrupt()) | ||
115 | sleep_on(&sh->wait_queue); | ||
116 | else | ||
117 | return 0; | ||
118 | |||
119 | } | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | static void shaper_kick(struct shaper *sh); | 103 | static void shaper_kick(struct shaper *sh); |
124 | 104 | ||
125 | static void shaper_unlock(struct shaper *sh) | ||
126 | { | ||
127 | clear_bit(0, &sh->locked); | ||
128 | wake_up(&sh->wait_queue); | ||
129 | shaper_kick(sh); | ||
130 | } | ||
131 | |||
132 | /* | 105 | /* |
133 | * Compute clocks on a buffer | 106 | * Compute clocks on a buffer |
134 | */ | 107 | */ |
@@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) | |||
157 | * Throw a frame at a shaper. | 130 | * Throw a frame at a shaper. |
158 | */ | 131 | */ |
159 | 132 | ||
160 | static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) | 133 | |
134 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
161 | { | 135 | { |
136 | struct shaper *shaper = dev->priv; | ||
162 | struct sk_buff *ptr; | 137 | struct sk_buff *ptr; |
163 | 138 | ||
164 | /* | 139 | if (down_trylock(&shaper->sem)) |
165 | * Get ready to work on this shaper. Lock may fail if its | 140 | return -1; |
166 | * an interrupt and locked. | 141 | |
167 | */ | ||
168 | |||
169 | if(!shaper_lock(shaper)) | ||
170 | return -1; | ||
171 | ptr=shaper->sendq.prev; | 142 | ptr=shaper->sendq.prev; |
172 | 143 | ||
173 | /* | 144 | /* |
@@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) | |||
260 | dev_kfree_skb(ptr); | 231 | dev_kfree_skb(ptr); |
261 | shaper->stats.collisions++; | 232 | shaper->stats.collisions++; |
262 | } | 233 | } |
263 | shaper_unlock(shaper); | 234 | shaper_kick(shaper); |
235 | up(&shaper->sem); | ||
264 | return 0; | 236 | return 0; |
265 | } | 237 | } |
266 | 238 | ||
@@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) | |||
297 | 269 | ||
298 | static void shaper_timer(unsigned long data) | 270 | static void shaper_timer(unsigned long data) |
299 | { | 271 | { |
300 | struct shaper *sh=(struct shaper *)data; | 272 | struct shaper *shaper = (struct shaper *)data; |
301 | shaper_kick(sh); | 273 | |
274 | if (!down_trylock(&shaper->sem)) { | ||
275 | shaper_kick(shaper); | ||
276 | up(&shaper->sem); | ||
277 | } else | ||
278 | mod_timer(&shaper->timer, jiffies); | ||
302 | } | 279 | } |
303 | 280 | ||
304 | /* | 281 | /* |
@@ -311,19 +288,6 @@ static void shaper_kick(struct shaper *shaper) | |||
311 | struct sk_buff *skb; | 288 | struct sk_buff *skb; |
312 | 289 | ||
313 | /* | 290 | /* |
314 | * Shaper unlock will kick | ||
315 | */ | ||
316 | |||
317 | if (test_and_set_bit(0, &shaper->locked)) | ||
318 | { | ||
319 | if(sh_debug) | ||
320 | printk("Shaper locked.\n"); | ||
321 | mod_timer(&shaper->timer, jiffies); | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | |||
326 | /* | ||
327 | * Walk the list (may be empty) | 291 | * Walk the list (may be empty) |
328 | */ | 292 | */ |
329 | 293 | ||
@@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper) | |||
364 | 328 | ||
365 | if(skb!=NULL) | 329 | if(skb!=NULL) |
366 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); | 330 | mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); |
367 | |||
368 | clear_bit(0, &shaper->locked); | ||
369 | } | 331 | } |
370 | 332 | ||
371 | 333 | ||
@@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper) | |||
376 | static void shaper_flush(struct shaper *shaper) | 338 | static void shaper_flush(struct shaper *shaper) |
377 | { | 339 | { |
378 | struct sk_buff *skb; | 340 | struct sk_buff *skb; |
379 | if(!shaper_lock(shaper)) | 341 | |
380 | { | 342 | down(&shaper->sem); |
381 | printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); | ||
382 | return; | ||
383 | } | ||
384 | while((skb=skb_dequeue(&shaper->sendq))!=NULL) | 343 | while((skb=skb_dequeue(&shaper->sendq))!=NULL) |
385 | dev_kfree_skb(skb); | 344 | dev_kfree_skb(skb); |
386 | shaper_unlock(shaper); | 345 | shaper_kick(shaper); |
346 | up(&shaper->sem); | ||
387 | } | 347 | } |
388 | 348 | ||
389 | /* | 349 | /* |
@@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev) | |||
426 | * ARP and other resolutions and not before. | 386 | * ARP and other resolutions and not before. |
427 | */ | 387 | */ |
428 | 388 | ||
429 | |||
430 | static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
431 | { | ||
432 | struct shaper *sh=dev->priv; | ||
433 | return shaper_qframe(sh, skb); | ||
434 | } | ||
435 | |||
436 | static struct net_device_stats *shaper_get_stats(struct net_device *dev) | 389 | static struct net_device_stats *shaper_get_stats(struct net_device *dev) |
437 | { | 390 | { |
438 | struct shaper *sh=dev->priv; | 391 | struct shaper *sh=dev->priv; |
@@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev) | |||
623 | init_timer(&sh->timer); | 576 | init_timer(&sh->timer); |
624 | sh->timer.function=shaper_timer; | 577 | sh->timer.function=shaper_timer; |
625 | sh->timer.data=(unsigned long)sh; | 578 | sh->timer.data=(unsigned long)sh; |
626 | init_waitqueue_head(&sh->wait_queue); | ||
627 | } | 579 | } |
628 | 580 | ||
629 | /* | 581 | /* |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f10dd74988c4..fc9b5cd957aa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -133,6 +133,8 @@ | |||
133 | /* number of ETHTOOL_GSTATS u64's */ | 133 | /* number of ETHTOOL_GSTATS u64's */ |
134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) | 134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) |
135 | 135 | ||
136 | #define TG3_NUM_TEST 6 | ||
137 | |||
136 | static char version[] __devinitdata = | 138 | static char version[] __devinitdata = |
137 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 139 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
138 | 140 | ||
@@ -316,6 +318,17 @@ static struct { | |||
316 | { "nic_tx_threshold_hit" } | 318 | { "nic_tx_threshold_hit" } |
317 | }; | 319 | }; |
318 | 320 | ||
321 | static struct { | ||
322 | const char string[ETH_GSTRING_LEN]; | ||
323 | } ethtool_test_keys[TG3_NUM_TEST] = { | ||
324 | { "nvram test (online) " }, | ||
325 | { "link test (online) " }, | ||
326 | { "register test (offline)" }, | ||
327 | { "memory test (offline)" }, | ||
328 | { "loopback test (offline)" }, | ||
329 | { "interrupt test (offline)" }, | ||
330 | }; | ||
331 | |||
319 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 332 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
320 | { | 333 | { |
321 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 334 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { |
@@ -3070,7 +3083,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3070 | } | 3083 | } |
3071 | 3084 | ||
3072 | static int tg3_init_hw(struct tg3 *); | 3085 | static int tg3_init_hw(struct tg3 *); |
3073 | static int tg3_halt(struct tg3 *, int); | 3086 | static int tg3_halt(struct tg3 *, int, int); |
3074 | 3087 | ||
3075 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3088 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3076 | static void tg3_poll_controller(struct net_device *dev) | 3089 | static void tg3_poll_controller(struct net_device *dev) |
@@ -3094,7 +3107,7 @@ static void tg3_reset_task(void *_data) | |||
3094 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; | 3107 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; |
3095 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3108 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
3096 | 3109 | ||
3097 | tg3_halt(tp, 0); | 3110 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
3098 | tg3_init_hw(tp); | 3111 | tg3_init_hw(tp); |
3099 | 3112 | ||
3100 | tg3_netif_start(tp); | 3113 | tg3_netif_start(tp); |
@@ -3440,7 +3453,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
3440 | spin_lock_irq(&tp->lock); | 3453 | spin_lock_irq(&tp->lock); |
3441 | spin_lock(&tp->tx_lock); | 3454 | spin_lock(&tp->tx_lock); |
3442 | 3455 | ||
3443 | tg3_halt(tp, 1); | 3456 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
3444 | 3457 | ||
3445 | tg3_set_mtu(dev, tp, new_mtu); | 3458 | tg3_set_mtu(dev, tp, new_mtu); |
3446 | 3459 | ||
@@ -4131,19 +4144,19 @@ static void tg3_stop_fw(struct tg3 *tp) | |||
4131 | } | 4144 | } |
4132 | 4145 | ||
4133 | /* tp->lock is held. */ | 4146 | /* tp->lock is held. */ |
4134 | static int tg3_halt(struct tg3 *tp, int silent) | 4147 | static int tg3_halt(struct tg3 *tp, int kind, int silent) |
4135 | { | 4148 | { |
4136 | int err; | 4149 | int err; |
4137 | 4150 | ||
4138 | tg3_stop_fw(tp); | 4151 | tg3_stop_fw(tp); |
4139 | 4152 | ||
4140 | tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); | 4153 | tg3_write_sig_pre_reset(tp, kind); |
4141 | 4154 | ||
4142 | tg3_abort_hw(tp, silent); | 4155 | tg3_abort_hw(tp, silent); |
4143 | err = tg3_chip_reset(tp); | 4156 | err = tg3_chip_reset(tp); |
4144 | 4157 | ||
4145 | tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); | 4158 | tg3_write_sig_legacy(tp, kind); |
4146 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | 4159 | tg3_write_sig_post_reset(tp, kind); |
4147 | 4160 | ||
4148 | if (err) | 4161 | if (err) |
4149 | return err; | 4162 | return err; |
@@ -4357,7 +4370,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4357 | */ | 4370 | */ |
4358 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | 4371 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; |
4359 | 4372 | ||
4373 | /* It is possible that bootcode is still loading at this point. | ||
4374 | * Get the nvram lock first before halting the cpu. | ||
4375 | */ | ||
4376 | tg3_nvram_lock(tp); | ||
4360 | err = tg3_halt_cpu(tp, cpu_base); | 4377 | err = tg3_halt_cpu(tp, cpu_base); |
4378 | tg3_nvram_unlock(tp); | ||
4361 | if (err) | 4379 | if (err) |
4362 | goto out; | 4380 | goto out; |
4363 | 4381 | ||
@@ -5881,6 +5899,9 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
5881 | int err, i; | 5899 | int err, i; |
5882 | u32 int_mbox = 0; | 5900 | u32 int_mbox = 0; |
5883 | 5901 | ||
5902 | if (!netif_running(dev)) | ||
5903 | return -ENODEV; | ||
5904 | |||
5884 | tg3_disable_ints(tp); | 5905 | tg3_disable_ints(tp); |
5885 | 5906 | ||
5886 | free_irq(tp->pdev->irq, dev); | 5907 | free_irq(tp->pdev->irq, dev); |
@@ -5984,7 +6005,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
5984 | spin_lock_irq(&tp->lock); | 6005 | spin_lock_irq(&tp->lock); |
5985 | spin_lock(&tp->tx_lock); | 6006 | spin_lock(&tp->tx_lock); |
5986 | 6007 | ||
5987 | tg3_halt(tp, 1); | 6008 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
5988 | err = tg3_init_hw(tp); | 6009 | err = tg3_init_hw(tp); |
5989 | 6010 | ||
5990 | spin_unlock(&tp->tx_lock); | 6011 | spin_unlock(&tp->tx_lock); |
@@ -6060,7 +6081,7 @@ static int tg3_open(struct net_device *dev) | |||
6060 | 6081 | ||
6061 | err = tg3_init_hw(tp); | 6082 | err = tg3_init_hw(tp); |
6062 | if (err) { | 6083 | if (err) { |
6063 | tg3_halt(tp, 1); | 6084 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6064 | tg3_free_rings(tp); | 6085 | tg3_free_rings(tp); |
6065 | } else { | 6086 | } else { |
6066 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | 6087 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) |
@@ -6104,7 +6125,7 @@ static int tg3_open(struct net_device *dev) | |||
6104 | pci_disable_msi(tp->pdev); | 6125 | pci_disable_msi(tp->pdev); |
6105 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 6126 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
6106 | } | 6127 | } |
6107 | tg3_halt(tp, 1); | 6128 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6108 | tg3_free_rings(tp); | 6129 | tg3_free_rings(tp); |
6109 | tg3_free_consistent(tp); | 6130 | tg3_free_consistent(tp); |
6110 | 6131 | ||
@@ -6377,7 +6398,7 @@ static int tg3_close(struct net_device *dev) | |||
6377 | 6398 | ||
6378 | tg3_disable_ints(tp); | 6399 | tg3_disable_ints(tp); |
6379 | 6400 | ||
6380 | tg3_halt(tp, 1); | 6401 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6381 | tg3_free_rings(tp); | 6402 | tg3_free_rings(tp); |
6382 | tp->tg3_flags &= | 6403 | tp->tg3_flags &= |
6383 | ~(TG3_FLAG_INIT_COMPLETE | | 6404 | ~(TG3_FLAG_INIT_COMPLETE | |
@@ -7097,7 +7118,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7097 | tp->tx_pending = ering->tx_pending; | 7118 | tp->tx_pending = ering->tx_pending; |
7098 | 7119 | ||
7099 | if (netif_running(dev)) { | 7120 | if (netif_running(dev)) { |
7100 | tg3_halt(tp, 1); | 7121 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7101 | tg3_init_hw(tp); | 7122 | tg3_init_hw(tp); |
7102 | tg3_netif_start(tp); | 7123 | tg3_netif_start(tp); |
7103 | } | 7124 | } |
@@ -7140,7 +7161,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7140 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; | 7161 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; |
7141 | 7162 | ||
7142 | if (netif_running(dev)) { | 7163 | if (netif_running(dev)) { |
7143 | tg3_halt(tp, 1); | 7164 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7144 | tg3_init_hw(tp); | 7165 | tg3_init_hw(tp); |
7145 | tg3_netif_start(tp); | 7166 | tg3_netif_start(tp); |
7146 | } | 7167 | } |
@@ -7199,12 +7220,20 @@ static int tg3_get_stats_count (struct net_device *dev) | |||
7199 | return TG3_NUM_STATS; | 7220 | return TG3_NUM_STATS; |
7200 | } | 7221 | } |
7201 | 7222 | ||
7223 | static int tg3_get_test_count (struct net_device *dev) | ||
7224 | { | ||
7225 | return TG3_NUM_TEST; | ||
7226 | } | ||
7227 | |||
7202 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) | 7228 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) |
7203 | { | 7229 | { |
7204 | switch (stringset) { | 7230 | switch (stringset) { |
7205 | case ETH_SS_STATS: | 7231 | case ETH_SS_STATS: |
7206 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); | 7232 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); |
7207 | break; | 7233 | break; |
7234 | case ETH_SS_TEST: | ||
7235 | memcpy(buf, ðtool_test_keys, sizeof(ethtool_test_keys)); | ||
7236 | break; | ||
7208 | default: | 7237 | default: |
7209 | WARN_ON(1); /* we need a WARN() */ | 7238 | WARN_ON(1); /* we need a WARN() */ |
7210 | break; | 7239 | break; |
@@ -7218,6 +7247,516 @@ static void tg3_get_ethtool_stats (struct net_device *dev, | |||
7218 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); | 7247 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); |
7219 | } | 7248 | } |
7220 | 7249 | ||
7250 | #define NVRAM_TEST_SIZE 0x100 | ||
7251 | |||
7252 | static int tg3_test_nvram(struct tg3 *tp) | ||
7253 | { | ||
7254 | u32 *buf, csum; | ||
7255 | int i, j, err = 0; | ||
7256 | |||
7257 | buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); | ||
7258 | if (buf == NULL) | ||
7259 | return -ENOMEM; | ||
7260 | |||
7261 | for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { | ||
7262 | u32 val; | ||
7263 | |||
7264 | if ((err = tg3_nvram_read(tp, i, &val)) != 0) | ||
7265 | break; | ||
7266 | buf[j] = cpu_to_le32(val); | ||
7267 | } | ||
7268 | if (i < NVRAM_TEST_SIZE) | ||
7269 | goto out; | ||
7270 | |||
7271 | err = -EIO; | ||
7272 | if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) | ||
7273 | goto out; | ||
7274 | |||
7275 | /* Bootstrap checksum at offset 0x10 */ | ||
7276 | csum = calc_crc((unsigned char *) buf, 0x10); | ||
7277 | if(csum != cpu_to_le32(buf[0x10/4])) | ||
7278 | goto out; | ||
7279 | |||
7280 | /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ | ||
7281 | csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); | ||
7282 | if (csum != cpu_to_le32(buf[0xfc/4])) | ||
7283 | goto out; | ||
7284 | |||
7285 | err = 0; | ||
7286 | |||
7287 | out: | ||
7288 | kfree(buf); | ||
7289 | return err; | ||
7290 | } | ||
7291 | |||
7292 | #define TG3_SERDES_TIMEOUT_SEC 2 | ||
7293 | #define TG3_COPPER_TIMEOUT_SEC 6 | ||
7294 | |||
7295 | static int tg3_test_link(struct tg3 *tp) | ||
7296 | { | ||
7297 | int i, max; | ||
7298 | |||
7299 | if (!netif_running(tp->dev)) | ||
7300 | return -ENODEV; | ||
7301 | |||
7302 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | ||
7303 | max = TG3_SERDES_TIMEOUT_SEC; | ||
7304 | else | ||
7305 | max = TG3_COPPER_TIMEOUT_SEC; | ||
7306 | |||
7307 | for (i = 0; i < max; i++) { | ||
7308 | if (netif_carrier_ok(tp->dev)) | ||
7309 | return 0; | ||
7310 | |||
7311 | if (msleep_interruptible(1000)) | ||
7312 | break; | ||
7313 | } | ||
7314 | |||
7315 | return -EIO; | ||
7316 | } | ||
7317 | |||
7318 | /* Only test the commonly used registers */ | ||
7319 | static int tg3_test_registers(struct tg3 *tp) | ||
7320 | { | ||
7321 | int i, is_5705; | ||
7322 | u32 offset, read_mask, write_mask, val, save_val, read_val; | ||
7323 | static struct { | ||
7324 | u16 offset; | ||
7325 | u16 flags; | ||
7326 | #define TG3_FL_5705 0x1 | ||
7327 | #define TG3_FL_NOT_5705 0x2 | ||
7328 | #define TG3_FL_NOT_5788 0x4 | ||
7329 | u32 read_mask; | ||
7330 | u32 write_mask; | ||
7331 | } reg_tbl[] = { | ||
7332 | /* MAC Control Registers */ | ||
7333 | { MAC_MODE, TG3_FL_NOT_5705, | ||
7334 | 0x00000000, 0x00ef6f8c }, | ||
7335 | { MAC_MODE, TG3_FL_5705, | ||
7336 | 0x00000000, 0x01ef6b8c }, | ||
7337 | { MAC_STATUS, TG3_FL_NOT_5705, | ||
7338 | 0x03800107, 0x00000000 }, | ||
7339 | { MAC_STATUS, TG3_FL_5705, | ||
7340 | 0x03800100, 0x00000000 }, | ||
7341 | { MAC_ADDR_0_HIGH, 0x0000, | ||
7342 | 0x00000000, 0x0000ffff }, | ||
7343 | { MAC_ADDR_0_LOW, 0x0000, | ||
7344 | 0x00000000, 0xffffffff }, | ||
7345 | { MAC_RX_MTU_SIZE, 0x0000, | ||
7346 | 0x00000000, 0x0000ffff }, | ||
7347 | { MAC_TX_MODE, 0x0000, | ||
7348 | 0x00000000, 0x00000070 }, | ||
7349 | { MAC_TX_LENGTHS, 0x0000, | ||
7350 | 0x00000000, 0x00003fff }, | ||
7351 | { MAC_RX_MODE, TG3_FL_NOT_5705, | ||
7352 | 0x00000000, 0x000007fc }, | ||
7353 | { MAC_RX_MODE, TG3_FL_5705, | ||
7354 | 0x00000000, 0x000007dc }, | ||
7355 | { MAC_HASH_REG_0, 0x0000, | ||
7356 | 0x00000000, 0xffffffff }, | ||
7357 | { MAC_HASH_REG_1, 0x0000, | ||
7358 | 0x00000000, 0xffffffff }, | ||
7359 | { MAC_HASH_REG_2, 0x0000, | ||
7360 | 0x00000000, 0xffffffff }, | ||
7361 | { MAC_HASH_REG_3, 0x0000, | ||
7362 | 0x00000000, 0xffffffff }, | ||
7363 | |||
7364 | /* Receive Data and Receive BD Initiator Control Registers. */ | ||
7365 | { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, | ||
7366 | 0x00000000, 0xffffffff }, | ||
7367 | { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, | ||
7368 | 0x00000000, 0xffffffff }, | ||
7369 | { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, | ||
7370 | 0x00000000, 0x00000003 }, | ||
7371 | { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, | ||
7372 | 0x00000000, 0xffffffff }, | ||
7373 | { RCVDBDI_STD_BD+0, 0x0000, | ||
7374 | 0x00000000, 0xffffffff }, | ||
7375 | { RCVDBDI_STD_BD+4, 0x0000, | ||
7376 | 0x00000000, 0xffffffff }, | ||
7377 | { RCVDBDI_STD_BD+8, 0x0000, | ||
7378 | 0x00000000, 0xffff0002 }, | ||
7379 | { RCVDBDI_STD_BD+0xc, 0x0000, | ||
7380 | 0x00000000, 0xffffffff }, | ||
7381 | |||
7382 | /* Receive BD Initiator Control Registers. */ | ||
7383 | { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, | ||
7384 | 0x00000000, 0xffffffff }, | ||
7385 | { RCVBDI_STD_THRESH, TG3_FL_5705, | ||
7386 | 0x00000000, 0x000003ff }, | ||
7387 | { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, | ||
7388 | 0x00000000, 0xffffffff }, | ||
7389 | |||
7390 | /* Host Coalescing Control Registers. */ | ||
7391 | { HOSTCC_MODE, TG3_FL_NOT_5705, | ||
7392 | 0x00000000, 0x00000004 }, | ||
7393 | { HOSTCC_MODE, TG3_FL_5705, | ||
7394 | 0x00000000, 0x000000f6 }, | ||
7395 | { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, | ||
7396 | 0x00000000, 0xffffffff }, | ||
7397 | { HOSTCC_RXCOL_TICKS, TG3_FL_5705, | ||
7398 | 0x00000000, 0x000003ff }, | ||
7399 | { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, | ||
7400 | 0x00000000, 0xffffffff }, | ||
7401 | { HOSTCC_TXCOL_TICKS, TG3_FL_5705, | ||
7402 | 0x00000000, 0x000003ff }, | ||
7403 | { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7404 | 0x00000000, 0xffffffff }, | ||
7405 | { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7406 | 0x00000000, 0x000000ff }, | ||
7407 | { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7408 | 0x00000000, 0xffffffff }, | ||
7409 | { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7410 | 0x00000000, 0x000000ff }, | ||
7411 | { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7412 | 0x00000000, 0xffffffff }, | ||
7413 | { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7414 | 0x00000000, 0xffffffff }, | ||
7415 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7416 | 0x00000000, 0xffffffff }, | ||
7417 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7418 | 0x00000000, 0x000000ff }, | ||
7419 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7420 | 0x00000000, 0xffffffff }, | ||
7421 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7422 | 0x00000000, 0x000000ff }, | ||
7423 | { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, | ||
7424 | 0x00000000, 0xffffffff }, | ||
7425 | { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, | ||
7426 | 0x00000000, 0xffffffff }, | ||
7427 | { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, | ||
7428 | 0x00000000, 0xffffffff }, | ||
7429 | { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, | ||
7430 | 0x00000000, 0xffffffff }, | ||
7431 | { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, | ||
7432 | 0x00000000, 0xffffffff }, | ||
7433 | { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, | ||
7434 | 0xffffffff, 0x00000000 }, | ||
7435 | { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, | ||
7436 | 0xffffffff, 0x00000000 }, | ||
7437 | |||
7438 | /* Buffer Manager Control Registers. */ | ||
7439 | { BUFMGR_MB_POOL_ADDR, 0x0000, | ||
7440 | 0x00000000, 0x007fff80 }, | ||
7441 | { BUFMGR_MB_POOL_SIZE, 0x0000, | ||
7442 | 0x00000000, 0x007fffff }, | ||
7443 | { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, | ||
7444 | 0x00000000, 0x0000003f }, | ||
7445 | { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, | ||
7446 | 0x00000000, 0x000001ff }, | ||
7447 | { BUFMGR_MB_HIGH_WATER, 0x0000, | ||
7448 | 0x00000000, 0x000001ff }, | ||
7449 | { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, | ||
7450 | 0xffffffff, 0x00000000 }, | ||
7451 | { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, | ||
7452 | 0xffffffff, 0x00000000 }, | ||
7453 | |||
7454 | /* Mailbox Registers */ | ||
7455 | { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, | ||
7456 | 0x00000000, 0x000001ff }, | ||
7457 | { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, | ||
7458 | 0x00000000, 0x000001ff }, | ||
7459 | { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, | ||
7460 | 0x00000000, 0x000007ff }, | ||
7461 | { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, | ||
7462 | 0x00000000, 0x000001ff }, | ||
7463 | |||
7464 | { 0xffff, 0x0000, 0x00000000, 0x00000000 }, | ||
7465 | }; | ||
7466 | |||
7467 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7468 | is_5705 = 1; | ||
7469 | else | ||
7470 | is_5705 = 0; | ||
7471 | |||
7472 | for (i = 0; reg_tbl[i].offset != 0xffff; i++) { | ||
7473 | if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) | ||
7474 | continue; | ||
7475 | |||
7476 | if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) | ||
7477 | continue; | ||
7478 | |||
7479 | if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) && | ||
7480 | (reg_tbl[i].flags & TG3_FL_NOT_5788)) | ||
7481 | continue; | ||
7482 | |||
7483 | offset = (u32) reg_tbl[i].offset; | ||
7484 | read_mask = reg_tbl[i].read_mask; | ||
7485 | write_mask = reg_tbl[i].write_mask; | ||
7486 | |||
7487 | /* Save the original register content */ | ||
7488 | save_val = tr32(offset); | ||
7489 | |||
7490 | /* Determine the read-only value. */ | ||
7491 | read_val = save_val & read_mask; | ||
7492 | |||
7493 | /* Write zero to the register, then make sure the read-only bits | ||
7494 | * are not changed and the read/write bits are all zeros. | ||
7495 | */ | ||
7496 | tw32(offset, 0); | ||
7497 | |||
7498 | val = tr32(offset); | ||
7499 | |||
7500 | /* Test the read-only and read/write bits. */ | ||
7501 | if (((val & read_mask) != read_val) || (val & write_mask)) | ||
7502 | goto out; | ||
7503 | |||
7504 | /* Write ones to all the bits defined by RdMask and WrMask, then | ||
7505 | * make sure the read-only bits are not changed and the | ||
7506 | * read/write bits are all ones. | ||
7507 | */ | ||
7508 | tw32(offset, read_mask | write_mask); | ||
7509 | |||
7510 | val = tr32(offset); | ||
7511 | |||
7512 | /* Test the read-only bits. */ | ||
7513 | if ((val & read_mask) != read_val) | ||
7514 | goto out; | ||
7515 | |||
7516 | /* Test the read/write bits. */ | ||
7517 | if ((val & write_mask) != write_mask) | ||
7518 | goto out; | ||
7519 | |||
7520 | tw32(offset, save_val); | ||
7521 | } | ||
7522 | |||
7523 | return 0; | ||
7524 | |||
7525 | out: | ||
7526 | printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); | ||
7527 | tw32(offset, save_val); | ||
7528 | return -EIO; | ||
7529 | } | ||
7530 | |||
7531 | static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) | ||
7532 | { | ||
7533 | static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; | ||
7534 | int i; | ||
7535 | u32 j; | ||
7536 | |||
7537 | for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) { | ||
7538 | for (j = 0; j < len; j += 4) { | ||
7539 | u32 val; | ||
7540 | |||
7541 | tg3_write_mem(tp, offset + j, test_pattern[i]); | ||
7542 | tg3_read_mem(tp, offset + j, &val); | ||
7543 | if (val != test_pattern[i]) | ||
7544 | return -EIO; | ||
7545 | } | ||
7546 | } | ||
7547 | return 0; | ||
7548 | } | ||
7549 | |||
7550 | static int tg3_test_memory(struct tg3 *tp) | ||
7551 | { | ||
7552 | static struct mem_entry { | ||
7553 | u32 offset; | ||
7554 | u32 len; | ||
7555 | } mem_tbl_570x[] = { | ||
7556 | { 0x00000000, 0x01000}, | ||
7557 | { 0x00002000, 0x1c000}, | ||
7558 | { 0xffffffff, 0x00000} | ||
7559 | }, mem_tbl_5705[] = { | ||
7560 | { 0x00000100, 0x0000c}, | ||
7561 | { 0x00000200, 0x00008}, | ||
7562 | { 0x00000b50, 0x00400}, | ||
7563 | { 0x00004000, 0x00800}, | ||
7564 | { 0x00006000, 0x01000}, | ||
7565 | { 0x00008000, 0x02000}, | ||
7566 | { 0x00010000, 0x0e000}, | ||
7567 | { 0xffffffff, 0x00000} | ||
7568 | }; | ||
7569 | struct mem_entry *mem_tbl; | ||
7570 | int err = 0; | ||
7571 | int i; | ||
7572 | |||
7573 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7574 | mem_tbl = mem_tbl_5705; | ||
7575 | else | ||
7576 | mem_tbl = mem_tbl_570x; | ||
7577 | |||
7578 | for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { | ||
7579 | if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset, | ||
7580 | mem_tbl[i].len)) != 0) | ||
7581 | break; | ||
7582 | } | ||
7583 | |||
7584 | return err; | ||
7585 | } | ||
7586 | |||
7587 | static int tg3_test_loopback(struct tg3 *tp) | ||
7588 | { | ||
7589 | u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; | ||
7590 | u32 desc_idx; | ||
7591 | struct sk_buff *skb, *rx_skb; | ||
7592 | u8 *tx_data; | ||
7593 | dma_addr_t map; | ||
7594 | int num_pkts, tx_len, rx_len, i, err; | ||
7595 | struct tg3_rx_buffer_desc *desc; | ||
7596 | |||
7597 | if (!netif_running(tp->dev)) | ||
7598 | return -ENODEV; | ||
7599 | |||
7600 | err = -EIO; | ||
7601 | |||
7602 | tg3_abort_hw(tp, 1); | ||
7603 | |||
7604 | /* Clearing this flag to keep interrupts disabled */ | ||
7605 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | ||
7606 | tg3_reset_hw(tp); | ||
7607 | |||
7608 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | ||
7609 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | ||
7610 | MAC_MODE_PORT_MODE_GMII; | ||
7611 | tw32(MAC_MODE, mac_mode); | ||
7612 | |||
7613 | tx_len = 1514; | ||
7614 | skb = dev_alloc_skb(tx_len); | ||
7615 | tx_data = skb_put(skb, tx_len); | ||
7616 | memcpy(tx_data, tp->dev->dev_addr, 6); | ||
7617 | memset(tx_data + 6, 0x0, 8); | ||
7618 | |||
7619 | tw32(MAC_RX_MTU_SIZE, tx_len + 4); | ||
7620 | |||
7621 | for (i = 14; i < tx_len; i++) | ||
7622 | tx_data[i] = (u8) (i & 0xff); | ||
7623 | |||
7624 | map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE); | ||
7625 | |||
7626 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
7627 | HOSTCC_MODE_NOW); | ||
7628 | |||
7629 | udelay(10); | ||
7630 | |||
7631 | rx_start_idx = tp->hw_status->idx[0].rx_producer; | ||
7632 | |||
7633 | send_idx = 0; | ||
7634 | num_pkts = 0; | ||
7635 | |||
7636 | tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); | ||
7637 | |||
7638 | send_idx++; | ||
7639 | num_pkts++; | ||
7640 | |||
7641 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | ||
7642 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | ||
7643 | |||
7644 | udelay(10); | ||
7645 | |||
7646 | for (i = 0; i < 10; i++) { | ||
7647 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
7648 | HOSTCC_MODE_NOW); | ||
7649 | |||
7650 | udelay(10); | ||
7651 | |||
7652 | tx_idx = tp->hw_status->idx[0].tx_consumer; | ||
7653 | rx_idx = tp->hw_status->idx[0].rx_producer; | ||
7654 | if ((tx_idx == send_idx) && | ||
7655 | (rx_idx == (rx_start_idx + num_pkts))) | ||
7656 | break; | ||
7657 | } | ||
7658 | |||
7659 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); | ||
7660 | dev_kfree_skb(skb); | ||
7661 | |||
7662 | if (tx_idx != send_idx) | ||
7663 | goto out; | ||
7664 | |||
7665 | if (rx_idx != rx_start_idx + num_pkts) | ||
7666 | goto out; | ||
7667 | |||
7668 | desc = &tp->rx_rcb[rx_start_idx]; | ||
7669 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | ||
7670 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | ||
7671 | if (opaque_key != RXD_OPAQUE_RING_STD) | ||
7672 | goto out; | ||
7673 | |||
7674 | if ((desc->err_vlan & RXD_ERR_MASK) != 0 && | ||
7675 | (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) | ||
7676 | goto out; | ||
7677 | |||
7678 | rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; | ||
7679 | if (rx_len != tx_len) | ||
7680 | goto out; | ||
7681 | |||
7682 | rx_skb = tp->rx_std_buffers[desc_idx].skb; | ||
7683 | |||
7684 | map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping); | ||
7685 | pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE); | ||
7686 | |||
7687 | for (i = 14; i < tx_len; i++) { | ||
7688 | if (*(rx_skb->data + i) != (u8) (i & 0xff)) | ||
7689 | goto out; | ||
7690 | } | ||
7691 | err = 0; | ||
7692 | |||
7693 | /* tg3_free_rings will unmap and free the rx_skb */ | ||
7694 | out: | ||
7695 | return err; | ||
7696 | } | ||
7697 | |||
7698 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | ||
7699 | u64 *data) | ||
7700 | { | ||
7701 | struct tg3 *tp = netdev_priv(dev); | ||
7702 | |||
7703 | memset(data, 0, sizeof(u64) * TG3_NUM_TEST); | ||
7704 | |||
7705 | if (tg3_test_nvram(tp) != 0) { | ||
7706 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7707 | data[0] = 1; | ||
7708 | } | ||
7709 | if (tg3_test_link(tp) != 0) { | ||
7710 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7711 | data[1] = 1; | ||
7712 | } | ||
7713 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | ||
7714 | if (netif_running(dev)) | ||
7715 | tg3_netif_stop(tp); | ||
7716 | |||
7717 | spin_lock_irq(&tp->lock); | ||
7718 | spin_lock(&tp->tx_lock); | ||
7719 | |||
7720 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | ||
7721 | tg3_nvram_lock(tp); | ||
7722 | tg3_halt_cpu(tp, RX_CPU_BASE); | ||
7723 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | ||
7724 | tg3_halt_cpu(tp, TX_CPU_BASE); | ||
7725 | tg3_nvram_unlock(tp); | ||
7726 | |||
7727 | if (tg3_test_registers(tp) != 0) { | ||
7728 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7729 | data[2] = 1; | ||
7730 | } | ||
7731 | if (tg3_test_memory(tp) != 0) { | ||
7732 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7733 | data[3] = 1; | ||
7734 | } | ||
7735 | if (tg3_test_loopback(tp) != 0) { | ||
7736 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7737 | data[4] = 1; | ||
7738 | } | ||
7739 | |||
7740 | spin_unlock(&tp->tx_lock); | ||
7741 | spin_unlock_irq(&tp->lock); | ||
7742 | if (tg3_test_interrupt(tp) != 0) { | ||
7743 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7744 | data[5] = 1; | ||
7745 | } | ||
7746 | spin_lock_irq(&tp->lock); | ||
7747 | spin_lock(&tp->tx_lock); | ||
7748 | |||
7749 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
7750 | if (netif_running(dev)) { | ||
7751 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | ||
7752 | tg3_init_hw(tp); | ||
7753 | tg3_netif_start(tp); | ||
7754 | } | ||
7755 | spin_unlock(&tp->tx_lock); | ||
7756 | spin_unlock_irq(&tp->lock); | ||
7757 | } | ||
7758 | } | ||
7759 | |||
7221 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 7760 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
7222 | { | 7761 | { |
7223 | struct mii_ioctl_data *data = if_mii(ifr); | 7762 | struct mii_ioctl_data *data = if_mii(ifr); |
@@ -7331,6 +7870,8 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
7331 | .get_tso = ethtool_op_get_tso, | 7870 | .get_tso = ethtool_op_get_tso, |
7332 | .set_tso = tg3_set_tso, | 7871 | .set_tso = tg3_set_tso, |
7333 | #endif | 7872 | #endif |
7873 | .self_test_count = tg3_get_test_count, | ||
7874 | .self_test = tg3_self_test, | ||
7334 | .get_strings = tg3_get_strings, | 7875 | .get_strings = tg3_get_strings, |
7335 | .get_stats_count = tg3_get_stats_count, | 7876 | .get_stats_count = tg3_get_stats_count, |
7336 | .get_ethtool_stats = tg3_get_ethtool_stats, | 7877 | .get_ethtool_stats = tg3_get_ethtool_stats, |
@@ -9478,7 +10019,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
9478 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 10019 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
9479 | pci_save_state(tp->pdev); | 10020 | pci_save_state(tp->pdev); |
9480 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | 10021 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); |
9481 | tg3_halt(tp, 1); | 10022 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
9482 | } | 10023 | } |
9483 | 10024 | ||
9484 | err = tg3_test_dma(tp); | 10025 | err = tg3_test_dma(tp); |
@@ -9605,7 +10146,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
9605 | 10146 | ||
9606 | spin_lock_irq(&tp->lock); | 10147 | spin_lock_irq(&tp->lock); |
9607 | spin_lock(&tp->tx_lock); | 10148 | spin_lock(&tp->tx_lock); |
9608 | tg3_halt(tp, 1); | 10149 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
9609 | spin_unlock(&tp->tx_lock); | 10150 | spin_unlock(&tp->tx_lock); |
9610 | spin_unlock_irq(&tp->lock); | 10151 | spin_unlock_irq(&tp->lock); |
9611 | 10152 | ||
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 7f450b51a6cb..a5d6891c9d4c 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
3 | * Frame Relay support | 3 | * Frame Relay support |
4 | * | 4 | * |
5 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of version 2 of the GNU General Public License | 8 | * under the terms of version 2 of the GNU General Public License |
@@ -27,6 +27,10 @@ | |||
27 | active = open and "link reliable" | 27 | active = open and "link reliable" |
28 | exist = new = not used | 28 | exist = new = not used |
29 | 29 | ||
30 | CCITT LMI: ITU-T Q.933 Annex A | ||
31 | ANSI LMI: ANSI T1.617 Annex D | ||
32 | CISCO LMI: the original, aka "Gang of Four" LMI | ||
33 | |||
30 | */ | 34 | */ |
31 | 35 | ||
32 | #include <linux/module.h> | 36 | #include <linux/module.h> |
@@ -49,45 +53,41 @@ | |||
49 | #undef DEBUG_ECN | 53 | #undef DEBUG_ECN |
50 | #undef DEBUG_LINK | 54 | #undef DEBUG_LINK |
51 | 55 | ||
52 | #define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */ | 56 | #define FR_UI 0x03 |
53 | 57 | #define FR_PAD 0x00 | |
54 | #define PVC_STATE_NEW 0x01 | 58 | |
55 | #define PVC_STATE_ACTIVE 0x02 | 59 | #define NLPID_IP 0xCC |
56 | #define PVC_STATE_FECN 0x08 /* FECN condition */ | 60 | #define NLPID_IPV6 0x8E |
57 | #define PVC_STATE_BECN 0x10 /* BECN condition */ | 61 | #define NLPID_SNAP 0x80 |
58 | 62 | #define NLPID_PAD 0x00 | |
59 | 63 | #define NLPID_CCITT_ANSI_LMI 0x08 | |
60 | #define FR_UI 0x03 | 64 | #define NLPID_CISCO_LMI 0x09 |
61 | #define FR_PAD 0x00 | 65 | |
62 | 66 | ||
63 | #define NLPID_IP 0xCC | 67 | #define LMI_CCITT_ANSI_DLCI 0 /* LMI DLCI */ |
64 | #define NLPID_IPV6 0x8E | 68 | #define LMI_CISCO_DLCI 1023 |
65 | #define NLPID_SNAP 0x80 | 69 | |
66 | #define NLPID_PAD 0x00 | 70 | #define LMI_CALLREF 0x00 /* Call Reference */ |
67 | #define NLPID_Q933 0x08 | 71 | #define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI locking shift */ |
68 | 72 | #define LMI_ANSI_CISCO_REPTYPE 0x01 /* report type */ | |
69 | 73 | #define LMI_CCITT_REPTYPE 0x51 | |
70 | #define LMI_DLCI 0 /* LMI DLCI */ | 74 | #define LMI_ANSI_CISCO_ALIVE 0x03 /* keep alive */ |
71 | #define LMI_PROTO 0x08 | 75 | #define LMI_CCITT_ALIVE 0x53 |
72 | #define LMI_CALLREF 0x00 /* Call Reference */ | 76 | #define LMI_ANSI_CISCO_PVCSTAT 0x07 /* PVC status */ |
73 | #define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI lockshift */ | 77 | #define LMI_CCITT_PVCSTAT 0x57 |
74 | #define LMI_REPTYPE 1 /* report type */ | 78 | |
75 | #define LMI_CCITT_REPTYPE 0x51 | 79 | #define LMI_FULLREP 0x00 /* full report */ |
76 | #define LMI_ALIVE 3 /* keep alive */ | 80 | #define LMI_INTEGRITY 0x01 /* link integrity report */ |
77 | #define LMI_CCITT_ALIVE 0x53 | 81 | #define LMI_SINGLE 0x02 /* single PVC report */ |
78 | #define LMI_PVCSTAT 7 /* pvc status */ | 82 | |
79 | #define LMI_CCITT_PVCSTAT 0x57 | ||
80 | #define LMI_FULLREP 0 /* full report */ | ||
81 | #define LMI_INTEGRITY 1 /* link integrity report */ | ||
82 | #define LMI_SINGLE 2 /* single pvc report */ | ||
83 | #define LMI_STATUS_ENQUIRY 0x75 | 83 | #define LMI_STATUS_ENQUIRY 0x75 |
84 | #define LMI_STATUS 0x7D /* reply */ | 84 | #define LMI_STATUS 0x7D /* reply */ |
85 | 85 | ||
86 | #define LMI_REPT_LEN 1 /* report type element length */ | 86 | #define LMI_REPT_LEN 1 /* report type element length */ |
87 | #define LMI_INTEG_LEN 2 /* link integrity element length */ | 87 | #define LMI_INTEG_LEN 2 /* link integrity element length */ |
88 | 88 | ||
89 | #define LMI_LENGTH 13 /* standard LMI frame length */ | 89 | #define LMI_CCITT_CISCO_LENGTH 13 /* LMI frame lengths */ |
90 | #define LMI_ANSI_LENGTH 14 | 90 | #define LMI_ANSI_LENGTH 14 |
91 | 91 | ||
92 | 92 | ||
93 | typedef struct { | 93 | typedef struct { |
@@ -223,51 +223,34 @@ static inline struct net_device** get_dev_p(pvc_device *pvc, int type) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | 225 | ||
226 | static inline u16 status_to_dlci(u8 *status, int *active, int *new) | ||
227 | { | ||
228 | *new = (status[2] & 0x08) ? 1 : 0; | ||
229 | *active = (status[2] & 0x02) ? 1 : 0; | ||
230 | |||
231 | return ((status[0] & 0x3F) << 4) | ((status[1] & 0x78) >> 3); | ||
232 | } | ||
233 | |||
234 | |||
235 | static inline void dlci_to_status(u16 dlci, u8 *status, int active, int new) | ||
236 | { | ||
237 | status[0] = (dlci >> 4) & 0x3F; | ||
238 | status[1] = ((dlci << 3) & 0x78) | 0x80; | ||
239 | status[2] = 0x80; | ||
240 | |||
241 | if (new) | ||
242 | status[2] |= 0x08; | ||
243 | else if (active) | ||
244 | status[2] |= 0x02; | ||
245 | } | ||
246 | |||
247 | |||
248 | |||
249 | static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) | 226 | static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) |
250 | { | 227 | { |
251 | u16 head_len; | 228 | u16 head_len; |
252 | struct sk_buff *skb = *skb_p; | 229 | struct sk_buff *skb = *skb_p; |
253 | 230 | ||
254 | switch (skb->protocol) { | 231 | switch (skb->protocol) { |
255 | case __constant_ntohs(ETH_P_IP): | 232 | case __constant_ntohs(NLPID_CCITT_ANSI_LMI): |
256 | head_len = 4; | 233 | head_len = 4; |
257 | skb_push(skb, head_len); | 234 | skb_push(skb, head_len); |
258 | skb->data[3] = NLPID_IP; | 235 | skb->data[3] = NLPID_CCITT_ANSI_LMI; |
259 | break; | 236 | break; |
260 | 237 | ||
261 | case __constant_ntohs(ETH_P_IPV6): | 238 | case __constant_ntohs(NLPID_CISCO_LMI): |
262 | head_len = 4; | 239 | head_len = 4; |
263 | skb_push(skb, head_len); | 240 | skb_push(skb, head_len); |
264 | skb->data[3] = NLPID_IPV6; | 241 | skb->data[3] = NLPID_CISCO_LMI; |
265 | break; | 242 | break; |
266 | 243 | ||
267 | case __constant_ntohs(LMI_PROTO): | 244 | case __constant_ntohs(ETH_P_IP): |
245 | head_len = 4; | ||
246 | skb_push(skb, head_len); | ||
247 | skb->data[3] = NLPID_IP; | ||
248 | break; | ||
249 | |||
250 | case __constant_ntohs(ETH_P_IPV6): | ||
268 | head_len = 4; | 251 | head_len = 4; |
269 | skb_push(skb, head_len); | 252 | skb_push(skb, head_len); |
270 | skb->data[3] = LMI_PROTO; | 253 | skb->data[3] = NLPID_IPV6; |
271 | break; | 254 | break; |
272 | 255 | ||
273 | case __constant_ntohs(ETH_P_802_3): | 256 | case __constant_ntohs(ETH_P_802_3): |
@@ -461,13 +444,14 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
461 | hdlc_device *hdlc = dev_to_hdlc(dev); | 444 | hdlc_device *hdlc = dev_to_hdlc(dev); |
462 | struct sk_buff *skb; | 445 | struct sk_buff *skb; |
463 | pvc_device *pvc = hdlc->state.fr.first_pvc; | 446 | pvc_device *pvc = hdlc->state.fr.first_pvc; |
464 | int len = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? LMI_ANSI_LENGTH | 447 | int lmi = hdlc->state.fr.settings.lmi; |
465 | : LMI_LENGTH; | 448 | int dce = hdlc->state.fr.settings.dce; |
466 | int stat_len = 3; | 449 | int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; |
450 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3; | ||
467 | u8 *data; | 451 | u8 *data; |
468 | int i = 0; | 452 | int i = 0; |
469 | 453 | ||
470 | if (hdlc->state.fr.settings.dce && fullrep) { | 454 | if (dce && fullrep) { |
471 | len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); | 455 | len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); |
472 | if (len > HDLC_MAX_MRU) { | 456 | if (len > HDLC_MAX_MRU) { |
473 | printk(KERN_WARNING "%s: Too many PVCs while sending " | 457 | printk(KERN_WARNING "%s: Too many PVCs while sending " |
@@ -484,29 +468,31 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
484 | } | 468 | } |
485 | memset(skb->data, 0, len); | 469 | memset(skb->data, 0, len); |
486 | skb_reserve(skb, 4); | 470 | skb_reserve(skb, 4); |
487 | skb->protocol = __constant_htons(LMI_PROTO); | 471 | if (lmi == LMI_CISCO) { |
488 | fr_hard_header(&skb, LMI_DLCI); | 472 | skb->protocol = __constant_htons(NLPID_CISCO_LMI); |
473 | fr_hard_header(&skb, LMI_CISCO_DLCI); | ||
474 | } else { | ||
475 | skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI); | ||
476 | fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI); | ||
477 | } | ||
489 | data = skb->tail; | 478 | data = skb->tail; |
490 | data[i++] = LMI_CALLREF; | 479 | data[i++] = LMI_CALLREF; |
491 | data[i++] = hdlc->state.fr.settings.dce | 480 | data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY; |
492 | ? LMI_STATUS : LMI_STATUS_ENQUIRY; | 481 | if (lmi == LMI_ANSI) |
493 | if (hdlc->state.fr.settings.lmi == LMI_ANSI) | ||
494 | data[i++] = LMI_ANSI_LOCKSHIFT; | 482 | data[i++] = LMI_ANSI_LOCKSHIFT; |
495 | data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT) | 483 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : |
496 | ? LMI_CCITT_REPTYPE : LMI_REPTYPE; | 484 | LMI_ANSI_CISCO_REPTYPE; |
497 | data[i++] = LMI_REPT_LEN; | 485 | data[i++] = LMI_REPT_LEN; |
498 | data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; | 486 | data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; |
499 | 487 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; | |
500 | data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT) | ||
501 | ? LMI_CCITT_ALIVE : LMI_ALIVE; | ||
502 | data[i++] = LMI_INTEG_LEN; | 488 | data[i++] = LMI_INTEG_LEN; |
503 | data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); | 489 | data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); |
504 | data[i++] = hdlc->state.fr.rxseq; | 490 | data[i++] = hdlc->state.fr.rxseq; |
505 | 491 | ||
506 | if (hdlc->state.fr.settings.dce && fullrep) { | 492 | if (dce && fullrep) { |
507 | while (pvc) { | 493 | while (pvc) { |
508 | data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT) | 494 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : |
509 | ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT; | 495 | LMI_ANSI_CISCO_PVCSTAT; |
510 | data[i++] = stat_len; | 496 | data[i++] = stat_len; |
511 | 497 | ||
512 | /* LMI start/restart */ | 498 | /* LMI start/restart */ |
@@ -523,8 +509,20 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
523 | fr_log_dlci_active(pvc); | 509 | fr_log_dlci_active(pvc); |
524 | } | 510 | } |
525 | 511 | ||
526 | dlci_to_status(pvc->dlci, data + i, | 512 | if (lmi == LMI_CISCO) { |
527 | pvc->state.active, pvc->state.new); | 513 | data[i] = pvc->dlci >> 8; |
514 | data[i + 1] = pvc->dlci & 0xFF; | ||
515 | } else { | ||
516 | data[i] = (pvc->dlci >> 4) & 0x3F; | ||
517 | data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80; | ||
518 | data[i + 2] = 0x80; | ||
519 | } | ||
520 | |||
521 | if (pvc->state.new) | ||
522 | data[i + 2] |= 0x08; | ||
523 | else if (pvc->state.active) | ||
524 | data[i + 2] |= 0x02; | ||
525 | |||
528 | i += stat_len; | 526 | i += stat_len; |
529 | pvc = pvc->next; | 527 | pvc = pvc->next; |
530 | } | 528 | } |
@@ -569,6 +567,8 @@ static void fr_set_link_state(int reliable, struct net_device *dev) | |||
569 | pvc_carrier(0, pvc); | 567 | pvc_carrier(0, pvc); |
570 | pvc->state.exist = pvc->state.active = 0; | 568 | pvc->state.exist = pvc->state.active = 0; |
571 | pvc->state.new = 0; | 569 | pvc->state.new = 0; |
570 | if (!hdlc->state.fr.settings.dce) | ||
571 | pvc->state.bandwidth = 0; | ||
572 | pvc = pvc->next; | 572 | pvc = pvc->next; |
573 | } | 573 | } |
574 | } | 574 | } |
@@ -583,11 +583,12 @@ static void fr_timer(unsigned long arg) | |||
583 | int i, cnt = 0, reliable; | 583 | int i, cnt = 0, reliable; |
584 | u32 list; | 584 | u32 list; |
585 | 585 | ||
586 | if (hdlc->state.fr.settings.dce) | 586 | if (hdlc->state.fr.settings.dce) { |
587 | reliable = hdlc->state.fr.request && | 587 | reliable = hdlc->state.fr.request && |
588 | time_before(jiffies, hdlc->state.fr.last_poll + | 588 | time_before(jiffies, hdlc->state.fr.last_poll + |
589 | hdlc->state.fr.settings.t392 * HZ); | 589 | hdlc->state.fr.settings.t392 * HZ); |
590 | else { | 590 | hdlc->state.fr.request = 0; |
591 | } else { | ||
591 | hdlc->state.fr.last_errors <<= 1; /* Shift the list */ | 592 | hdlc->state.fr.last_errors <<= 1; /* Shift the list */ |
592 | if (hdlc->state.fr.request) { | 593 | if (hdlc->state.fr.request) { |
593 | if (hdlc->state.fr.reliable) | 594 | if (hdlc->state.fr.reliable) |
@@ -634,65 +635,88 @@ static void fr_timer(unsigned long arg) | |||
634 | static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | 635 | static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) |
635 | { | 636 | { |
636 | hdlc_device *hdlc = dev_to_hdlc(dev); | 637 | hdlc_device *hdlc = dev_to_hdlc(dev); |
637 | int stat_len; | ||
638 | pvc_device *pvc; | 638 | pvc_device *pvc; |
639 | int reptype = -1, error, no_ram; | ||
640 | u8 rxseq, txseq; | 639 | u8 rxseq, txseq; |
641 | int i; | 640 | int lmi = hdlc->state.fr.settings.lmi; |
641 | int dce = hdlc->state.fr.settings.dce; | ||
642 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; | ||
642 | 643 | ||
643 | if (skb->len < ((hdlc->state.fr.settings.lmi == LMI_ANSI) | 644 | if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : |
644 | ? LMI_ANSI_LENGTH : LMI_LENGTH)) { | 645 | LMI_CCITT_CISCO_LENGTH)) { |
645 | printk(KERN_INFO "%s: Short LMI frame\n", dev->name); | 646 | printk(KERN_INFO "%s: Short LMI frame\n", dev->name); |
646 | return 1; | 647 | return 1; |
647 | } | 648 | } |
648 | 649 | ||
649 | if (skb->data[5] != (!hdlc->state.fr.settings.dce ? | 650 | if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : |
650 | LMI_STATUS : LMI_STATUS_ENQUIRY)) { | 651 | NLPID_CCITT_ANSI_LMI)) { |
651 | printk(KERN_INFO "%s: LMI msgtype=%x, Not LMI status %s\n", | 652 | printk(KERN_INFO "%s: Received non-LMI frame with LMI" |
652 | dev->name, skb->data[2], | 653 | " DLCI\n", dev->name); |
653 | hdlc->state.fr.settings.dce ? "enquiry" : "reply"); | 654 | return 1; |
655 | } | ||
656 | |||
657 | if (skb->data[4] != LMI_CALLREF) { | ||
658 | printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n", | ||
659 | dev->name, skb->data[4]); | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) { | ||
664 | printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n", | ||
665 | dev->name, skb->data[5]); | ||
654 | return 1; | 666 | return 1; |
655 | } | 667 | } |
656 | 668 | ||
657 | i = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? 7 : 6; | 669 | if (lmi == LMI_ANSI) { |
670 | if (skb->data[6] != LMI_ANSI_LOCKSHIFT) { | ||
671 | printk(KERN_INFO "%s: Not ANSI locking shift in LMI" | ||
672 | " message (0x%02X)\n", dev->name, skb->data[6]); | ||
673 | return 1; | ||
674 | } | ||
675 | i = 7; | ||
676 | } else | ||
677 | i = 6; | ||
658 | 678 | ||
659 | if (skb->data[i] != | 679 | if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE : |
660 | ((hdlc->state.fr.settings.lmi == LMI_CCITT) | 680 | LMI_ANSI_CISCO_REPTYPE)) { |
661 | ? LMI_CCITT_REPTYPE : LMI_REPTYPE)) { | 681 | printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n", |
662 | printk(KERN_INFO "%s: Not a report type=%x\n", | ||
663 | dev->name, skb->data[i]); | 682 | dev->name, skb->data[i]); |
664 | return 1; | 683 | return 1; |
665 | } | 684 | } |
666 | i++; | ||
667 | 685 | ||
668 | i++; /* Skip length field */ | 686 | if (skb->data[++i] != LMI_REPT_LEN) { |
687 | printk(KERN_INFO "%s: Invalid LMI Report type IE length" | ||
688 | " (%u)\n", dev->name, skb->data[i]); | ||
689 | return 1; | ||
690 | } | ||
669 | 691 | ||
670 | reptype = skb->data[i++]; | 692 | reptype = skb->data[++i]; |
693 | if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) { | ||
694 | printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n", | ||
695 | dev->name, reptype); | ||
696 | return 1; | ||
697 | } | ||
671 | 698 | ||
672 | if (skb->data[i]!= | 699 | if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE : |
673 | ((hdlc->state.fr.settings.lmi == LMI_CCITT) | 700 | LMI_ANSI_CISCO_ALIVE)) { |
674 | ? LMI_CCITT_ALIVE : LMI_ALIVE)) { | 701 | printk(KERN_INFO "%s: Not an LMI Link integrity verification" |
675 | printk(KERN_INFO "%s: Unsupported status element=%x\n", | 702 | " IE (0x%02X)\n", dev->name, skb->data[i]); |
676 | dev->name, skb->data[i]); | ||
677 | return 1; | 703 | return 1; |
678 | } | 704 | } |
679 | i++; | ||
680 | 705 | ||
681 | i++; /* Skip length field */ | 706 | if (skb->data[++i] != LMI_INTEG_LEN) { |
707 | printk(KERN_INFO "%s: Invalid LMI Link integrity verification" | ||
708 | " IE length (%u)\n", dev->name, skb->data[i]); | ||
709 | return 1; | ||
710 | } | ||
711 | i++; | ||
682 | 712 | ||
683 | hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ | 713 | hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ |
684 | rxseq = skb->data[i++]; /* Should confirm our sequence */ | 714 | rxseq = skb->data[i++]; /* Should confirm our sequence */ |
685 | 715 | ||
686 | txseq = hdlc->state.fr.txseq; | 716 | txseq = hdlc->state.fr.txseq; |
687 | 717 | ||
688 | if (hdlc->state.fr.settings.dce) { | 718 | if (dce) |
689 | if (reptype != LMI_FULLREP && reptype != LMI_INTEGRITY) { | ||
690 | printk(KERN_INFO "%s: Unsupported report type=%x\n", | ||
691 | dev->name, reptype); | ||
692 | return 1; | ||
693 | } | ||
694 | hdlc->state.fr.last_poll = jiffies; | 719 | hdlc->state.fr.last_poll = jiffies; |
695 | } | ||
696 | 720 | ||
697 | error = 0; | 721 | error = 0; |
698 | if (!hdlc->state.fr.reliable) | 722 | if (!hdlc->state.fr.reliable) |
@@ -703,7 +727,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
703 | error = 1; | 727 | error = 1; |
704 | } | 728 | } |
705 | 729 | ||
706 | if (hdlc->state.fr.settings.dce) { | 730 | if (dce) { |
707 | if (hdlc->state.fr.fullrep_sent && !error) { | 731 | if (hdlc->state.fr.fullrep_sent && !error) { |
708 | /* Stop sending full report - the last one has been confirmed by DTE */ | 732 | /* Stop sending full report - the last one has been confirmed by DTE */ |
709 | hdlc->state.fr.fullrep_sent = 0; | 733 | hdlc->state.fr.fullrep_sent = 0; |
@@ -725,6 +749,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
725 | hdlc->state.fr.dce_changed = 0; | 749 | hdlc->state.fr.dce_changed = 0; |
726 | } | 750 | } |
727 | 751 | ||
752 | hdlc->state.fr.request = 1; /* got request */ | ||
728 | fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); | 753 | fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); |
729 | return 0; | 754 | return 0; |
730 | } | 755 | } |
@@ -739,7 +764,6 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
739 | if (reptype != LMI_FULLREP) | 764 | if (reptype != LMI_FULLREP) |
740 | return 0; | 765 | return 0; |
741 | 766 | ||
742 | stat_len = 3; | ||
743 | pvc = hdlc->state.fr.first_pvc; | 767 | pvc = hdlc->state.fr.first_pvc; |
744 | 768 | ||
745 | while (pvc) { | 769 | while (pvc) { |
@@ -750,24 +774,35 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
750 | no_ram = 0; | 774 | no_ram = 0; |
751 | while (skb->len >= i + 2 + stat_len) { | 775 | while (skb->len >= i + 2 + stat_len) { |
752 | u16 dlci; | 776 | u16 dlci; |
777 | u32 bw; | ||
753 | unsigned int active, new; | 778 | unsigned int active, new; |
754 | 779 | ||
755 | if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT) | 780 | if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT : |
756 | ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) { | 781 | LMI_ANSI_CISCO_PVCSTAT)) { |
757 | printk(KERN_WARNING "%s: Invalid PVCSTAT ID: %x\n", | 782 | printk(KERN_INFO "%s: Not an LMI PVC status IE" |
758 | dev->name, skb->data[i]); | 783 | " (0x%02X)\n", dev->name, skb->data[i]); |
759 | return 1; | 784 | return 1; |
760 | } | 785 | } |
761 | i++; | ||
762 | 786 | ||
763 | if (skb->data[i] != stat_len) { | 787 | if (skb->data[++i] != stat_len) { |
764 | printk(KERN_WARNING "%s: Invalid PVCSTAT length: %x\n", | 788 | printk(KERN_INFO "%s: Invalid LMI PVC status IE length" |
765 | dev->name, skb->data[i]); | 789 | " (%u)\n", dev->name, skb->data[i]); |
766 | return 1; | 790 | return 1; |
767 | } | 791 | } |
768 | i++; | 792 | i++; |
769 | 793 | ||
770 | dlci = status_to_dlci(skb->data + i, &active, &new); | 794 | new = !! (skb->data[i + 2] & 0x08); |
795 | active = !! (skb->data[i + 2] & 0x02); | ||
796 | if (lmi == LMI_CISCO) { | ||
797 | dlci = (skb->data[i] << 8) | skb->data[i + 1]; | ||
798 | bw = (skb->data[i + 3] << 16) | | ||
799 | (skb->data[i + 4] << 8) | | ||
800 | (skb->data[i + 5]); | ||
801 | } else { | ||
802 | dlci = ((skb->data[i] & 0x3F) << 4) | | ||
803 | ((skb->data[i + 1] & 0x78) >> 3); | ||
804 | bw = 0; | ||
805 | } | ||
771 | 806 | ||
772 | pvc = add_pvc(dev, dlci); | 807 | pvc = add_pvc(dev, dlci); |
773 | 808 | ||
@@ -783,9 +818,11 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
783 | pvc->state.deleted = 0; | 818 | pvc->state.deleted = 0; |
784 | if (active != pvc->state.active || | 819 | if (active != pvc->state.active || |
785 | new != pvc->state.new || | 820 | new != pvc->state.new || |
821 | bw != pvc->state.bandwidth || | ||
786 | !pvc->state.exist) { | 822 | !pvc->state.exist) { |
787 | pvc->state.new = new; | 823 | pvc->state.new = new; |
788 | pvc->state.active = active; | 824 | pvc->state.active = active; |
825 | pvc->state.bandwidth = bw; | ||
789 | pvc_carrier(active, pvc); | 826 | pvc_carrier(active, pvc); |
790 | fr_log_dlci_active(pvc); | 827 | fr_log_dlci_active(pvc); |
791 | } | 828 | } |
@@ -801,6 +838,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
801 | pvc_carrier(0, pvc); | 838 | pvc_carrier(0, pvc); |
802 | pvc->state.active = pvc->state.new = 0; | 839 | pvc->state.active = pvc->state.new = 0; |
803 | pvc->state.exist = 0; | 840 | pvc->state.exist = 0; |
841 | pvc->state.bandwidth = 0; | ||
804 | fr_log_dlci_active(pvc); | 842 | fr_log_dlci_active(pvc); |
805 | } | 843 | } |
806 | pvc = pvc->next; | 844 | pvc = pvc->next; |
@@ -829,22 +867,15 @@ static int fr_rx(struct sk_buff *skb) | |||
829 | 867 | ||
830 | dlci = q922_to_dlci(skb->data); | 868 | dlci = q922_to_dlci(skb->data); |
831 | 869 | ||
832 | if (dlci == LMI_DLCI) { | 870 | if ((dlci == LMI_CCITT_ANSI_DLCI && |
833 | if (hdlc->state.fr.settings.lmi == LMI_NONE) | 871 | (hdlc->state.fr.settings.lmi == LMI_ANSI || |
834 | goto rx_error; /* LMI packet with no LMI? */ | 872 | hdlc->state.fr.settings.lmi == LMI_CCITT)) || |
835 | 873 | (dlci == LMI_CISCO_DLCI && | |
836 | if (data[3] == LMI_PROTO) { | 874 | hdlc->state.fr.settings.lmi == LMI_CISCO)) { |
837 | if (fr_lmi_recv(ndev, skb)) | 875 | if (fr_lmi_recv(ndev, skb)) |
838 | goto rx_error; | 876 | goto rx_error; |
839 | else { | 877 | dev_kfree_skb_any(skb); |
840 | dev_kfree_skb_any(skb); | 878 | return NET_RX_SUCCESS; |
841 | return NET_RX_SUCCESS; | ||
842 | } | ||
843 | } | ||
844 | |||
845 | printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n", | ||
846 | ndev->name); | ||
847 | goto rx_error; | ||
848 | } | 879 | } |
849 | 880 | ||
850 | pvc = find_pvc(hdlc, dlci); | 881 | pvc = find_pvc(hdlc, dlci); |
@@ -1170,7 +1201,8 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
1170 | 1201 | ||
1171 | if ((new_settings.lmi != LMI_NONE && | 1202 | if ((new_settings.lmi != LMI_NONE && |
1172 | new_settings.lmi != LMI_ANSI && | 1203 | new_settings.lmi != LMI_ANSI && |
1173 | new_settings.lmi != LMI_CCITT) || | 1204 | new_settings.lmi != LMI_CCITT && |
1205 | new_settings.lmi != LMI_CISCO) || | ||
1174 | new_settings.t391 < 1 || | 1206 | new_settings.t391 < 1 || |
1175 | new_settings.t392 < 2 || | 1207 | new_settings.t392 < 2 || |
1176 | new_settings.n391 < 1 || | 1208 | new_settings.n391 < 1 || |
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c index 6ed064cb4469..a63f6a2cc4f7 100644 --- a/drivers/net/wan/hdlc_generic.c +++ b/drivers/net/wan/hdlc_generic.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
3 | * | 3 | * |
4 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 4 | * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/hdlc.h> | 38 | #include <linux/hdlc.h> |
39 | 39 | ||
40 | 40 | ||
41 | static const char* version = "HDLC support module revision 1.17"; | 41 | static const char* version = "HDLC support module revision 1.18"; |
42 | 42 | ||
43 | #undef DEBUG_LINK | 43 | #undef DEBUG_LINK |
44 | 44 | ||
@@ -126,10 +126,13 @@ void hdlc_set_carrier(int on, struct net_device *dev) | |||
126 | if (!hdlc->open) | 126 | if (!hdlc->open) |
127 | goto carrier_exit; | 127 | goto carrier_exit; |
128 | 128 | ||
129 | if (hdlc->carrier) | 129 | if (hdlc->carrier) { |
130 | printk(KERN_INFO "%s: Carrier detected\n", dev->name); | ||
130 | __hdlc_set_carrier_on(dev); | 131 | __hdlc_set_carrier_on(dev); |
131 | else | 132 | } else { |
133 | printk(KERN_INFO "%s: Carrier lost\n", dev->name); | ||
132 | __hdlc_set_carrier_off(dev); | 134 | __hdlc_set_carrier_off(dev); |
135 | } | ||
133 | 136 | ||
134 | carrier_exit: | 137 | carrier_exit: |
135 | spin_unlock_irqrestore(&hdlc->state_lock, flags); | 138 | spin_unlock_irqrestore(&hdlc->state_lock, flags); |
@@ -157,8 +160,11 @@ int hdlc_open(struct net_device *dev) | |||
157 | 160 | ||
158 | spin_lock_irq(&hdlc->state_lock); | 161 | spin_lock_irq(&hdlc->state_lock); |
159 | 162 | ||
160 | if (hdlc->carrier) | 163 | if (hdlc->carrier) { |
164 | printk(KERN_INFO "%s: Carrier detected\n", dev->name); | ||
161 | __hdlc_set_carrier_on(dev); | 165 | __hdlc_set_carrier_on(dev); |
166 | } else | ||
167 | printk(KERN_INFO "%s: No carrier\n", dev->name); | ||
162 | 168 | ||
163 | hdlc->open = 1; | 169 | hdlc->open = 1; |
164 | 170 | ||
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index a3a32430ae9d..b1078baa1d5e 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -492,6 +492,9 @@ EXPORT_SYMBOL(orinoco_debug); | |||
492 | static int suppress_linkstatus; /* = 0 */ | 492 | static int suppress_linkstatus; /* = 0 */ |
493 | module_param(suppress_linkstatus, bool, 0644); | 493 | module_param(suppress_linkstatus, bool, 0644); |
494 | MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); | 494 | MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); |
495 | static int ignore_disconnect; /* = 0 */ | ||
496 | module_param(ignore_disconnect, int, 0644); | ||
497 | MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer"); | ||
495 | 498 | ||
496 | /********************************************************************/ | 499 | /********************************************************************/ |
497 | /* Compile time configuration and compatibility stuff */ | 500 | /* Compile time configuration and compatibility stuff */ |
@@ -604,7 +607,6 @@ struct hermes_rx_descriptor { | |||
604 | static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 607 | static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
605 | static int __orinoco_program_rids(struct net_device *dev); | 608 | static int __orinoco_program_rids(struct net_device *dev); |
606 | static void __orinoco_set_multicast_list(struct net_device *dev); | 609 | static void __orinoco_set_multicast_list(struct net_device *dev); |
607 | static int orinoco_debug_dump_recs(struct net_device *dev); | ||
608 | 610 | ||
609 | /********************************************************************/ | 611 | /********************************************************************/ |
610 | /* Internal helper functions */ | 612 | /* Internal helper functions */ |
@@ -655,7 +657,7 @@ static int orinoco_open(struct net_device *dev) | |||
655 | return err; | 657 | return err; |
656 | } | 658 | } |
657 | 659 | ||
658 | int orinoco_stop(struct net_device *dev) | 660 | static int orinoco_stop(struct net_device *dev) |
659 | { | 661 | { |
660 | struct orinoco_private *priv = netdev_priv(dev); | 662 | struct orinoco_private *priv = netdev_priv(dev); |
661 | int err = 0; | 663 | int err = 0; |
@@ -686,7 +688,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
686 | struct orinoco_private *priv = netdev_priv(dev); | 688 | struct orinoco_private *priv = netdev_priv(dev); |
687 | hermes_t *hw = &priv->hw; | 689 | hermes_t *hw = &priv->hw; |
688 | struct iw_statistics *wstats = &priv->wstats; | 690 | struct iw_statistics *wstats = &priv->wstats; |
689 | int err = 0; | 691 | int err; |
690 | unsigned long flags; | 692 | unsigned long flags; |
691 | 693 | ||
692 | if (! netif_device_present(dev)) { | 694 | if (! netif_device_present(dev)) { |
@@ -695,9 +697,21 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
695 | return NULL; /* FIXME: Can we do better than this? */ | 697 | return NULL; /* FIXME: Can we do better than this? */ |
696 | } | 698 | } |
697 | 699 | ||
700 | /* If busy, return the old stats. Returning NULL may cause | ||
701 | * the interface to disappear from /proc/net/wireless */ | ||
698 | if (orinoco_lock(priv, &flags) != 0) | 702 | if (orinoco_lock(priv, &flags) != 0) |
699 | return NULL; /* FIXME: Erg, we've been signalled, how | 703 | return wstats; |
700 | * do we propagate this back up? */ | 704 | |
705 | /* We can't really wait for the tallies inquiry command to | ||
706 | * complete, so we just use the previous results and trigger | ||
707 | * a new tallies inquiry command for next time - Jean II */ | ||
708 | /* FIXME: Really we should wait for the inquiry to come back - | ||
709 | * as it is the stats we give don't make a whole lot of sense. | ||
710 | * Unfortunately, it's not clear how to do that within the | ||
711 | * wireless extensions framework: I think we're in user | ||
712 | * context, but a lock seems to be held by the time we get in | ||
713 | * here so we're not safe to sleep here. */ | ||
714 | hermes_inquire(hw, HERMES_INQ_TALLIES); | ||
701 | 715 | ||
702 | if (priv->iw_mode == IW_MODE_ADHOC) { | 716 | if (priv->iw_mode == IW_MODE_ADHOC) { |
703 | memset(&wstats->qual, 0, sizeof(wstats->qual)); | 717 | memset(&wstats->qual, 0, sizeof(wstats->qual)); |
@@ -716,25 +730,16 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
716 | 730 | ||
717 | err = HERMES_READ_RECORD(hw, USER_BAP, | 731 | err = HERMES_READ_RECORD(hw, USER_BAP, |
718 | HERMES_RID_COMMSQUALITY, &cq); | 732 | HERMES_RID_COMMSQUALITY, &cq); |
719 | 733 | ||
720 | wstats->qual.qual = (int)le16_to_cpu(cq.qual); | 734 | if (!err) { |
721 | wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; | 735 | wstats->qual.qual = (int)le16_to_cpu(cq.qual); |
722 | wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; | 736 | wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; |
723 | wstats->qual.updated = 7; | 737 | wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; |
738 | wstats->qual.updated = 7; | ||
739 | } | ||
724 | } | 740 | } |
725 | 741 | ||
726 | /* We can't really wait for the tallies inquiry command to | ||
727 | * complete, so we just use the previous results and trigger | ||
728 | * a new tallies inquiry command for next time - Jean II */ | ||
729 | /* FIXME: We're in user context (I think?), so we should just | ||
730 | wait for the tallies to come through */ | ||
731 | err = hermes_inquire(hw, HERMES_INQ_TALLIES); | ||
732 | |||
733 | orinoco_unlock(priv, &flags); | 742 | orinoco_unlock(priv, &flags); |
734 | |||
735 | if (err) | ||
736 | return NULL; | ||
737 | |||
738 | return wstats; | 743 | return wstats; |
739 | } | 744 | } |
740 | 745 | ||
@@ -1275,9 +1280,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1275 | len = sizeof(tallies); | 1280 | len = sizeof(tallies); |
1276 | } | 1281 | } |
1277 | 1282 | ||
1278 | /* Read directly the data (no seek) */ | 1283 | err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, |
1279 | hermes_read_words(hw, HERMES_DATA1, (void *) &tallies, | 1284 | infofid, sizeof(info)); |
1280 | len / 2); /* FIXME: blech! */ | 1285 | if (err) |
1286 | break; | ||
1281 | 1287 | ||
1282 | /* Increment our various counters */ | 1288 | /* Increment our various counters */ |
1283 | /* wstats->discard.nwid - no wrong BSSID stuff */ | 1289 | /* wstats->discard.nwid - no wrong BSSID stuff */ |
@@ -1307,8 +1313,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1307 | break; | 1313 | break; |
1308 | } | 1314 | } |
1309 | 1315 | ||
1310 | hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus, | 1316 | err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, |
1311 | len / 2); | 1317 | infofid, sizeof(info)); |
1318 | if (err) | ||
1319 | break; | ||
1312 | newstatus = le16_to_cpu(linkstatus.linkstatus); | 1320 | newstatus = le16_to_cpu(linkstatus.linkstatus); |
1313 | 1321 | ||
1314 | connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) | 1322 | connected = (newstatus == HERMES_LINKSTATUS_CONNECTED) |
@@ -1317,7 +1325,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1317 | 1325 | ||
1318 | if (connected) | 1326 | if (connected) |
1319 | netif_carrier_on(dev); | 1327 | netif_carrier_on(dev); |
1320 | else | 1328 | else if (!ignore_disconnect) |
1321 | netif_carrier_off(dev); | 1329 | netif_carrier_off(dev); |
1322 | 1330 | ||
1323 | if (newstatus != priv->last_linkstatus) | 1331 | if (newstatus != priv->last_linkstatus) |
@@ -1350,6 +1358,8 @@ int __orinoco_up(struct net_device *dev) | |||
1350 | struct hermes *hw = &priv->hw; | 1358 | struct hermes *hw = &priv->hw; |
1351 | int err; | 1359 | int err; |
1352 | 1360 | ||
1361 | netif_carrier_off(dev); /* just to make sure */ | ||
1362 | |||
1353 | err = __orinoco_program_rids(dev); | 1363 | err = __orinoco_program_rids(dev); |
1354 | if (err) { | 1364 | if (err) { |
1355 | printk(KERN_ERR "%s: Error %d configuring card\n", | 1365 | printk(KERN_ERR "%s: Error %d configuring card\n", |
@@ -1413,7 +1423,7 @@ int orinoco_reinit_firmware(struct net_device *dev) | |||
1413 | return err; | 1423 | return err; |
1414 | 1424 | ||
1415 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | 1425 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); |
1416 | if (err == -EIO) { | 1426 | if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { |
1417 | /* Try workaround for old Symbol firmware bug */ | 1427 | /* Try workaround for old Symbol firmware bug */ |
1418 | printk(KERN_WARNING "%s: firmware ALLOC bug detected " | 1428 | printk(KERN_WARNING "%s: firmware ALLOC bug detected " |
1419 | "(old Symbol firmware?). Trying to work around... ", | 1429 | "(old Symbol firmware?). Trying to work around... ", |
@@ -1610,17 +1620,15 @@ static int __orinoco_program_rids(struct net_device *dev) | |||
1610 | return err; | 1620 | return err; |
1611 | } | 1621 | } |
1612 | /* Set the channel/frequency */ | 1622 | /* Set the channel/frequency */ |
1613 | if (priv->channel == 0) { | 1623 | if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) { |
1614 | printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name); | 1624 | err = hermes_write_wordrec(hw, USER_BAP, |
1615 | if (priv->createibss) | 1625 | HERMES_RID_CNFOWNCHANNEL, |
1616 | priv->channel = 10; | 1626 | priv->channel); |
1617 | } | 1627 | if (err) { |
1618 | err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL, | 1628 | printk(KERN_ERR "%s: Error %d setting channel %d\n", |
1619 | priv->channel); | 1629 | dev->name, err, priv->channel); |
1620 | if (err) { | 1630 | return err; |
1621 | printk(KERN_ERR "%s: Error %d setting channel\n", | 1631 | } |
1622 | dev->name, err); | ||
1623 | return err; | ||
1624 | } | 1632 | } |
1625 | 1633 | ||
1626 | if (priv->has_ibss) { | 1634 | if (priv->has_ibss) { |
@@ -1916,7 +1924,7 @@ static void orinoco_reset(struct net_device *dev) | |||
1916 | { | 1924 | { |
1917 | struct orinoco_private *priv = netdev_priv(dev); | 1925 | struct orinoco_private *priv = netdev_priv(dev); |
1918 | struct hermes *hw = &priv->hw; | 1926 | struct hermes *hw = &priv->hw; |
1919 | int err = 0; | 1927 | int err; |
1920 | unsigned long flags; | 1928 | unsigned long flags; |
1921 | 1929 | ||
1922 | if (orinoco_lock(priv, &flags) != 0) | 1930 | if (orinoco_lock(priv, &flags) != 0) |
@@ -1938,20 +1946,20 @@ static void orinoco_reset(struct net_device *dev) | |||
1938 | 1946 | ||
1939 | orinoco_unlock(priv, &flags); | 1947 | orinoco_unlock(priv, &flags); |
1940 | 1948 | ||
1941 | if (priv->hard_reset) | 1949 | if (priv->hard_reset) { |
1942 | err = (*priv->hard_reset)(priv); | 1950 | err = (*priv->hard_reset)(priv); |
1943 | if (err) { | 1951 | if (err) { |
1944 | printk(KERN_ERR "%s: orinoco_reset: Error %d " | 1952 | printk(KERN_ERR "%s: orinoco_reset: Error %d " |
1945 | "performing hard reset\n", dev->name, err); | 1953 | "performing hard reset\n", dev->name, err); |
1946 | /* FIXME: shutdown of some sort */ | 1954 | goto disable; |
1947 | return; | 1955 | } |
1948 | } | 1956 | } |
1949 | 1957 | ||
1950 | err = orinoco_reinit_firmware(dev); | 1958 | err = orinoco_reinit_firmware(dev); |
1951 | if (err) { | 1959 | if (err) { |
1952 | printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", | 1960 | printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n", |
1953 | dev->name, err); | 1961 | dev->name, err); |
1954 | return; | 1962 | goto disable; |
1955 | } | 1963 | } |
1956 | 1964 | ||
1957 | spin_lock_irq(&priv->lock); /* This has to be called from user context */ | 1965 | spin_lock_irq(&priv->lock); /* This has to be called from user context */ |
@@ -1972,6 +1980,10 @@ static void orinoco_reset(struct net_device *dev) | |||
1972 | spin_unlock_irq(&priv->lock); | 1980 | spin_unlock_irq(&priv->lock); |
1973 | 1981 | ||
1974 | return; | 1982 | return; |
1983 | disable: | ||
1984 | hermes_set_irqmask(hw, 0); | ||
1985 | netif_device_detach(dev); | ||
1986 | printk(KERN_ERR "%s: Device has been disabled!\n", dev->name); | ||
1975 | } | 1987 | } |
1976 | 1988 | ||
1977 | /********************************************************************/ | 1989 | /********************************************************************/ |
@@ -2056,7 +2068,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2056 | if (events & HERMES_EV_ALLOC) | 2068 | if (events & HERMES_EV_ALLOC) |
2057 | __orinoco_ev_alloc(dev, hw); | 2069 | __orinoco_ev_alloc(dev, hw); |
2058 | 2070 | ||
2059 | hermes_write_regn(hw, EVACK, events); | 2071 | hermes_write_regn(hw, EVACK, evstat); |
2060 | 2072 | ||
2061 | evstat = hermes_read_regn(hw, EVSTAT); | 2073 | evstat = hermes_read_regn(hw, EVSTAT); |
2062 | events = evstat & hw->inten; | 2074 | events = evstat & hw->inten; |
@@ -2215,6 +2227,8 @@ static int determine_firmware(struct net_device *dev) | |||
2215 | firmver >= 0x31000; | 2227 | firmver >= 0x31000; |
2216 | priv->has_preamble = (firmver >= 0x20000); | 2228 | priv->has_preamble = (firmver >= 0x20000); |
2217 | priv->ibss_port = 4; | 2229 | priv->ibss_port = 4; |
2230 | priv->broken_disableport = (firmver == 0x25013) || | ||
2231 | (firmver >= 0x30000 && firmver <= 0x31000); | ||
2218 | /* Tested with Intel firmware : 0x20015 => Jean II */ | 2232 | /* Tested with Intel firmware : 0x20015 => Jean II */ |
2219 | /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ | 2233 | /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ |
2220 | break; | 2234 | break; |
@@ -2267,7 +2281,7 @@ static int orinoco_init(struct net_device *dev) | |||
2267 | priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; | 2281 | priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; |
2268 | 2282 | ||
2269 | /* Initialize the firmware */ | 2283 | /* Initialize the firmware */ |
2270 | err = hermes_init(hw); | 2284 | err = orinoco_reinit_firmware(dev); |
2271 | if (err != 0) { | 2285 | if (err != 0) { |
2272 | printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", | 2286 | printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n", |
2273 | dev->name, err); | 2287 | dev->name, err); |
@@ -2400,31 +2414,12 @@ static int orinoco_init(struct net_device *dev) | |||
2400 | /* By default use IEEE/IBSS ad-hoc mode if we have it */ | 2414 | /* By default use IEEE/IBSS ad-hoc mode if we have it */ |
2401 | priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); | 2415 | priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss); |
2402 | set_port_type(priv); | 2416 | set_port_type(priv); |
2403 | priv->channel = 10; /* default channel, more-or-less arbitrary */ | 2417 | priv->channel = 0; /* use firmware default */ |
2404 | 2418 | ||
2405 | priv->promiscuous = 0; | 2419 | priv->promiscuous = 0; |
2406 | priv->wep_on = 0; | 2420 | priv->wep_on = 0; |
2407 | priv->tx_key = 0; | 2421 | priv->tx_key = 0; |
2408 | 2422 | ||
2409 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | ||
2410 | if (err == -EIO) { | ||
2411 | /* Try workaround for old Symbol firmware bug */ | ||
2412 | printk(KERN_WARNING "%s: firmware ALLOC bug detected " | ||
2413 | "(old Symbol firmware?). Trying to work around... ", | ||
2414 | dev->name); | ||
2415 | |||
2416 | priv->nicbuf_size = TX_NICBUF_SIZE_BUG; | ||
2417 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | ||
2418 | if (err) | ||
2419 | printk("failed!\n"); | ||
2420 | else | ||
2421 | printk("ok.\n"); | ||
2422 | } | ||
2423 | if (err) { | ||
2424 | printk("%s: Error %d allocating Tx buffer\n", dev->name, err); | ||
2425 | goto out; | ||
2426 | } | ||
2427 | |||
2428 | /* Make the hardware available, as long as it hasn't been | 2423 | /* Make the hardware available, as long as it hasn't been |
2429 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ | 2424 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ |
2430 | spin_lock_irq(&priv->lock); | 2425 | spin_lock_irq(&priv->lock); |
@@ -2450,7 +2445,7 @@ struct net_device *alloc_orinocodev(int sizeof_card, | |||
2450 | priv = netdev_priv(dev); | 2445 | priv = netdev_priv(dev); |
2451 | priv->ndev = dev; | 2446 | priv->ndev = dev; |
2452 | if (sizeof_card) | 2447 | if (sizeof_card) |
2453 | priv->card = (void *)((unsigned long)netdev_priv(dev) | 2448 | priv->card = (void *)((unsigned long)priv |
2454 | + sizeof(struct orinoco_private)); | 2449 | + sizeof(struct orinoco_private)); |
2455 | else | 2450 | else |
2456 | priv->card = NULL; | 2451 | priv->card = NULL; |
@@ -2555,6 +2550,7 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, | |||
2555 | } | 2550 | } |
2556 | 2551 | ||
2557 | len = le16_to_cpu(essidbuf.len); | 2552 | len = le16_to_cpu(essidbuf.len); |
2553 | BUG_ON(len > IW_ESSID_MAX_SIZE); | ||
2558 | 2554 | ||
2559 | memset(buf, 0, IW_ESSID_MAX_SIZE+1); | 2555 | memset(buf, 0, IW_ESSID_MAX_SIZE+1); |
2560 | memcpy(buf, p, len); | 2556 | memcpy(buf, p, len); |
@@ -2923,13 +2919,14 @@ static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq) | |||
2923 | memset(&essidbuf, 0, sizeof(essidbuf)); | 2919 | memset(&essidbuf, 0, sizeof(essidbuf)); |
2924 | 2920 | ||
2925 | if (erq->flags) { | 2921 | if (erq->flags) { |
2926 | if (erq->length > IW_ESSID_MAX_SIZE) | 2922 | /* iwconfig includes the NUL in the specified length */ |
2923 | if (erq->length > IW_ESSID_MAX_SIZE+1) | ||
2927 | return -E2BIG; | 2924 | return -E2BIG; |
2928 | 2925 | ||
2929 | if (copy_from_user(&essidbuf, erq->pointer, erq->length)) | 2926 | if (copy_from_user(&essidbuf, erq->pointer, erq->length)) |
2930 | return -EFAULT; | 2927 | return -EFAULT; |
2931 | 2928 | ||
2932 | essidbuf[erq->length] = '\0'; | 2929 | essidbuf[IW_ESSID_MAX_SIZE] = '\0'; |
2933 | } | 2930 | } |
2934 | 2931 | ||
2935 | if (orinoco_lock(priv, &flags) != 0) | 2932 | if (orinoco_lock(priv, &flags) != 0) |
@@ -3855,7 +3852,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
3855 | { SIOCIWFIRSTPRIV + 0x7, 0, | 3852 | { SIOCIWFIRSTPRIV + 0x7, 0, |
3856 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 3853 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
3857 | "get_ibssport" }, | 3854 | "get_ibssport" }, |
3858 | { SIOCIWLASTPRIV, 0, 0, "dump_recs" }, | ||
3859 | }; | 3855 | }; |
3860 | 3856 | ||
3861 | wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]); | 3857 | wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]); |
@@ -3943,14 +3939,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
3943 | err = orinoco_ioctl_getibssport(dev, wrq); | 3939 | err = orinoco_ioctl_getibssport(dev, wrq); |
3944 | break; | 3940 | break; |
3945 | 3941 | ||
3946 | case SIOCIWLASTPRIV: | ||
3947 | err = orinoco_debug_dump_recs(dev); | ||
3948 | if (err) | ||
3949 | printk(KERN_ERR "%s: Unable to dump records (%d)\n", | ||
3950 | dev->name, err); | ||
3951 | break; | ||
3952 | |||
3953 | |||
3954 | default: | 3942 | default: |
3955 | err = -EOPNOTSUPP; | 3943 | err = -EOPNOTSUPP; |
3956 | } | 3944 | } |
@@ -3964,187 +3952,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
3964 | return err; | 3952 | return err; |
3965 | } | 3953 | } |
3966 | 3954 | ||
3967 | struct { | ||
3968 | u16 rid; | ||
3969 | char *name; | ||
3970 | int displaytype; | ||
3971 | #define DISPLAY_WORDS 0 | ||
3972 | #define DISPLAY_BYTES 1 | ||
3973 | #define DISPLAY_STRING 2 | ||
3974 | #define DISPLAY_XSTRING 3 | ||
3975 | } record_table[] = { | ||
3976 | #define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type } | ||
3977 | DEBUG_REC(CNFPORTTYPE,WORDS), | ||
3978 | DEBUG_REC(CNFOWNMACADDR,BYTES), | ||
3979 | DEBUG_REC(CNFDESIREDSSID,STRING), | ||
3980 | DEBUG_REC(CNFOWNCHANNEL,WORDS), | ||
3981 | DEBUG_REC(CNFOWNSSID,STRING), | ||
3982 | DEBUG_REC(CNFOWNATIMWINDOW,WORDS), | ||
3983 | DEBUG_REC(CNFSYSTEMSCALE,WORDS), | ||
3984 | DEBUG_REC(CNFMAXDATALEN,WORDS), | ||
3985 | DEBUG_REC(CNFPMENABLED,WORDS), | ||
3986 | DEBUG_REC(CNFPMEPS,WORDS), | ||
3987 | DEBUG_REC(CNFMULTICASTRECEIVE,WORDS), | ||
3988 | DEBUG_REC(CNFMAXSLEEPDURATION,WORDS), | ||
3989 | DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS), | ||
3990 | DEBUG_REC(CNFOWNNAME,STRING), | ||
3991 | DEBUG_REC(CNFOWNDTIMPERIOD,WORDS), | ||
3992 | DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS), | ||
3993 | DEBUG_REC(CNFWEPENABLED_AGERE,WORDS), | ||
3994 | DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS), | ||
3995 | DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS), | ||
3996 | DEBUG_REC(CNFDEFAULTKEY0,BYTES), | ||
3997 | DEBUG_REC(CNFDEFAULTKEY1,BYTES), | ||
3998 | DEBUG_REC(CNFMWOROBUST_AGERE,WORDS), | ||
3999 | DEBUG_REC(CNFDEFAULTKEY2,BYTES), | ||
4000 | DEBUG_REC(CNFDEFAULTKEY3,BYTES), | ||
4001 | DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS), | ||
4002 | DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS), | ||
4003 | DEBUG_REC(CNFAUTHENTICATION,WORDS), | ||
4004 | DEBUG_REC(CNFMAXASSOCSTA,WORDS), | ||
4005 | DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS), | ||
4006 | DEBUG_REC(CNFTXCONTROL,WORDS), | ||
4007 | DEBUG_REC(CNFROAMINGMODE,WORDS), | ||
4008 | DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS), | ||
4009 | DEBUG_REC(CNFRCVCRCERROR,WORDS), | ||
4010 | DEBUG_REC(CNFMMLIFE,WORDS), | ||
4011 | DEBUG_REC(CNFALTRETRYCOUNT,WORDS), | ||
4012 | DEBUG_REC(CNFBEACONINT,WORDS), | ||
4013 | DEBUG_REC(CNFAPPCFINFO,WORDS), | ||
4014 | DEBUG_REC(CNFSTAPCFINFO,WORDS), | ||
4015 | DEBUG_REC(CNFPRIORITYQUSAGE,WORDS), | ||
4016 | DEBUG_REC(CNFTIMCTRL,WORDS), | ||
4017 | DEBUG_REC(CNFTHIRTY2TALLY,WORDS), | ||
4018 | DEBUG_REC(CNFENHSECURITY,WORDS), | ||
4019 | DEBUG_REC(CNFGROUPADDRESSES,BYTES), | ||
4020 | DEBUG_REC(CNFCREATEIBSS,WORDS), | ||
4021 | DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS), | ||
4022 | DEBUG_REC(CNFRTSTHRESHOLD,WORDS), | ||
4023 | DEBUG_REC(CNFTXRATECONTROL,WORDS), | ||
4024 | DEBUG_REC(CNFPROMISCUOUSMODE,WORDS), | ||
4025 | DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS), | ||
4026 | DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS), | ||
4027 | DEBUG_REC(CNFSHORTPREAMBLE,WORDS), | ||
4028 | DEBUG_REC(CNFWEPKEYS_AGERE,BYTES), | ||
4029 | DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS), | ||
4030 | DEBUG_REC(CNFTXKEY_AGERE,WORDS), | ||
4031 | DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS), | ||
4032 | DEBUG_REC(CNFBASICRATES,WORDS), | ||
4033 | DEBUG_REC(CNFSUPPORTEDRATES,WORDS), | ||
4034 | DEBUG_REC(CNFTICKTIME,WORDS), | ||
4035 | DEBUG_REC(CNFSCANREQUEST,WORDS), | ||
4036 | DEBUG_REC(CNFJOINREQUEST,WORDS), | ||
4037 | DEBUG_REC(CNFAUTHENTICATESTATION,WORDS), | ||
4038 | DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS), | ||
4039 | DEBUG_REC(MAXLOADTIME,WORDS), | ||
4040 | DEBUG_REC(DOWNLOADBUFFER,WORDS), | ||
4041 | DEBUG_REC(PRIID,WORDS), | ||
4042 | DEBUG_REC(PRISUPRANGE,WORDS), | ||
4043 | DEBUG_REC(CFIACTRANGES,WORDS), | ||
4044 | DEBUG_REC(NICSERNUM,XSTRING), | ||
4045 | DEBUG_REC(NICID,WORDS), | ||
4046 | DEBUG_REC(MFISUPRANGE,WORDS), | ||
4047 | DEBUG_REC(CFISUPRANGE,WORDS), | ||
4048 | DEBUG_REC(CHANNELLIST,WORDS), | ||
4049 | DEBUG_REC(REGULATORYDOMAINS,WORDS), | ||
4050 | DEBUG_REC(TEMPTYPE,WORDS), | ||
4051 | /* DEBUG_REC(CIS,BYTES), */ | ||
4052 | DEBUG_REC(STAID,WORDS), | ||
4053 | DEBUG_REC(CURRENTSSID,STRING), | ||
4054 | DEBUG_REC(CURRENTBSSID,BYTES), | ||
4055 | DEBUG_REC(COMMSQUALITY,WORDS), | ||
4056 | DEBUG_REC(CURRENTTXRATE,WORDS), | ||
4057 | DEBUG_REC(CURRENTBEACONINTERVAL,WORDS), | ||
4058 | DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS), | ||
4059 | DEBUG_REC(PROTOCOLRSPTIME,WORDS), | ||
4060 | DEBUG_REC(SHORTRETRYLIMIT,WORDS), | ||
4061 | DEBUG_REC(LONGRETRYLIMIT,WORDS), | ||
4062 | DEBUG_REC(MAXTRANSMITLIFETIME,WORDS), | ||
4063 | DEBUG_REC(MAXRECEIVELIFETIME,WORDS), | ||
4064 | DEBUG_REC(CFPOLLABLE,WORDS), | ||
4065 | DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS), | ||
4066 | DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS), | ||
4067 | DEBUG_REC(OWNMACADDR,BYTES), | ||
4068 | DEBUG_REC(SCANRESULTSTABLE,WORDS), | ||
4069 | DEBUG_REC(PHYTYPE,WORDS), | ||
4070 | DEBUG_REC(CURRENTCHANNEL,WORDS), | ||
4071 | DEBUG_REC(CURRENTPOWERSTATE,WORDS), | ||
4072 | DEBUG_REC(CCAMODE,WORDS), | ||
4073 | DEBUG_REC(SUPPORTEDDATARATES,WORDS), | ||
4074 | DEBUG_REC(BUILDSEQ,BYTES), | ||
4075 | DEBUG_REC(FWID,XSTRING) | ||
4076 | #undef DEBUG_REC | ||
4077 | }; | ||
4078 | |||
4079 | #define DEBUG_LTV_SIZE 128 | ||
4080 | |||
4081 | static int orinoco_debug_dump_recs(struct net_device *dev) | ||
4082 | { | ||
4083 | struct orinoco_private *priv = netdev_priv(dev); | ||
4084 | hermes_t *hw = &priv->hw; | ||
4085 | u8 *val8; | ||
4086 | u16 *val16; | ||
4087 | int i,j; | ||
4088 | u16 length; | ||
4089 | int err; | ||
4090 | |||
4091 | /* I'm not sure: we might have a lock here, so we'd better go | ||
4092 | atomic, just in case. */ | ||
4093 | val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC); | ||
4094 | if (! val8) | ||
4095 | return -ENOMEM; | ||
4096 | val16 = (u16 *)val8; | ||
4097 | |||
4098 | for (i = 0; i < ARRAY_SIZE(record_table); i++) { | ||
4099 | u16 rid = record_table[i].rid; | ||
4100 | int len; | ||
4101 | |||
4102 | memset(val8, 0, DEBUG_LTV_SIZE + 2); | ||
4103 | |||
4104 | err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE, | ||
4105 | &length, val8); | ||
4106 | if (err) { | ||
4107 | DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid); | ||
4108 | continue; | ||
4109 | } | ||
4110 | val16 = (u16 *)val8; | ||
4111 | if (length == 0) | ||
4112 | continue; | ||
4113 | |||
4114 | printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", | ||
4115 | record_table[i].name, | ||
4116 | rid, length, (length-1)*2); | ||
4117 | len = min(((int)length-1)*2, DEBUG_LTV_SIZE); | ||
4118 | |||
4119 | switch (record_table[i].displaytype) { | ||
4120 | case DISPLAY_WORDS: | ||
4121 | for (j = 0; j < len / 2; j++) | ||
4122 | printk("%04X-", le16_to_cpu(val16[j])); | ||
4123 | break; | ||
4124 | |||
4125 | case DISPLAY_BYTES: | ||
4126 | default: | ||
4127 | for (j = 0; j < len; j++) | ||
4128 | printk("%02X:", val8[j]); | ||
4129 | break; | ||
4130 | |||
4131 | case DISPLAY_STRING: | ||
4132 | len = min(len, le16_to_cpu(val16[0])+2); | ||
4133 | val8[len] = '\0'; | ||
4134 | printk("\"%s\"", (char *)&val16[1]); | ||
4135 | break; | ||
4136 | |||
4137 | case DISPLAY_XSTRING: | ||
4138 | printk("'%s'", (char *)val8); | ||
4139 | } | ||
4140 | |||
4141 | printk("\n"); | ||
4142 | } | ||
4143 | |||
4144 | kfree(val8); | ||
4145 | |||
4146 | return 0; | ||
4147 | } | ||
4148 | 3955 | ||
4149 | /********************************************************************/ | 3956 | /********************************************************************/ |
4150 | /* Debugging */ | 3957 | /* Debugging */ |
@@ -4218,7 +4025,6 @@ EXPORT_SYMBOL(free_orinocodev); | |||
4218 | 4025 | ||
4219 | EXPORT_SYMBOL(__orinoco_up); | 4026 | EXPORT_SYMBOL(__orinoco_up); |
4220 | EXPORT_SYMBOL(__orinoco_down); | 4027 | EXPORT_SYMBOL(__orinoco_down); |
4221 | EXPORT_SYMBOL(orinoco_stop); | ||
4222 | EXPORT_SYMBOL(orinoco_reinit_firmware); | 4028 | EXPORT_SYMBOL(orinoco_reinit_firmware); |
4223 | 4029 | ||
4224 | EXPORT_SYMBOL(orinoco_interrupt); | 4030 | EXPORT_SYMBOL(orinoco_interrupt); |
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h index 13e42c2afb27..f749b50d1088 100644 --- a/drivers/net/wireless/orinoco.h +++ b/drivers/net/wireless/orinoco.h | |||
@@ -119,7 +119,6 @@ extern struct net_device *alloc_orinocodev(int sizeof_card, | |||
119 | extern void free_orinocodev(struct net_device *dev); | 119 | extern void free_orinocodev(struct net_device *dev); |
120 | extern int __orinoco_up(struct net_device *dev); | 120 | extern int __orinoco_up(struct net_device *dev); |
121 | extern int __orinoco_down(struct net_device *dev); | 121 | extern int __orinoco_down(struct net_device *dev); |
122 | extern int orinoco_stop(struct net_device *dev); | ||
123 | extern int orinoco_reinit_firmware(struct net_device *dev); | 122 | extern int orinoco_reinit_firmware(struct net_device *dev); |
124 | extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); | 123 | extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); |
125 | 124 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 9e9dab7fe86a..8132d946c384 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CompactPCI Hot Plug Driver | 2 | * CompactPCI Hot Plug Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2002 SOMA Networks, Inc. | 4 | * Copyright (C) 2002,2005 SOMA Networks, Inc. |
5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) |
6 | * Copyright (C) 2001 IBM Corp. | 6 | * Copyright (C) 2001 IBM Corp. |
7 | * | 7 | * |
@@ -45,10 +45,10 @@ | |||
45 | 45 | ||
46 | #define dbg(format, arg...) \ | 46 | #define dbg(format, arg...) \ |
47 | do { \ | 47 | do { \ |
48 | if(cpci_debug) \ | 48 | if (cpci_debug) \ |
49 | printk (KERN_DEBUG "%s: " format "\n", \ | 49 | printk (KERN_DEBUG "%s: " format "\n", \ |
50 | MY_NAME , ## arg); \ | 50 | MY_NAME , ## arg); \ |
51 | } while(0) | 51 | } while (0) |
52 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 52 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
53 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 53 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
@@ -111,10 +111,8 @@ enable_slot(struct hotplug_slot *hotplug_slot) | |||
111 | 111 | ||
112 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); | 112 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); |
113 | 113 | ||
114 | if(controller->ops->set_power) { | 114 | if (controller->ops->set_power) |
115 | retval = controller->ops->set_power(slot, 1); | 115 | retval = controller->ops->set_power(slot, 1); |
116 | } | ||
117 | |||
118 | return retval; | 116 | return retval; |
119 | } | 117 | } |
120 | 118 | ||
@@ -126,37 +124,41 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
126 | 124 | ||
127 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); | 125 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); |
128 | 126 | ||
127 | down_write(&list_rwsem); | ||
128 | |||
129 | /* Unconfigure device */ | 129 | /* Unconfigure device */ |
130 | dbg("%s - unconfiguring slot %s", | 130 | dbg("%s - unconfiguring slot %s", |
131 | __FUNCTION__, slot->hotplug_slot->name); | 131 | __FUNCTION__, slot->hotplug_slot->name); |
132 | if((retval = cpci_unconfigure_slot(slot))) { | 132 | if ((retval = cpci_unconfigure_slot(slot))) { |
133 | err("%s - could not unconfigure slot %s", | 133 | err("%s - could not unconfigure slot %s", |
134 | __FUNCTION__, slot->hotplug_slot->name); | 134 | __FUNCTION__, slot->hotplug_slot->name); |
135 | return retval; | 135 | goto disable_error; |
136 | } | 136 | } |
137 | dbg("%s - finished unconfiguring slot %s", | 137 | dbg("%s - finished unconfiguring slot %s", |
138 | __FUNCTION__, slot->hotplug_slot->name); | 138 | __FUNCTION__, slot->hotplug_slot->name); |
139 | 139 | ||
140 | /* Clear EXT (by setting it) */ | 140 | /* Clear EXT (by setting it) */ |
141 | if(cpci_clear_ext(slot)) { | 141 | if (cpci_clear_ext(slot)) { |
142 | err("%s - could not clear EXT for slot %s", | 142 | err("%s - could not clear EXT for slot %s", |
143 | __FUNCTION__, slot->hotplug_slot->name); | 143 | __FUNCTION__, slot->hotplug_slot->name); |
144 | retval = -ENODEV; | 144 | retval = -ENODEV; |
145 | goto disable_error; | ||
145 | } | 146 | } |
146 | cpci_led_on(slot); | 147 | cpci_led_on(slot); |
147 | 148 | ||
148 | if(controller->ops->set_power) { | 149 | if (controller->ops->set_power) |
149 | retval = controller->ops->set_power(slot, 0); | 150 | if ((retval = controller->ops->set_power(slot, 0))) |
150 | } | 151 | goto disable_error; |
151 | 152 | ||
152 | if(update_adapter_status(slot->hotplug_slot, 0)) { | 153 | if (update_adapter_status(slot->hotplug_slot, 0)) |
153 | warn("failure to update adapter file"); | 154 | warn("failure to update adapter file"); |
154 | } | ||
155 | 155 | ||
156 | if(slot->extracting) { | 156 | if (slot->extracting) { |
157 | slot->extracting = 0; | 157 | slot->extracting = 0; |
158 | atomic_dec(&extracting); | 158 | atomic_dec(&extracting); |
159 | } | 159 | } |
160 | disable_error: | ||
161 | up_write(&list_rwsem); | ||
160 | return retval; | 162 | return retval; |
161 | } | 163 | } |
162 | 164 | ||
@@ -165,9 +167,8 @@ cpci_get_power_status(struct slot *slot) | |||
165 | { | 167 | { |
166 | u8 power = 1; | 168 | u8 power = 1; |
167 | 169 | ||
168 | if(controller->ops->get_power) { | 170 | if (controller->ops->get_power) |
169 | power = controller->ops->get_power(slot); | 171 | power = controller->ops->get_power(slot); |
170 | } | ||
171 | return power; | 172 | return power; |
172 | } | 173 | } |
173 | 174 | ||
@@ -237,9 +238,8 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) | |||
237 | int status = -ENOMEM; | 238 | int status = -ENOMEM; |
238 | int i; | 239 | int i; |
239 | 240 | ||
240 | if(!(controller && bus)) { | 241 | if (!(controller && bus)) |
241 | return -ENODEV; | 242 | return -ENODEV; |
242 | } | ||
243 | 243 | ||
244 | /* | 244 | /* |
245 | * Create a structure for each slot, and register that slot | 245 | * Create a structure for each slot, and register that slot |
@@ -316,32 +316,30 @@ int | |||
316 | cpci_hp_unregister_bus(struct pci_bus *bus) | 316 | cpci_hp_unregister_bus(struct pci_bus *bus) |
317 | { | 317 | { |
318 | struct slot *slot; | 318 | struct slot *slot; |
319 | struct list_head *tmp; | 319 | struct slot *tmp; |
320 | struct list_head *next; | 320 | int status = 0; |
321 | int status; | ||
322 | 321 | ||
323 | down_write(&list_rwsem); | 322 | down_write(&list_rwsem); |
324 | if(!slots) { | 323 | if (!slots) { |
325 | up_write(&list_rwsem); | 324 | up_write(&list_rwsem); |
326 | return -1; | 325 | return -1; |
327 | } | 326 | } |
328 | list_for_each_safe(tmp, next, &slot_list) { | 327 | list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { |
329 | slot = list_entry(tmp, struct slot, slot_list); | 328 | if (slot->bus == bus) { |
330 | if(slot->bus == bus) { | 329 | list_del(&slot->slot_list); |
330 | slots--; | ||
331 | |||
331 | dbg("deregistering slot %s", slot->hotplug_slot->name); | 332 | dbg("deregistering slot %s", slot->hotplug_slot->name); |
332 | status = pci_hp_deregister(slot->hotplug_slot); | 333 | status = pci_hp_deregister(slot->hotplug_slot); |
333 | if(status) { | 334 | if (status) { |
334 | err("pci_hp_deregister failed with error %d", | 335 | err("pci_hp_deregister failed with error %d", |
335 | status); | 336 | status); |
336 | return status; | 337 | break; |
337 | } | 338 | } |
338 | |||
339 | list_del(&slot->slot_list); | ||
340 | slots--; | ||
341 | } | 339 | } |
342 | } | 340 | } |
343 | up_write(&list_rwsem); | 341 | up_write(&list_rwsem); |
344 | return 0; | 342 | return status; |
345 | } | 343 | } |
346 | 344 | ||
347 | /* This is the interrupt mode interrupt handler */ | 345 | /* This is the interrupt mode interrupt handler */ |
@@ -351,7 +349,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
351 | dbg("entered cpci_hp_intr"); | 349 | dbg("entered cpci_hp_intr"); |
352 | 350 | ||
353 | /* Check to see if it was our interrupt */ | 351 | /* Check to see if it was our interrupt */ |
354 | if((controller->irq_flags & SA_SHIRQ) && | 352 | if ((controller->irq_flags & SA_SHIRQ) && |
355 | !controller->ops->check_irq(controller->dev_id)) { | 353 | !controller->ops->check_irq(controller->dev_id)) { |
356 | dbg("exited cpci_hp_intr, not our interrupt"); | 354 | dbg("exited cpci_hp_intr, not our interrupt"); |
357 | return IRQ_NONE; | 355 | return IRQ_NONE; |
@@ -373,38 +371,30 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
373 | * INS bits of the cold-inserted devices. | 371 | * INS bits of the cold-inserted devices. |
374 | */ | 372 | */ |
375 | static int | 373 | static int |
376 | init_slots(void) | 374 | init_slots(int clear_ins) |
377 | { | 375 | { |
378 | struct slot *slot; | 376 | struct slot *slot; |
379 | struct list_head *tmp; | ||
380 | struct pci_dev* dev; | 377 | struct pci_dev* dev; |
381 | 378 | ||
382 | dbg("%s - enter", __FUNCTION__); | 379 | dbg("%s - enter", __FUNCTION__); |
383 | down_read(&list_rwsem); | 380 | down_read(&list_rwsem); |
384 | if(!slots) { | 381 | if (!slots) { |
385 | up_read(&list_rwsem); | 382 | up_read(&list_rwsem); |
386 | return -1; | 383 | return -1; |
387 | } | 384 | } |
388 | list_for_each(tmp, &slot_list) { | 385 | list_for_each_entry(slot, &slot_list, slot_list) { |
389 | slot = list_entry(tmp, struct slot, slot_list); | ||
390 | dbg("%s - looking at slot %s", | 386 | dbg("%s - looking at slot %s", |
391 | __FUNCTION__, slot->hotplug_slot->name); | 387 | __FUNCTION__, slot->hotplug_slot->name); |
392 | if(cpci_check_and_clear_ins(slot)) { | 388 | if (clear_ins && cpci_check_and_clear_ins(slot)) |
393 | dbg("%s - cleared INS for slot %s", | 389 | dbg("%s - cleared INS for slot %s", |
394 | __FUNCTION__, slot->hotplug_slot->name); | 390 | __FUNCTION__, slot->hotplug_slot->name); |
395 | dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0)); | 391 | dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); |
396 | if(dev) { | 392 | if (dev) { |
397 | if(update_adapter_status(slot->hotplug_slot, 1)) { | 393 | if (update_adapter_status(slot->hotplug_slot, 1)) |
398 | warn("failure to update adapter file"); | 394 | warn("failure to update adapter file"); |
399 | } | 395 | if (update_latch_status(slot->hotplug_slot, 1)) |
400 | if(update_latch_status(slot->hotplug_slot, 1)) { | 396 | warn("failure to update latch file"); |
401 | warn("failure to update latch file"); | 397 | slot->dev = dev; |
402 | } | ||
403 | slot->dev = dev; | ||
404 | } else { | ||
405 | err("%s - no driver attached to device in slot %s", | ||
406 | __FUNCTION__, slot->hotplug_slot->name); | ||
407 | } | ||
408 | } | 398 | } |
409 | } | 399 | } |
410 | up_read(&list_rwsem); | 400 | up_read(&list_rwsem); |
@@ -416,26 +406,28 @@ static int | |||
416 | check_slots(void) | 406 | check_slots(void) |
417 | { | 407 | { |
418 | struct slot *slot; | 408 | struct slot *slot; |
419 | struct list_head *tmp; | ||
420 | int extracted; | 409 | int extracted; |
421 | int inserted; | 410 | int inserted; |
422 | u16 hs_csr; | 411 | u16 hs_csr; |
423 | 412 | ||
424 | down_read(&list_rwsem); | 413 | down_read(&list_rwsem); |
425 | if(!slots) { | 414 | if (!slots) { |
426 | up_read(&list_rwsem); | 415 | up_read(&list_rwsem); |
427 | err("no slots registered, shutting down"); | 416 | err("no slots registered, shutting down"); |
428 | return -1; | 417 | return -1; |
429 | } | 418 | } |
430 | extracted = inserted = 0; | 419 | extracted = inserted = 0; |
431 | list_for_each(tmp, &slot_list) { | 420 | list_for_each_entry(slot, &slot_list, slot_list) { |
432 | slot = list_entry(tmp, struct slot, slot_list); | ||
433 | dbg("%s - looking at slot %s", | 421 | dbg("%s - looking at slot %s", |
434 | __FUNCTION__, slot->hotplug_slot->name); | 422 | __FUNCTION__, slot->hotplug_slot->name); |
435 | if(cpci_check_and_clear_ins(slot)) { | 423 | if (cpci_check_and_clear_ins(slot)) { |
436 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ | 424 | /* |
437 | if(slot->dev) { | 425 | * Some broken hardware (e.g. PLX 9054AB) asserts |
438 | warn("slot %s already inserted", slot->hotplug_slot->name); | 426 | * ENUM# twice... |
427 | */ | ||
428 | if (slot->dev) { | ||
429 | warn("slot %s already inserted", | ||
430 | slot->hotplug_slot->name); | ||
439 | inserted++; | 431 | inserted++; |
440 | continue; | 432 | continue; |
441 | } | 433 | } |
@@ -452,7 +444,7 @@ check_slots(void) | |||
452 | /* Configure device */ | 444 | /* Configure device */ |
453 | dbg("%s - configuring slot %s", | 445 | dbg("%s - configuring slot %s", |
454 | __FUNCTION__, slot->hotplug_slot->name); | 446 | __FUNCTION__, slot->hotplug_slot->name); |
455 | if(cpci_configure_slot(slot)) { | 447 | if (cpci_configure_slot(slot)) { |
456 | err("%s - could not configure slot %s", | 448 | err("%s - could not configure slot %s", |
457 | __FUNCTION__, slot->hotplug_slot->name); | 449 | __FUNCTION__, slot->hotplug_slot->name); |
458 | continue; | 450 | continue; |
@@ -465,13 +457,11 @@ check_slots(void) | |||
465 | dbg("%s - slot %s HS_CSR (2) = %04x", | 457 | dbg("%s - slot %s HS_CSR (2) = %04x", |
466 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 458 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
467 | 459 | ||
468 | if(update_latch_status(slot->hotplug_slot, 1)) { | 460 | if (update_latch_status(slot->hotplug_slot, 1)) |
469 | warn("failure to update latch file"); | 461 | warn("failure to update latch file"); |
470 | } | ||
471 | 462 | ||
472 | if(update_adapter_status(slot->hotplug_slot, 1)) { | 463 | if (update_adapter_status(slot->hotplug_slot, 1)) |
473 | warn("failure to update adapter file"); | 464 | warn("failure to update adapter file"); |
474 | } | ||
475 | 465 | ||
476 | cpci_led_off(slot); | 466 | cpci_led_off(slot); |
477 | 467 | ||
@@ -481,7 +471,7 @@ check_slots(void) | |||
481 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 471 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
482 | 472 | ||
483 | inserted++; | 473 | inserted++; |
484 | } else if(cpci_check_ext(slot)) { | 474 | } else if (cpci_check_ext(slot)) { |
485 | /* Process extraction request */ | 475 | /* Process extraction request */ |
486 | dbg("%s - slot %s extracted", | 476 | dbg("%s - slot %s extracted", |
487 | __FUNCTION__, slot->hotplug_slot->name); | 477 | __FUNCTION__, slot->hotplug_slot->name); |
@@ -491,27 +481,25 @@ check_slots(void) | |||
491 | dbg("%s - slot %s HS_CSR = %04x", | 481 | dbg("%s - slot %s HS_CSR = %04x", |
492 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 482 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
493 | 483 | ||
494 | if(!slot->extracting) { | 484 | if (!slot->extracting) { |
495 | if(update_latch_status(slot->hotplug_slot, 0)) { | 485 | if (update_latch_status(slot->hotplug_slot, 0)) { |
496 | warn("failure to update latch file"); | 486 | warn("failure to update latch file"); |
497 | |||
498 | } | 487 | } |
499 | atomic_inc(&extracting); | ||
500 | slot->extracting = 1; | 488 | slot->extracting = 1; |
489 | atomic_inc(&extracting); | ||
501 | } | 490 | } |
502 | extracted++; | 491 | extracted++; |
503 | } else if(slot->extracting) { | 492 | } else if (slot->extracting) { |
504 | hs_csr = cpci_get_hs_csr(slot); | 493 | hs_csr = cpci_get_hs_csr(slot); |
505 | if(hs_csr == 0xffff) { | 494 | if (hs_csr == 0xffff) { |
506 | /* | 495 | /* |
507 | * Hmmm, we're likely hosed at this point, should we | 496 | * Hmmm, we're likely hosed at this point, should we |
508 | * bother trying to tell the driver or not? | 497 | * bother trying to tell the driver or not? |
509 | */ | 498 | */ |
510 | err("card in slot %s was improperly removed", | 499 | err("card in slot %s was improperly removed", |
511 | slot->hotplug_slot->name); | 500 | slot->hotplug_slot->name); |
512 | if(update_adapter_status(slot->hotplug_slot, 0)) { | 501 | if (update_adapter_status(slot->hotplug_slot, 0)) |
513 | warn("failure to update adapter file"); | 502 | warn("failure to update adapter file"); |
514 | } | ||
515 | slot->extracting = 0; | 503 | slot->extracting = 0; |
516 | atomic_dec(&extracting); | 504 | atomic_dec(&extracting); |
517 | } | 505 | } |
@@ -520,10 +508,9 @@ check_slots(void) | |||
520 | up_read(&list_rwsem); | 508 | up_read(&list_rwsem); |
521 | dbg("inserted=%d, extracted=%d, extracting=%d", | 509 | dbg("inserted=%d, extracted=%d, extracting=%d", |
522 | inserted, extracted, atomic_read(&extracting)); | 510 | inserted, extracted, atomic_read(&extracting)); |
523 | if(inserted || extracted) { | 511 | if (inserted || extracted) |
524 | return extracted; | 512 | return extracted; |
525 | } | 513 | else if (!atomic_read(&extracting)) { |
526 | else if(!atomic_read(&extracting)) { | ||
527 | err("cannot find ENUM# source, shutting down"); | 514 | err("cannot find ENUM# source, shutting down"); |
528 | return -1; | 515 | return -1; |
529 | } | 516 | } |
@@ -541,12 +528,12 @@ event_thread(void *data) | |||
541 | unlock_kernel(); | 528 | unlock_kernel(); |
542 | 529 | ||
543 | dbg("%s - event thread started", __FUNCTION__); | 530 | dbg("%s - event thread started", __FUNCTION__); |
544 | while(1) { | 531 | while (1) { |
545 | dbg("event thread sleeping"); | 532 | dbg("event thread sleeping"); |
546 | down_interruptible(&event_semaphore); | 533 | down_interruptible(&event_semaphore); |
547 | dbg("event thread woken, thread_finished = %d", | 534 | dbg("event thread woken, thread_finished = %d", |
548 | thread_finished); | 535 | thread_finished); |
549 | if(thread_finished || signal_pending(current)) | 536 | if (thread_finished || signal_pending(current)) |
550 | break; | 537 | break; |
551 | do { | 538 | do { |
552 | rc = check_slots(); | 539 | rc = check_slots(); |
@@ -558,7 +545,9 @@ event_thread(void *data) | |||
558 | thread_finished = 1; | 545 | thread_finished = 1; |
559 | break; | 546 | break; |
560 | } | 547 | } |
561 | } while(atomic_read(&extracting) != 0); | 548 | } while (atomic_read(&extracting) && !thread_finished); |
549 | if (thread_finished) | ||
550 | break; | ||
562 | 551 | ||
563 | /* Re-enable ENUM# interrupt */ | 552 | /* Re-enable ENUM# interrupt */ |
564 | dbg("%s - re-enabling irq", __FUNCTION__); | 553 | dbg("%s - re-enabling irq", __FUNCTION__); |
@@ -579,21 +568,21 @@ poll_thread(void *data) | |||
579 | daemonize("cpci_hp_polld"); | 568 | daemonize("cpci_hp_polld"); |
580 | unlock_kernel(); | 569 | unlock_kernel(); |
581 | 570 | ||
582 | while(1) { | 571 | while (1) { |
583 | if(thread_finished || signal_pending(current)) | 572 | if (thread_finished || signal_pending(current)) |
584 | break; | 573 | break; |
585 | if(controller->ops->query_enum()) { | 574 | if (controller->ops->query_enum()) { |
586 | do { | 575 | do { |
587 | rc = check_slots(); | 576 | rc = check_slots(); |
588 | if(rc > 0) { | 577 | if (rc > 0) { |
589 | /* Give userspace a chance to handle extraction */ | 578 | /* Give userspace a chance to handle extraction */ |
590 | msleep(500); | 579 | msleep(500); |
591 | } else if(rc < 0) { | 580 | } else if (rc < 0) { |
592 | dbg("%s - error checking slots", __FUNCTION__); | 581 | dbg("%s - error checking slots", __FUNCTION__); |
593 | thread_finished = 1; | 582 | thread_finished = 1; |
594 | break; | 583 | break; |
595 | } | 584 | } |
596 | } while(atomic_read(&extracting) != 0); | 585 | } while (atomic_read(&extracting) && !thread_finished); |
597 | } | 586 | } |
598 | msleep(100); | 587 | msleep(100); |
599 | } | 588 | } |
@@ -612,12 +601,11 @@ cpci_start_thread(void) | |||
612 | init_MUTEX_LOCKED(&thread_exit); | 601 | init_MUTEX_LOCKED(&thread_exit); |
613 | thread_finished = 0; | 602 | thread_finished = 0; |
614 | 603 | ||
615 | if(controller->irq) { | 604 | if (controller->irq) |
616 | pid = kernel_thread(event_thread, NULL, 0); | 605 | pid = kernel_thread(event_thread, NULL, 0); |
617 | } else { | 606 | else |
618 | pid = kernel_thread(poll_thread, NULL, 0); | 607 | pid = kernel_thread(poll_thread, NULL, 0); |
619 | } | 608 | if (pid < 0) { |
620 | if(pid < 0) { | ||
621 | err("Can't start up our thread"); | 609 | err("Can't start up our thread"); |
622 | return -1; | 610 | return -1; |
623 | } | 611 | } |
@@ -630,9 +618,8 @@ cpci_stop_thread(void) | |||
630 | { | 618 | { |
631 | thread_finished = 1; | 619 | thread_finished = 1; |
632 | dbg("thread finish command given"); | 620 | dbg("thread finish command given"); |
633 | if(controller->irq) { | 621 | if (controller->irq) |
634 | up(&event_semaphore); | 622 | up(&event_semaphore); |
635 | } | ||
636 | dbg("wait for thread to exit"); | 623 | dbg("wait for thread to exit"); |
637 | down(&thread_exit); | 624 | down(&thread_exit); |
638 | } | 625 | } |
@@ -642,45 +629,67 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller) | |||
642 | { | 629 | { |
643 | int status = 0; | 630 | int status = 0; |
644 | 631 | ||
645 | if(!controller) { | 632 | if (controller) |
646 | controller = new_controller; | 633 | return -1; |
647 | if(controller->irq) { | 634 | if (!(new_controller && new_controller->ops)) |
648 | if(request_irq(controller->irq, | 635 | return -EINVAL; |
649 | cpci_hp_intr, | 636 | if (new_controller->irq) { |
650 | controller->irq_flags, | 637 | if (!(new_controller->ops->enable_irq && |
651 | MY_NAME, controller->dev_id)) { | 638 | new_controller->ops->disable_irq)) |
652 | err("Can't get irq %d for the hotplug cPCI controller", controller->irq); | 639 | status = -EINVAL; |
653 | status = -ENODEV; | 640 | if (request_irq(new_controller->irq, |
654 | } | 641 | cpci_hp_intr, |
655 | dbg("%s - acquired controller irq %d", __FUNCTION__, | 642 | new_controller->irq_flags, |
656 | controller->irq); | 643 | MY_NAME, |
644 | new_controller->dev_id)) { | ||
645 | err("Can't get irq %d for the hotplug cPCI controller", | ||
646 | new_controller->irq); | ||
647 | status = -ENODEV; | ||
657 | } | 648 | } |
658 | } else { | 649 | dbg("%s - acquired controller irq %d", |
659 | err("cPCI hotplug controller already registered"); | 650 | __FUNCTION__, new_controller->irq); |
660 | status = -1; | ||
661 | } | 651 | } |
652 | if (!status) | ||
653 | controller = new_controller; | ||
662 | return status; | 654 | return status; |
663 | } | 655 | } |
664 | 656 | ||
657 | static void | ||
658 | cleanup_slots(void) | ||
659 | { | ||
660 | struct slot *slot; | ||
661 | struct slot *tmp; | ||
662 | |||
663 | /* | ||
664 | * Unregister all of our slots with the pci_hotplug subsystem, | ||
665 | * and free up all memory that we had allocated. | ||
666 | */ | ||
667 | down_write(&list_rwsem); | ||
668 | if (!slots) | ||
669 | goto cleanup_null; | ||
670 | list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { | ||
671 | list_del(&slot->slot_list); | ||
672 | pci_hp_deregister(slot->hotplug_slot); | ||
673 | } | ||
674 | cleanup_null: | ||
675 | up_write(&list_rwsem); | ||
676 | return; | ||
677 | } | ||
678 | |||
665 | int | 679 | int |
666 | cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) | 680 | cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) |
667 | { | 681 | { |
668 | int status = 0; | 682 | int status = 0; |
669 | 683 | ||
670 | if(controller) { | 684 | if (controller) { |
671 | if(atomic_read(&extracting) != 0) { | 685 | if (!thread_finished) |
672 | return -EBUSY; | ||
673 | } | ||
674 | if(!thread_finished) { | ||
675 | cpci_stop_thread(); | 686 | cpci_stop_thread(); |
676 | } | 687 | if (controller->irq) |
677 | if(controller->irq) { | ||
678 | free_irq(controller->irq, controller->dev_id); | 688 | free_irq(controller->irq, controller->dev_id); |
679 | } | ||
680 | controller = NULL; | 689 | controller = NULL; |
681 | } else { | 690 | cleanup_slots(); |
691 | } else | ||
682 | status = -ENODEV; | 692 | status = -ENODEV; |
683 | } | ||
684 | return status; | 693 | return status; |
685 | } | 694 | } |
686 | 695 | ||
@@ -691,32 +700,28 @@ cpci_hp_start(void) | |||
691 | int status; | 700 | int status; |
692 | 701 | ||
693 | dbg("%s - enter", __FUNCTION__); | 702 | dbg("%s - enter", __FUNCTION__); |
694 | if(!controller) { | 703 | if (!controller) |
695 | return -ENODEV; | 704 | return -ENODEV; |
696 | } | ||
697 | 705 | ||
698 | down_read(&list_rwsem); | 706 | down_read(&list_rwsem); |
699 | if(list_empty(&slot_list)) { | 707 | if (list_empty(&slot_list)) { |
700 | up_read(&list_rwsem); | 708 | up_read(&list_rwsem); |
701 | return -ENODEV; | 709 | return -ENODEV; |
702 | } | 710 | } |
703 | up_read(&list_rwsem); | 711 | up_read(&list_rwsem); |
704 | 712 | ||
705 | if(first) { | 713 | status = init_slots(first); |
706 | status = init_slots(); | 714 | if (first) |
707 | if(status) { | ||
708 | return status; | ||
709 | } | ||
710 | first = 0; | 715 | first = 0; |
711 | } | 716 | if (status) |
717 | return status; | ||
712 | 718 | ||
713 | status = cpci_start_thread(); | 719 | status = cpci_start_thread(); |
714 | if(status) { | 720 | if (status) |
715 | return status; | 721 | return status; |
716 | } | ||
717 | dbg("%s - thread started", __FUNCTION__); | 722 | dbg("%s - thread started", __FUNCTION__); |
718 | 723 | ||
719 | if(controller->irq) { | 724 | if (controller->irq) { |
720 | /* Start enum interrupt processing */ | 725 | /* Start enum interrupt processing */ |
721 | dbg("%s - enabling irq", __FUNCTION__); | 726 | dbg("%s - enabling irq", __FUNCTION__); |
722 | controller->ops->enable_irq(); | 727 | controller->ops->enable_irq(); |
@@ -728,13 +733,9 @@ cpci_hp_start(void) | |||
728 | int | 733 | int |
729 | cpci_hp_stop(void) | 734 | cpci_hp_stop(void) |
730 | { | 735 | { |
731 | if(!controller) { | 736 | if (!controller) |
732 | return -ENODEV; | 737 | return -ENODEV; |
733 | } | 738 | if (controller->irq) { |
734 | if(atomic_read(&extracting) != 0) { | ||
735 | return -EBUSY; | ||
736 | } | ||
737 | if(controller->irq) { | ||
738 | /* Stop enum interrupt processing */ | 739 | /* Stop enum interrupt processing */ |
739 | dbg("%s - disabling irq", __FUNCTION__); | 740 | dbg("%s - disabling irq", __FUNCTION__); |
740 | controller->ops->disable_irq(); | 741 | controller->ops->disable_irq(); |
@@ -743,34 +744,6 @@ cpci_hp_stop(void) | |||
743 | return 0; | 744 | return 0; |
744 | } | 745 | } |
745 | 746 | ||
746 | static void __exit | ||
747 | cleanup_slots(void) | ||
748 | { | ||
749 | struct list_head *tmp; | ||
750 | struct slot *slot; | ||
751 | |||
752 | /* | ||
753 | * Unregister all of our slots with the pci_hotplug subsystem, | ||
754 | * and free up all memory that we had allocated. | ||
755 | */ | ||
756 | down_write(&list_rwsem); | ||
757 | if(!slots) { | ||
758 | goto null_cleanup; | ||
759 | } | ||
760 | list_for_each(tmp, &slot_list) { | ||
761 | slot = list_entry(tmp, struct slot, slot_list); | ||
762 | list_del(&slot->slot_list); | ||
763 | pci_hp_deregister(slot->hotplug_slot); | ||
764 | kfree(slot->hotplug_slot->info); | ||
765 | kfree(slot->hotplug_slot->name); | ||
766 | kfree(slot->hotplug_slot); | ||
767 | kfree(slot); | ||
768 | } | ||
769 | null_cleanup: | ||
770 | up_write(&list_rwsem); | ||
771 | return; | ||
772 | } | ||
773 | |||
774 | int __init | 747 | int __init |
775 | cpci_hotplug_init(int debug) | 748 | cpci_hotplug_init(int debug) |
776 | { | 749 | { |
@@ -784,7 +757,8 @@ cpci_hotplug_exit(void) | |||
784 | /* | 757 | /* |
785 | * Clean everything up. | 758 | * Clean everything up. |
786 | */ | 759 | */ |
787 | cleanup_slots(); | 760 | cpci_hp_stop(); |
761 | cpci_hp_unregister_controller(controller); | ||
788 | } | 762 | } |
789 | 763 | ||
790 | EXPORT_SYMBOL_GPL(cpci_hp_register_controller); | 764 | EXPORT_SYMBOL_GPL(cpci_hp_register_controller); |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 69eb4fc54f2f..c878028ad215 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CompactPCI Hot Plug Driver PCI functions | 2 | * CompactPCI Hot Plug Driver PCI functions |
3 | * | 3 | * |
4 | * Copyright (C) 2002 by SOMA Networks, Inc. | 4 | * Copyright (C) 2002,2005 by SOMA Networks, Inc. |
5 | * | 5 | * |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -38,10 +38,10 @@ extern int cpci_debug; | |||
38 | 38 | ||
39 | #define dbg(format, arg...) \ | 39 | #define dbg(format, arg...) \ |
40 | do { \ | 40 | do { \ |
41 | if(cpci_debug) \ | 41 | if (cpci_debug) \ |
42 | printk (KERN_DEBUG "%s: " format "\n", \ | 42 | printk (KERN_DEBUG "%s: " format "\n", \ |
43 | MY_NAME , ## arg); \ | 43 | MY_NAME , ## arg); \ |
44 | } while(0) | 44 | } while (0) |
45 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 45 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
46 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 46 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
47 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 47 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
@@ -57,16 +57,15 @@ u8 cpci_get_attention_status(struct slot* slot) | |||
57 | hs_cap = pci_bus_find_capability(slot->bus, | 57 | hs_cap = pci_bus_find_capability(slot->bus, |
58 | slot->devfn, | 58 | slot->devfn, |
59 | PCI_CAP_ID_CHSWP); | 59 | PCI_CAP_ID_CHSWP); |
60 | if(!hs_cap) { | 60 | if (!hs_cap) |
61 | return 0; | 61 | return 0; |
62 | } | ||
63 | 62 | ||
64 | if(pci_bus_read_config_word(slot->bus, | 63 | if (pci_bus_read_config_word(slot->bus, |
65 | slot->devfn, | 64 | slot->devfn, |
66 | hs_cap + 2, | 65 | hs_cap + 2, |
67 | &hs_csr)) { | 66 | &hs_csr)) |
68 | return 0; | 67 | return 0; |
69 | } | 68 | |
70 | return hs_csr & 0x0008 ? 1 : 0; | 69 | return hs_csr & 0x0008 ? 1 : 0; |
71 | } | 70 | } |
72 | 71 | ||
@@ -78,27 +77,22 @@ int cpci_set_attention_status(struct slot* slot, int status) | |||
78 | hs_cap = pci_bus_find_capability(slot->bus, | 77 | hs_cap = pci_bus_find_capability(slot->bus, |
79 | slot->devfn, | 78 | slot->devfn, |
80 | PCI_CAP_ID_CHSWP); | 79 | PCI_CAP_ID_CHSWP); |
81 | if(!hs_cap) { | 80 | if (!hs_cap) |
82 | return 0; | 81 | return 0; |
83 | } | 82 | if (pci_bus_read_config_word(slot->bus, |
84 | |||
85 | if(pci_bus_read_config_word(slot->bus, | ||
86 | slot->devfn, | 83 | slot->devfn, |
87 | hs_cap + 2, | 84 | hs_cap + 2, |
88 | &hs_csr)) { | 85 | &hs_csr)) |
89 | return 0; | 86 | return 0; |
90 | } | 87 | if (status) |
91 | if(status) { | ||
92 | hs_csr |= HS_CSR_LOO; | 88 | hs_csr |= HS_CSR_LOO; |
93 | } else { | 89 | else |
94 | hs_csr &= ~HS_CSR_LOO; | 90 | hs_csr &= ~HS_CSR_LOO; |
95 | } | 91 | if (pci_bus_write_config_word(slot->bus, |
96 | if(pci_bus_write_config_word(slot->bus, | ||
97 | slot->devfn, | 92 | slot->devfn, |
98 | hs_cap + 2, | 93 | hs_cap + 2, |
99 | hs_csr)) { | 94 | hs_csr)) |
100 | return 0; | 95 | return 0; |
101 | } | ||
102 | return 1; | 96 | return 1; |
103 | } | 97 | } |
104 | 98 | ||
@@ -110,16 +104,13 @@ u16 cpci_get_hs_csr(struct slot* slot) | |||
110 | hs_cap = pci_bus_find_capability(slot->bus, | 104 | hs_cap = pci_bus_find_capability(slot->bus, |
111 | slot->devfn, | 105 | slot->devfn, |
112 | PCI_CAP_ID_CHSWP); | 106 | PCI_CAP_ID_CHSWP); |
113 | if(!hs_cap) { | 107 | if (!hs_cap) |
114 | return 0xFFFF; | 108 | return 0xFFFF; |
115 | } | 109 | if (pci_bus_read_config_word(slot->bus, |
116 | |||
117 | if(pci_bus_read_config_word(slot->bus, | ||
118 | slot->devfn, | 110 | slot->devfn, |
119 | hs_cap + 2, | 111 | hs_cap + 2, |
120 | &hs_csr)) { | 112 | &hs_csr)) |
121 | return 0xFFFF; | 113 | return 0xFFFF; |
122 | } | ||
123 | return hs_csr; | 114 | return hs_csr; |
124 | } | 115 | } |
125 | 116 | ||
@@ -132,24 +123,22 @@ int cpci_check_and_clear_ins(struct slot* slot) | |||
132 | hs_cap = pci_bus_find_capability(slot->bus, | 123 | hs_cap = pci_bus_find_capability(slot->bus, |
133 | slot->devfn, | 124 | slot->devfn, |
134 | PCI_CAP_ID_CHSWP); | 125 | PCI_CAP_ID_CHSWP); |
135 | if(!hs_cap) { | 126 | if (!hs_cap) |
136 | return 0; | 127 | return 0; |
137 | } | 128 | if (pci_bus_read_config_word(slot->bus, |
138 | if(pci_bus_read_config_word(slot->bus, | ||
139 | slot->devfn, | 129 | slot->devfn, |
140 | hs_cap + 2, | 130 | hs_cap + 2, |
141 | &hs_csr)) { | 131 | &hs_csr)) |
142 | return 0; | 132 | return 0; |
143 | } | 133 | if (hs_csr & HS_CSR_INS) { |
144 | if(hs_csr & HS_CSR_INS) { | ||
145 | /* Clear INS (by setting it) */ | 134 | /* Clear INS (by setting it) */ |
146 | if(pci_bus_write_config_word(slot->bus, | 135 | if (pci_bus_write_config_word(slot->bus, |
147 | slot->devfn, | 136 | slot->devfn, |
148 | hs_cap + 2, | 137 | hs_cap + 2, |
149 | hs_csr)) { | 138 | hs_csr)) |
150 | ins = 0; | 139 | ins = 0; |
151 | } | 140 | else |
152 | ins = 1; | 141 | ins = 1; |
153 | } | 142 | } |
154 | return ins; | 143 | return ins; |
155 | } | 144 | } |
@@ -163,18 +152,15 @@ int cpci_check_ext(struct slot* slot) | |||
163 | hs_cap = pci_bus_find_capability(slot->bus, | 152 | hs_cap = pci_bus_find_capability(slot->bus, |
164 | slot->devfn, | 153 | slot->devfn, |
165 | PCI_CAP_ID_CHSWP); | 154 | PCI_CAP_ID_CHSWP); |
166 | if(!hs_cap) { | 155 | if (!hs_cap) |
167 | return 0; | 156 | return 0; |
168 | } | 157 | if (pci_bus_read_config_word(slot->bus, |
169 | if(pci_bus_read_config_word(slot->bus, | ||
170 | slot->devfn, | 158 | slot->devfn, |
171 | hs_cap + 2, | 159 | hs_cap + 2, |
172 | &hs_csr)) { | 160 | &hs_csr)) |
173 | return 0; | 161 | return 0; |
174 | } | 162 | if (hs_csr & HS_CSR_EXT) |
175 | if(hs_csr & HS_CSR_EXT) { | ||
176 | ext = 1; | 163 | ext = 1; |
177 | } | ||
178 | return ext; | 164 | return ext; |
179 | } | 165 | } |
180 | 166 | ||
@@ -186,23 +172,20 @@ int cpci_clear_ext(struct slot* slot) | |||
186 | hs_cap = pci_bus_find_capability(slot->bus, | 172 | hs_cap = pci_bus_find_capability(slot->bus, |
187 | slot->devfn, | 173 | slot->devfn, |
188 | PCI_CAP_ID_CHSWP); | 174 | PCI_CAP_ID_CHSWP); |
189 | if(!hs_cap) { | 175 | if (!hs_cap) |
190 | return -ENODEV; | 176 | return -ENODEV; |
191 | } | 177 | if (pci_bus_read_config_word(slot->bus, |
192 | if(pci_bus_read_config_word(slot->bus, | ||
193 | slot->devfn, | 178 | slot->devfn, |
194 | hs_cap + 2, | 179 | hs_cap + 2, |
195 | &hs_csr)) { | 180 | &hs_csr)) |
196 | return -ENODEV; | 181 | return -ENODEV; |
197 | } | 182 | if (hs_csr & HS_CSR_EXT) { |
198 | if(hs_csr & HS_CSR_EXT) { | ||
199 | /* Clear EXT (by setting it) */ | 183 | /* Clear EXT (by setting it) */ |
200 | if(pci_bus_write_config_word(slot->bus, | 184 | if (pci_bus_write_config_word(slot->bus, |
201 | slot->devfn, | 185 | slot->devfn, |
202 | hs_cap + 2, | 186 | hs_cap + 2, |
203 | hs_csr)) { | 187 | hs_csr)) |
204 | return -ENODEV; | 188 | return -ENODEV; |
205 | } | ||
206 | } | 189 | } |
207 | return 0; | 190 | return 0; |
208 | } | 191 | } |
@@ -215,18 +198,16 @@ int cpci_led_on(struct slot* slot) | |||
215 | hs_cap = pci_bus_find_capability(slot->bus, | 198 | hs_cap = pci_bus_find_capability(slot->bus, |
216 | slot->devfn, | 199 | slot->devfn, |
217 | PCI_CAP_ID_CHSWP); | 200 | PCI_CAP_ID_CHSWP); |
218 | if(!hs_cap) { | 201 | if (!hs_cap) |
219 | return -ENODEV; | 202 | return -ENODEV; |
220 | } | 203 | if (pci_bus_read_config_word(slot->bus, |
221 | if(pci_bus_read_config_word(slot->bus, | ||
222 | slot->devfn, | 204 | slot->devfn, |
223 | hs_cap + 2, | 205 | hs_cap + 2, |
224 | &hs_csr)) { | 206 | &hs_csr)) |
225 | return -ENODEV; | 207 | return -ENODEV; |
226 | } | 208 | if ((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { |
227 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { | ||
228 | hs_csr |= HS_CSR_LOO; | 209 | hs_csr |= HS_CSR_LOO; |
229 | if(pci_bus_write_config_word(slot->bus, | 210 | if (pci_bus_write_config_word(slot->bus, |
230 | slot->devfn, | 211 | slot->devfn, |
231 | hs_cap + 2, | 212 | hs_cap + 2, |
232 | hs_csr)) { | 213 | hs_csr)) { |
@@ -246,18 +227,16 @@ int cpci_led_off(struct slot* slot) | |||
246 | hs_cap = pci_bus_find_capability(slot->bus, | 227 | hs_cap = pci_bus_find_capability(slot->bus, |
247 | slot->devfn, | 228 | slot->devfn, |
248 | PCI_CAP_ID_CHSWP); | 229 | PCI_CAP_ID_CHSWP); |
249 | if(!hs_cap) { | 230 | if (!hs_cap) |
250 | return -ENODEV; | 231 | return -ENODEV; |
251 | } | 232 | if (pci_bus_read_config_word(slot->bus, |
252 | if(pci_bus_read_config_word(slot->bus, | ||
253 | slot->devfn, | 233 | slot->devfn, |
254 | hs_cap + 2, | 234 | hs_cap + 2, |
255 | &hs_csr)) { | 235 | &hs_csr)) |
256 | return -ENODEV; | 236 | return -ENODEV; |
257 | } | 237 | if (hs_csr & HS_CSR_LOO) { |
258 | if(hs_csr & HS_CSR_LOO) { | ||
259 | hs_csr &= ~HS_CSR_LOO; | 238 | hs_csr &= ~HS_CSR_LOO; |
260 | if(pci_bus_write_config_word(slot->bus, | 239 | if (pci_bus_write_config_word(slot->bus, |
261 | slot->devfn, | 240 | slot->devfn, |
262 | hs_cap + 2, | 241 | hs_cap + 2, |
263 | hs_csr)) { | 242 | hs_csr)) { |
@@ -274,19 +253,6 @@ int cpci_led_off(struct slot* slot) | |||
274 | * Device configuration functions | 253 | * Device configuration functions |
275 | */ | 254 | */ |
276 | 255 | ||
277 | static void cpci_enable_device(struct pci_dev *dev) | ||
278 | { | ||
279 | struct pci_bus *bus; | ||
280 | |||
281 | pci_enable_device(dev); | ||
282 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
283 | bus = dev->subordinate; | ||
284 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
285 | cpci_enable_device(dev); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | int cpci_configure_slot(struct slot* slot) | 256 | int cpci_configure_slot(struct slot* slot) |
291 | { | 257 | { |
292 | unsigned char busnr; | 258 | unsigned char busnr; |
@@ -294,14 +260,14 @@ int cpci_configure_slot(struct slot* slot) | |||
294 | 260 | ||
295 | dbg("%s - enter", __FUNCTION__); | 261 | dbg("%s - enter", __FUNCTION__); |
296 | 262 | ||
297 | if(slot->dev == NULL) { | 263 | if (slot->dev == NULL) { |
298 | dbg("pci_dev null, finding %02x:%02x:%x", | 264 | dbg("pci_dev null, finding %02x:%02x:%x", |
299 | slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); | 265 | slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); |
300 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 266 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
301 | } | 267 | } |
302 | 268 | ||
303 | /* Still NULL? Well then scan for it! */ | 269 | /* Still NULL? Well then scan for it! */ |
304 | if(slot->dev == NULL) { | 270 | if (slot->dev == NULL) { |
305 | int n; | 271 | int n; |
306 | dbg("pci_dev still null"); | 272 | dbg("pci_dev still null"); |
307 | 273 | ||
@@ -311,10 +277,10 @@ int cpci_configure_slot(struct slot* slot) | |||
311 | */ | 277 | */ |
312 | n = pci_scan_slot(slot->bus, slot->devfn); | 278 | n = pci_scan_slot(slot->bus, slot->devfn); |
313 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); | 279 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); |
314 | if(n > 0) | 280 | if (n > 0) |
315 | pci_bus_add_devices(slot->bus); | 281 | pci_bus_add_devices(slot->bus); |
316 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 282 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
317 | if(slot->dev == NULL) { | 283 | if (slot->dev == NULL) { |
318 | err("Could not find PCI device for slot %02x", slot->number); | 284 | err("Could not find PCI device for slot %02x", slot->number); |
319 | return 1; | 285 | return 1; |
320 | } | 286 | } |
@@ -329,8 +295,6 @@ int cpci_configure_slot(struct slot* slot) | |||
329 | 295 | ||
330 | pci_bus_assign_resources(slot->dev->bus); | 296 | pci_bus_assign_resources(slot->dev->bus); |
331 | 297 | ||
332 | cpci_enable_device(slot->dev); | ||
333 | |||
334 | dbg("%s - exit", __FUNCTION__); | 298 | dbg("%s - exit", __FUNCTION__); |
335 | return 0; | 299 | return 0; |
336 | } | 300 | } |
@@ -341,15 +305,15 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
341 | struct pci_dev *dev; | 305 | struct pci_dev *dev; |
342 | 306 | ||
343 | dbg("%s - enter", __FUNCTION__); | 307 | dbg("%s - enter", __FUNCTION__); |
344 | if(!slot->dev) { | 308 | if (!slot->dev) { |
345 | err("No device for slot %02x\n", slot->number); | 309 | err("No device for slot %02x\n", slot->number); |
346 | return -ENODEV; | 310 | return -ENODEV; |
347 | } | 311 | } |
348 | 312 | ||
349 | for (i = 0; i < 8; i++) { | 313 | for (i = 0; i < 8; i++) { |
350 | dev = pci_find_slot(slot->bus->number, | 314 | dev = pci_get_slot(slot->bus, |
351 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 315 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
352 | if(dev) { | 316 | if (dev) { |
353 | pci_remove_bus_device(dev); | 317 | pci_remove_bus_device(dev); |
354 | slot->dev = NULL; | 318 | slot->dev = NULL; |
355 | } | 319 | } |
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 243a51d88b86..7957cdc72cd0 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c | |||
@@ -1626,7 +1626,7 @@ int shpchprm_set_hpp( | |||
1626 | pci_bus->number = func->bus; | 1626 | pci_bus->number = func->bus; |
1627 | devfn = PCI_DEVFN(func->device, func->function); | 1627 | devfn = PCI_DEVFN(func->device, func->function); |
1628 | 1628 | ||
1629 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); | 1629 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); |
1630 | 1630 | ||
1631 | if (ab) { | 1631 | if (ab) { |
1632 | if (ab->_hpp) { | 1632 | if (ab->_hpp) { |
@@ -1681,7 +1681,7 @@ void shpchprm_enable_card( | |||
1681 | | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; | 1681 | | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; |
1682 | bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; | 1682 | bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; |
1683 | 1683 | ||
1684 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); | 1684 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); |
1685 | if (ab) { | 1685 | if (ab) { |
1686 | if (ab->_hpp) { | 1686 | if (ab->_hpp) { |
1687 | if (ab->_hpp->enable_perr) { | 1687 | if (ab->_hpp->enable_perr) { |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index da5bd33d982d..fc5263c6b102 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/dma-mapping.h> | ||
35 | #include "scsi.h" | 36 | #include "scsi.h" |
36 | #include <scsi/scsi_host.h> | 37 | #include <scsi/scsi_host.h> |
37 | #include <linux/libata.h> | 38 | #include <linux/libata.h> |
@@ -289,6 +290,8 @@ static void ahci_host_stop(struct ata_host_set *host_set) | |||
289 | { | 290 | { |
290 | struct ahci_host_priv *hpriv = host_set->private_data; | 291 | struct ahci_host_priv *hpriv = host_set->private_data; |
291 | kfree(hpriv); | 292 | kfree(hpriv); |
293 | |||
294 | ata_host_stop(host_set); | ||
292 | } | 295 | } |
293 | 296 | ||
294 | static int ahci_port_start(struct ata_port *ap) | 297 | static int ahci_port_start(struct ata_port *ap) |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 550c9921691a..7c02b7dc7098 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -2488,7 +2488,7 @@ ahd_linux_dv_thread(void *data) | |||
2488 | sprintf(current->comm, "ahd_dv_%d", ahd->unit); | 2488 | sprintf(current->comm, "ahd_dv_%d", ahd->unit); |
2489 | #else | 2489 | #else |
2490 | daemonize("ahd_dv_%d", ahd->unit); | 2490 | daemonize("ahd_dv_%d", ahd->unit); |
2491 | current->flags |= PF_FREEZE; | 2491 | current->flags |= PF_NOFREEZE; |
2492 | #endif | 2492 | #endif |
2493 | unlock_kernel(); | 2493 | unlock_kernel(); |
2494 | 2494 | ||
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 3867f91ef8c7..3be546439252 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -153,6 +153,7 @@ static struct ata_port_operations piix_pata_ops = { | |||
153 | 153 | ||
154 | .port_start = ata_port_start, | 154 | .port_start = ata_port_start, |
155 | .port_stop = ata_port_stop, | 155 | .port_stop = ata_port_stop, |
156 | .host_stop = ata_host_stop, | ||
156 | }; | 157 | }; |
157 | 158 | ||
158 | static struct ata_port_operations piix_sata_ops = { | 159 | static struct ata_port_operations piix_sata_ops = { |
@@ -180,6 +181,7 @@ static struct ata_port_operations piix_sata_ops = { | |||
180 | 181 | ||
181 | .port_start = ata_port_start, | 182 | .port_start = ata_port_start, |
182 | .port_stop = ata_port_stop, | 183 | .port_stop = ata_port_stop, |
184 | .host_stop = ata_host_stop, | ||
183 | }; | 185 | }; |
184 | 186 | ||
185 | static struct ata_port_info piix_port_info[] = { | 187 | static struct ata_port_info piix_port_info[] = { |
@@ -663,15 +665,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
663 | return ata_pci_init_one(pdev, port_info, n_ports); | 665 | return ata_pci_init_one(pdev, port_info, n_ports); |
664 | } | 666 | } |
665 | 667 | ||
666 | /** | ||
667 | * piix_init - | ||
668 | * | ||
669 | * LOCKING: | ||
670 | * | ||
671 | * RETURNS: | ||
672 | * | ||
673 | */ | ||
674 | |||
675 | static int __init piix_init(void) | 668 | static int __init piix_init(void) |
676 | { | 669 | { |
677 | int rc; | 670 | int rc; |
@@ -687,13 +680,6 @@ static int __init piix_init(void) | |||
687 | return 0; | 680 | return 0; |
688 | } | 681 | } |
689 | 682 | ||
690 | /** | ||
691 | * piix_exit - | ||
692 | * | ||
693 | * LOCKING: | ||
694 | * | ||
695 | */ | ||
696 | |||
697 | static void __exit piix_exit(void) | 683 | static void __exit piix_exit(void) |
698 | { | 684 | { |
699 | pci_unregister_driver(&piix_pci_driver); | 685 | pci_unregister_driver(&piix_pci_driver); |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 63d3f70d06e1..21d194c6ace3 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -186,6 +186,28 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) | |||
186 | ata_wait_idle(ap); | 186 | ata_wait_idle(ap); |
187 | } | 187 | } |
188 | 188 | ||
189 | |||
190 | /** | ||
191 | * ata_tf_load - send taskfile registers to host controller | ||
192 | * @ap: Port to which output is sent | ||
193 | * @tf: ATA taskfile register set | ||
194 | * | ||
195 | * Outputs ATA taskfile to standard ATA host controller using MMIO | ||
196 | * or PIO as indicated by the ATA_FLAG_MMIO flag. | ||
197 | * Writes the control, feature, nsect, lbal, lbam, and lbah registers. | ||
198 | * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, | ||
199 | * hob_lbal, hob_lbam, and hob_lbah. | ||
200 | * | ||
201 | * This function waits for idle (!BUSY and !DRQ) after writing | ||
202 | * registers. If the control register has a new value, this | ||
203 | * function also waits for idle after writing control and before | ||
204 | * writing the remaining registers. | ||
205 | * | ||
206 | * May be used as the tf_load() entry in ata_port_operations. | ||
207 | * | ||
208 | * LOCKING: | ||
209 | * Inherited from caller. | ||
210 | */ | ||
189 | void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) | 211 | void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) |
190 | { | 212 | { |
191 | if (ap->flags & ATA_FLAG_MMIO) | 213 | if (ap->flags & ATA_FLAG_MMIO) |
@@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) | |||
195 | } | 217 | } |
196 | 218 | ||
197 | /** | 219 | /** |
198 | * ata_exec_command - issue ATA command to host controller | 220 | * ata_exec_command_pio - issue ATA command to host controller |
199 | * @ap: port to which command is being issued | 221 | * @ap: port to which command is being issued |
200 | * @tf: ATA taskfile register set | 222 | * @tf: ATA taskfile register set |
201 | * | 223 | * |
202 | * Issues PIO/MMIO write to ATA command register, with proper | 224 | * Issues PIO write to ATA command register, with proper |
203 | * synchronization with interrupt handler / other threads. | 225 | * synchronization with interrupt handler / other threads. |
204 | * | 226 | * |
205 | * LOCKING: | 227 | * LOCKING: |
@@ -235,6 +257,18 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) | |||
235 | ata_pause(ap); | 257 | ata_pause(ap); |
236 | } | 258 | } |
237 | 259 | ||
260 | |||
261 | /** | ||
262 | * ata_exec_command - issue ATA command to host controller | ||
263 | * @ap: port to which command is being issued | ||
264 | * @tf: ATA taskfile register set | ||
265 | * | ||
266 | * Issues PIO/MMIO write to ATA command register, with proper | ||
267 | * synchronization with interrupt handler / other threads. | ||
268 | * | ||
269 | * LOCKING: | ||
270 | * spin_lock_irqsave(host_set lock) | ||
271 | */ | ||
238 | void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf) | 272 | void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf) |
239 | { | 273 | { |
240 | if (ap->flags & ATA_FLAG_MMIO) | 274 | if (ap->flags & ATA_FLAG_MMIO) |
@@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf) | |||
305 | } | 339 | } |
306 | 340 | ||
307 | /** | 341 | /** |
308 | * ata_tf_read - input device's ATA taskfile shadow registers | 342 | * ata_tf_read_pio - input device's ATA taskfile shadow registers |
309 | * @ap: Port from which input is read | 343 | * @ap: Port from which input is read |
310 | * @tf: ATA taskfile register set for storing input | 344 | * @tf: ATA taskfile register set for storing input |
311 | * | 345 | * |
@@ -368,6 +402,23 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) | |||
368 | } | 402 | } |
369 | } | 403 | } |
370 | 404 | ||
405 | |||
406 | /** | ||
407 | * ata_tf_read - input device's ATA taskfile shadow registers | ||
408 | * @ap: Port from which input is read | ||
409 | * @tf: ATA taskfile register set for storing input | ||
410 | * | ||
411 | * Reads ATA taskfile registers for currently-selected device | ||
412 | * into @tf. | ||
413 | * | ||
414 | * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 | ||
415 | * is set, also reads the hob registers. | ||
416 | * | ||
417 | * May be used as the tf_read() entry in ata_port_operations. | ||
418 | * | ||
419 | * LOCKING: | ||
420 | * Inherited from caller. | ||
421 | */ | ||
371 | void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | 422 | void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) |
372 | { | 423 | { |
373 | if (ap->flags & ATA_FLAG_MMIO) | 424 | if (ap->flags & ATA_FLAG_MMIO) |
@@ -381,7 +432,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
381 | * @ap: port where the device is | 432 | * @ap: port where the device is |
382 | * | 433 | * |
383 | * Reads ATA taskfile status register for currently-selected device | 434 | * Reads ATA taskfile status register for currently-selected device |
384 | * and return it's value. This also clears pending interrupts | 435 | * and return its value. This also clears pending interrupts |
385 | * from this device | 436 | * from this device |
386 | * | 437 | * |
387 | * LOCKING: | 438 | * LOCKING: |
@@ -397,7 +448,7 @@ static u8 ata_check_status_pio(struct ata_port *ap) | |||
397 | * @ap: port where the device is | 448 | * @ap: port where the device is |
398 | * | 449 | * |
399 | * Reads ATA taskfile status register for currently-selected device | 450 | * Reads ATA taskfile status register for currently-selected device |
400 | * via MMIO and return it's value. This also clears pending interrupts | 451 | * via MMIO and return its value. This also clears pending interrupts |
401 | * from this device | 452 | * from this device |
402 | * | 453 | * |
403 | * LOCKING: | 454 | * LOCKING: |
@@ -408,6 +459,20 @@ static u8 ata_check_status_mmio(struct ata_port *ap) | |||
408 | return readb((void __iomem *) ap->ioaddr.status_addr); | 459 | return readb((void __iomem *) ap->ioaddr.status_addr); |
409 | } | 460 | } |
410 | 461 | ||
462 | |||
463 | /** | ||
464 | * ata_check_status - Read device status reg & clear interrupt | ||
465 | * @ap: port where the device is | ||
466 | * | ||
467 | * Reads ATA taskfile status register for currently-selected device | ||
468 | * and return its value. This also clears pending interrupts | ||
469 | * from this device | ||
470 | * | ||
471 | * May be used as the check_status() entry in ata_port_operations. | ||
472 | * | ||
473 | * LOCKING: | ||
474 | * Inherited from caller. | ||
475 | */ | ||
411 | u8 ata_check_status(struct ata_port *ap) | 476 | u8 ata_check_status(struct ata_port *ap) |
412 | { | 477 | { |
413 | if (ap->flags & ATA_FLAG_MMIO) | 478 | if (ap->flags & ATA_FLAG_MMIO) |
@@ -415,6 +480,20 @@ u8 ata_check_status(struct ata_port *ap) | |||
415 | return ata_check_status_pio(ap); | 480 | return ata_check_status_pio(ap); |
416 | } | 481 | } |
417 | 482 | ||
483 | |||
484 | /** | ||
485 | * ata_altstatus - Read device alternate status reg | ||
486 | * @ap: port where the device is | ||
487 | * | ||
488 | * Reads ATA taskfile alternate status register for | ||
489 | * currently-selected device and return its value. | ||
490 | * | ||
491 | * Note: may NOT be used as the check_altstatus() entry in | ||
492 | * ata_port_operations. | ||
493 | * | ||
494 | * LOCKING: | ||
495 | * Inherited from caller. | ||
496 | */ | ||
418 | u8 ata_altstatus(struct ata_port *ap) | 497 | u8 ata_altstatus(struct ata_port *ap) |
419 | { | 498 | { |
420 | if (ap->ops->check_altstatus) | 499 | if (ap->ops->check_altstatus) |
@@ -425,6 +504,20 @@ u8 ata_altstatus(struct ata_port *ap) | |||
425 | return inb(ap->ioaddr.altstatus_addr); | 504 | return inb(ap->ioaddr.altstatus_addr); |
426 | } | 505 | } |
427 | 506 | ||
507 | |||
508 | /** | ||
509 | * ata_chk_err - Read device error reg | ||
510 | * @ap: port where the device is | ||
511 | * | ||
512 | * Reads ATA taskfile error register for | ||
513 | * currently-selected device and return its value. | ||
514 | * | ||
515 | * Note: may NOT be used as the check_err() entry in | ||
516 | * ata_port_operations. | ||
517 | * | ||
518 | * LOCKING: | ||
519 | * Inherited from caller. | ||
520 | */ | ||
428 | u8 ata_chk_err(struct ata_port *ap) | 521 | u8 ata_chk_err(struct ata_port *ap) |
429 | { | 522 | { |
430 | if (ap->ops->check_err) | 523 | if (ap->ops->check_err) |
@@ -873,10 +966,24 @@ void ata_dev_id_string(u16 *id, unsigned char *s, | |||
873 | } | 966 | } |
874 | } | 967 | } |
875 | 968 | ||
969 | |||
970 | /** | ||
971 | * ata_noop_dev_select - Select device 0/1 on ATA bus | ||
972 | * @ap: ATA channel to manipulate | ||
973 | * @device: ATA device (numbered from zero) to select | ||
974 | * | ||
975 | * This function performs no actual function. | ||
976 | * | ||
977 | * May be used as the dev_select() entry in ata_port_operations. | ||
978 | * | ||
979 | * LOCKING: | ||
980 | * caller. | ||
981 | */ | ||
876 | void ata_noop_dev_select (struct ata_port *ap, unsigned int device) | 982 | void ata_noop_dev_select (struct ata_port *ap, unsigned int device) |
877 | { | 983 | { |
878 | } | 984 | } |
879 | 985 | ||
986 | |||
880 | /** | 987 | /** |
881 | * ata_std_dev_select - Select device 0/1 on ATA bus | 988 | * ata_std_dev_select - Select device 0/1 on ATA bus |
882 | * @ap: ATA channel to manipulate | 989 | * @ap: ATA channel to manipulate |
@@ -884,7 +991,9 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device) | |||
884 | * | 991 | * |
885 | * Use the method defined in the ATA specification to | 992 | * Use the method defined in the ATA specification to |
886 | * make either device 0, or device 1, active on the | 993 | * make either device 0, or device 1, active on the |
887 | * ATA channel. | 994 | * ATA channel. Works with both PIO and MMIO. |
995 | * | ||
996 | * May be used as the dev_select() entry in ata_port_operations. | ||
888 | * | 997 | * |
889 | * LOCKING: | 998 | * LOCKING: |
890 | * caller. | 999 | * caller. |
@@ -1190,7 +1299,12 @@ err_out: | |||
1190 | * ata_bus_probe - Reset and probe ATA bus | 1299 | * ata_bus_probe - Reset and probe ATA bus |
1191 | * @ap: Bus to probe | 1300 | * @ap: Bus to probe |
1192 | * | 1301 | * |
1302 | * Master ATA bus probing function. Initiates a hardware-dependent | ||
1303 | * bus reset, then attempts to identify any devices found on | ||
1304 | * the bus. | ||
1305 | * | ||
1193 | * LOCKING: | 1306 | * LOCKING: |
1307 | * PCI/etc. bus probe sem. | ||
1194 | * | 1308 | * |
1195 | * RETURNS: | 1309 | * RETURNS: |
1196 | * Zero on success, non-zero on error. | 1310 | * Zero on success, non-zero on error. |
@@ -1229,10 +1343,14 @@ err_out: | |||
1229 | } | 1343 | } |
1230 | 1344 | ||
1231 | /** | 1345 | /** |
1232 | * ata_port_probe - | 1346 | * ata_port_probe - Mark port as enabled |
1233 | * @ap: | 1347 | * @ap: Port for which we indicate enablement |
1234 | * | 1348 | * |
1235 | * LOCKING: | 1349 | * Modify @ap data structure such that the system |
1350 | * thinks that the entire port is enabled. | ||
1351 | * | ||
1352 | * LOCKING: host_set lock, or some other form of | ||
1353 | * serialization. | ||
1236 | */ | 1354 | */ |
1237 | 1355 | ||
1238 | void ata_port_probe(struct ata_port *ap) | 1356 | void ata_port_probe(struct ata_port *ap) |
@@ -1241,10 +1359,15 @@ void ata_port_probe(struct ata_port *ap) | |||
1241 | } | 1359 | } |
1242 | 1360 | ||
1243 | /** | 1361 | /** |
1244 | * __sata_phy_reset - | 1362 | * __sata_phy_reset - Wake/reset a low-level SATA PHY |
1245 | * @ap: | 1363 | * @ap: SATA port associated with target SATA PHY. |
1364 | * | ||
1365 | * This function issues commands to standard SATA Sxxx | ||
1366 | * PHY registers, to wake up the phy (and device), and | ||
1367 | * clear any reset condition. | ||
1246 | * | 1368 | * |
1247 | * LOCKING: | 1369 | * LOCKING: |
1370 | * PCI/etc. bus probe sem. | ||
1248 | * | 1371 | * |
1249 | */ | 1372 | */ |
1250 | void __sata_phy_reset(struct ata_port *ap) | 1373 | void __sata_phy_reset(struct ata_port *ap) |
@@ -1289,10 +1412,14 @@ void __sata_phy_reset(struct ata_port *ap) | |||
1289 | } | 1412 | } |
1290 | 1413 | ||
1291 | /** | 1414 | /** |
1292 | * __sata_phy_reset - | 1415 | * sata_phy_reset - Reset SATA bus. |
1293 | * @ap: | 1416 | * @ap: SATA port associated with target SATA PHY. |
1417 | * | ||
1418 | * This function resets the SATA bus, and then probes | ||
1419 | * the bus for devices. | ||
1294 | * | 1420 | * |
1295 | * LOCKING: | 1421 | * LOCKING: |
1422 | * PCI/etc. bus probe sem. | ||
1296 | * | 1423 | * |
1297 | */ | 1424 | */ |
1298 | void sata_phy_reset(struct ata_port *ap) | 1425 | void sata_phy_reset(struct ata_port *ap) |
@@ -1304,10 +1431,16 @@ void sata_phy_reset(struct ata_port *ap) | |||
1304 | } | 1431 | } |
1305 | 1432 | ||
1306 | /** | 1433 | /** |
1307 | * ata_port_disable - | 1434 | * ata_port_disable - Disable port. |
1308 | * @ap: | 1435 | * @ap: Port to be disabled. |
1309 | * | 1436 | * |
1310 | * LOCKING: | 1437 | * Modify @ap data structure such that the system |
1438 | * thinks that the entire port is disabled, and should | ||
1439 | * never attempt to probe or communicate with devices | ||
1440 | * on this port. | ||
1441 | * | ||
1442 | * LOCKING: host_set lock, or some other form of | ||
1443 | * serialization. | ||
1311 | */ | 1444 | */ |
1312 | 1445 | ||
1313 | void ata_port_disable(struct ata_port *ap) | 1446 | void ata_port_disable(struct ata_port *ap) |
@@ -1416,7 +1549,10 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, | |||
1416 | * ata_set_mode - Program timings and issue SET FEATURES - XFER | 1549 | * ata_set_mode - Program timings and issue SET FEATURES - XFER |
1417 | * @ap: port on which timings will be programmed | 1550 | * @ap: port on which timings will be programmed |
1418 | * | 1551 | * |
1552 | * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). | ||
1553 | * | ||
1419 | * LOCKING: | 1554 | * LOCKING: |
1555 | * PCI/etc. bus probe sem. | ||
1420 | * | 1556 | * |
1421 | */ | 1557 | */ |
1422 | static void ata_set_mode(struct ata_port *ap) | 1558 | static void ata_set_mode(struct ata_port *ap) |
@@ -1467,7 +1603,10 @@ err_out: | |||
1467 | * @tmout_pat: impatience timeout | 1603 | * @tmout_pat: impatience timeout |
1468 | * @tmout: overall timeout | 1604 | * @tmout: overall timeout |
1469 | * | 1605 | * |
1470 | * LOCKING: | 1606 | * Sleep until ATA Status register bit BSY clears, |
1607 | * or a timeout occurs. | ||
1608 | * | ||
1609 | * LOCKING: None. | ||
1471 | * | 1610 | * |
1472 | */ | 1611 | */ |
1473 | 1612 | ||
@@ -1553,10 +1692,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) | |||
1553 | } | 1692 | } |
1554 | 1693 | ||
1555 | /** | 1694 | /** |
1556 | * ata_bus_edd - | 1695 | * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. |
1557 | * @ap: | 1696 | * @ap: Port to reset and probe |
1697 | * | ||
1698 | * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and | ||
1699 | * probe the bus. Not often used these days. | ||
1558 | * | 1700 | * |
1559 | * LOCKING: | 1701 | * LOCKING: |
1702 | * PCI/etc. bus probe sem. | ||
1560 | * | 1703 | * |
1561 | */ | 1704 | */ |
1562 | 1705 | ||
@@ -1633,8 +1776,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, | |||
1633 | * the device is ATA or ATAPI. | 1776 | * the device is ATA or ATAPI. |
1634 | * | 1777 | * |
1635 | * LOCKING: | 1778 | * LOCKING: |
1636 | * Inherited from caller. Some functions called by this function | 1779 | * PCI/etc. bus probe sem. |
1637 | * obtain the host_set lock. | 1780 | * Obtains host_set lock. |
1638 | * | 1781 | * |
1639 | * SIDE EFFECTS: | 1782 | * SIDE EFFECTS: |
1640 | * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. | 1783 | * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. |
@@ -1876,7 +2019,11 @@ static int fgb(u32 bitmap) | |||
1876 | * @xfer_mode_out: (output) SET FEATURES - XFER MODE code | 2019 | * @xfer_mode_out: (output) SET FEATURES - XFER MODE code |
1877 | * @xfer_shift_out: (output) bit shift that selects this mode | 2020 | * @xfer_shift_out: (output) bit shift that selects this mode |
1878 | * | 2021 | * |
2022 | * Based on host and device capabilities, determine the | ||
2023 | * maximum transfer mode that is amenable to all. | ||
2024 | * | ||
1879 | * LOCKING: | 2025 | * LOCKING: |
2026 | * PCI/etc. bus probe sem. | ||
1880 | * | 2027 | * |
1881 | * RETURNS: | 2028 | * RETURNS: |
1882 | * Zero on success, negative on error. | 2029 | * Zero on success, negative on error. |
@@ -1909,7 +2056,11 @@ static int ata_choose_xfer_mode(struct ata_port *ap, | |||
1909 | * @ap: Port associated with device @dev | 2056 | * @ap: Port associated with device @dev |
1910 | * @dev: Device to which command will be sent | 2057 | * @dev: Device to which command will be sent |
1911 | * | 2058 | * |
2059 | * Issue SET FEATURES - XFER MODE command to device @dev | ||
2060 | * on port @ap. | ||
2061 | * | ||
1912 | * LOCKING: | 2062 | * LOCKING: |
2063 | * PCI/etc. bus probe sem. | ||
1913 | */ | 2064 | */ |
1914 | 2065 | ||
1915 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | 2066 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) |
@@ -1947,10 +2098,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
1947 | } | 2098 | } |
1948 | 2099 | ||
1949 | /** | 2100 | /** |
1950 | * ata_sg_clean - | 2101 | * ata_sg_clean - Unmap DMA memory associated with command |
1951 | * @qc: | 2102 | * @qc: Command containing DMA memory to be released |
2103 | * | ||
2104 | * Unmap all mapped DMA memory associated with this command. | ||
1952 | * | 2105 | * |
1953 | * LOCKING: | 2106 | * LOCKING: |
2107 | * spin_lock_irqsave(host_set lock) | ||
1954 | */ | 2108 | */ |
1955 | 2109 | ||
1956 | static void ata_sg_clean(struct ata_queued_cmd *qc) | 2110 | static void ata_sg_clean(struct ata_queued_cmd *qc) |
@@ -1981,7 +2135,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
1981 | * ata_fill_sg - Fill PCI IDE PRD table | 2135 | * ata_fill_sg - Fill PCI IDE PRD table |
1982 | * @qc: Metadata associated with taskfile to be transferred | 2136 | * @qc: Metadata associated with taskfile to be transferred |
1983 | * | 2137 | * |
2138 | * Fill PCI IDE PRD (scatter-gather) table with segments | ||
2139 | * associated with the current disk command. | ||
2140 | * | ||
1984 | * LOCKING: | 2141 | * LOCKING: |
2142 | * spin_lock_irqsave(host_set lock) | ||
1985 | * | 2143 | * |
1986 | */ | 2144 | */ |
1987 | static void ata_fill_sg(struct ata_queued_cmd *qc) | 2145 | static void ata_fill_sg(struct ata_queued_cmd *qc) |
@@ -2028,7 +2186,13 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) | |||
2028 | * ata_check_atapi_dma - Check whether ATAPI DMA can be supported | 2186 | * ata_check_atapi_dma - Check whether ATAPI DMA can be supported |
2029 | * @qc: Metadata associated with taskfile to check | 2187 | * @qc: Metadata associated with taskfile to check |
2030 | * | 2188 | * |
2189 | * Allow low-level driver to filter ATA PACKET commands, returning | ||
2190 | * a status indicating whether or not it is OK to use DMA for the | ||
2191 | * supplied PACKET command. | ||
2192 | * | ||
2031 | * LOCKING: | 2193 | * LOCKING: |
2194 | * spin_lock_irqsave(host_set lock) | ||
2195 | * | ||
2032 | * RETURNS: 0 when ATAPI DMA can be used | 2196 | * RETURNS: 0 when ATAPI DMA can be used |
2033 | * nonzero otherwise | 2197 | * nonzero otherwise |
2034 | */ | 2198 | */ |
@@ -2046,6 +2210,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) | |||
2046 | * ata_qc_prep - Prepare taskfile for submission | 2210 | * ata_qc_prep - Prepare taskfile for submission |
2047 | * @qc: Metadata associated with taskfile to be prepared | 2211 | * @qc: Metadata associated with taskfile to be prepared |
2048 | * | 2212 | * |
2213 | * Prepare ATA taskfile for submission. | ||
2214 | * | ||
2049 | * LOCKING: | 2215 | * LOCKING: |
2050 | * spin_lock_irqsave(host_set lock) | 2216 | * spin_lock_irqsave(host_set lock) |
2051 | */ | 2217 | */ |
@@ -2057,6 +2223,32 @@ void ata_qc_prep(struct ata_queued_cmd *qc) | |||
2057 | ata_fill_sg(qc); | 2223 | ata_fill_sg(qc); |
2058 | } | 2224 | } |
2059 | 2225 | ||
2226 | /** | ||
2227 | * ata_sg_init_one - Associate command with memory buffer | ||
2228 | * @qc: Command to be associated | ||
2229 | * @buf: Memory buffer | ||
2230 | * @buflen: Length of memory buffer, in bytes. | ||
2231 | * | ||
2232 | * Initialize the data-related elements of queued_cmd @qc | ||
2233 | * to point to a single memory buffer, @buf of byte length @buflen. | ||
2234 | * | ||
2235 | * LOCKING: | ||
2236 | * spin_lock_irqsave(host_set lock) | ||
2237 | */ | ||
2238 | |||
2239 | |||
2240 | |||
2241 | /** | ||
2242 | * ata_sg_init_one - Prepare a one-entry scatter-gather list. | ||
2243 | * @qc: Queued command | ||
2244 | * @buf: transfer buffer | ||
2245 | * @buflen: length of buf | ||
2246 | * | ||
2247 | * Builds a single-entry scatter-gather list to initiate a | ||
2248 | * transfer utilizing the specified buffer. | ||
2249 | * | ||
2250 | * LOCKING: | ||
2251 | */ | ||
2060 | void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) | 2252 | void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) |
2061 | { | 2253 | { |
2062 | struct scatterlist *sg; | 2254 | struct scatterlist *sg; |
@@ -2074,6 +2266,32 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) | |||
2074 | sg->length = buflen; | 2266 | sg->length = buflen; |
2075 | } | 2267 | } |
2076 | 2268 | ||
2269 | /** | ||
2270 | * ata_sg_init - Associate command with scatter-gather table. | ||
2271 | * @qc: Command to be associated | ||
2272 | * @sg: Scatter-gather table. | ||
2273 | * @n_elem: Number of elements in s/g table. | ||
2274 | * | ||
2275 | * Initialize the data-related elements of queued_cmd @qc | ||
2276 | * to point to a scatter-gather table @sg, containing @n_elem | ||
2277 | * elements. | ||
2278 | * | ||
2279 | * LOCKING: | ||
2280 | * spin_lock_irqsave(host_set lock) | ||
2281 | */ | ||
2282 | |||
2283 | |||
2284 | /** | ||
2285 | * ata_sg_init - Assign a scatter gather list to a queued command | ||
2286 | * @qc: Queued command | ||
2287 | * @sg: Scatter-gather list | ||
2288 | * @n_elem: length of sg list | ||
2289 | * | ||
2290 | * Attaches a scatter-gather list to a queued command. | ||
2291 | * | ||
2292 | * LOCKING: | ||
2293 | */ | ||
2294 | |||
2077 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | 2295 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, |
2078 | unsigned int n_elem) | 2296 | unsigned int n_elem) |
2079 | { | 2297 | { |
@@ -2083,14 +2301,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | |||
2083 | } | 2301 | } |
2084 | 2302 | ||
2085 | /** | 2303 | /** |
2086 | * ata_sg_setup_one - | 2304 | * ata_sg_setup_one - DMA-map the memory buffer associated with a command. |
2087 | * @qc: | 2305 | * @qc: Command with memory buffer to be mapped. |
2306 | * | ||
2307 | * DMA-map the memory buffer associated with queued_cmd @qc. | ||
2088 | * | 2308 | * |
2089 | * LOCKING: | 2309 | * LOCKING: |
2090 | * spin_lock_irqsave(host_set lock) | 2310 | * spin_lock_irqsave(host_set lock) |
2091 | * | 2311 | * |
2092 | * RETURNS: | 2312 | * RETURNS: |
2093 | * | 2313 | * Zero on success, negative on error. |
2094 | */ | 2314 | */ |
2095 | 2315 | ||
2096 | static int ata_sg_setup_one(struct ata_queued_cmd *qc) | 2316 | static int ata_sg_setup_one(struct ata_queued_cmd *qc) |
@@ -2115,13 +2335,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2115 | } | 2335 | } |
2116 | 2336 | ||
2117 | /** | 2337 | /** |
2118 | * ata_sg_setup - | 2338 | * ata_sg_setup - DMA-map the scatter-gather table associated with a command. |
2119 | * @qc: | 2339 | * @qc: Command with scatter-gather table to be mapped. |
2340 | * | ||
2341 | * DMA-map the scatter-gather table associated with queued_cmd @qc. | ||
2120 | * | 2342 | * |
2121 | * LOCKING: | 2343 | * LOCKING: |
2122 | * spin_lock_irqsave(host_set lock) | 2344 | * spin_lock_irqsave(host_set lock) |
2123 | * | 2345 | * |
2124 | * RETURNS: | 2346 | * RETURNS: |
2347 | * Zero on success, negative on error. | ||
2125 | * | 2348 | * |
2126 | */ | 2349 | */ |
2127 | 2350 | ||
@@ -2151,6 +2374,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
2151 | * @ap: | 2374 | * @ap: |
2152 | * | 2375 | * |
2153 | * LOCKING: | 2376 | * LOCKING: |
2377 | * None. (executing in kernel thread context) | ||
2154 | * | 2378 | * |
2155 | * RETURNS: | 2379 | * RETURNS: |
2156 | * | 2380 | * |
@@ -2198,6 +2422,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap) | |||
2198 | * @ap: | 2422 | * @ap: |
2199 | * | 2423 | * |
2200 | * LOCKING: | 2424 | * LOCKING: |
2425 | * None. (executing in kernel thread context) | ||
2201 | */ | 2426 | */ |
2202 | 2427 | ||
2203 | static void ata_pio_complete (struct ata_port *ap) | 2428 | static void ata_pio_complete (struct ata_port *ap) |
@@ -2240,6 +2465,18 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2240 | ata_qc_complete(qc, drv_stat); | 2465 | ata_qc_complete(qc, drv_stat); |
2241 | } | 2466 | } |
2242 | 2467 | ||
2468 | |||
2469 | /** | ||
2470 | * swap_buf_le16 - | ||
2471 | * @buf: Buffer to swap | ||
2472 | * @buf_words: Number of 16-bit words in buffer. | ||
2473 | * | ||
2474 | * Swap halves of 16-bit words if needed to convert from | ||
2475 | * little-endian byte order to native cpu byte order, or | ||
2476 | * vice-versa. | ||
2477 | * | ||
2478 | * LOCKING: | ||
2479 | */ | ||
2243 | void swap_buf_le16(u16 *buf, unsigned int buf_words) | 2480 | void swap_buf_le16(u16 *buf, unsigned int buf_words) |
2244 | { | 2481 | { |
2245 | #ifdef __BIG_ENDIAN | 2482 | #ifdef __BIG_ENDIAN |
@@ -2415,6 +2652,7 @@ err_out: | |||
2415 | * @ap: | 2652 | * @ap: |
2416 | * | 2653 | * |
2417 | * LOCKING: | 2654 | * LOCKING: |
2655 | * None. (executing in kernel thread context) | ||
2418 | */ | 2656 | */ |
2419 | 2657 | ||
2420 | static void ata_pio_block(struct ata_port *ap) | 2658 | static void ata_pio_block(struct ata_port *ap) |
@@ -2583,6 +2821,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
2583 | * transaction completed successfully. | 2821 | * transaction completed successfully. |
2584 | * | 2822 | * |
2585 | * LOCKING: | 2823 | * LOCKING: |
2824 | * Inherited from SCSI layer (none, can sleep) | ||
2586 | */ | 2825 | */ |
2587 | 2826 | ||
2588 | static void ata_qc_timeout(struct ata_queued_cmd *qc) | 2827 | static void ata_qc_timeout(struct ata_queued_cmd *qc) |
@@ -2692,6 +2931,7 @@ out: | |||
2692 | * @dev: Device from whom we request an available command structure | 2931 | * @dev: Device from whom we request an available command structure |
2693 | * | 2932 | * |
2694 | * LOCKING: | 2933 | * LOCKING: |
2934 | * None. | ||
2695 | */ | 2935 | */ |
2696 | 2936 | ||
2697 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | 2937 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) |
@@ -2717,6 +2957,7 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | |||
2717 | * @dev: Device from whom we request an available command structure | 2957 | * @dev: Device from whom we request an available command structure |
2718 | * | 2958 | * |
2719 | * LOCKING: | 2959 | * LOCKING: |
2960 | * None. | ||
2720 | */ | 2961 | */ |
2721 | 2962 | ||
2722 | struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | 2963 | struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, |
@@ -2781,6 +3022,7 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc) | |||
2781 | * in case something prevents using it. | 3022 | * in case something prevents using it. |
2782 | * | 3023 | * |
2783 | * LOCKING: | 3024 | * LOCKING: |
3025 | * spin_lock_irqsave(host_set lock) | ||
2784 | * | 3026 | * |
2785 | */ | 3027 | */ |
2786 | void ata_qc_free(struct ata_queued_cmd *qc) | 3028 | void ata_qc_free(struct ata_queued_cmd *qc) |
@@ -2794,9 +3036,13 @@ void ata_qc_free(struct ata_queued_cmd *qc) | |||
2794 | /** | 3036 | /** |
2795 | * ata_qc_complete - Complete an active ATA command | 3037 | * ata_qc_complete - Complete an active ATA command |
2796 | * @qc: Command to complete | 3038 | * @qc: Command to complete |
2797 | * @drv_stat: ATA status register contents | 3039 | * @drv_stat: ATA Status register contents |
3040 | * | ||
3041 | * Indicate to the mid and upper layers that an ATA | ||
3042 | * command has completed, with either an ok or not-ok status. | ||
2798 | * | 3043 | * |
2799 | * LOCKING: | 3044 | * LOCKING: |
3045 | * spin_lock_irqsave(host_set lock) | ||
2800 | * | 3046 | * |
2801 | */ | 3047 | */ |
2802 | 3048 | ||
@@ -2892,6 +3138,7 @@ err_out: | |||
2892 | return -1; | 3138 | return -1; |
2893 | } | 3139 | } |
2894 | 3140 | ||
3141 | |||
2895 | /** | 3142 | /** |
2896 | * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner | 3143 | * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner |
2897 | * @qc: command to issue to device | 3144 | * @qc: command to issue to device |
@@ -2901,6 +3148,8 @@ err_out: | |||
2901 | * classes called "protocols", and issuing each type of protocol | 3148 | * classes called "protocols", and issuing each type of protocol |
2902 | * is slightly different. | 3149 | * is slightly different. |
2903 | * | 3150 | * |
3151 | * May be used as the qc_issue() entry in ata_port_operations. | ||
3152 | * | ||
2904 | * LOCKING: | 3153 | * LOCKING: |
2905 | * spin_lock_irqsave(host_set lock) | 3154 | * spin_lock_irqsave(host_set lock) |
2906 | * | 3155 | * |
@@ -2958,7 +3207,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) | |||
2958 | } | 3207 | } |
2959 | 3208 | ||
2960 | /** | 3209 | /** |
2961 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction | 3210 | * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction |
2962 | * @qc: Info associated with this ATA transaction. | 3211 | * @qc: Info associated with this ATA transaction. |
2963 | * | 3212 | * |
2964 | * LOCKING: | 3213 | * LOCKING: |
@@ -3065,6 +3314,18 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc) | |||
3065 | ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | 3314 | ap->ioaddr.bmdma_addr + ATA_DMA_CMD); |
3066 | } | 3315 | } |
3067 | 3316 | ||
3317 | |||
3318 | /** | ||
3319 | * ata_bmdma_start - Start a PCI IDE BMDMA transaction | ||
3320 | * @qc: Info associated with this ATA transaction. | ||
3321 | * | ||
3322 | * Writes the ATA_DMA_START flag to the DMA command register. | ||
3323 | * | ||
3324 | * May be used as the bmdma_start() entry in ata_port_operations. | ||
3325 | * | ||
3326 | * LOCKING: | ||
3327 | * spin_lock_irqsave(host_set lock) | ||
3328 | */ | ||
3068 | void ata_bmdma_start(struct ata_queued_cmd *qc) | 3329 | void ata_bmdma_start(struct ata_queued_cmd *qc) |
3069 | { | 3330 | { |
3070 | if (qc->ap->flags & ATA_FLAG_MMIO) | 3331 | if (qc->ap->flags & ATA_FLAG_MMIO) |
@@ -3073,6 +3334,20 @@ void ata_bmdma_start(struct ata_queued_cmd *qc) | |||
3073 | ata_bmdma_start_pio(qc); | 3334 | ata_bmdma_start_pio(qc); |
3074 | } | 3335 | } |
3075 | 3336 | ||
3337 | |||
3338 | /** | ||
3339 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction | ||
3340 | * @qc: Info associated with this ATA transaction. | ||
3341 | * | ||
3342 | * Writes address of PRD table to device's PRD Table Address | ||
3343 | * register, sets the DMA control register, and calls | ||
3344 | * ops->exec_command() to start the transfer. | ||
3345 | * | ||
3346 | * May be used as the bmdma_setup() entry in ata_port_operations. | ||
3347 | * | ||
3348 | * LOCKING: | ||
3349 | * spin_lock_irqsave(host_set lock) | ||
3350 | */ | ||
3076 | void ata_bmdma_setup(struct ata_queued_cmd *qc) | 3351 | void ata_bmdma_setup(struct ata_queued_cmd *qc) |
3077 | { | 3352 | { |
3078 | if (qc->ap->flags & ATA_FLAG_MMIO) | 3353 | if (qc->ap->flags & ATA_FLAG_MMIO) |
@@ -3081,6 +3356,19 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc) | |||
3081 | ata_bmdma_setup_pio(qc); | 3356 | ata_bmdma_setup_pio(qc); |
3082 | } | 3357 | } |
3083 | 3358 | ||
3359 | |||
3360 | /** | ||
3361 | * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. | ||
3362 | * @ap: Port associated with this ATA transaction. | ||
3363 | * | ||
3364 | * Clear interrupt and error flags in DMA status register. | ||
3365 | * | ||
3366 | * May be used as the irq_clear() entry in ata_port_operations. | ||
3367 | * | ||
3368 | * LOCKING: | ||
3369 | * spin_lock_irqsave(host_set lock) | ||
3370 | */ | ||
3371 | |||
3084 | void ata_bmdma_irq_clear(struct ata_port *ap) | 3372 | void ata_bmdma_irq_clear(struct ata_port *ap) |
3085 | { | 3373 | { |
3086 | if (ap->flags & ATA_FLAG_MMIO) { | 3374 | if (ap->flags & ATA_FLAG_MMIO) { |
@@ -3093,6 +3381,19 @@ void ata_bmdma_irq_clear(struct ata_port *ap) | |||
3093 | 3381 | ||
3094 | } | 3382 | } |
3095 | 3383 | ||
3384 | |||
3385 | /** | ||
3386 | * ata_bmdma_status - Read PCI IDE BMDMA status | ||
3387 | * @ap: Port associated with this ATA transaction. | ||
3388 | * | ||
3389 | * Read and return BMDMA status register. | ||
3390 | * | ||
3391 | * May be used as the bmdma_status() entry in ata_port_operations. | ||
3392 | * | ||
3393 | * LOCKING: | ||
3394 | * spin_lock_irqsave(host_set lock) | ||
3395 | */ | ||
3396 | |||
3096 | u8 ata_bmdma_status(struct ata_port *ap) | 3397 | u8 ata_bmdma_status(struct ata_port *ap) |
3097 | { | 3398 | { |
3098 | u8 host_stat; | 3399 | u8 host_stat; |
@@ -3104,6 +3405,19 @@ u8 ata_bmdma_status(struct ata_port *ap) | |||
3104 | return host_stat; | 3405 | return host_stat; |
3105 | } | 3406 | } |
3106 | 3407 | ||
3408 | |||
3409 | /** | ||
3410 | * ata_bmdma_stop - Stop PCI IDE BMDMA transfer | ||
3411 | * @ap: Port associated with this ATA transaction. | ||
3412 | * | ||
3413 | * Clears the ATA_DMA_START flag in the dma control register | ||
3414 | * | ||
3415 | * May be used as the bmdma_stop() entry in ata_port_operations. | ||
3416 | * | ||
3417 | * LOCKING: | ||
3418 | * spin_lock_irqsave(host_set lock) | ||
3419 | */ | ||
3420 | |||
3107 | void ata_bmdma_stop(struct ata_port *ap) | 3421 | void ata_bmdma_stop(struct ata_port *ap) |
3108 | { | 3422 | { |
3109 | if (ap->flags & ATA_FLAG_MMIO) { | 3423 | if (ap->flags & ATA_FLAG_MMIO) { |
@@ -3203,13 +3517,18 @@ idle_irq: | |||
3203 | 3517 | ||
3204 | /** | 3518 | /** |
3205 | * ata_interrupt - Default ATA host interrupt handler | 3519 | * ata_interrupt - Default ATA host interrupt handler |
3206 | * @irq: irq line | 3520 | * @irq: irq line (unused) |
3207 | * @dev_instance: pointer to our host information structure | 3521 | * @dev_instance: pointer to our ata_host_set information structure |
3208 | * @regs: unused | 3522 | * @regs: unused |
3209 | * | 3523 | * |
3524 | * Default interrupt handler for PCI IDE devices. Calls | ||
3525 | * ata_host_intr() for each port that is not disabled. | ||
3526 | * | ||
3210 | * LOCKING: | 3527 | * LOCKING: |
3528 | * Obtains host_set lock during operation. | ||
3211 | * | 3529 | * |
3212 | * RETURNS: | 3530 | * RETURNS: |
3531 | * IRQ_NONE or IRQ_HANDLED. | ||
3213 | * | 3532 | * |
3214 | */ | 3533 | */ |
3215 | 3534 | ||
@@ -3302,6 +3621,19 @@ err_out: | |||
3302 | ata_qc_complete(qc, ATA_ERR); | 3621 | ata_qc_complete(qc, ATA_ERR); |
3303 | } | 3622 | } |
3304 | 3623 | ||
3624 | |||
3625 | /** | ||
3626 | * ata_port_start - Set port up for dma. | ||
3627 | * @ap: Port to initialize | ||
3628 | * | ||
3629 | * Called just after data structures for each port are | ||
3630 | * initialized. Allocates space for PRD table. | ||
3631 | * | ||
3632 | * May be used as the port_start() entry in ata_port_operations. | ||
3633 | * | ||
3634 | * LOCKING: | ||
3635 | */ | ||
3636 | |||
3305 | int ata_port_start (struct ata_port *ap) | 3637 | int ata_port_start (struct ata_port *ap) |
3306 | { | 3638 | { |
3307 | struct device *dev = ap->host_set->dev; | 3639 | struct device *dev = ap->host_set->dev; |
@@ -3315,6 +3647,18 @@ int ata_port_start (struct ata_port *ap) | |||
3315 | return 0; | 3647 | return 0; |
3316 | } | 3648 | } |
3317 | 3649 | ||
3650 | |||
3651 | /** | ||
3652 | * ata_port_stop - Undo ata_port_start() | ||
3653 | * @ap: Port to shut down | ||
3654 | * | ||
3655 | * Frees the PRD table. | ||
3656 | * | ||
3657 | * May be used as the port_stop() entry in ata_port_operations. | ||
3658 | * | ||
3659 | * LOCKING: | ||
3660 | */ | ||
3661 | |||
3318 | void ata_port_stop (struct ata_port *ap) | 3662 | void ata_port_stop (struct ata_port *ap) |
3319 | { | 3663 | { |
3320 | struct device *dev = ap->host_set->dev; | 3664 | struct device *dev = ap->host_set->dev; |
@@ -3322,6 +3666,13 @@ void ata_port_stop (struct ata_port *ap) | |||
3322 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); | 3666 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); |
3323 | } | 3667 | } |
3324 | 3668 | ||
3669 | void ata_host_stop (struct ata_host_set *host_set) | ||
3670 | { | ||
3671 | if (host_set->mmio_base) | ||
3672 | iounmap(host_set->mmio_base); | ||
3673 | } | ||
3674 | |||
3675 | |||
3325 | /** | 3676 | /** |
3326 | * ata_host_remove - Unregister SCSI host structure with upper layers | 3677 | * ata_host_remove - Unregister SCSI host structure with upper layers |
3327 | * @ap: Port to unregister | 3678 | * @ap: Port to unregister |
@@ -3350,7 +3701,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) | |||
3350 | * @ent: Probe information provided by low-level driver | 3701 | * @ent: Probe information provided by low-level driver |
3351 | * @port_no: Port number associated with this ata_port | 3702 | * @port_no: Port number associated with this ata_port |
3352 | * | 3703 | * |
3704 | * Initialize a new ata_port structure, and its associated | ||
3705 | * scsi_host. | ||
3706 | * | ||
3353 | * LOCKING: | 3707 | * LOCKING: |
3708 | * Inherited from caller. | ||
3354 | * | 3709 | * |
3355 | */ | 3710 | */ |
3356 | 3711 | ||
@@ -3405,9 +3760,13 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | |||
3405 | * @host_set: Collections of ports to which we add | 3760 | * @host_set: Collections of ports to which we add |
3406 | * @port_no: Port number associated with this host | 3761 | * @port_no: Port number associated with this host |
3407 | * | 3762 | * |
3763 | * Attach low-level ATA driver to system. | ||
3764 | * | ||
3408 | * LOCKING: | 3765 | * LOCKING: |
3766 | * PCI/etc. bus probe sem. | ||
3409 | * | 3767 | * |
3410 | * RETURNS: | 3768 | * RETURNS: |
3769 | * New ata_port on success, for NULL on error. | ||
3411 | * | 3770 | * |
3412 | */ | 3771 | */ |
3413 | 3772 | ||
@@ -3440,12 +3799,22 @@ err_out: | |||
3440 | } | 3799 | } |
3441 | 3800 | ||
3442 | /** | 3801 | /** |
3443 | * ata_device_add - | 3802 | * ata_device_add - Register hardware device with ATA and SCSI layers |
3444 | * @ent: | 3803 | * @ent: Probe information describing hardware device to be registered |
3804 | * | ||
3805 | * This function processes the information provided in the probe | ||
3806 | * information struct @ent, allocates the necessary ATA and SCSI | ||
3807 | * host information structures, initializes them, and registers | ||
3808 | * everything with requisite kernel subsystems. | ||
3809 | * | ||
3810 | * This function requests irqs, probes the ATA bus, and probes | ||
3811 | * the SCSI bus. | ||
3445 | * | 3812 | * |
3446 | * LOCKING: | 3813 | * LOCKING: |
3814 | * PCI/etc. bus probe sem. | ||
3447 | * | 3815 | * |
3448 | * RETURNS: | 3816 | * RETURNS: |
3817 | * Number of ports registered. Zero on error (no ports registered). | ||
3449 | * | 3818 | * |
3450 | */ | 3819 | */ |
3451 | 3820 | ||
@@ -3597,7 +3966,15 @@ int ata_scsi_release(struct Scsi_Host *host) | |||
3597 | /** | 3966 | /** |
3598 | * ata_std_ports - initialize ioaddr with standard port offsets. | 3967 | * ata_std_ports - initialize ioaddr with standard port offsets. |
3599 | * @ioaddr: IO address structure to be initialized | 3968 | * @ioaddr: IO address structure to be initialized |
3969 | * | ||
3970 | * Utility function which initializes data_addr, error_addr, | ||
3971 | * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr, | ||
3972 | * device_addr, status_addr, and command_addr to standard offsets | ||
3973 | * relative to cmd_addr. | ||
3974 | * | ||
3975 | * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr. | ||
3600 | */ | 3976 | */ |
3977 | |||
3601 | void ata_std_ports(struct ata_ioports *ioaddr) | 3978 | void ata_std_ports(struct ata_ioports *ioaddr) |
3602 | { | 3979 | { |
3603 | ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA; | 3980 | ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA; |
@@ -3639,6 +4016,20 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port) | |||
3639 | return probe_ent; | 4016 | return probe_ent; |
3640 | } | 4017 | } |
3641 | 4018 | ||
4019 | |||
4020 | |||
4021 | /** | ||
4022 | * ata_pci_init_native_mode - Initialize native-mode driver | ||
4023 | * @pdev: pci device to be initialized | ||
4024 | * @port: array[2] of pointers to port info structures. | ||
4025 | * | ||
4026 | * Utility function which allocates and initializes an | ||
4027 | * ata_probe_ent structure for a standard dual-port | ||
4028 | * PIO-based IDE controller. The returned ata_probe_ent | ||
4029 | * structure can be passed to ata_device_add(). The returned | ||
4030 | * ata_probe_ent structure should then be freed with kfree(). | ||
4031 | */ | ||
4032 | |||
3642 | #ifdef CONFIG_PCI | 4033 | #ifdef CONFIG_PCI |
3643 | struct ata_probe_ent * | 4034 | struct ata_probe_ent * |
3644 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) | 4035 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) |
@@ -3720,10 +4111,19 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port, | |||
3720 | * @port_info: Information from low-level host driver | 4111 | * @port_info: Information from low-level host driver |
3721 | * @n_ports: Number of ports attached to host controller | 4112 | * @n_ports: Number of ports attached to host controller |
3722 | * | 4113 | * |
4114 | * This is a helper function which can be called from a driver's | ||
4115 | * xxx_init_one() probe function if the hardware uses traditional | ||
4116 | * IDE taskfile registers. | ||
4117 | * | ||
4118 | * This function calls pci_enable_device(), reserves its register | ||
4119 | * regions, sets the dma mask, enables bus master mode, and calls | ||
4120 | * ata_device_add() | ||
4121 | * | ||
3723 | * LOCKING: | 4122 | * LOCKING: |
3724 | * Inherited from PCI layer (may sleep). | 4123 | * Inherited from PCI layer (may sleep). |
3725 | * | 4124 | * |
3726 | * RETURNS: | 4125 | * RETURNS: |
4126 | * Zero on success, negative on errno-based value on error. | ||
3727 | * | 4127 | * |
3728 | */ | 4128 | */ |
3729 | 4129 | ||
@@ -3878,10 +4278,6 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
3878 | } | 4278 | } |
3879 | 4279 | ||
3880 | free_irq(host_set->irq, host_set); | 4280 | free_irq(host_set->irq, host_set); |
3881 | if (host_set->ops->host_stop) | ||
3882 | host_set->ops->host_stop(host_set); | ||
3883 | if (host_set->mmio_base) | ||
3884 | iounmap(host_set->mmio_base); | ||
3885 | 4281 | ||
3886 | for (i = 0; i < host_set->n_ports; i++) { | 4282 | for (i = 0; i < host_set->n_ports; i++) { |
3887 | ap = host_set->ports[i]; | 4283 | ap = host_set->ports[i]; |
@@ -3900,6 +4296,9 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
3900 | scsi_host_put(ap->host); | 4296 | scsi_host_put(ap->host); |
3901 | } | 4297 | } |
3902 | 4298 | ||
4299 | if (host_set->ops->host_stop) | ||
4300 | host_set->ops->host_stop(host_set); | ||
4301 | |||
3903 | kfree(host_set); | 4302 | kfree(host_set); |
3904 | 4303 | ||
3905 | pci_release_regions(pdev); | 4304 | pci_release_regions(pdev); |
@@ -3943,15 +4342,6 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits) | |||
3943 | #endif /* CONFIG_PCI */ | 4342 | #endif /* CONFIG_PCI */ |
3944 | 4343 | ||
3945 | 4344 | ||
3946 | /** | ||
3947 | * ata_init - | ||
3948 | * | ||
3949 | * LOCKING: | ||
3950 | * | ||
3951 | * RETURNS: | ||
3952 | * | ||
3953 | */ | ||
3954 | |||
3955 | static int __init ata_init(void) | 4345 | static int __init ata_init(void) |
3956 | { | 4346 | { |
3957 | ata_wq = create_workqueue("ata"); | 4347 | ata_wq = create_workqueue("ata"); |
@@ -3997,6 +4387,7 @@ EXPORT_SYMBOL_GPL(ata_chk_err); | |||
3997 | EXPORT_SYMBOL_GPL(ata_exec_command); | 4387 | EXPORT_SYMBOL_GPL(ata_exec_command); |
3998 | EXPORT_SYMBOL_GPL(ata_port_start); | 4388 | EXPORT_SYMBOL_GPL(ata_port_start); |
3999 | EXPORT_SYMBOL_GPL(ata_port_stop); | 4389 | EXPORT_SYMBOL_GPL(ata_port_stop); |
4390 | EXPORT_SYMBOL_GPL(ata_host_stop); | ||
4000 | EXPORT_SYMBOL_GPL(ata_interrupt); | 4391 | EXPORT_SYMBOL_GPL(ata_interrupt); |
4001 | EXPORT_SYMBOL_GPL(ata_qc_prep); | 4392 | EXPORT_SYMBOL_GPL(ata_qc_prep); |
4002 | EXPORT_SYMBOL_GPL(ata_bmdma_setup); | 4393 | EXPORT_SYMBOL_GPL(ata_bmdma_setup); |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 416ba67ba9ee..7a4adc4c8f09 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -947,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, | |||
947 | } | 947 | } |
948 | 948 | ||
949 | /** | 949 | /** |
950 | * ata_scsiop_noop - | 950 | * ata_scsiop_noop - Command handler that simply returns success. |
951 | * @args: device IDENTIFY data / SCSI command of interest. | 951 | * @args: device IDENTIFY data / SCSI command of interest. |
952 | * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. | 952 | * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. |
953 | * @buflen: Response buffer length. | 953 | * @buflen: Response buffer length. |
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 6518226b8f87..d90430bbb0de 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define __LIBATA_H__ | 26 | #define __LIBATA_H__ |
27 | 27 | ||
28 | #define DRV_NAME "libata" | 28 | #define DRV_NAME "libata" |
29 | #define DRV_VERSION "1.10" /* must be exactly four chars */ | 29 | #define DRV_VERSION "1.11" /* must be exactly four chars */ |
30 | 30 | ||
31 | struct ata_scsi_args { | 31 | struct ata_scsi_args { |
32 | u16 *id; | 32 | u16 *id; |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 579448222d69..3c97aa45772d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
507 | int ret, i; | 507 | int ret, i; |
508 | unsigned int id, lun; | 508 | unsigned int id, lun; |
509 | unsigned long serial; | 509 | unsigned long serial; |
510 | unsigned long flags; | ||
510 | 511 | ||
511 | if (!CMD_SP(cmd)) | 512 | if (!CMD_SP(cmd)) |
512 | return FAILED; | 513 | return FAILED; |
@@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
519 | 520 | ||
520 | /* Check active list for command command. */ | 521 | /* Check active list for command command. */ |
521 | spin_unlock_irq(ha->host->host_lock); | 522 | spin_unlock_irq(ha->host->host_lock); |
522 | spin_lock(&ha->hardware_lock); | 523 | spin_lock_irqsave(&ha->hardware_lock, flags); |
523 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { | 524 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { |
524 | sp = ha->outstanding_cmds[i]; | 525 | sp = ha->outstanding_cmds[i]; |
525 | 526 | ||
@@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
534 | sp->state)); | 535 | sp->state)); |
535 | DEBUG3(qla2x00_print_scsi_cmd(cmd);) | 536 | DEBUG3(qla2x00_print_scsi_cmd(cmd);) |
536 | 537 | ||
537 | spin_unlock(&ha->hardware_lock); | 538 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
538 | if (qla2x00_abort_command(ha, sp)) { | 539 | if (qla2x00_abort_command(ha, sp)) { |
539 | DEBUG2(printk("%s(%ld): abort_command " | 540 | DEBUG2(printk("%s(%ld): abort_command " |
540 | "mbx failed.\n", __func__, ha->host_no)); | 541 | "mbx failed.\n", __func__, ha->host_no)); |
@@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
543 | "mbx success.\n", __func__, ha->host_no)); | 544 | "mbx success.\n", __func__, ha->host_no)); |
544 | ret = SUCCESS; | 545 | ret = SUCCESS; |
545 | } | 546 | } |
546 | spin_lock(&ha->hardware_lock); | 547 | spin_lock_irqsave(&ha->hardware_lock, flags); |
547 | 548 | ||
548 | break; | 549 | break; |
549 | } | 550 | } |
551 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
550 | 552 | ||
551 | /* Wait for the command to be returned. */ | 553 | /* Wait for the command to be returned. */ |
552 | if (ret == SUCCESS) { | 554 | if (ret == SUCCESS) { |
553 | spin_unlock(&ha->hardware_lock); | ||
554 | if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { | 555 | if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { |
555 | qla_printk(KERN_ERR, ha, | 556 | qla_printk(KERN_ERR, ha, |
556 | "scsi(%ld:%d:%d): Abort handler timed out -- %lx " | 557 | "scsi(%ld:%d:%d): Abort handler timed out -- %lx " |
557 | "%x.\n", ha->host_no, id, lun, serial, ret); | 558 | "%x.\n", ha->host_no, id, lun, serial, ret); |
558 | } | 559 | } |
559 | spin_lock(&ha->hardware_lock); | ||
560 | } | 560 | } |
561 | spin_lock_irq(ha->host->host_lock); | 561 | spin_lock_irq(ha->host->host_lock); |
562 | 562 | ||
@@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
588 | int status; | 588 | int status; |
589 | srb_t *sp; | 589 | srb_t *sp; |
590 | struct scsi_cmnd *cmd; | 590 | struct scsi_cmnd *cmd; |
591 | unsigned long flags; | ||
591 | 592 | ||
592 | status = 0; | 593 | status = 0; |
593 | 594 | ||
@@ -596,11 +597,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
596 | * array | 597 | * array |
597 | */ | 598 | */ |
598 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | 599 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
599 | spin_lock(&ha->hardware_lock); | 600 | spin_lock_irqsave(&ha->hardware_lock, flags); |
600 | sp = ha->outstanding_cmds[cnt]; | 601 | sp = ha->outstanding_cmds[cnt]; |
601 | if (sp) { | 602 | if (sp) { |
602 | cmd = sp->cmd; | 603 | cmd = sp->cmd; |
603 | spin_unlock(&ha->hardware_lock); | 604 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
604 | if (cmd->device->id == t) { | 605 | if (cmd->device->id == t) { |
605 | if (!qla2x00_eh_wait_on_command(ha, cmd)) { | 606 | if (!qla2x00_eh_wait_on_command(ha, cmd)) { |
606 | status = 1; | 607 | status = 1; |
@@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
608 | } | 609 | } |
609 | } | 610 | } |
610 | } else { | 611 | } else { |
611 | spin_unlock(&ha->hardware_lock); | 612 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
612 | } | 613 | } |
613 | } | 614 | } |
614 | return (status); | 615 | return (status); |
@@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | |||
740 | int status; | 741 | int status; |
741 | srb_t *sp; | 742 | srb_t *sp; |
742 | struct scsi_cmnd *cmd; | 743 | struct scsi_cmnd *cmd; |
744 | unsigned long flags; | ||
743 | 745 | ||
744 | status = 1; | 746 | status = 1; |
745 | 747 | ||
@@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | |||
748 | * array | 750 | * array |
749 | */ | 751 | */ |
750 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | 752 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
751 | spin_lock(&ha->hardware_lock); | 753 | spin_lock_irqsave(&ha->hardware_lock, flags); |
752 | sp = ha->outstanding_cmds[cnt]; | 754 | sp = ha->outstanding_cmds[cnt]; |
753 | if (sp) { | 755 | if (sp) { |
754 | cmd = sp->cmd; | 756 | cmd = sp->cmd; |
755 | spin_unlock(&ha->hardware_lock); | 757 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
756 | status = qla2x00_eh_wait_on_command(ha, cmd); | 758 | status = qla2x00_eh_wait_on_command(ha, cmd); |
757 | if (status == 0) | 759 | if (status == 0) |
758 | break; | 760 | break; |
759 | } | 761 | } |
760 | else { | 762 | else { |
761 | spin_unlock(&ha->hardware_lock); | 763 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
762 | } | 764 | } |
763 | } | 765 | } |
764 | return (status); | 766 | return (status); |
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 69009f853a49..b0403ccd8a25 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
@@ -329,6 +329,8 @@ static void nv_host_stop (struct ata_host_set *host_set) | |||
329 | host->host_desc->disable_hotplug(host_set); | 329 | host->host_desc->disable_hotplug(host_set); |
330 | 330 | ||
331 | kfree(host); | 331 | kfree(host); |
332 | |||
333 | ata_host_stop(host_set); | ||
332 | } | 334 | } |
333 | 335 | ||
334 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 336 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index c4e9e0298122..b18c90582e67 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -122,6 +122,7 @@ static struct ata_port_operations pdc_ata_ops = { | |||
122 | .scr_write = pdc_sata_scr_write, | 122 | .scr_write = pdc_sata_scr_write, |
123 | .port_start = pdc_port_start, | 123 | .port_start = pdc_port_start, |
124 | .port_stop = pdc_port_stop, | 124 | .port_stop = pdc_port_stop, |
125 | .host_stop = ata_host_stop, | ||
125 | }; | 126 | }; |
126 | 127 | ||
127 | static struct ata_port_info pdc_port_info[] = { | 128 | static struct ata_port_info pdc_port_info[] = { |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index dfd362104717..1383e8a28d72 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -536,6 +536,8 @@ static void qs_host_stop(struct ata_host_set *host_set) | |||
536 | 536 | ||
537 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ | 537 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ |
538 | writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ | 538 | writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ |
539 | |||
540 | ata_host_stop(host_set); | ||
539 | } | 541 | } |
540 | 542 | ||
541 | static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | 543 | static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 2b2ff48be396..238580d244e6 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -161,6 +161,7 @@ static struct ata_port_operations sil_ops = { | |||
161 | .scr_write = sil_scr_write, | 161 | .scr_write = sil_scr_write, |
162 | .port_start = ata_port_start, | 162 | .port_start = ata_port_start, |
163 | .port_stop = ata_port_stop, | 163 | .port_stop = ata_port_stop, |
164 | .host_stop = ata_host_stop, | ||
164 | }; | 165 | }; |
165 | 166 | ||
166 | static struct ata_port_info sil_port_info[] = { | 167 | static struct ata_port_info sil_port_info[] = { |
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 5105ddd08447..e418b89c6b9d 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c | |||
@@ -114,6 +114,7 @@ static struct ata_port_operations sis_ops = { | |||
114 | .scr_write = sis_scr_write, | 114 | .scr_write = sis_scr_write, |
115 | .port_start = ata_port_start, | 115 | .port_start = ata_port_start, |
116 | .port_stop = ata_port_stop, | 116 | .port_stop = ata_port_stop, |
117 | .host_stop = ata_host_stop, | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | static struct ata_port_info sis_port_info = { | 120 | static struct ata_port_info sis_port_info = { |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 05075bd3a893..edef1fa969fc 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -313,6 +313,7 @@ static struct ata_port_operations k2_sata_ops = { | |||
313 | .scr_write = k2_sata_scr_write, | 313 | .scr_write = k2_sata_scr_write, |
314 | .port_start = ata_port_start, | 314 | .port_start = ata_port_start, |
315 | .port_stop = ata_port_stop, | 315 | .port_stop = ata_port_stop, |
316 | .host_stop = ata_host_stop, | ||
316 | }; | 317 | }; |
317 | 318 | ||
318 | static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) | 319 | static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 70118650c461..140cea05de3f 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -245,6 +245,8 @@ static void pdc20621_host_stop(struct ata_host_set *host_set) | |||
245 | 245 | ||
246 | iounmap(dimm_mmio); | 246 | iounmap(dimm_mmio); |
247 | kfree(hpriv); | 247 | kfree(hpriv); |
248 | |||
249 | ata_host_stop(host_set); | ||
248 | } | 250 | } |
249 | 251 | ||
250 | static int pdc_port_start(struct ata_port *ap) | 252 | static int pdc_port_start(struct ata_port *ap) |
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 0bff4f475f26..a71fb54eebd3 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c | |||
@@ -113,6 +113,7 @@ static struct ata_port_operations uli_ops = { | |||
113 | 113 | ||
114 | .port_start = ata_port_start, | 114 | .port_start = ata_port_start, |
115 | .port_stop = ata_port_stop, | 115 | .port_stop = ata_port_stop, |
116 | .host_stop = ata_host_stop, | ||
116 | }; | 117 | }; |
117 | 118 | ||
118 | static struct ata_port_info uli_port_info = { | 119 | static struct ata_port_info uli_port_info = { |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 3a7830667277..f43183c19a12 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
@@ -134,6 +134,7 @@ static struct ata_port_operations svia_sata_ops = { | |||
134 | 134 | ||
135 | .port_start = ata_port_start, | 135 | .port_start = ata_port_start, |
136 | .port_stop = ata_port_stop, | 136 | .port_stop = ata_port_stop, |
137 | .host_stop = ata_host_stop, | ||
137 | }; | 138 | }; |
138 | 139 | ||
139 | static struct ata_port_info svia_port_info = { | 140 | static struct ata_port_info svia_port_info = { |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2c28f0ad73c2..c5e09dc6f3de 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/dma-mapping.h> | ||
24 | #include "scsi.h" | 25 | #include "scsi.h" |
25 | #include <scsi/scsi_host.h> | 26 | #include <scsi/scsi_host.h> |
26 | #include <linux/libata.h> | 27 | #include <linux/libata.h> |
@@ -230,6 +231,7 @@ static struct ata_port_operations vsc_sata_ops = { | |||
230 | .scr_write = vsc_sata_scr_write, | 231 | .scr_write = vsc_sata_scr_write, |
231 | .port_start = ata_port_start, | 232 | .port_start = ata_port_start, |
232 | .port_stop = ata_port_stop, | 233 | .port_stop = ata_port_stop, |
234 | .host_stop = ata_host_stop, | ||
233 | }; | 235 | }; |
234 | 236 | ||
235 | static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) | 237 | static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index cca772624ae7..8d0d302844a1 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -1197,6 +1197,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, | |||
1197 | if (!starget) | 1197 | if (!starget) |
1198 | return ERR_PTR(-ENOMEM); | 1198 | return ERR_PTR(-ENOMEM); |
1199 | 1199 | ||
1200 | get_device(&starget->dev); | ||
1200 | down(&shost->scan_mutex); | 1201 | down(&shost->scan_mutex); |
1201 | res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); | 1202 | res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); |
1202 | if (res != SCSI_SCAN_LUN_PRESENT) | 1203 | if (res != SCSI_SCAN_LUN_PRESENT) |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4ab50009291d..4d0c9e65cd03 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -290,32 +290,30 @@ static ssize_t show_modalias(struct device *dev, char *buf) | |||
290 | { | 290 | { |
291 | struct usb_interface *intf; | 291 | struct usb_interface *intf; |
292 | struct usb_device *udev; | 292 | struct usb_device *udev; |
293 | int len; | ||
293 | 294 | ||
294 | intf = to_usb_interface(dev); | 295 | intf = to_usb_interface(dev); |
295 | udev = interface_to_usbdev(intf); | 296 | udev = interface_to_usbdev(intf); |
296 | if (udev->descriptor.bDeviceClass == 0) { | ||
297 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
298 | 297 | ||
299 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n", | 298 | len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", |
300 | le16_to_cpu(udev->descriptor.idVendor), | 299 | le16_to_cpu(udev->descriptor.idVendor), |
301 | le16_to_cpu(udev->descriptor.idProduct), | 300 | le16_to_cpu(udev->descriptor.idProduct), |
302 | le16_to_cpu(udev->descriptor.bcdDevice), | 301 | le16_to_cpu(udev->descriptor.bcdDevice), |
303 | udev->descriptor.bDeviceClass, | 302 | udev->descriptor.bDeviceClass, |
304 | udev->descriptor.bDeviceSubClass, | 303 | udev->descriptor.bDeviceSubClass, |
305 | udev->descriptor.bDeviceProtocol, | 304 | udev->descriptor.bDeviceProtocol); |
305 | buf += len; | ||
306 | |||
307 | if (udev->descriptor.bDeviceClass == 0) { | ||
308 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
309 | |||
310 | return len + sprintf(buf, "%02Xisc%02Xip%02X\n", | ||
306 | alt->desc.bInterfaceClass, | 311 | alt->desc.bInterfaceClass, |
307 | alt->desc.bInterfaceSubClass, | 312 | alt->desc.bInterfaceSubClass, |
308 | alt->desc.bInterfaceProtocol); | 313 | alt->desc.bInterfaceProtocol); |
309 | } else { | 314 | } else { |
310 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n", | 315 | return len + sprintf(buf, "*isc*ip*\n"); |
311 | le16_to_cpu(udev->descriptor.idVendor), | ||
312 | le16_to_cpu(udev->descriptor.idProduct), | ||
313 | le16_to_cpu(udev->descriptor.bcdDevice), | ||
314 | udev->descriptor.bDeviceClass, | ||
315 | udev->descriptor.bDeviceSubClass, | ||
316 | udev->descriptor.bDeviceProtocol); | ||
317 | } | 316 | } |
318 | |||
319 | } | 317 | } |
320 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | 318 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); |
321 | 319 | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3196c3265ff5..19e598c9641f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -124,3 +124,14 @@ config USB_SL811_HCD | |||
124 | To compile this driver as a module, choose M here: the | 124 | To compile this driver as a module, choose M here: the |
125 | module will be called sl811-hcd. | 125 | module will be called sl811-hcd. |
126 | 126 | ||
127 | config USB_SL811_CS | ||
128 | tristate "CF/PCMCIA support for SL811HS HCD" | ||
129 | depends on USB_SL811_HCD && PCMCIA | ||
130 | default N | ||
131 | help | ||
132 | Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC | ||
133 | REX-CFU1U CF card (often used with PDAs). If unsure, say N. | ||
134 | |||
135 | To compile this driver as a module, choose M here: the | ||
136 | module will be called "sl811_cs". | ||
137 | |||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index a574ca06cf6b..5dbd3e7a27c7 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | |||
7 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 7 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
8 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 8 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
9 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | 9 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o |
10 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | ||
10 | obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o | 11 | obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a374b7692073..99d43f758ad0 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * SL811HS HCD (Host Controller Driver) for USB. | 2 | * SL811HS HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) | 4 | * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) |
5 | * Copyright (C) 2004 David Brownell | 5 | * Copyright (C) 2004-2005 David Brownell |
6 | * | 6 | * |
7 | * Periodic scheduling is based on Roman's OHCI code | 7 | * Periodic scheduling is based on Roman's OHCI code |
8 | * Copyright (C) 1999 Roman Weissgaerber | 8 | * Copyright (C) 1999 Roman Weissgaerber |
9 | * | 9 | * |
@@ -15,7 +15,7 @@ | |||
15 | * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" | 15 | * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" |
16 | * document (providing significant pieces missing from that spec); plus | 16 | * document (providing significant pieces missing from that spec); plus |
17 | * the SL811S spec if you want peripheral side info. | 17 | * the SL811S spec if you want peripheral side info. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Status: Passed basic stress testing, works with hubs, mice, keyboards, | 21 | * Status: Passed basic stress testing, works with hubs, mice, keyboards, |
@@ -67,7 +67,7 @@ | |||
67 | MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); | 67 | MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); |
68 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
69 | 69 | ||
70 | #define DRIVER_VERSION "15 Dec 2004" | 70 | #define DRIVER_VERSION "19 May 2005" |
71 | 71 | ||
72 | 72 | ||
73 | #ifndef DEBUG | 73 | #ifndef DEBUG |
@@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on) | |||
121 | /* reset as thoroughly as we can */ | 121 | /* reset as thoroughly as we can */ |
122 | if (sl811->board && sl811->board->reset) | 122 | if (sl811->board && sl811->board->reset) |
123 | sl811->board->reset(hcd->self.controller); | 123 | sl811->board->reset(hcd->self.controller); |
124 | else { | ||
125 | sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); | ||
126 | mdelay(20); | ||
127 | } | ||
124 | 128 | ||
125 | sl811_write(sl811, SL11H_IRQ_ENABLE, 0); | 129 | sl811_write(sl811, SL11H_IRQ_ENABLE, 0); |
126 | sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); | 130 | sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); |
@@ -443,6 +447,7 @@ static void finish_request( | |||
443 | spin_lock(&urb->lock); | 447 | spin_lock(&urb->lock); |
444 | if (urb->status == -EINPROGRESS) | 448 | if (urb->status == -EINPROGRESS) |
445 | urb->status = status; | 449 | urb->status = status; |
450 | urb->hcpriv = NULL; | ||
446 | spin_unlock(&urb->lock); | 451 | spin_unlock(&urb->lock); |
447 | 452 | ||
448 | spin_unlock(&sl811->lock); | 453 | spin_unlock(&sl811->lock); |
@@ -472,7 +477,7 @@ static void finish_request( | |||
472 | if (*prev) | 477 | if (*prev) |
473 | *prev = ep->next; | 478 | *prev = ep->next; |
474 | sl811->load[i] -= ep->load; | 479 | sl811->load[i] -= ep->load; |
475 | } | 480 | } |
476 | ep->branch = PERIODIC_SIZE; | 481 | ep->branch = PERIODIC_SIZE; |
477 | sl811->periodic_count--; | 482 | sl811->periodic_count--; |
478 | sl811_to_hcd(sl811)->self.bandwidth_allocated | 483 | sl811_to_hcd(sl811)->self.bandwidth_allocated |
@@ -661,9 +666,9 @@ retry: | |||
661 | 666 | ||
662 | #ifdef QUIRK2 | 667 | #ifdef QUIRK2 |
663 | /* this may no longer be necessary ... */ | 668 | /* this may no longer be necessary ... */ |
664 | if (irqstat == 0 && ret == IRQ_NONE) { | 669 | if (irqstat == 0) { |
665 | irqstat = checkdone(sl811); | 670 | irqstat = checkdone(sl811); |
666 | if (irqstat /* && irq != ~0 */ ) | 671 | if (irqstat) |
667 | sl811->stat_lost++; | 672 | sl811->stat_lost++; |
668 | } | 673 | } |
669 | #endif | 674 | #endif |
@@ -722,7 +727,8 @@ retry: | |||
722 | if (sl811->active_a) { | 727 | if (sl811->active_a) { |
723 | sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); | 728 | sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); |
724 | finish_request(sl811, sl811->active_a, | 729 | finish_request(sl811, sl811->active_a, |
725 | container_of(sl811->active_a->hep->urb_list.next, | 730 | container_of(sl811->active_a |
731 | ->hep->urb_list.next, | ||
726 | struct urb, urb_list), | 732 | struct urb, urb_list), |
727 | NULL, -ESHUTDOWN); | 733 | NULL, -ESHUTDOWN); |
728 | sl811->active_a = NULL; | 734 | sl811->active_a = NULL; |
@@ -731,7 +737,8 @@ retry: | |||
731 | if (sl811->active_b) { | 737 | if (sl811->active_b) { |
732 | sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); | 738 | sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); |
733 | finish_request(sl811, sl811->active_b, | 739 | finish_request(sl811, sl811->active_b, |
734 | container_of(sl811->active_b->hep->urb_list.next, | 740 | container_of(sl811->active_b |
741 | ->hep->urb_list.next, | ||
735 | struct urb, urb_list), | 742 | struct urb, urb_list), |
736 | NULL, -ESHUTDOWN); | 743 | NULL, -ESHUTDOWN); |
737 | sl811->active_b = NULL; | 744 | sl811->active_b = NULL; |
@@ -761,7 +768,7 @@ retry: | |||
761 | goto retry; | 768 | goto retry; |
762 | } | 769 | } |
763 | 770 | ||
764 | if (sl811->periodic_count == 0 && list_empty(&sl811->async)) | 771 | if (sl811->periodic_count == 0 && list_empty(&sl811->async)) |
765 | sofirq_off(sl811); | 772 | sofirq_off(sl811); |
766 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); | 773 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); |
767 | 774 | ||
@@ -796,7 +803,7 @@ static int balance(struct sl811 *sl811, u16 period, u16 load) | |||
796 | } | 803 | } |
797 | if (j < PERIODIC_SIZE) | 804 | if (j < PERIODIC_SIZE) |
798 | continue; | 805 | continue; |
799 | branch = i; | 806 | branch = i; |
800 | } | 807 | } |
801 | } | 808 | } |
802 | return branch; | 809 | return branch; |
@@ -890,6 +897,7 @@ static int sl811h_urb_enqueue( | |||
890 | break; | 897 | break; |
891 | } | 898 | } |
892 | 899 | ||
900 | ep->hep = hep; | ||
893 | hep->hcpriv = ep; | 901 | hep->hcpriv = ep; |
894 | } | 902 | } |
895 | 903 | ||
@@ -961,15 +969,16 @@ fail: | |||
961 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 969 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) |
962 | { | 970 | { |
963 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 971 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
964 | struct usb_host_endpoint *hep = urb->hcpriv; | 972 | struct usb_host_endpoint *hep; |
965 | unsigned long flags; | 973 | unsigned long flags; |
966 | struct sl811h_ep *ep; | 974 | struct sl811h_ep *ep; |
967 | int retval = 0; | 975 | int retval = 0; |
968 | 976 | ||
977 | spin_lock_irqsave(&sl811->lock, flags); | ||
978 | hep = urb->hcpriv; | ||
969 | if (!hep) | 979 | if (!hep) |
970 | return -EINVAL; | 980 | goto fail; |
971 | 981 | ||
972 | spin_lock_irqsave(&sl811->lock, flags); | ||
973 | ep = hep->hcpriv; | 982 | ep = hep->hcpriv; |
974 | if (ep) { | 983 | if (ep) { |
975 | /* finish right away if this urb can't be active ... | 984 | /* finish right away if this urb can't be active ... |
@@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1017 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, | 1026 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, |
1018 | (sl811->active_a == ep) ? "A" : "B"); | 1027 | (sl811->active_a == ep) ? "A" : "B"); |
1019 | } else | 1028 | } else |
1029 | fail: | ||
1020 | retval = -EINVAL; | 1030 | retval = -EINVAL; |
1021 | spin_unlock_irqrestore(&sl811->lock, flags); | 1031 | spin_unlock_irqrestore(&sl811->lock, flags); |
1022 | return retval; | 1032 | return retval; |
@@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd) | |||
1576 | if (sl811->board && sl811->board->power) | 1586 | if (sl811->board && sl811->board->power) |
1577 | hub_set_power_budget(udev, sl811->board->power * 2); | 1587 | hub_set_power_budget(udev, sl811->board->power * 2); |
1578 | 1588 | ||
1589 | /* enable power and interupts */ | ||
1590 | port_power(sl811, 1); | ||
1591 | |||
1579 | return 0; | 1592 | return 0; |
1580 | } | 1593 | } |
1581 | 1594 | ||
@@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = { | |||
1618 | 1631 | ||
1619 | /*-------------------------------------------------------------------------*/ | 1632 | /*-------------------------------------------------------------------------*/ |
1620 | 1633 | ||
1621 | static int __init_or_module | 1634 | static int __devexit |
1622 | sl811h_remove(struct device *dev) | 1635 | sl811h_remove(struct device *dev) |
1623 | { | 1636 | { |
1624 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1637 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
@@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev) | |||
1631 | remove_debug_file(sl811); | 1644 | remove_debug_file(sl811); |
1632 | usb_remove_hcd(hcd); | 1645 | usb_remove_hcd(hcd); |
1633 | 1646 | ||
1634 | iounmap(sl811->data_reg); | 1647 | /* some platforms may use IORESOURCE_IO */ |
1635 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1648 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1636 | release_mem_region(res->start, 1); | 1649 | if (res) |
1650 | iounmap(sl811->data_reg); | ||
1637 | 1651 | ||
1638 | iounmap(sl811->addr_reg); | ||
1639 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1652 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1640 | release_mem_region(res->start, 1); | 1653 | if (res) |
1654 | iounmap(sl811->addr_reg); | ||
1641 | 1655 | ||
1642 | usb_put_hcd(hcd); | 1656 | usb_put_hcd(hcd); |
1643 | return 0; | 1657 | return 0; |
1644 | } | 1658 | } |
1645 | 1659 | ||
1646 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1660 | static int __devinit |
1647 | |||
1648 | static int __init | ||
1649 | sl811h_probe(struct device *dev) | 1661 | sl811h_probe(struct device *dev) |
1650 | { | 1662 | { |
1651 | struct usb_hcd *hcd; | 1663 | struct usb_hcd *hcd; |
@@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev) | |||
1656 | void __iomem *addr_reg; | 1668 | void __iomem *addr_reg; |
1657 | void __iomem *data_reg; | 1669 | void __iomem *data_reg; |
1658 | int retval; | 1670 | int retval; |
1659 | u8 tmp; | 1671 | u8 tmp, ioaddr = 0; |
1660 | 1672 | ||
1661 | /* basic sanity checks first. board-specific init logic should | 1673 | /* basic sanity checks first. board-specific init logic should |
1662 | * have initialized these three resources and probably board | 1674 | * have initialized these three resources and probably board |
@@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev) | |||
1664 | * minimal sanity checking. | 1676 | * minimal sanity checking. |
1665 | */ | 1677 | */ |
1666 | pdev = container_of(dev, struct platform_device, dev); | 1678 | pdev = container_of(dev, struct platform_device, dev); |
1667 | if (pdev->num_resources < 3) | ||
1668 | return -ENODEV; | ||
1669 | |||
1670 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1671 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1672 | irq = platform_get_irq(pdev, 0); | 1679 | irq = platform_get_irq(pdev, 0); |
1673 | if (!addr || !data || irq < 0) | 1680 | if (pdev->num_resources < 3 || irq < 0) |
1674 | return -ENODEV; | 1681 | return -ENODEV; |
1675 | 1682 | ||
1676 | /* refuse to confuse usbcore */ | 1683 | /* refuse to confuse usbcore */ |
@@ -1679,24 +1686,31 @@ sl811h_probe(struct device *dev) | |||
1679 | return -EINVAL; | 1686 | return -EINVAL; |
1680 | } | 1687 | } |
1681 | 1688 | ||
1682 | if (!request_mem_region(addr->start, 1, hcd_name)) { | 1689 | /* the chip may be wired for either kind of addressing */ |
1683 | retval = -EBUSY; | 1690 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1684 | goto err1; | 1691 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1685 | } | 1692 | retval = -EBUSY; |
1686 | addr_reg = ioremap(addr->start, resource_len(addr)); | 1693 | if (!addr || !data) { |
1687 | if (addr_reg == NULL) { | 1694 | addr = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1688 | retval = -ENOMEM; | 1695 | data = platform_get_resource(pdev, IORESOURCE_IO, 1); |
1689 | goto err2; | 1696 | if (!addr || !data) |
1690 | } | 1697 | return -ENODEV; |
1698 | ioaddr = 1; | ||
1699 | |||
1700 | addr_reg = (void __iomem *) addr->start; | ||
1701 | data_reg = (void __iomem *) data->start; | ||
1702 | } else { | ||
1703 | addr_reg = ioremap(addr->start, 1); | ||
1704 | if (addr_reg == NULL) { | ||
1705 | retval = -ENOMEM; | ||
1706 | goto err2; | ||
1707 | } | ||
1691 | 1708 | ||
1692 | if (!request_mem_region(data->start, 1, hcd_name)) { | 1709 | data_reg = ioremap(data->start, 1); |
1693 | retval = -EBUSY; | 1710 | if (data_reg == NULL) { |
1694 | goto err3; | 1711 | retval = -ENOMEM; |
1695 | } | 1712 | goto err4; |
1696 | data_reg = ioremap(data->start, resource_len(addr)); | 1713 | } |
1697 | if (data_reg == NULL) { | ||
1698 | retval = -ENOMEM; | ||
1699 | goto err4; | ||
1700 | } | 1714 | } |
1701 | 1715 | ||
1702 | /* allocate and initialize hcd */ | 1716 | /* allocate and initialize hcd */ |
@@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev) | |||
1737 | goto err6; | 1751 | goto err6; |
1738 | } | 1752 | } |
1739 | 1753 | ||
1740 | /* sl811s would need a different handler for this irq */ | 1754 | /* The chip's IRQ is level triggered, active high. A requirement |
1741 | #ifdef CONFIG_ARM | 1755 | * for platform device setup is to cope with things like signal |
1742 | /* Cypress docs say the IRQ is IRQT_HIGH ... */ | 1756 | * inverters (e.g. CF is active low) or working only with edge |
1743 | set_irq_type(irq, IRQT_RISING); | 1757 | * triggers (e.g. most ARM CPUs). Initial driver stress testing |
1744 | #endif | 1758 | * was on a system with single edge triggering, so most sorts of |
1745 | retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); | 1759 | * triggering arrangement should work. |
1760 | */ | ||
1761 | retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); | ||
1746 | if (retval != 0) | 1762 | if (retval != 0) |
1747 | goto err6; | 1763 | goto err6; |
1748 | 1764 | ||
@@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev) | |||
1752 | err6: | 1768 | err6: |
1753 | usb_put_hcd(hcd); | 1769 | usb_put_hcd(hcd); |
1754 | err5: | 1770 | err5: |
1755 | iounmap(data_reg); | 1771 | if (!ioaddr) |
1772 | iounmap(data_reg); | ||
1756 | err4: | 1773 | err4: |
1757 | release_mem_region(data->start, 1); | 1774 | if (!ioaddr) |
1758 | err3: | 1775 | iounmap(addr_reg); |
1759 | iounmap(addr_reg); | ||
1760 | err2: | 1776 | err2: |
1761 | release_mem_region(addr->start, 1); | ||
1762 | err1: | ||
1763 | DBG("init error, %d\n", retval); | 1777 | DBG("init error, %d\n", retval); |
1764 | return retval; | 1778 | return retval; |
1765 | } | 1779 | } |
@@ -1767,7 +1781,7 @@ sl811h_probe(struct device *dev) | |||
1767 | #ifdef CONFIG_PM | 1781 | #ifdef CONFIG_PM |
1768 | 1782 | ||
1769 | /* for this device there's no useful distinction between the controller | 1783 | /* for this device there's no useful distinction between the controller |
1770 | * and its root hub, except that the root hub only gets direct PM calls | 1784 | * and its root hub, except that the root hub only gets direct PM calls |
1771 | * when CONFIG_USB_SUSPEND is enabled. | 1785 | * when CONFIG_USB_SUSPEND is enabled. |
1772 | */ | 1786 | */ |
1773 | 1787 | ||
@@ -1821,20 +1835,22 @@ sl811h_resume(struct device *dev, u32 phase) | |||
1821 | #endif | 1835 | #endif |
1822 | 1836 | ||
1823 | 1837 | ||
1824 | static struct device_driver sl811h_driver = { | 1838 | /* this driver is exported so sl811_cs can depend on it */ |
1839 | struct device_driver sl811h_driver = { | ||
1825 | .name = (char *) hcd_name, | 1840 | .name = (char *) hcd_name, |
1826 | .bus = &platform_bus_type, | 1841 | .bus = &platform_bus_type, |
1827 | 1842 | ||
1828 | .probe = sl811h_probe, | 1843 | .probe = sl811h_probe, |
1829 | .remove = sl811h_remove, | 1844 | .remove = __devexit_p(sl811h_remove), |
1830 | 1845 | ||
1831 | .suspend = sl811h_suspend, | 1846 | .suspend = sl811h_suspend, |
1832 | .resume = sl811h_resume, | 1847 | .resume = sl811h_resume, |
1833 | }; | 1848 | }; |
1849 | EXPORT_SYMBOL(sl811h_driver); | ||
1834 | 1850 | ||
1835 | /*-------------------------------------------------------------------------*/ | 1851 | /*-------------------------------------------------------------------------*/ |
1836 | 1852 | ||
1837 | static int __init sl811h_init(void) | 1853 | static int __init sl811h_init(void) |
1838 | { | 1854 | { |
1839 | if (usb_disabled()) | 1855 | if (usb_disabled()) |
1840 | return -ENODEV; | 1856 | return -ENODEV; |
@@ -1844,8 +1860,8 @@ static int __init sl811h_init(void) | |||
1844 | } | 1860 | } |
1845 | module_init(sl811h_init); | 1861 | module_init(sl811h_init); |
1846 | 1862 | ||
1847 | static void __exit sl811h_cleanup(void) | 1863 | static void __exit sl811h_cleanup(void) |
1848 | { | 1864 | { |
1849 | driver_unregister(&sl811h_driver); | 1865 | driver_unregister(&sl811h_driver); |
1850 | } | 1866 | } |
1851 | module_exit(sl811h_cleanup); | 1867 | module_exit(sl811h_cleanup); |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c new file mode 100644 index 000000000000..6e173265095c --- /dev/null +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -0,0 +1,442 @@ | |||
1 | /* | ||
2 | * PCMCIA driver for SL811HS (as found in REX-CFU1U) | ||
3 | * Filename: sl811_cs.c | ||
4 | * Author: Yukio Yamamoto | ||
5 | * | ||
6 | * Port to sl811-hcd and 2.6.x by | ||
7 | * Botond Botyanszki <boti@rocketmail.com> | ||
8 | * Simon Pickering | ||
9 | * | ||
10 | * Last update: 2005-05-12 | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/sched.h> | ||
17 | #include <linux/ptrace.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/ioport.h> | ||
22 | |||
23 | #include <pcmcia/version.h> | ||
24 | #include <pcmcia/cs_types.h> | ||
25 | #include <pcmcia/cs.h> | ||
26 | #include <pcmcia/cistpl.h> | ||
27 | #include <pcmcia/cisreg.h> | ||
28 | #include <pcmcia/ds.h> | ||
29 | |||
30 | #include <linux/usb_sl811.h> | ||
31 | |||
32 | MODULE_AUTHOR("Botond Botyanszki"); | ||
33 | MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | |||
37 | /*====================================================================*/ | ||
38 | /* MACROS */ | ||
39 | /*====================================================================*/ | ||
40 | |||
41 | #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) | ||
42 | |||
43 | static int pc_debug = 0; | ||
44 | module_param(pc_debug, int, 0644); | ||
45 | |||
46 | #define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) | ||
47 | |||
48 | #else | ||
49 | #define DBG(n, args...) do{}while(0) | ||
50 | #endif /* no debugging */ | ||
51 | |||
52 | #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) | ||
53 | |||
54 | #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) | ||
55 | |||
56 | #define CS_CHECK(fn, ret) \ | ||
57 | do { \ | ||
58 | last_fn = (fn); \ | ||
59 | if ((last_ret = (ret)) != 0) \ | ||
60 | goto cs_failed; \ | ||
61 | } while (0) | ||
62 | |||
63 | /*====================================================================*/ | ||
64 | /* VARIABLES */ | ||
65 | /*====================================================================*/ | ||
66 | |||
67 | static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; | ||
68 | |||
69 | static dev_link_t *dev_list = NULL; | ||
70 | |||
71 | static int irq_list[4] = { -1 }; | ||
72 | static int irq_list_count; | ||
73 | |||
74 | module_param_array(irq_list, int, &irq_list_count, 0444); | ||
75 | |||
76 | INT_MODULE_PARM(irq_mask, 0xdeb8); | ||
77 | |||
78 | typedef struct local_info_t { | ||
79 | dev_link_t link; | ||
80 | dev_node_t node; | ||
81 | } local_info_t; | ||
82 | |||
83 | /*====================================================================*/ | ||
84 | |||
85 | static void release_platform_dev(struct device * dev) | ||
86 | { | ||
87 | DBG(0, "sl811_cs platform_dev release\n"); | ||
88 | dev->parent = NULL; | ||
89 | } | ||
90 | |||
91 | static struct sl811_platform_data platform_data = { | ||
92 | .potpg = 100, | ||
93 | .power = 50, /* == 100mA */ | ||
94 | // .reset = ... FIXME: invoke CF reset on the card | ||
95 | }; | ||
96 | |||
97 | static struct resource resources[] = { | ||
98 | [0] = { | ||
99 | .flags = IORESOURCE_IRQ, | ||
100 | }, | ||
101 | [1] = { | ||
102 | // .name = "address", | ||
103 | .flags = IORESOURCE_IO, | ||
104 | }, | ||
105 | [2] = { | ||
106 | // .name = "data", | ||
107 | .flags = IORESOURCE_IO, | ||
108 | }, | ||
109 | }; | ||
110 | |||
111 | extern struct device_driver sl811h_driver; | ||
112 | |||
113 | static struct platform_device platform_dev = { | ||
114 | .id = -1, | ||
115 | .dev = { | ||
116 | .platform_data = &platform_data, | ||
117 | .release = release_platform_dev, | ||
118 | }, | ||
119 | .resource = resources, | ||
120 | .num_resources = ARRAY_SIZE(resources), | ||
121 | }; | ||
122 | |||
123 | static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | ||
124 | { | ||
125 | if (platform_dev.dev.parent) | ||
126 | return -EBUSY; | ||
127 | platform_dev.dev.parent = parent; | ||
128 | |||
129 | /* finish seting up the platform device */ | ||
130 | resources[0].start = irq; | ||
131 | |||
132 | resources[1].start = base_addr; | ||
133 | resources[1].end = base_addr; | ||
134 | |||
135 | resources[2].start = base_addr + 1; | ||
136 | resources[2].end = base_addr + 1; | ||
137 | |||
138 | /* The driver core will probe for us. We know sl811-hcd has been | ||
139 | * initialized already because of the link order dependency. | ||
140 | */ | ||
141 | platform_dev.name = sl811h_driver.name; | ||
142 | return platform_device_register(&platform_dev); | ||
143 | } | ||
144 | |||
145 | /*====================================================================*/ | ||
146 | |||
147 | static void sl811_cs_detach(dev_link_t *link) | ||
148 | { | ||
149 | dev_link_t **linkp; | ||
150 | |||
151 | DBG(0, "sl811_cs_detach(0x%p)\n", link); | ||
152 | |||
153 | /* Locate device structure */ | ||
154 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { | ||
155 | if (*linkp == link) | ||
156 | break; | ||
157 | } | ||
158 | if (*linkp == NULL) | ||
159 | return; | ||
160 | |||
161 | /* Break the link with Card Services */ | ||
162 | if (link->handle) | ||
163 | pcmcia_deregister_client(link->handle); | ||
164 | |||
165 | /* Unlink device structure, and free it */ | ||
166 | *linkp = link->next; | ||
167 | /* This points to the parent local_info_t struct */ | ||
168 | kfree(link->priv); | ||
169 | } | ||
170 | |||
171 | static void sl811_cs_release(dev_link_t * link) | ||
172 | { | ||
173 | |||
174 | DBG(0, "sl811_cs_release(0x%p)\n", link); | ||
175 | |||
176 | if (link->open) { | ||
177 | DBG(1, "sl811_cs: release postponed, '%s' still open\n", | ||
178 | link->dev->dev_name); | ||
179 | link->state |= DEV_STALE_CONFIG; | ||
180 | return; | ||
181 | } | ||
182 | |||
183 | /* Unlink the device chain */ | ||
184 | link->dev = NULL; | ||
185 | |||
186 | platform_device_unregister(&platform_dev); | ||
187 | pcmcia_release_configuration(link->handle); | ||
188 | if (link->io.NumPorts1) | ||
189 | pcmcia_release_io(link->handle, &link->io); | ||
190 | if (link->irq.AssignedIRQ) | ||
191 | pcmcia_release_irq(link->handle, &link->irq); | ||
192 | link->state &= ~DEV_CONFIG; | ||
193 | |||
194 | if (link->state & DEV_STALE_LINK) | ||
195 | sl811_cs_detach(link); | ||
196 | } | ||
197 | |||
198 | static void sl811_cs_config(dev_link_t *link) | ||
199 | { | ||
200 | client_handle_t handle = link->handle; | ||
201 | struct device *parent = &handle_to_dev(handle); | ||
202 | local_info_t *dev = link->priv; | ||
203 | tuple_t tuple; | ||
204 | cisparse_t parse; | ||
205 | int last_fn, last_ret; | ||
206 | u_char buf[64]; | ||
207 | config_info_t conf; | ||
208 | cistpl_cftable_entry_t dflt = { 0 }; | ||
209 | |||
210 | DBG(0, "sl811_cs_config(0x%p)\n", link); | ||
211 | |||
212 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
213 | tuple.Attributes = 0; | ||
214 | tuple.TupleData = buf; | ||
215 | tuple.TupleDataMax = sizeof(buf); | ||
216 | tuple.TupleOffset = 0; | ||
217 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
218 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | ||
219 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | ||
220 | link->conf.ConfigBase = parse.config.base; | ||
221 | link->conf.Present = parse.config.rmask[0]; | ||
222 | |||
223 | /* Configure card */ | ||
224 | link->state |= DEV_CONFIG; | ||
225 | |||
226 | /* Look up the current Vcc */ | ||
227 | CS_CHECK(GetConfigurationInfo, | ||
228 | pcmcia_get_configuration_info(handle, &conf)); | ||
229 | link->conf.Vcc = conf.Vcc; | ||
230 | |||
231 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
232 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
233 | while (1) { | ||
234 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | ||
235 | |||
236 | if (pcmcia_get_tuple_data(handle, &tuple) != 0 | ||
237 | || pcmcia_parse_tuple(handle, &tuple, &parse) | ||
238 | != 0) | ||
239 | goto next_entry; | ||
240 | |||
241 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { | ||
242 | dflt = *cfg; | ||
243 | } | ||
244 | |||
245 | if (cfg->index == 0) | ||
246 | goto next_entry; | ||
247 | |||
248 | link->conf.ConfigIndex = cfg->index; | ||
249 | |||
250 | /* Use power settings for Vcc and Vpp if present */ | ||
251 | /* Note that the CIS values need to be rescaled */ | ||
252 | if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
253 | if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 | ||
254 | != conf.Vcc) | ||
255 | goto next_entry; | ||
256 | } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
257 | if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 | ||
258 | != conf.Vcc) | ||
259 | goto next_entry; | ||
260 | } | ||
261 | |||
262 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
263 | link->conf.Vpp1 = link->conf.Vpp2 = | ||
264 | cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
265 | else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
266 | link->conf.Vpp1 = link->conf.Vpp2 = | ||
267 | dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
268 | |||
269 | /* we need an interrupt */ | ||
270 | if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) | ||
271 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
272 | |||
273 | /* IO window settings */ | ||
274 | link->io.NumPorts1 = link->io.NumPorts2 = 0; | ||
275 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
276 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
277 | |||
278 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
279 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
280 | link->io.BasePort1 = io->win[0].base; | ||
281 | link->io.NumPorts1 = io->win[0].len; | ||
282 | |||
283 | if (pcmcia_request_io(link->handle, &link->io) != 0) | ||
284 | goto next_entry; | ||
285 | } | ||
286 | break; | ||
287 | |||
288 | next_entry: | ||
289 | if (link->io.NumPorts1) | ||
290 | pcmcia_release_io(link->handle, &link->io); | ||
291 | last_ret = pcmcia_get_next_tuple(handle, &tuple); | ||
292 | } | ||
293 | |||
294 | /* require an IRQ and two registers */ | ||
295 | if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) | ||
296 | goto cs_failed; | ||
297 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | ||
298 | CS_CHECK(RequestIRQ, | ||
299 | pcmcia_request_irq(link->handle, &link->irq)); | ||
300 | else | ||
301 | goto cs_failed; | ||
302 | |||
303 | CS_CHECK(RequestConfiguration, | ||
304 | pcmcia_request_configuration(link->handle, &link->conf)); | ||
305 | |||
306 | sprintf(dev->node.dev_name, driver_name); | ||
307 | dev->node.major = dev->node.minor = 0; | ||
308 | link->dev = &dev->node; | ||
309 | |||
310 | printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", | ||
311 | dev->node.dev_name, link->conf.ConfigIndex, | ||
312 | link->conf.Vcc/10, link->conf.Vcc%10); | ||
313 | if (link->conf.Vpp1) | ||
314 | printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); | ||
315 | printk(", irq %d", link->irq.AssignedIRQ); | ||
316 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | ||
317 | link->io.BasePort1+link->io.NumPorts1-1); | ||
318 | printk("\n"); | ||
319 | |||
320 | link->state &= ~DEV_CONFIG_PENDING; | ||
321 | |||
322 | if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) | ||
323 | < 0) { | ||
324 | cs_failed: | ||
325 | printk("sl811_cs_config failed\n"); | ||
326 | cs_error(link->handle, last_fn, last_ret); | ||
327 | sl811_cs_release(link); | ||
328 | link->state &= ~DEV_CONFIG_PENDING; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | static int | ||
333 | sl811_cs_event(event_t event, int priority, event_callback_args_t *args) | ||
334 | { | ||
335 | dev_link_t *link = args->client_data; | ||
336 | |||
337 | DBG(1, "sl811_cs_event(0x%06x)\n", event); | ||
338 | |||
339 | switch (event) { | ||
340 | case CS_EVENT_CARD_REMOVAL: | ||
341 | link->state &= ~DEV_PRESENT; | ||
342 | if (link->state & DEV_CONFIG) | ||
343 | sl811_cs_release(link); | ||
344 | break; | ||
345 | |||
346 | case CS_EVENT_CARD_INSERTION: | ||
347 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
348 | sl811_cs_config(link); | ||
349 | break; | ||
350 | |||
351 | case CS_EVENT_PM_SUSPEND: | ||
352 | link->state |= DEV_SUSPEND; | ||
353 | /* Fall through... */ | ||
354 | case CS_EVENT_RESET_PHYSICAL: | ||
355 | if (link->state & DEV_CONFIG) | ||
356 | pcmcia_release_configuration(link->handle); | ||
357 | break; | ||
358 | |||
359 | case CS_EVENT_PM_RESUME: | ||
360 | link->state &= ~DEV_SUSPEND; | ||
361 | /* Fall through... */ | ||
362 | case CS_EVENT_CARD_RESET: | ||
363 | if (link->state & DEV_CONFIG) | ||
364 | pcmcia_request_configuration(link->handle, &link->conf); | ||
365 | DBG(0, "reset sl811-hcd here?\n"); | ||
366 | break; | ||
367 | } | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static dev_link_t *sl811_cs_attach(void) | ||
372 | { | ||
373 | local_info_t *local; | ||
374 | dev_link_t *link; | ||
375 | client_reg_t client_reg; | ||
376 | int ret, i; | ||
377 | |||
378 | local = kmalloc(sizeof(local_info_t), GFP_KERNEL); | ||
379 | if (!local) | ||
380 | return NULL; | ||
381 | memset(local, 0, sizeof(local_info_t)); | ||
382 | link = &local->link; | ||
383 | link->priv = local; | ||
384 | |||
385 | /* Initialize */ | ||
386 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
387 | link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; | ||
388 | if (irq_list[0] == -1) | ||
389 | link->irq.IRQInfo2 = irq_mask; | ||
390 | else | ||
391 | for (i = 0; i < irq_list_count; i++) | ||
392 | link->irq.IRQInfo2 |= 1 << irq_list[i]; | ||
393 | link->irq.Handler = NULL; | ||
394 | |||
395 | link->conf.Attributes = 0; | ||
396 | link->conf.Vcc = 33; | ||
397 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
398 | |||
399 | /* Register with Card Services */ | ||
400 | link->next = dev_list; | ||
401 | dev_list = link; | ||
402 | client_reg.dev_info = (dev_info_t *) &driver_name; | ||
403 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; | ||
404 | client_reg.EventMask = | ||
405 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | | ||
406 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | | ||
407 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; | ||
408 | client_reg.event_handler = &sl811_cs_event; | ||
409 | client_reg.Version = 0x0210; | ||
410 | client_reg.event_callback_args.client_data = link; | ||
411 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
412 | if (ret != CS_SUCCESS) { | ||
413 | cs_error(link->handle, RegisterClient, ret); | ||
414 | sl811_cs_detach(link); | ||
415 | return NULL; | ||
416 | } | ||
417 | |||
418 | return link; | ||
419 | } | ||
420 | |||
421 | static struct pcmcia_driver sl811_cs_driver = { | ||
422 | .owner = THIS_MODULE, | ||
423 | .drv = { | ||
424 | .name = (char *)driver_name, | ||
425 | }, | ||
426 | .attach = sl811_cs_attach, | ||
427 | .detach = sl811_cs_detach, | ||
428 | }; | ||
429 | |||
430 | /*====================================================================*/ | ||
431 | |||
432 | static int __init init_sl811_cs(void) | ||
433 | { | ||
434 | return pcmcia_register_driver(&sl811_cs_driver); | ||
435 | } | ||
436 | module_init(init_sl811_cs); | ||
437 | |||
438 | static void __exit exit_sl811_cs(void) | ||
439 | { | ||
440 | pcmcia_unregister_driver(&sl811_cs_driver); | ||
441 | } | ||
442 | module_exit(exit_sl811_cs); | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 869ff73690ac..2d8bd9dcc6ed 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1315,6 +1315,8 @@ void hid_init_reports(struct hid_device *hid) | |||
1315 | #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 | 1315 | #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 |
1316 | #define USB_DEVICE_ID_WACOM_VOLITO 0x0060 | 1316 | #define USB_DEVICE_ID_WACOM_VOLITO 0x0060 |
1317 | #define USB_DEVICE_ID_WACOM_PTU 0x0003 | 1317 | #define USB_DEVICE_ID_WACOM_PTU 0x0003 |
1318 | #define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 | ||
1319 | #define USB_DEVICE_ID_WACOM_CINTIQ 0x003F | ||
1318 | 1320 | ||
1319 | #define USB_VENDOR_ID_KBGEAR 0x084e | 1321 | #define USB_VENDOR_ID_KBGEAR 0x084e |
1320 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 1322 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
@@ -1401,6 +1403,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1401 | 1403 | ||
1402 | #define USB_VENDOR_ID_DELORME 0x1163 | 1404 | #define USB_VENDOR_ID_DELORME 0x1163 |
1403 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 | 1405 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 |
1406 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 | ||
1404 | 1407 | ||
1405 | #define USB_VENDOR_ID_MCC 0x09db | 1408 | #define USB_VENDOR_ID_MCC 0x09db |
1406 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 | 1409 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 |
@@ -1412,6 +1415,12 @@ void hid_init_reports(struct hid_device *hid) | |||
1412 | #define USB_VENDOR_ID_BTC 0x046e | 1415 | #define USB_VENDOR_ID_BTC 0x046e |
1413 | #define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 | 1416 | #define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 |
1414 | 1417 | ||
1418 | #define USB_VENDOR_ID_VERNIER 0x08f7 | ||
1419 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | ||
1420 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | ||
1421 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | ||
1422 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | ||
1423 | |||
1415 | 1424 | ||
1416 | /* | 1425 | /* |
1417 | * Alphabetically sorted blacklist by quirk type. | 1426 | * Alphabetically sorted blacklist by quirk type. |
@@ -1437,6 +1446,7 @@ static struct hid_blacklist { | |||
1437 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, | 1446 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, |
1438 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, | 1447 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, |
1439 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, | 1448 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, |
1449 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, | ||
1440 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, | 1450 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, |
1441 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, | 1451 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, |
1442 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, | 1452 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, |
@@ -1456,6 +1466,10 @@ static struct hid_blacklist { | |||
1456 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, | 1466 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, |
1457 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, | 1467 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, |
1458 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, | 1468 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, |
1469 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, | ||
1470 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, | ||
1471 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, | ||
1472 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, | ||
1459 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, | 1473 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, |
1460 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, | 1474 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, |
1461 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, | 1475 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, |
@@ -1481,6 +1495,10 @@ static struct hid_blacklist { | |||
1481 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, | 1495 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, |
1482 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, | 1496 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, |
1483 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, | 1497 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, |
1498 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, | ||
1499 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, | ||
1500 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, | ||
1501 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, | ||
1484 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1502 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1485 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1503 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1486 | 1504 | ||
diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog deleted file mode 100644 index b2eb71a9afb5..000000000000 --- a/drivers/usb/media/pwc/ChangeLog +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | 9.0.2 | ||
2 | |||
3 | * Adding #ifdef to compile PWC before and after 2.6.5 | ||
4 | |||
5 | 9.0.1 | ||
6 | |||
7 | 9.0 | ||
8 | |||
9 | |||
10 | 8.12 | ||
11 | |||
12 | * Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere. | ||
13 | |||
14 | 8.11.1 | ||
15 | |||
16 | * Fix for PCVC720/40, would not be able to set videomode | ||
17 | * Fix for Samsung MPC models, appearantly they are based on a newer chipset | ||
18 | |||
19 | 8.11 | ||
20 | |||
21 | * 20 dev_hints (per request) | ||
22 | * Hot unplugging should be better, no more dangling pointers or memory leaks | ||
23 | * Added reserved Logitech webcam IDs | ||
24 | * Device now remembers size & fps between close()/open() | ||
25 | * Removed palette stuff altogether | ||
26 | |||
27 | 8.10.1 | ||
28 | |||
29 | * Added IDs for PCVC720K/40 and Creative Labs Webcam Pro | ||
30 | |||
31 | 8.10 | ||
32 | |||
33 | * Fixed ID for QuickCam Notebook pro | ||
34 | * Added GREALSIZE ioctl() call | ||
35 | * Fixed bug in case PWCX was not loaded and invalid size was set | ||
36 | |||
37 | 8.9 | ||
38 | |||
39 | * Merging with kernel 2.5.49 | ||
40 | * Adding IDs for QuickCam Zoom & QuickCam Notebook | ||
41 | |||
42 | 8.8 | ||
43 | |||
44 | * Fixing 'leds' parameter | ||
45 | * Adding IDs for Logitech QuickCam Pro 4000 | ||
46 | * Making URB init/cleanup a little nicer | ||
47 | |||
48 | 8.7 | ||
49 | |||
50 | * Incorporating changes in ioctl() parameter passing | ||
51 | * Also changes to URB mechanism | ||
52 | |||
53 | 8.6 | ||
54 | |||
55 | * Added ID's for Visionite VCS UM100 and UC300 | ||
56 | * Removed YUV420-interlaced palette altogether (was confusing) | ||
57 | * Removed MIRROR stuff as it didn't work anyway | ||
58 | * Fixed a problem with the 'leds' parameter (wouldn't blink) | ||
59 | * Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s, | ||
60 | CONTOUR, BACKLIGHT, FLICKER, DYNNOISE. | ||
61 | * VIDIOCGCAP.name now contains real camera model name instead of | ||
62 | 'Philips xxx webcam' | ||
63 | * Added PROBE ioctl (see previous point & API doc) | ||
64 | |||
65 | 8.5 | ||
66 | |||
67 | * Adding IDs for Creative Labs Webcam 5 | ||
68 | * Adding IDs for SOTEC CMS-001 webcam | ||
69 | * Solving possible hang in VIDIOCSYNC when unplugging the cam | ||
70 | * Forgot to return structure in VIDIOCPWCGAWB, oops | ||
71 | * Time interval for the LEDs are now in milliseconds | ||
72 | |||
73 | 8.4 | ||
74 | |||
75 | * Fixing power_save option for Vesta range | ||
76 | * Handling new error codes in ISOC callback | ||
77 | * Adding dev_hint module parameter, to specify /dev/videoX device nodes | ||
78 | |||
79 | 8.3 | ||
80 | |||
81 | * Adding Samsung C10 and C30 cameras | ||
82 | * Removing palette module parameter | ||
83 | * Fixed typo in ID of QuickCam 3000 Pro | ||
84 | * Adding LED settings (blinking while in use) for ToUCam cameras. | ||
85 | * Turns LED off when camera is not in use. | ||
86 | |||
87 | 8.2 | ||
88 | |||
89 | * Making module more silent when trace = 0 | ||
90 | * Adding QuickCam 3000 Pro IDs | ||
91 | * Chrominance control for the Vesta cameras | ||
92 | * Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM | ||
93 | * Included Oliver Neukem's lock_kernel() patch | ||
94 | * Allocates less memory for image buffers | ||
95 | * Adds ioctl()s for the whitebalancing | ||
96 | |||
97 | 8.1 | ||
98 | |||
99 | * Adding support for 750 | ||
100 | * Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls | ||
101 | |||
102 | 8.0 | ||
103 | * 'damage control' after inclusion in 2.4.5. | ||
104 | * Changed wait-queue mechanism in read/mmap/poll according to the book. | ||
105 | * Included YUV420P palette. | ||
106 | * Changed interface to decompressor module. | ||
107 | * Cleaned up pwc structure a bit. | ||
108 | |||
109 | 7.0 | ||
110 | |||
111 | * Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned. | ||
112 | * There is now a clear error message when an image size is selected that | ||
113 | is only supported using the decompressor, and the decompressor isn't | ||
114 | loaded. | ||
115 | * When the decompressor wasn't loaded, selecting large image size | ||
116 | would create skewed or double images. | ||
117 | |||
118 | 6.3 | ||
119 | |||
120 | * Introduced spinlocks for the buffer pointer manipulation; a number of | ||
121 | reports seem to suggest the down()/up() semaphores were the cause of | ||
122 | lockups, since they are not suitable for interrupt/user locking. | ||
123 | * Separated decompressor and core code into 2 modules. | ||
124 | |||
125 | 6.2 | ||
126 | |||
127 | * Non-integral image sizes are now padded with gray or black. | ||
128 | * Added SHUTTERSPEED ioctl(). | ||
129 | * Fixed buglet in VIDIOCPWCSAGC; the function would always return an error, | ||
130 | even though the call succeeded. | ||
131 | * Added hotplug support for 2.4.*. | ||
132 | * Memory: the 645/646 uses less memory now. | ||
133 | |||
134 | 6.1 | ||
135 | |||
136 | * VIDIOCSPICT returns -EINVAL with invalid palettes. | ||
137 | * Added saturation control. | ||
138 | * Split decompressors from rest. | ||
139 | * Fixed bug that would reset the framerate to the default framerate if | ||
140 | the rate field was set to 0 (which is not what I intended, nl. do not | ||
141 | change the framerate!). | ||
142 | * VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately. | ||
143 | * Workaround for a bug in the 730 sensor. | ||
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 3e1e4fe20d85..53099190952c 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c | |||
@@ -48,8 +48,6 @@ | |||
48 | #include "pwc-uncompress.h" | 48 | #include "pwc-uncompress.h" |
49 | #include "pwc-kiara.h" | 49 | #include "pwc-kiara.h" |
50 | #include "pwc-timon.h" | 50 | #include "pwc-timon.h" |
51 | #include "pwc-dec1.h" | ||
52 | #include "pwc-dec23.h" | ||
53 | 51 | ||
54 | /* Request types: video */ | 52 | /* Request types: video */ |
55 | #define SET_LUM_CTL 0x01 | 53 | #define SET_LUM_CTL 0x01 |
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c index c596083f06ba..bc3b1635eab0 100644 --- a/drivers/usb/media/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | #include "pwc.h" | 30 | #include "pwc.h" |
31 | #include "pwc-uncompress.h" | 31 | #include "pwc-uncompress.h" |
32 | #include "pwc-dec1.h" | ||
33 | #include "pwc-dec23.h" | ||
34 | 32 | ||
35 | int pwc_decompress(struct pwc_device *pdev) | 33 | int pwc_decompress(struct pwc_device *pdev) |
36 | { | 34 | { |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 85476e76b244..4cbb408af727 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf) | |||
2765 | } | 2765 | } |
2766 | /* expect bcdVersion 1.0, ignore */ | 2766 | /* expect bcdVersion 1.0, ignore */ |
2767 | if (memcmp(&desc->bGUID, blan_guid, 16) | 2767 | if (memcmp(&desc->bGUID, blan_guid, 16) |
2768 | && memcmp(&desc->bGUID, blan_guid, 16) ) { | 2768 | && memcmp(&desc->bGUID, safe_guid, 16) ) { |
2769 | /* hey, this one might _really_ be MDLM! */ | 2769 | /* hey, this one might _really_ be MDLM! */ |
2770 | dev_dbg (&intf->dev, "MDLM guid\n"); | 2770 | dev_dbg (&intf->dev, "MDLM guid\n"); |
2771 | goto bad_desc; | 2771 | goto bad_desc; |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index bc798edf0358..9438909e87a5 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -455,6 +455,17 @@ config USB_SERIAL_XIRCOM | |||
455 | To compile this driver as a module, choose M here: the | 455 | To compile this driver as a module, choose M here: the |
456 | module will be called keyspan_pda. | 456 | module will be called keyspan_pda. |
457 | 457 | ||
458 | config USB_SERIAL_OPTION | ||
459 | tristate "USB Option PCMCIA serial driver" | ||
460 | depends on USB_SERIAL && USB_OHCI_HCD && PCCARD | ||
461 | help | ||
462 | Say Y here if you want to use an Option card. This is a | ||
463 | GSM card, controlled by three serial ports which are connected | ||
464 | via an OHCI adapter located on a PC card. | ||
465 | |||
466 | To compile this driver as a module, choose M here: the | ||
467 | module will be called option. | ||
468 | |||
458 | config USB_SERIAL_OMNINET | 469 | config USB_SERIAL_OMNINET |
459 | tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" | 470 | tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" |
460 | depends on USB_SERIAL && EXPERIMENTAL | 471 | depends on USB_SERIAL && EXPERIMENTAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index d56ff6d86cce..6c7cdcc99a9e 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -32,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o | |||
32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o | 32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o |
33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o | 33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o |
34 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 34 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
35 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | ||
35 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 36 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
36 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 37 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
37 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 38 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 7e9bb63eb466..4ace9964fc6b 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -7,6 +7,14 @@ | |||
7 | * modify it under the terms of the GNU General Public License version | 7 | * modify it under the terms of the GNU General Public License version |
8 | * 2 as published by the Free Software Foundation. | 8 | * 2 as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * Support to set flow control line levels using TIOCMGET and TIOCMSET | ||
11 | * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow | ||
12 | * control thanks to Munir Nassar nassarmu@real-time.com | ||
13 | * | ||
14 | * Outstanding Issues: | ||
15 | * Buffers are not flushed when the port is opened. | ||
16 | * Multiple calls to write() may fail with "Resource temporarily unavailable" | ||
17 | * | ||
10 | */ | 18 | */ |
11 | 19 | ||
12 | #include <linux/config.h> | 20 | #include <linux/config.h> |
@@ -24,7 +32,7 @@ | |||
24 | /* | 32 | /* |
25 | * Version Information | 33 | * Version Information |
26 | */ | 34 | */ |
27 | #define DRIVER_VERSION "v0.03" | 35 | #define DRIVER_VERSION "v0.04" |
28 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" | 36 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" |
29 | 37 | ||
30 | /* | 38 | /* |
@@ -35,6 +43,9 @@ static void cp2101_cleanup(struct usb_serial_port*); | |||
35 | static void cp2101_close(struct usb_serial_port*, struct file*); | 43 | static void cp2101_close(struct usb_serial_port*, struct file*); |
36 | static void cp2101_get_termios(struct usb_serial_port*); | 44 | static void cp2101_get_termios(struct usb_serial_port*); |
37 | static void cp2101_set_termios(struct usb_serial_port*, struct termios*); | 45 | static void cp2101_set_termios(struct usb_serial_port*, struct termios*); |
46 | static int cp2101_tiocmget (struct usb_serial_port *, struct file *); | ||
47 | static int cp2101_tiocmset (struct usb_serial_port *, struct file *, | ||
48 | unsigned int, unsigned int); | ||
38 | static void cp2101_break_ctl(struct usb_serial_port*, int); | 49 | static void cp2101_break_ctl(struct usb_serial_port*, int); |
39 | static int cp2101_startup (struct usb_serial *); | 50 | static int cp2101_startup (struct usb_serial *); |
40 | static void cp2101_shutdown(struct usb_serial*); | 51 | static void cp2101_shutdown(struct usb_serial*); |
@@ -43,9 +54,10 @@ static void cp2101_shutdown(struct usb_serial*); | |||
43 | static int debug; | 54 | static int debug; |
44 | 55 | ||
45 | static struct usb_device_id id_table [] = { | 56 | static struct usb_device_id id_table [] = { |
46 | {USB_DEVICE(0x10c4, 0xea60) }, /*Silicon labs factory default*/ | 57 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
47 | {USB_DEVICE(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ | 58 | { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ |
48 | { } /* Terminating Entry*/ | 59 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
60 | { } /* Terminating Entry */ | ||
49 | }; | 61 | }; |
50 | 62 | ||
51 | MODULE_DEVICE_TABLE (usb, id_table); | 63 | MODULE_DEVICE_TABLE (usb, id_table); |
@@ -70,32 +82,35 @@ static struct usb_serial_device_type cp2101_device = { | |||
70 | .close = cp2101_close, | 82 | .close = cp2101_close, |
71 | .break_ctl = cp2101_break_ctl, | 83 | .break_ctl = cp2101_break_ctl, |
72 | .set_termios = cp2101_set_termios, | 84 | .set_termios = cp2101_set_termios, |
85 | .tiocmget = cp2101_tiocmget, | ||
86 | .tiocmset = cp2101_tiocmset, | ||
73 | .attach = cp2101_startup, | 87 | .attach = cp2101_startup, |
74 | .shutdown = cp2101_shutdown, | 88 | .shutdown = cp2101_shutdown, |
75 | }; | 89 | }; |
76 | 90 | ||
77 | /*Config request types*/ | 91 | /* Config request types */ |
78 | #define REQTYPE_HOST_TO_DEVICE 0x41 | 92 | #define REQTYPE_HOST_TO_DEVICE 0x41 |
79 | #define REQTYPE_DEVICE_TO_HOST 0xc1 | 93 | #define REQTYPE_DEVICE_TO_HOST 0xc1 |
80 | 94 | ||
81 | /*Config SET requests. To GET, add 1 to the request number*/ | 95 | /* Config SET requests. To GET, add 1 to the request number */ |
82 | #define CP2101_UART 0x00 /*Enable / Disable*/ | 96 | #define CP2101_UART 0x00 /* Enable / Disable */ |
83 | #define CP2101_BAUDRATE 0x01 /*(BAUD_RATE_GEN_FREQ / baudrate)*/ | 97 | #define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ |
84 | #define CP2101_BITS 0x03 /*0x(0)(data bits)(parity)(stop bits)*/ | 98 | #define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ |
85 | #define CP2101_BREAK 0x05 /*On / Off*/ | 99 | #define CP2101_BREAK 0x05 /* On / Off */ |
86 | #define CP2101_DTRRTS 0x07 /*101 / 202 ???*/ | 100 | #define CP2101_CONTROL 0x07 /* Flow control line states */ |
87 | #define CP2101_CONFIG_16 0x13 /*16 bytes of config data ???*/ | 101 | #define CP2101_MODEMCTL 0x13 /* Modem controls */ |
88 | #define CP2101_CONFIG_6 0x19 /*6 bytes of config data ???*/ | 102 | #define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ |
89 | 103 | ||
90 | /*CP2101_UART*/ | 104 | /* CP2101_UART */ |
91 | #define UART_ENABLE 0x0001 | 105 | #define UART_ENABLE 0x0001 |
92 | #define UART_DISABLE 0x0000 | 106 | #define UART_DISABLE 0x0000 |
93 | 107 | ||
94 | /*CP2101_BAUDRATE*/ | 108 | /* CP2101_BAUDRATE */ |
95 | #define BAUD_RATE_GEN_FREQ 0x384000 | 109 | #define BAUD_RATE_GEN_FREQ 0x384000 |
96 | 110 | ||
97 | /*CP2101_BITS*/ | 111 | /* CP2101_BITS */ |
98 | #define BITS_DATA_MASK 0X0f00 | 112 | #define BITS_DATA_MASK 0X0f00 |
113 | #define BITS_DATA_5 0X0500 | ||
99 | #define BITS_DATA_6 0X0600 | 114 | #define BITS_DATA_6 0X0600 |
100 | #define BITS_DATA_7 0X0700 | 115 | #define BITS_DATA_7 0X0700 |
101 | #define BITS_DATA_8 0X0800 | 116 | #define BITS_DATA_8 0X0800 |
@@ -112,64 +127,137 @@ static struct usb_serial_device_type cp2101_device = { | |||
112 | #define BITS_STOP_1 0x0000 | 127 | #define BITS_STOP_1 0x0000 |
113 | #define BITS_STOP_1_5 0x0001 | 128 | #define BITS_STOP_1_5 0x0001 |
114 | #define BITS_STOP_2 0x0002 | 129 | #define BITS_STOP_2 0x0002 |
130 | |||
131 | /* CP2101_BREAK */ | ||
115 | #define BREAK_ON 0x0000 | 132 | #define BREAK_ON 0x0000 |
116 | #define BREAK_OFF 0x0001 | 133 | #define BREAK_OFF 0x0001 |
117 | 134 | ||
135 | /* CP2101_CONTROL */ | ||
136 | #define CONTROL_DTR 0x0001 | ||
137 | #define CONTROL_RTS 0x0002 | ||
138 | #define CONTROL_CTS 0x0010 | ||
139 | #define CONTROL_DSR 0x0020 | ||
140 | #define CONTROL_RING 0x0040 | ||
141 | #define CONTROL_DCD 0x0080 | ||
142 | #define CONTROL_WRITE_DTR 0x0100 | ||
143 | #define CONTROL_WRITE_RTS 0x0200 | ||
118 | 144 | ||
119 | static int cp2101_get_config(struct usb_serial_port* port, u8 request) | 145 | /* |
146 | * cp2101_get_config | ||
147 | * Reads from the CP2101 configuration registers | ||
148 | * 'size' is specified in bytes. | ||
149 | * 'data' is a pointer to a pre-allocated array of integers large | ||
150 | * enough to hold 'size' bytes (with 4 bytes to each integer) | ||
151 | */ | ||
152 | static int cp2101_get_config(struct usb_serial_port* port, u8 request, | ||
153 | unsigned int *data, int size) | ||
120 | { | 154 | { |
121 | struct usb_serial *serial = port->serial; | 155 | struct usb_serial *serial = port->serial; |
122 | unsigned char buf[4]; | 156 | u32 *buf; |
123 | unsigned int value; | 157 | int result, i, length; |
124 | int result, i; | 158 | |
159 | /* Number of integers required to contain the array */ | ||
160 | length = (((size - 1) | 3) + 1)/4; | ||
161 | |||
162 | buf = kmalloc (length * sizeof(u32), GFP_KERNEL); | ||
163 | memset(buf, 0, length * sizeof(u32)); | ||
164 | |||
165 | if (!buf) { | ||
166 | dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); | ||
167 | return -ENOMEM; | ||
168 | } | ||
125 | 169 | ||
126 | /*For get requests, the request number must be incremented*/ | 170 | /* For get requests, the request number must be incremented */ |
127 | request++; | 171 | request++; |
128 | 172 | ||
129 | /*Issue the request, attempting to read 4 bytes*/ | 173 | /* Issue the request, attempting to read 'size' bytes */ |
130 | result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), | 174 | result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), |
131 | request, REQTYPE_DEVICE_TO_HOST, 0x0000, | 175 | request, REQTYPE_DEVICE_TO_HOST, 0x0000, |
132 | 0, buf, 4, 300); | 176 | 0, buf, size, 300); |
133 | 177 | ||
134 | if (result < 0) { | 178 | /* Convert data into an array of integers */ |
135 | dev_err(&port->dev, "%s - Unable to send config request, " | 179 | for (i=0; i<length; i++) |
136 | "request=0x%x result=%d\n", | 180 | data[i] = le32_to_cpu(buf[i]); |
137 | __FUNCTION__, request, result); | ||
138 | return result; | ||
139 | } | ||
140 | 181 | ||
141 | /*Assemble each byte read into an integer value*/ | 182 | kfree(buf); |
142 | value = 0; | ||
143 | for (i=0; i<4 && i<result; i++) | ||
144 | value |= (buf[i] << (i * 8)); | ||
145 | 183 | ||
146 | dbg( " %s - request=0x%x result=%d value=0x%x", | 184 | if (result != size) { |
147 | __FUNCTION__, request, result, value); | 185 | dev_err(&port->dev, "%s - Unable to send config request, " |
186 | "request=0x%x size=%d result=%d\n", | ||
187 | __FUNCTION__, request, size, result); | ||
188 | return -EPROTO; | ||
189 | } | ||
148 | 190 | ||
149 | return value; | 191 | return 0; |
150 | } | 192 | } |
151 | 193 | ||
152 | static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value) | 194 | /* |
195 | * cp2101_set_config | ||
196 | * Writes to the CP2101 configuration registers | ||
197 | * Values less than 16 bits wide are sent directly | ||
198 | * 'size' is specified in bytes. | ||
199 | */ | ||
200 | static int cp2101_set_config(struct usb_serial_port* port, u8 request, | ||
201 | unsigned int *data, int size) | ||
153 | { | 202 | { |
154 | struct usb_serial *serial = port->serial; | 203 | struct usb_serial *serial = port->serial; |
155 | int result; | 204 | u32 *buf; |
156 | result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), | 205 | int result, i, length; |
157 | request, REQTYPE_HOST_TO_DEVICE, value, | ||
158 | 0, NULL, 0, 300); | ||
159 | 206 | ||
160 | if (result <0) { | 207 | /* Number of integers required to contain the array */ |
161 | dev_err(&port->dev, "%s - Unable to send config request, " | 208 | length = (((size - 1) | 3) + 1)/4; |
162 | "request=0x%x value=0x%x result=%d\n", | 209 | |
163 | __FUNCTION__, request, value, result); | 210 | buf = kmalloc(length * sizeof(u32), GFP_KERNEL); |
164 | return result; | 211 | if (!buf) { |
212 | dev_err(&port->dev, "%s - out of memory.\n", | ||
213 | __FUNCTION__); | ||
214 | return -ENOMEM; | ||
215 | } | ||
216 | |||
217 | /* Array of integers into bytes */ | ||
218 | for (i = 0; i < length; i++) | ||
219 | buf[i] = cpu_to_le32(data[i]); | ||
220 | |||
221 | if (size > 2) { | ||
222 | result = usb_control_msg (serial->dev, | ||
223 | usb_sndctrlpipe(serial->dev, 0), | ||
224 | request, REQTYPE_HOST_TO_DEVICE, 0x0000, | ||
225 | 0, buf, size, 300); | ||
226 | } else { | ||
227 | result = usb_control_msg (serial->dev, | ||
228 | usb_sndctrlpipe(serial->dev, 0), | ||
229 | request, REQTYPE_HOST_TO_DEVICE, data[0], | ||
230 | 0, NULL, 0, 300); | ||
165 | } | 231 | } |
166 | 232 | ||
167 | dbg(" %s - request=0x%x value=0x%x result=%d", | 233 | kfree(buf); |
168 | __FUNCTION__, request, value, result); | 234 | |
235 | if ((size > 2 && result != size) || result < 0) { | ||
236 | dev_err(&port->dev, "%s - Unable to send request, " | ||
237 | "request=0x%x size=%d result=%d\n", | ||
238 | __FUNCTION__, request, size, result); | ||
239 | return -EPROTO; | ||
240 | } | ||
169 | 241 | ||
242 | /* Single data value */ | ||
243 | result = usb_control_msg (serial->dev, | ||
244 | usb_sndctrlpipe(serial->dev, 0), | ||
245 | request, REQTYPE_HOST_TO_DEVICE, data[0], | ||
246 | 0, NULL, 0, 300); | ||
170 | return 0; | 247 | return 0; |
171 | } | 248 | } |
172 | 249 | ||
250 | /* | ||
251 | * cp2101_set_config_single | ||
252 | * Convenience function for calling cp2101_set_config on single data values | ||
253 | * without requiring an integer pointer | ||
254 | */ | ||
255 | static inline int cp2101_set_config_single(struct usb_serial_port* port, | ||
256 | u8 request, unsigned int data) | ||
257 | { | ||
258 | return cp2101_set_config(port, request, &data, 2); | ||
259 | } | ||
260 | |||
173 | static int cp2101_open (struct usb_serial_port *port, struct file *filp) | 261 | static int cp2101_open (struct usb_serial_port *port, struct file *filp) |
174 | { | 262 | { |
175 | struct usb_serial *serial = port->serial; | 263 | struct usb_serial *serial = port->serial; |
@@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) | |||
177 | 265 | ||
178 | dbg("%s - port %d", __FUNCTION__, port->number); | 266 | dbg("%s - port %d", __FUNCTION__, port->number); |
179 | 267 | ||
180 | if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { | 268 | if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { |
181 | dev_err(&port->dev, "%s - Unable to enable UART\n", | 269 | dev_err(&port->dev, "%s - Unable to enable UART\n", |
182 | __FUNCTION__); | 270 | __FUNCTION__); |
183 | return -EPROTO; | 271 | return -EPROTO; |
@@ -198,9 +286,12 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) | |||
198 | return result; | 286 | return result; |
199 | } | 287 | } |
200 | 288 | ||
201 | /*Configure the termios structure*/ | 289 | /* Configure the termios structure */ |
202 | cp2101_get_termios(port); | 290 | cp2101_get_termios(port); |
203 | 291 | ||
292 | /* Set the DTR and RTS pins low */ | ||
293 | cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); | ||
294 | |||
204 | return 0; | 295 | return 0; |
205 | } | 296 | } |
206 | 297 | ||
@@ -228,16 +319,18 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) | |||
228 | usb_kill_urb(port->write_urb); | 319 | usb_kill_urb(port->write_urb); |
229 | usb_kill_urb(port->read_urb); | 320 | usb_kill_urb(port->read_urb); |
230 | 321 | ||
231 | cp2101_set_config(port, CP2101_UART, UART_DISABLE); | 322 | cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); |
232 | } | 323 | } |
233 | 324 | ||
234 | /* cp2101_get_termios*/ | 325 | /* |
235 | /* Reads the baud rate, data bits, parity and stop bits from the device*/ | 326 | * cp2101_get_termios |
236 | /* Corrects any unsupported values*/ | 327 | * Reads the baud rate, data bits, parity, stop bits and flow control mode |
237 | /* Configures the termios structure to reflect the state of the device*/ | 328 | * from the device, corrects any unsupported values, and configures the |
329 | * termios structure to reflect the state of the device | ||
330 | */ | ||
238 | static void cp2101_get_termios (struct usb_serial_port *port) | 331 | static void cp2101_get_termios (struct usb_serial_port *port) |
239 | { | 332 | { |
240 | unsigned int cflag; | 333 | unsigned int cflag, modem_ctl[4]; |
241 | int baud; | 334 | int baud; |
242 | int bits; | 335 | int bits; |
243 | 336 | ||
@@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
249 | } | 342 | } |
250 | cflag = port->tty->termios->c_cflag; | 343 | cflag = port->tty->termios->c_cflag; |
251 | 344 | ||
252 | baud = cp2101_get_config(port, CP2101_BAUDRATE); | 345 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); |
253 | /*Convert to baudrate*/ | 346 | /* Convert to baudrate */ |
254 | if (baud) | 347 | if (baud) |
255 | baud = BAUD_RATE_GEN_FREQ / baud; | 348 | baud = BAUD_RATE_GEN_FREQ / baud; |
256 | 349 | ||
257 | dbg("%s - baud rate = %d", __FUNCTION__, baud); | 350 | dbg("%s - baud rate = %d", __FUNCTION__, baud); |
258 | cflag &= ~CBAUD; | 351 | cflag &= ~CBAUD; |
259 | switch (baud) { | 352 | switch (baud) { |
260 | /* The baud rates which are commented out below | 353 | /* |
354 | * The baud rates which are commented out below | ||
261 | * appear to be supported by the device | 355 | * appear to be supported by the device |
262 | * but are non-standard | 356 | * but are non-standard |
263 | */ | 357 | */ |
@@ -284,14 +378,18 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
284 | dbg("%s - Baud rate is not supported, " | 378 | dbg("%s - Baud rate is not supported, " |
285 | "using 9600 baud", __FUNCTION__); | 379 | "using 9600 baud", __FUNCTION__); |
286 | cflag |= B9600; | 380 | cflag |= B9600; |
287 | cp2101_set_config(port, CP2101_BAUDRATE, | 381 | cp2101_set_config_single(port, CP2101_BAUDRATE, |
288 | (BAUD_RATE_GEN_FREQ/9600)); | 382 | (BAUD_RATE_GEN_FREQ/9600)); |
289 | break; | 383 | break; |
290 | } | 384 | } |
291 | 385 | ||
292 | bits = cp2101_get_config(port, CP2101_BITS); | 386 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
293 | cflag &= ~CSIZE; | 387 | cflag &= ~CSIZE; |
294 | switch(bits & BITS_DATA_MASK) { | 388 | switch(bits & BITS_DATA_MASK) { |
389 | case BITS_DATA_5: | ||
390 | dbg("%s - data bits = 5", __FUNCTION__); | ||
391 | cflag |= CS5; | ||
392 | break; | ||
295 | case BITS_DATA_6: | 393 | case BITS_DATA_6: |
296 | dbg("%s - data bits = 6", __FUNCTION__); | 394 | dbg("%s - data bits = 6", __FUNCTION__); |
297 | cflag |= CS6; | 395 | cflag |= CS6; |
@@ -310,7 +408,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
310 | cflag |= CS8; | 408 | cflag |= CS8; |
311 | bits &= ~BITS_DATA_MASK; | 409 | bits &= ~BITS_DATA_MASK; |
312 | bits |= BITS_DATA_8; | 410 | bits |= BITS_DATA_8; |
313 | cp2101_set_config(port, CP2101_BITS, bits); | 411 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
314 | break; | 412 | break; |
315 | default: | 413 | default: |
316 | dbg("%s - Unknown number of data bits, " | 414 | dbg("%s - Unknown number of data bits, " |
@@ -318,7 +416,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
318 | cflag |= CS8; | 416 | cflag |= CS8; |
319 | bits &= ~BITS_DATA_MASK; | 417 | bits &= ~BITS_DATA_MASK; |
320 | bits |= BITS_DATA_8; | 418 | bits |= BITS_DATA_8; |
321 | cp2101_set_config(port, CP2101_BITS, bits); | 419 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
322 | break; | 420 | break; |
323 | } | 421 | } |
324 | 422 | ||
@@ -341,21 +439,21 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
341 | "disabling parity)", __FUNCTION__); | 439 | "disabling parity)", __FUNCTION__); |
342 | cflag &= ~PARENB; | 440 | cflag &= ~PARENB; |
343 | bits &= ~BITS_PARITY_MASK; | 441 | bits &= ~BITS_PARITY_MASK; |
344 | cp2101_set_config(port, CP2101_BITS, bits); | 442 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
345 | break; | 443 | break; |
346 | case BITS_PARITY_SPACE: | 444 | case BITS_PARITY_SPACE: |
347 | dbg("%s - parity = SPACE (not supported, " | 445 | dbg("%s - parity = SPACE (not supported, " |
348 | "disabling parity)", __FUNCTION__); | 446 | "disabling parity)", __FUNCTION__); |
349 | cflag &= ~PARENB; | 447 | cflag &= ~PARENB; |
350 | bits &= ~BITS_PARITY_MASK; | 448 | bits &= ~BITS_PARITY_MASK; |
351 | cp2101_set_config(port, CP2101_BITS, bits); | 449 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
352 | break; | 450 | break; |
353 | default: | 451 | default: |
354 | dbg("%s - Unknown parity mode, " | 452 | dbg("%s - Unknown parity mode, " |
355 | "disabling parity", __FUNCTION__); | 453 | "disabling parity", __FUNCTION__); |
356 | cflag &= ~PARENB; | 454 | cflag &= ~PARENB; |
357 | bits &= ~BITS_PARITY_MASK; | 455 | bits &= ~BITS_PARITY_MASK; |
358 | cp2101_set_config(port, CP2101_BITS, bits); | 456 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
359 | break; | 457 | break; |
360 | } | 458 | } |
361 | 459 | ||
@@ -366,9 +464,9 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
366 | break; | 464 | break; |
367 | case BITS_STOP_1_5: | 465 | case BITS_STOP_1_5: |
368 | dbg("%s - stop bits = 1.5 (not supported, " | 466 | dbg("%s - stop bits = 1.5 (not supported, " |
369 | "using 1 stop bit", __FUNCTION__); | 467 | "using 1 stop bit)", __FUNCTION__); |
370 | bits &= ~BITS_STOP_MASK; | 468 | bits &= ~BITS_STOP_MASK; |
371 | cp2101_set_config(port, CP2101_BITS, bits); | 469 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
372 | break; | 470 | break; |
373 | case BITS_STOP_2: | 471 | case BITS_STOP_2: |
374 | dbg("%s - stop bits = 2", __FUNCTION__); | 472 | dbg("%s - stop bits = 2", __FUNCTION__); |
@@ -378,10 +476,19 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
378 | dbg("%s - Unknown number of stop bits, " | 476 | dbg("%s - Unknown number of stop bits, " |
379 | "using 1 stop bit", __FUNCTION__); | 477 | "using 1 stop bit", __FUNCTION__); |
380 | bits &= ~BITS_STOP_MASK; | 478 | bits &= ~BITS_STOP_MASK; |
381 | cp2101_set_config(port, CP2101_BITS, bits); | 479 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
382 | break; | 480 | break; |
383 | } | 481 | } |
384 | 482 | ||
483 | cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); | ||
484 | if (modem_ctl[0] & 0x0008) { | ||
485 | dbg("%s - flow control = CRTSCTS", __FUNCTION__); | ||
486 | cflag |= CRTSCTS; | ||
487 | } else { | ||
488 | dbg("%s - flow control = NONE", __FUNCTION__); | ||
489 | cflag &= ~CRTSCTS; | ||
490 | } | ||
491 | |||
385 | port->tty->termios->c_cflag = cflag; | 492 | port->tty->termios->c_cflag = cflag; |
386 | } | 493 | } |
387 | 494 | ||
@@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
389 | struct termios *old_termios) | 496 | struct termios *old_termios) |
390 | { | 497 | { |
391 | unsigned int cflag, old_cflag=0; | 498 | unsigned int cflag, old_cflag=0; |
392 | int baud=0; | 499 | int baud=0, bits; |
393 | int bits; | 500 | unsigned int modem_ctl[4]; |
394 | 501 | ||
395 | dbg("%s - port %d", __FUNCTION__, port->number); | 502 | dbg("%s - port %d", __FUNCTION__, port->number); |
396 | 503 | ||
@@ -400,7 +507,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
400 | } | 507 | } |
401 | cflag = port->tty->termios->c_cflag; | 508 | cflag = port->tty->termios->c_cflag; |
402 | 509 | ||
403 | /* check that they really want us to change something */ | 510 | /* Check that they really want us to change something */ |
404 | if (old_termios) { | 511 | if (old_termios) { |
405 | if ((cflag == old_termios->c_cflag) && | 512 | if ((cflag == old_termios->c_cflag) && |
406 | (RELEVANT_IFLAG(port->tty->termios->c_iflag) | 513 | (RELEVANT_IFLAG(port->tty->termios->c_iflag) |
@@ -415,7 +522,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
415 | /* If the baud rate is to be updated*/ | 522 | /* If the baud rate is to be updated*/ |
416 | if ((cflag & CBAUD) != (old_cflag & CBAUD)) { | 523 | if ((cflag & CBAUD) != (old_cflag & CBAUD)) { |
417 | switch (cflag & CBAUD) { | 524 | switch (cflag & CBAUD) { |
418 | /* The baud rates which are commented out below | 525 | /* |
526 | * The baud rates which are commented out below | ||
419 | * appear to be supported by the device | 527 | * appear to be supported by the device |
420 | * but are non-standard | 528 | * but are non-standard |
421 | */ | 529 | */ |
@@ -448,18 +556,22 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
448 | if (baud) { | 556 | if (baud) { |
449 | dbg("%s - Setting baud rate to %d baud", __FUNCTION__, | 557 | dbg("%s - Setting baud rate to %d baud", __FUNCTION__, |
450 | baud); | 558 | baud); |
451 | if (cp2101_set_config(port, CP2101_BAUDRATE, | 559 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, |
452 | (BAUD_RATE_GEN_FREQ / baud))) | 560 | (BAUD_RATE_GEN_FREQ / baud))) |
453 | dev_err(&port->dev, "Baud rate requested not " | 561 | dev_err(&port->dev, "Baud rate requested not " |
454 | "supported by device\n"); | 562 | "supported by device\n"); |
455 | } | 563 | } |
456 | } | 564 | } |
457 | 565 | ||
458 | /*If the number of data bits is to be updated*/ | 566 | /* If the number of data bits is to be updated */ |
459 | if ((cflag & CSIZE) != (old_cflag & CSIZE)) { | 567 | if ((cflag & CSIZE) != (old_cflag & CSIZE)) { |
460 | bits = cp2101_get_config(port, CP2101_BITS); | 568 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
461 | bits &= ~BITS_DATA_MASK; | 569 | bits &= ~BITS_DATA_MASK; |
462 | switch (cflag & CSIZE) { | 570 | switch (cflag & CSIZE) { |
571 | case CS5: | ||
572 | bits |= BITS_DATA_5; | ||
573 | dbg("%s - data bits = 5", __FUNCTION__); | ||
574 | break; | ||
463 | case CS6: | 575 | case CS6: |
464 | bits |= BITS_DATA_6; | 576 | bits |= BITS_DATA_6; |
465 | dbg("%s - data bits = 6", __FUNCTION__); | 577 | dbg("%s - data bits = 6", __FUNCTION__); |
@@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
483 | bits |= BITS_DATA_8; | 595 | bits |= BITS_DATA_8; |
484 | break; | 596 | break; |
485 | } | 597 | } |
486 | if (cp2101_set_config(port, CP2101_BITS, bits)) | 598 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
487 | dev_err(&port->dev, "Number of data bits requested " | 599 | dev_err(&port->dev, "Number of data bits requested " |
488 | "not supported by device\n"); | 600 | "not supported by device\n"); |
489 | } | 601 | } |
490 | 602 | ||
491 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { | 603 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { |
492 | bits = cp2101_get_config(port, CP2101_BITS); | 604 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
493 | bits &= ~BITS_PARITY_MASK; | 605 | bits &= ~BITS_PARITY_MASK; |
494 | if (cflag & PARENB) { | 606 | if (cflag & PARENB) { |
495 | if (cflag & PARODD) { | 607 | if (cflag & PARODD) { |
@@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
500 | dbg("%s - parity = EVEN", __FUNCTION__); | 612 | dbg("%s - parity = EVEN", __FUNCTION__); |
501 | } | 613 | } |
502 | } | 614 | } |
503 | if (cp2101_set_config(port, CP2101_BITS, bits)) | 615 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
504 | dev_err(&port->dev, "Parity mode not supported " | 616 | dev_err(&port->dev, "Parity mode not supported " |
505 | "by device\n"); | 617 | "by device\n"); |
506 | } | 618 | } |
507 | 619 | ||
508 | if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { | 620 | if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { |
509 | bits = cp2101_get_config(port, CP2101_BITS); | 621 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
510 | bits &= ~BITS_STOP_MASK; | 622 | bits &= ~BITS_STOP_MASK; |
511 | if (cflag & CSTOPB) { | 623 | if (cflag & CSTOPB) { |
512 | bits |= BITS_STOP_2; | 624 | bits |= BITS_STOP_2; |
@@ -515,15 +627,90 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
515 | bits |= BITS_STOP_1; | 627 | bits |= BITS_STOP_1; |
516 | dbg("%s - stop bits = 1", __FUNCTION__); | 628 | dbg("%s - stop bits = 1", __FUNCTION__); |
517 | } | 629 | } |
518 | if (cp2101_set_config(port, CP2101_BITS, bits)) | 630 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
519 | dev_err(&port->dev, "Number of stop bits requested " | 631 | dev_err(&port->dev, "Number of stop bits requested " |
520 | "not supported by device\n"); | 632 | "not supported by device\n"); |
521 | } | 633 | } |
634 | |||
635 | if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { | ||
636 | cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); | ||
637 | dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", | ||
638 | __FUNCTION__, modem_ctl[0], modem_ctl[1], | ||
639 | modem_ctl[2], modem_ctl[3]); | ||
640 | |||
641 | if (cflag & CRTSCTS) { | ||
642 | modem_ctl[0] &= ~0x7B; | ||
643 | modem_ctl[0] |= 0x09; | ||
644 | modem_ctl[1] = 0x80; | ||
645 | dbg("%s - flow control = CRTSCTS", __FUNCTION__); | ||
646 | } else { | ||
647 | modem_ctl[0] &= ~0x7B; | ||
648 | modem_ctl[0] |= 0x01; | ||
649 | modem_ctl[1] |= 0x40; | ||
650 | dbg("%s - flow control = NONE", __FUNCTION__); | ||
651 | } | ||
652 | |||
653 | dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", | ||
654 | __FUNCTION__, modem_ctl[0], modem_ctl[1], | ||
655 | modem_ctl[2], modem_ctl[3]); | ||
656 | cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); | ||
657 | } | ||
658 | |||
659 | } | ||
660 | |||
661 | static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, | ||
662 | unsigned int set, unsigned int clear) | ||
663 | { | ||
664 | int control = 0; | ||
665 | |||
666 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
667 | |||
668 | if (set & TIOCM_RTS) { | ||
669 | control |= CONTROL_RTS; | ||
670 | control |= CONTROL_WRITE_RTS; | ||
671 | } | ||
672 | if (set & TIOCM_DTR) { | ||
673 | control |= CONTROL_DTR; | ||
674 | control |= CONTROL_WRITE_DTR; | ||
675 | } | ||
676 | if (clear & TIOCM_RTS) { | ||
677 | control &= ~CONTROL_RTS; | ||
678 | control |= CONTROL_WRITE_RTS; | ||
679 | } | ||
680 | if (clear & TIOCM_DTR) { | ||
681 | control &= ~CONTROL_DTR; | ||
682 | control |= CONTROL_WRITE_DTR; | ||
683 | } | ||
684 | |||
685 | dbg("%s - control = 0x%.4x", __FUNCTION__, control); | ||
686 | |||
687 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | ||
688 | |||
689 | } | ||
690 | |||
691 | static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) | ||
692 | { | ||
693 | int control, result; | ||
694 | |||
695 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
696 | |||
697 | cp2101_get_config(port, CP2101_CONTROL, &control, 1); | ||
698 | |||
699 | result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) | ||
700 | |((control & CONTROL_RTS) ? TIOCM_RTS : 0) | ||
701 | |((control & CONTROL_CTS) ? TIOCM_CTS : 0) | ||
702 | |((control & CONTROL_DSR) ? TIOCM_DSR : 0) | ||
703 | |((control & CONTROL_RING)? TIOCM_RI : 0) | ||
704 | |((control & CONTROL_DCD) ? TIOCM_CD : 0); | ||
705 | |||
706 | dbg("%s - control = 0x%.2x", __FUNCTION__, control); | ||
707 | |||
708 | return result; | ||
522 | } | 709 | } |
523 | 710 | ||
524 | static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) | 711 | static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) |
525 | { | 712 | { |
526 | u16 state; | 713 | int state; |
527 | 714 | ||
528 | dbg("%s - port %d", __FUNCTION__, port->number); | 715 | dbg("%s - port %d", __FUNCTION__, port->number); |
529 | if (break_state == 0) | 716 | if (break_state == 0) |
@@ -532,12 +719,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) | |||
532 | state = BREAK_ON; | 719 | state = BREAK_ON; |
533 | dbg("%s - turning break %s", __FUNCTION__, | 720 | dbg("%s - turning break %s", __FUNCTION__, |
534 | state==BREAK_OFF ? "off" : "on"); | 721 | state==BREAK_OFF ? "off" : "on"); |
535 | cp2101_set_config(port, CP2101_BREAK, state); | 722 | cp2101_set_config(port, CP2101_BREAK, &state, 2); |
536 | } | 723 | } |
537 | 724 | ||
538 | static int cp2101_startup (struct usb_serial *serial) | 725 | static int cp2101_startup (struct usb_serial *serial) |
539 | { | 726 | { |
540 | /*CP2101 buffers behave strangely unless device is reset*/ | 727 | /* CP2101 buffers behave strangely unless device is reset */ |
541 | usb_reset_device(serial->dev); | 728 | usb_reset_device(serial->dev); |
542 | return 0; | 729 | return 0; |
543 | } | 730 | } |
@@ -548,7 +735,7 @@ static void cp2101_shutdown (struct usb_serial *serial) | |||
548 | 735 | ||
549 | dbg("%s", __FUNCTION__); | 736 | dbg("%s", __FUNCTION__); |
550 | 737 | ||
551 | /* stop reads and writes on all ports */ | 738 | /* Stop reads and writes on all ports */ |
552 | for (i=0; i < serial->num_ports; ++i) { | 739 | for (i=0; i < serial->num_ports; ++i) { |
553 | cp2101_cleanup(serial->port[i]); | 740 | cp2101_cleanup(serial->port[i]); |
554 | } | 741 | } |
@@ -560,16 +747,16 @@ static int __init cp2101_init (void) | |||
560 | 747 | ||
561 | retval = usb_serial_register(&cp2101_device); | 748 | retval = usb_serial_register(&cp2101_device); |
562 | if (retval) | 749 | if (retval) |
563 | return retval; /*Failed to register*/ | 750 | return retval; /* Failed to register */ |
564 | 751 | ||
565 | retval = usb_register(&cp2101_driver); | 752 | retval = usb_register(&cp2101_driver); |
566 | if (retval) { | 753 | if (retval) { |
567 | /*Failed to register*/ | 754 | /* Failed to register */ |
568 | usb_serial_deregister(&cp2101_device); | 755 | usb_serial_deregister(&cp2101_device); |
569 | return retval; | 756 | return retval; |
570 | } | 757 | } |
571 | 758 | ||
572 | /*Success*/ | 759 | /* Success */ |
573 | info(DRIVER_DESC " " DRIVER_VERSION); | 760 | info(DRIVER_DESC " " DRIVER_VERSION); |
574 | return 0; | 761 | return 0; |
575 | } | 762 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 52394f08a947..051c3a77b41b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -364,6 +364,7 @@ static struct usb_device_id id_table_8U232AM [] = { | |||
364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, | 364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, |
365 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, | 365 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, |
366 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, | 366 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, |
367 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, | ||
367 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, | 368 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, |
368 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, | 369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, |
369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, | 370 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, |
@@ -475,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = { | |||
475 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, |
476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 477 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, |
477 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, | 478 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, |
479 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, | ||
478 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 480 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, |
479 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 481 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, |
480 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 482 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, |
@@ -618,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { | |||
618 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 620 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, |
619 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 621 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, |
620 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, | 622 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, |
623 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, | ||
621 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 624 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, |
622 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 625 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, |
623 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 626 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index a52bb13a9ce4..8866376823a5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -144,6 +144,8 @@ | |||
144 | 144 | ||
145 | /* ELV USB Module UO100 (PID sent by Stefan Frings) */ | 145 | /* ELV USB Module UO100 (PID sent by Stefan Frings) */ |
146 | #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ | 146 | #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ |
147 | /* ELV USB Module UM100 (PID sent by Arnim Laeuger) */ | ||
148 | #define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */ | ||
147 | 149 | ||
148 | /* | 150 | /* |
149 | * Definitions for ID TECH (www.idt-net.com) devices | 151 | * Definitions for ID TECH (www.idt-net.com) devices |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c new file mode 100644 index 000000000000..b722175f108f --- /dev/null +++ b/drivers/usb/serial/option.c | |||
@@ -0,0 +1,729 @@ | |||
1 | /* | ||
2 | Option Card (PCMCIA to) USB to Serial Driver | ||
3 | |||
4 | Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> | ||
5 | |||
6 | This driver is free software; you can redistribute it and/or modify | ||
7 | it under the terms of Version 2 of the GNU General Public License as | ||
8 | published by the Free Software Foundation. | ||
9 | |||
10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> | ||
11 | |||
12 | History: | ||
13 | |||
14 | 2005-05-19 v0.1 Initial version, based on incomplete docs | ||
15 | and analysis of misbehavior of the standard driver | ||
16 | 2005-05-20 v0.2 Extended the input buffer to avoid losing | ||
17 | random 64-byte chunks of data | ||
18 | 2005-05-21 v0.3 implemented chars_in_buffer() | ||
19 | turned on low_latency | ||
20 | simplified the code somewhat | ||
21 | */ | ||
22 | #define DRIVER_VERSION "v0.3" | ||
23 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" | ||
24 | #define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/tty.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include "usb-serial.h" | ||
35 | |||
36 | /* Function prototypes */ | ||
37 | static int option_open (struct usb_serial_port *port, struct file *filp); | ||
38 | static void option_close (struct usb_serial_port *port, struct file *filp); | ||
39 | static int option_startup (struct usb_serial *serial); | ||
40 | static void option_shutdown (struct usb_serial *serial); | ||
41 | static void option_rx_throttle (struct usb_serial_port *port); | ||
42 | static void option_rx_unthrottle (struct usb_serial_port *port); | ||
43 | static int option_write_room (struct usb_serial_port *port); | ||
44 | |||
45 | static void option_instat_callback(struct urb *urb, struct pt_regs *regs); | ||
46 | |||
47 | |||
48 | static int option_write (struct usb_serial_port *port, | ||
49 | const unsigned char *buf, int count); | ||
50 | |||
51 | static int option_chars_in_buffer (struct usb_serial_port *port); | ||
52 | static int option_ioctl (struct usb_serial_port *port, struct file *file, | ||
53 | unsigned int cmd, unsigned long arg); | ||
54 | static void option_set_termios (struct usb_serial_port *port, | ||
55 | struct termios *old); | ||
56 | static void option_break_ctl (struct usb_serial_port *port, int break_state); | ||
57 | static int option_tiocmget (struct usb_serial_port *port, struct file *file); | ||
58 | static int option_tiocmset (struct usb_serial_port *port, struct file *file, | ||
59 | unsigned int set, unsigned int clear); | ||
60 | static int option_send_setup (struct usb_serial_port *port); | ||
61 | |||
62 | /* Vendor and product IDs */ | ||
63 | #define OPTION_VENDOR_ID 0x0AF0 | ||
64 | |||
65 | #define OPTION_PRODUCT_OLD 0x5000 | ||
66 | #define OPTION_PRODUCT_WLAN 0x6000 | ||
67 | |||
68 | static struct usb_device_id option_ids[] = { | ||
69 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, | ||
70 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) }, | ||
71 | { } /* Terminating entry */ | ||
72 | }; | ||
73 | |||
74 | MODULE_DEVICE_TABLE(usb, option_ids); | ||
75 | |||
76 | static struct usb_driver option_driver = { | ||
77 | .owner = THIS_MODULE, | ||
78 | .name = "option", | ||
79 | .probe = usb_serial_probe, | ||
80 | .disconnect = usb_serial_disconnect, | ||
81 | .id_table = option_ids, | ||
82 | }; | ||
83 | |||
84 | /* The card has three separate interfaces, wich the serial driver | ||
85 | * recognizes separately, thus num_port=1. | ||
86 | */ | ||
87 | static struct usb_serial_device_type option_3port_device = { | ||
88 | .owner = THIS_MODULE, | ||
89 | .name = "Option 3-port card", | ||
90 | .short_name = "option", | ||
91 | .id_table = option_ids, | ||
92 | .num_interrupt_in = NUM_DONT_CARE, | ||
93 | .num_bulk_in = NUM_DONT_CARE, | ||
94 | .num_bulk_out = NUM_DONT_CARE, | ||
95 | .num_ports = 1, /* 3 */ | ||
96 | .open = option_open, | ||
97 | .close = option_close, | ||
98 | .write = option_write, | ||
99 | .write_room = option_write_room, | ||
100 | .chars_in_buffer = option_chars_in_buffer, | ||
101 | .throttle = option_rx_throttle, | ||
102 | .unthrottle = option_rx_unthrottle, | ||
103 | .ioctl = option_ioctl, | ||
104 | .set_termios = option_set_termios, | ||
105 | .break_ctl = option_break_ctl, | ||
106 | .tiocmget = option_tiocmget, | ||
107 | .tiocmset = option_tiocmset, | ||
108 | .attach = option_startup, | ||
109 | .shutdown = option_shutdown, | ||
110 | .read_int_callback = option_instat_callback, | ||
111 | }; | ||
112 | |||
113 | static int debug; | ||
114 | |||
115 | /* per port private data */ | ||
116 | |||
117 | #define N_IN_URB 4 | ||
118 | #define N_OUT_URB 1 | ||
119 | #define IN_BUFLEN 1024 | ||
120 | #define OUT_BUFLEN 1024 | ||
121 | |||
122 | struct option_port_private { | ||
123 | /* Input endpoints and buffer for this port */ | ||
124 | struct urb *in_urbs[N_IN_URB]; | ||
125 | char in_buffer[N_IN_URB][IN_BUFLEN]; | ||
126 | /* Output endpoints and buffer for this port */ | ||
127 | struct urb *out_urbs[N_OUT_URB]; | ||
128 | char out_buffer[N_OUT_URB][OUT_BUFLEN]; | ||
129 | |||
130 | /* Settings for the port */ | ||
131 | int rts_state; /* Handshaking pins (outputs) */ | ||
132 | int dtr_state; | ||
133 | int cts_state; /* Handshaking pins (inputs) */ | ||
134 | int dsr_state; | ||
135 | int dcd_state; | ||
136 | int ri_state; | ||
137 | // int break_on; | ||
138 | |||
139 | unsigned long tx_start_time[N_OUT_URB]; | ||
140 | }; | ||
141 | |||
142 | |||
143 | /* Functions used by new usb-serial code. */ | ||
144 | static int __init | ||
145 | option_init (void) | ||
146 | { | ||
147 | int retval; | ||
148 | retval = usb_serial_register(&option_3port_device); | ||
149 | if (retval) | ||
150 | goto failed_3port_device_register; | ||
151 | retval = usb_register(&option_driver); | ||
152 | if (retval) | ||
153 | goto failed_driver_register; | ||
154 | |||
155 | info(DRIVER_DESC ": " DRIVER_VERSION); | ||
156 | |||
157 | return 0; | ||
158 | |||
159 | failed_driver_register: | ||
160 | usb_serial_deregister (&option_3port_device); | ||
161 | failed_3port_device_register: | ||
162 | return retval; | ||
163 | } | ||
164 | |||
165 | static void __exit | ||
166 | option_exit (void) | ||
167 | { | ||
168 | usb_deregister (&option_driver); | ||
169 | usb_serial_deregister (&option_3port_device); | ||
170 | } | ||
171 | |||
172 | module_init(option_init); | ||
173 | module_exit(option_exit); | ||
174 | |||
175 | static void | ||
176 | option_rx_throttle (struct usb_serial_port *port) | ||
177 | { | ||
178 | dbg("%s", __FUNCTION__); | ||
179 | } | ||
180 | |||
181 | |||
182 | static void | ||
183 | option_rx_unthrottle (struct usb_serial_port *port) | ||
184 | { | ||
185 | dbg("%s", __FUNCTION__); | ||
186 | } | ||
187 | |||
188 | |||
189 | static void | ||
190 | option_break_ctl (struct usb_serial_port *port, int break_state) | ||
191 | { | ||
192 | /* Unfortunately, I don't know how to send a break */ | ||
193 | dbg("%s", __FUNCTION__); | ||
194 | } | ||
195 | |||
196 | |||
197 | static void | ||
198 | option_set_termios (struct usb_serial_port *port, | ||
199 | struct termios *old_termios) | ||
200 | { | ||
201 | dbg("%s", __FUNCTION__); | ||
202 | |||
203 | option_send_setup(port); | ||
204 | } | ||
205 | |||
206 | static int | ||
207 | option_tiocmget(struct usb_serial_port *port, struct file *file) | ||
208 | { | ||
209 | unsigned int value; | ||
210 | struct option_port_private *portdata; | ||
211 | |||
212 | portdata = usb_get_serial_port_data(port); | ||
213 | |||
214 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | | ||
215 | ((portdata->dtr_state) ? TIOCM_DTR : 0) | | ||
216 | ((portdata->cts_state) ? TIOCM_CTS : 0) | | ||
217 | ((portdata->dsr_state) ? TIOCM_DSR : 0) | | ||
218 | ((portdata->dcd_state) ? TIOCM_CAR : 0) | | ||
219 | ((portdata->ri_state) ? TIOCM_RNG : 0); | ||
220 | |||
221 | return value; | ||
222 | } | ||
223 | |||
224 | static int | ||
225 | option_tiocmset (struct usb_serial_port *port, struct file *file, | ||
226 | unsigned int set, unsigned int clear) | ||
227 | { | ||
228 | struct option_port_private *portdata; | ||
229 | |||
230 | portdata = usb_get_serial_port_data(port); | ||
231 | |||
232 | if (set & TIOCM_RTS) | ||
233 | portdata->rts_state = 1; | ||
234 | if (set & TIOCM_DTR) | ||
235 | portdata->dtr_state = 1; | ||
236 | |||
237 | if (clear & TIOCM_RTS) | ||
238 | portdata->rts_state = 0; | ||
239 | if (clear & TIOCM_DTR) | ||
240 | portdata->dtr_state = 0; | ||
241 | return option_send_setup(port); | ||
242 | } | ||
243 | |||
244 | static int | ||
245 | option_ioctl (struct usb_serial_port *port, struct file *file, | ||
246 | unsigned int cmd, unsigned long arg) | ||
247 | { | ||
248 | return -ENOIOCTLCMD; | ||
249 | } | ||
250 | |||
251 | /* Write */ | ||
252 | static int | ||
253 | option_write(struct usb_serial_port *port, | ||
254 | const unsigned char *buf, int count) | ||
255 | { | ||
256 | struct option_port_private *portdata; | ||
257 | int i; | ||
258 | int left, todo; | ||
259 | struct urb *this_urb = NULL; /* spurious */ | ||
260 | int err; | ||
261 | |||
262 | portdata = usb_get_serial_port_data(port); | ||
263 | |||
264 | dbg("%s: write (%d chars)", __FUNCTION__, count); | ||
265 | |||
266 | #if 0 | ||
267 | spin_lock(&port->lock); | ||
268 | if (port->write_urb_busy) { | ||
269 | spin_unlock(&port->lock); | ||
270 | dbg("%s: already writing", __FUNCTION__); | ||
271 | return 0; | ||
272 | } | ||
273 | port->write_urb_busy = 1; | ||
274 | spin_unlock(&port->lock); | ||
275 | #endif | ||
276 | |||
277 | i = 0; | ||
278 | left = count; | ||
279 | while (left>0) { | ||
280 | todo = left; | ||
281 | if (todo > OUT_BUFLEN) | ||
282 | todo = OUT_BUFLEN; | ||
283 | |||
284 | for (;i < N_OUT_URB; i++) { | ||
285 | /* Check we have a valid urb/endpoint before we use it... */ | ||
286 | this_urb = portdata->out_urbs[i]; | ||
287 | if (this_urb->status != -EINPROGRESS) | ||
288 | break; | ||
289 | if (this_urb->transfer_flags & URB_ASYNC_UNLINK) | ||
290 | continue; | ||
291 | if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ)) | ||
292 | continue; | ||
293 | this_urb->transfer_flags |= URB_ASYNC_UNLINK; | ||
294 | usb_unlink_urb(this_urb); | ||
295 | } | ||
296 | |||
297 | if (i == N_OUT_URB) { | ||
298 | /* no bulk out free! */ | ||
299 | dbg("%s: no output urb -- left %d", __FUNCTION__,count-left); | ||
300 | #if 0 | ||
301 | port->write_urb_busy = 0; | ||
302 | #endif | ||
303 | return count-left; | ||
304 | } | ||
305 | |||
306 | dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i); | ||
307 | |||
308 | memcpy (this_urb->transfer_buffer, buf, todo); | ||
309 | |||
310 | /* send the data out the bulk port */ | ||
311 | this_urb->transfer_buffer_length = todo; | ||
312 | |||
313 | this_urb->transfer_flags &= ~URB_ASYNC_UNLINK; | ||
314 | this_urb->dev = port->serial->dev; | ||
315 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
316 | if (err) { | ||
317 | dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status); | ||
318 | continue; | ||
319 | } | ||
320 | portdata->tx_start_time[i] = jiffies; | ||
321 | buf += todo; | ||
322 | left -= todo; | ||
323 | } | ||
324 | |||
325 | count -= left; | ||
326 | #if 0 | ||
327 | port->write_urb_busy = 0; | ||
328 | #endif | ||
329 | dbg("%s: wrote (did %d)", __FUNCTION__, count); | ||
330 | return count; | ||
331 | } | ||
332 | |||
333 | static void | ||
334 | option_indat_callback (struct urb *urb, struct pt_regs *regs) | ||
335 | { | ||
336 | int i, err; | ||
337 | int endpoint; | ||
338 | struct usb_serial_port *port; | ||
339 | struct tty_struct *tty; | ||
340 | unsigned char *data = urb->transfer_buffer; | ||
341 | |||
342 | dbg("%s: %p", __FUNCTION__, urb); | ||
343 | |||
344 | endpoint = usb_pipeendpoint(urb->pipe); | ||
345 | port = (struct usb_serial_port *) urb->context; | ||
346 | |||
347 | if (urb->status) { | ||
348 | dbg("%s: nonzero status: %d on endpoint %02x.", | ||
349 | __FUNCTION__, urb->status, endpoint); | ||
350 | } else { | ||
351 | tty = port->tty; | ||
352 | if (urb->actual_length) { | ||
353 | for (i = 0; i < urb->actual_length ; ++i) { | ||
354 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
355 | tty_flip_buffer_push(tty); | ||
356 | tty_insert_flip_char(tty, data[i], 0); | ||
357 | } | ||
358 | tty_flip_buffer_push(tty); | ||
359 | } else { | ||
360 | dbg("%s: empty read urb received", __FUNCTION__); | ||
361 | } | ||
362 | |||
363 | /* Resubmit urb so we continue receiving */ | ||
364 | if (port->open_count && urb->status != -ESHUTDOWN) { | ||
365 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
366 | if (err) | ||
367 | printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err); | ||
368 | } | ||
369 | } | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | static void | ||
374 | option_outdat_callback (struct urb *urb, struct pt_regs *regs) | ||
375 | { | ||
376 | struct usb_serial_port *port; | ||
377 | |||
378 | dbg("%s", __FUNCTION__); | ||
379 | |||
380 | port = (struct usb_serial_port *) urb->context; | ||
381 | |||
382 | if (port->open_count) | ||
383 | schedule_work(&port->work); | ||
384 | } | ||
385 | |||
386 | static void | ||
387 | option_instat_callback (struct urb *urb, struct pt_regs *regs) | ||
388 | { | ||
389 | int err; | ||
390 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | ||
391 | struct option_port_private *portdata = usb_get_serial_port_data(port); | ||
392 | struct usb_serial *serial = port->serial; | ||
393 | |||
394 | dbg("%s", __FUNCTION__); | ||
395 | dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); | ||
396 | |||
397 | if (urb->status == 0) { | ||
398 | struct usb_ctrlrequest *req_pkt = | ||
399 | (struct usb_ctrlrequest *)urb->transfer_buffer; | ||
400 | |||
401 | if (!req_pkt) { | ||
402 | dbg("%s: NULL req_pkt\n", __FUNCTION__); | ||
403 | return; | ||
404 | } | ||
405 | if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) { | ||
406 | int old_dcd_state; | ||
407 | unsigned char signals = *((unsigned char *) | ||
408 | urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); | ||
409 | |||
410 | dbg("%s: signal x%x", __FUNCTION__, signals); | ||
411 | |||
412 | old_dcd_state = portdata->dcd_state; | ||
413 | portdata->cts_state = 1; | ||
414 | portdata->dcd_state = ((signals & 0x01) ? 1 : 0); | ||
415 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | ||
416 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | ||
417 | |||
418 | if (port->tty && !C_CLOCAL(port->tty) | ||
419 | && old_dcd_state && !portdata->dcd_state) { | ||
420 | tty_hangup(port->tty); | ||
421 | } | ||
422 | } else | ||
423 | dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest); | ||
424 | } else | ||
425 | dbg("%s: error %d", __FUNCTION__, urb->status); | ||
426 | |||
427 | /* Resubmit urb so we continue receiving IRQ data */ | ||
428 | if (urb->status != -ESHUTDOWN) { | ||
429 | urb->dev = serial->dev; | ||
430 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
431 | if (err) | ||
432 | dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | |||
437 | static int | ||
438 | option_write_room (struct usb_serial_port *port) | ||
439 | { | ||
440 | struct option_port_private *portdata; | ||
441 | int i; | ||
442 | int data_len = 0; | ||
443 | struct urb *this_urb; | ||
444 | |||
445 | portdata = usb_get_serial_port_data(port); | ||
446 | |||
447 | for (i=0; i < N_OUT_URB; i++) | ||
448 | this_urb = portdata->out_urbs[i]; | ||
449 | if (this_urb && this_urb->status != -EINPROGRESS) | ||
450 | data_len += OUT_BUFLEN; | ||
451 | |||
452 | dbg("%s: %d", __FUNCTION__, data_len); | ||
453 | return data_len; | ||
454 | } | ||
455 | |||
456 | |||
457 | static int | ||
458 | option_chars_in_buffer (struct usb_serial_port *port) | ||
459 | { | ||
460 | struct option_port_private *portdata; | ||
461 | int i; | ||
462 | int data_len = 0; | ||
463 | struct urb *this_urb; | ||
464 | |||
465 | portdata = usb_get_serial_port_data(port); | ||
466 | |||
467 | for (i=0; i < N_OUT_URB; i++) | ||
468 | this_urb = portdata->out_urbs[i]; | ||
469 | if (this_urb && this_urb->status == -EINPROGRESS) | ||
470 | data_len += this_urb->transfer_buffer_length; | ||
471 | |||
472 | dbg("%s: %d", __FUNCTION__, data_len); | ||
473 | return data_len; | ||
474 | } | ||
475 | |||
476 | |||
477 | static int | ||
478 | option_open (struct usb_serial_port *port, struct file *filp) | ||
479 | { | ||
480 | struct option_port_private *portdata; | ||
481 | struct usb_serial *serial = port->serial; | ||
482 | int i, err; | ||
483 | struct urb *urb; | ||
484 | |||
485 | portdata = usb_get_serial_port_data(port); | ||
486 | |||
487 | dbg("%s", __FUNCTION__); | ||
488 | |||
489 | /* Set some sane defaults */ | ||
490 | portdata->rts_state = 1; | ||
491 | portdata->dtr_state = 1; | ||
492 | |||
493 | /* Reset low level data toggle and start reading from endpoints */ | ||
494 | for (i = 0; i < N_IN_URB; i++) { | ||
495 | urb = portdata->in_urbs[i]; | ||
496 | if (! urb) | ||
497 | continue; | ||
498 | if (urb->dev != serial->dev) { | ||
499 | dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev); | ||
500 | continue; | ||
501 | } | ||
502 | |||
503 | /* make sure endpoint data toggle is synchronized with the device */ | ||
504 | |||
505 | usb_clear_halt(urb->dev, urb->pipe); | ||
506 | |||
507 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
508 | if (err) { | ||
509 | dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err, | ||
510 | urb->transfer_buffer_length); | ||
511 | } | ||
512 | } | ||
513 | |||
514 | /* Reset low level data toggle on out endpoints */ | ||
515 | for (i = 0; i < N_OUT_URB; i++) { | ||
516 | urb = portdata->out_urbs[i]; | ||
517 | if (! urb) | ||
518 | continue; | ||
519 | urb->dev = serial->dev; | ||
520 | /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ | ||
521 | } | ||
522 | |||
523 | port->tty->low_latency = 1; | ||
524 | |||
525 | option_send_setup(port); | ||
526 | |||
527 | return (0); | ||
528 | } | ||
529 | |||
530 | static inline void | ||
531 | stop_urb(struct urb *urb) | ||
532 | { | ||
533 | if (urb && urb->status == -EINPROGRESS) { | ||
534 | urb->transfer_flags &= ~URB_ASYNC_UNLINK; | ||
535 | usb_kill_urb(urb); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | static void | ||
540 | option_close(struct usb_serial_port *port, struct file *filp) | ||
541 | { | ||
542 | int i; | ||
543 | struct usb_serial *serial = port->serial; | ||
544 | struct option_port_private *portdata; | ||
545 | |||
546 | dbg("%s", __FUNCTION__); | ||
547 | portdata = usb_get_serial_port_data(port); | ||
548 | |||
549 | portdata->rts_state = 0; | ||
550 | portdata->dtr_state = 0; | ||
551 | |||
552 | if (serial->dev) { | ||
553 | option_send_setup(port); | ||
554 | |||
555 | /* Stop reading/writing urbs */ | ||
556 | for (i = 0; i < N_IN_URB; i++) | ||
557 | stop_urb(portdata->in_urbs[i]); | ||
558 | for (i = 0; i < N_OUT_URB; i++) | ||
559 | stop_urb(portdata->out_urbs[i]); | ||
560 | } | ||
561 | port->tty = NULL; | ||
562 | } | ||
563 | |||
564 | |||
565 | /* Helper functions used by option_setup_urbs */ | ||
566 | static struct urb * | ||
567 | option_setup_urb (struct usb_serial *serial, int endpoint, | ||
568 | int dir, void *ctx, char *buf, int len, | ||
569 | void (*callback)(struct urb *, struct pt_regs *regs)) | ||
570 | { | ||
571 | struct urb *urb; | ||
572 | |||
573 | if (endpoint == -1) | ||
574 | return NULL; /* endpoint not needed */ | ||
575 | |||
576 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | ||
577 | if (urb == NULL) { | ||
578 | dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); | ||
579 | return NULL; | ||
580 | } | ||
581 | |||
582 | /* Fill URB using supplied data. */ | ||
583 | usb_fill_bulk_urb(urb, serial->dev, | ||
584 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
585 | buf, len, callback, ctx); | ||
586 | |||
587 | return urb; | ||
588 | } | ||
589 | |||
590 | /* Setup urbs */ | ||
591 | static void | ||
592 | option_setup_urbs(struct usb_serial *serial) | ||
593 | { | ||
594 | int j; | ||
595 | struct usb_serial_port *port; | ||
596 | struct option_port_private *portdata; | ||
597 | |||
598 | dbg("%s", __FUNCTION__); | ||
599 | |||
600 | port = serial->port[0]; | ||
601 | portdata = usb_get_serial_port_data(port); | ||
602 | |||
603 | /* Do indat endpoints first */ | ||
604 | for (j = 0; j <= N_IN_URB; ++j) { | ||
605 | portdata->in_urbs[j] = option_setup_urb (serial, | ||
606 | port->bulk_in_endpointAddress, USB_DIR_IN, port, | ||
607 | portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); | ||
608 | } | ||
609 | |||
610 | /* outdat endpoints */ | ||
611 | for (j = 0; j <= N_OUT_URB; ++j) { | ||
612 | portdata->out_urbs[j] = option_setup_urb (serial, | ||
613 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, | ||
614 | portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | |||
619 | static int | ||
620 | option_send_setup(struct usb_serial_port *port) | ||
621 | { | ||
622 | struct usb_serial *serial = port->serial; | ||
623 | struct option_port_private *portdata; | ||
624 | |||
625 | dbg("%s", __FUNCTION__); | ||
626 | |||
627 | portdata = usb_get_serial_port_data(port); | ||
628 | |||
629 | if (port->tty) { | ||
630 | int val = 0; | ||
631 | if (portdata->dtr_state) | ||
632 | val |= 0x01; | ||
633 | if (portdata->rts_state) | ||
634 | val |= 0x02; | ||
635 | |||
636 | return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
637 | 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); | ||
638 | } | ||
639 | |||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | |||
644 | static int | ||
645 | option_startup (struct usb_serial *serial) | ||
646 | { | ||
647 | int i, err; | ||
648 | struct usb_serial_port *port; | ||
649 | struct option_port_private *portdata; | ||
650 | |||
651 | dbg("%s", __FUNCTION__); | ||
652 | |||
653 | /* Now setup per port private data */ | ||
654 | for (i = 0; i < serial->num_ports; i++) { | ||
655 | port = serial->port[i]; | ||
656 | portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL); | ||
657 | if (!portdata) { | ||
658 | dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i); | ||
659 | return (1); | ||
660 | } | ||
661 | memset(portdata, 0, sizeof(struct option_port_private)); | ||
662 | |||
663 | usb_set_serial_port_data(port, portdata); | ||
664 | |||
665 | if (! port->interrupt_in_urb) | ||
666 | continue; | ||
667 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
668 | if (err) | ||
669 | dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err); | ||
670 | } | ||
671 | |||
672 | option_setup_urbs(serial); | ||
673 | |||
674 | return (0); | ||
675 | } | ||
676 | |||
677 | static void | ||
678 | option_shutdown (struct usb_serial *serial) | ||
679 | { | ||
680 | int i, j; | ||
681 | struct usb_serial_port *port; | ||
682 | struct option_port_private *portdata; | ||
683 | |||
684 | dbg("%s", __FUNCTION__); | ||
685 | |||
686 | /* Stop reading/writing urbs */ | ||
687 | for (i = 0; i < serial->num_ports; ++i) { | ||
688 | port = serial->port[i]; | ||
689 | portdata = usb_get_serial_port_data(port); | ||
690 | for (j = 0; j < N_IN_URB; j++) | ||
691 | stop_urb(portdata->in_urbs[j]); | ||
692 | for (j = 0; j < N_OUT_URB; j++) | ||
693 | stop_urb(portdata->out_urbs[j]); | ||
694 | } | ||
695 | |||
696 | /* Now free them */ | ||
697 | for (i = 0; i < serial->num_ports; ++i) { | ||
698 | port = serial->port[i]; | ||
699 | portdata = usb_get_serial_port_data(port); | ||
700 | |||
701 | for (j = 0; j < N_IN_URB; j++) { | ||
702 | if (portdata->in_urbs[j]) { | ||
703 | usb_free_urb(portdata->in_urbs[j]); | ||
704 | portdata->in_urbs[j] = NULL; | ||
705 | } | ||
706 | } | ||
707 | for (j = 0; j < N_OUT_URB; j++) { | ||
708 | if (portdata->out_urbs[j]) { | ||
709 | usb_free_urb(portdata->out_urbs[j]); | ||
710 | portdata->out_urbs[j] = NULL; | ||
711 | } | ||
712 | } | ||
713 | } | ||
714 | |||
715 | /* Now free per port private data */ | ||
716 | for (i = 0; i < serial->num_ports; i++) { | ||
717 | port = serial->port[i]; | ||
718 | kfree(usb_get_serial_port_data(port)); | ||
719 | } | ||
720 | } | ||
721 | |||
722 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
723 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
724 | MODULE_VERSION(DRIVER_VERSION); | ||
725 | MODULE_LICENSE("GPL"); | ||
726 | |||
727 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
728 | MODULE_PARM_DESC(debug, "Debug messages"); | ||
729 | |||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4536f63faaea..5da76dd8fb28 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -1297,13 +1297,6 @@ static int __init usb_serial_init(void) | |||
1297 | goto exit_bus; | 1297 | goto exit_bus; |
1298 | } | 1298 | } |
1299 | 1299 | ||
1300 | /* register the generic driver, if we should */ | ||
1301 | result = usb_serial_generic_register(debug); | ||
1302 | if (result < 0) { | ||
1303 | err("%s - registering generic driver failed", __FUNCTION__); | ||
1304 | goto exit_generic; | ||
1305 | } | ||
1306 | |||
1307 | usb_serial_tty_driver->owner = THIS_MODULE; | 1300 | usb_serial_tty_driver->owner = THIS_MODULE; |
1308 | usb_serial_tty_driver->driver_name = "usbserial"; | 1301 | usb_serial_tty_driver->driver_name = "usbserial"; |
1309 | usb_serial_tty_driver->devfs_name = "usb/tts/"; | 1302 | usb_serial_tty_driver->devfs_name = "usb/tts/"; |
@@ -1329,17 +1322,24 @@ static int __init usb_serial_init(void) | |||
1329 | goto exit_tty; | 1322 | goto exit_tty; |
1330 | } | 1323 | } |
1331 | 1324 | ||
1325 | /* register the generic driver, if we should */ | ||
1326 | result = usb_serial_generic_register(debug); | ||
1327 | if (result < 0) { | ||
1328 | err("%s - registering generic driver failed", __FUNCTION__); | ||
1329 | goto exit_generic; | ||
1330 | } | ||
1331 | |||
1332 | info(DRIVER_DESC " " DRIVER_VERSION); | 1332 | info(DRIVER_DESC " " DRIVER_VERSION); |
1333 | 1333 | ||
1334 | return result; | 1334 | return result; |
1335 | 1335 | ||
1336 | exit_generic: | ||
1337 | usb_deregister(&usb_serial_driver); | ||
1338 | |||
1336 | exit_tty: | 1339 | exit_tty: |
1337 | tty_unregister_driver(usb_serial_tty_driver); | 1340 | tty_unregister_driver(usb_serial_tty_driver); |
1338 | 1341 | ||
1339 | exit_reg_driver: | 1342 | exit_reg_driver: |
1340 | usb_serial_generic_deregister(); | ||
1341 | |||
1342 | exit_generic: | ||
1343 | bus_unregister(&usb_serial_bus_type); | 1343 | bus_unregister(&usb_serial_bus_type); |
1344 | 1344 | ||
1345 | exit_bus: | 1345 | exit_bus: |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d2891f475793..9fcc7bd1fbe4 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -862,6 +862,15 @@ UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100, | |||
862 | US_SC_DEVICE, US_PR_BULK, NULL, | 862 | US_SC_DEVICE, US_PR_BULK, NULL, |
863 | US_FL_NEED_OVERRIDE ), | 863 | US_FL_NEED_OVERRIDE ), |
864 | 864 | ||
865 | /* Reported by Filippo Bardelli <filibard@libero.it> | ||
866 | * The device reports a subclass of RBC, which is wrong. | ||
867 | */ | ||
868 | UNUSUAL_DEV( 0x090a, 0x1050, 0x0100, 0x0100, | ||
869 | "Trumpion Microelectronics, Inc.", | ||
870 | "33520 USB Digital Voice Recorder", | ||
871 | US_SC_UFI, US_PR_DEVICE, NULL, | ||
872 | 0), | ||
873 | |||
865 | /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ | 874 | /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ |
866 | UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, | 875 | UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, |
867 | "Trumpion", | 876 | "Trumpion", |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 549e22939260..25f9a9a65c24 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -228,17 +228,17 @@ MODULE_DESCRIPTION( | |||
228 | MODULE_LICENSE("Dual BSD/GPL"); | 228 | MODULE_LICENSE("Dual BSD/GPL"); |
229 | MODULE_DEVICE_TABLE(pci, intelfb_pci_table); | 229 | MODULE_DEVICE_TABLE(pci, intelfb_pci_table); |
230 | 230 | ||
231 | static int accel __initdata = 1; | 231 | static int accel = 1; |
232 | static int vram __initdata = 4; | 232 | static int vram = 4; |
233 | static int hwcursor __initdata = 1; | 233 | static int hwcursor = 1; |
234 | static int mtrr __initdata = 1; | 234 | static int mtrr = 1; |
235 | static int fixed __initdata = 0; | 235 | static int fixed = 0; |
236 | static int noinit __initdata = 0; | 236 | static int noinit = 0; |
237 | static int noregister __initdata = 0; | 237 | static int noregister = 0; |
238 | static int probeonly __initdata = 0; | 238 | static int probeonly = 0; |
239 | static int idonly __initdata = 0; | 239 | static int idonly = 0; |
240 | static int bailearly __initdata = 0; | 240 | static int bailearly = 0; |
241 | static char *mode __initdata = NULL; | 241 | static char *mode = NULL; |
242 | 242 | ||
243 | module_param(accel, bool, S_IRUGO); | 243 | module_param(accel, bool, S_IRUGO); |
244 | MODULE_PARM_DESC(accel, "Enable console acceleration"); | 244 | MODULE_PARM_DESC(accel, "Enable console acceleration"); |
diff --git a/fs/cifs/README b/fs/cifs/README index e74df0c73256..34b0cf7111f3 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -371,7 +371,7 @@ A partial list of the supported mount options follows: | |||
371 | on newly created files, directories, and devices (create, | 371 | on newly created files, directories, and devices (create, |
372 | mkdir, mknod) which will result in the server setting the | 372 | mkdir, mknod) which will result in the server setting the |
373 | uid and gid to the default (usually the server uid of the | 373 | uid and gid to the default (usually the server uid of the |
374 | usern who mounted the share). Letting the server (rather than | 374 | user who mounted the share). Letting the server (rather than |
375 | the client) set the uid and gid is the default. This | 375 | the client) set the uid and gid is the default. This |
376 | parameter has no effect if the CIFS Unix Extensions are not | 376 | parameter has no effect if the CIFS Unix Extensions are not |
377 | negotiated. | 377 | negotiated. |
@@ -384,7 +384,7 @@ A partial list of the supported mount options follows: | |||
384 | client (e.g. when the application is doing large sequential | 384 | client (e.g. when the application is doing large sequential |
385 | reads bigger than page size without rereading the same data) | 385 | reads bigger than page size without rereading the same data) |
386 | this can provide better performance than the default | 386 | this can provide better performance than the default |
387 | behavior which caches reads (reaadahead) and writes | 387 | behavior which caches reads (readahead) and writes |
388 | (writebehind) through the local Linux client pagecache | 388 | (writebehind) through the local Linux client pagecache |
389 | if oplock (caching token) is granted and held. Note that | 389 | if oplock (caching token) is granted and held. Note that |
390 | direct allows write operations larger than page size | 390 | direct allows write operations larger than page size |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 0010511083fc..ea239dea571e 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -228,7 +228,7 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, | |||
228 | const struct nls_table *nls_codepage, | 228 | const struct nls_table *nls_codepage, |
229 | int remap_special_chars); | 229 | int remap_special_chars); |
230 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 230 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
231 | extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen, | 231 | extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, |
232 | const struct nls_table * codepage); | 232 | const struct nls_table * codepage); |
233 | extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, | 233 | extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, |
234 | const struct nls_table * cp, int mapChars); | 234 | const struct nls_table * cp, int mapChars); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 741ff0c69f37..3c628bf667a5 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -567,7 +567,7 @@ DelFileRetry: | |||
567 | 567 | ||
568 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 568 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
569 | name_len = | 569 | name_len = |
570 | cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, | 570 | cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, |
571 | PATH_MAX, nls_codepage, remap); | 571 | PATH_MAX, nls_codepage, remap); |
572 | name_len++; /* trailing null */ | 572 | name_len++; /* trailing null */ |
573 | name_len *= 2; | 573 | name_len *= 2; |
@@ -665,7 +665,7 @@ MkDirRetry: | |||
665 | return rc; | 665 | return rc; |
666 | 666 | ||
667 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 667 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
668 | name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, | 668 | name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, |
669 | PATH_MAX, nls_codepage, remap); | 669 | PATH_MAX, nls_codepage, remap); |
670 | name_len++; /* trailing null */ | 670 | name_len++; /* trailing null */ |
671 | name_len *= 2; | 671 | name_len *= 2; |
@@ -719,7 +719,7 @@ openRetry: | |||
719 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 719 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
720 | count = 1; /* account for one byte pad to word boundary */ | 720 | count = 1; /* account for one byte pad to word boundary */ |
721 | name_len = | 721 | name_len = |
722 | cifsConvertToUCS((__u16 *) (pSMB->fileName + 1), | 722 | cifsConvertToUCS((__le16 *) (pSMB->fileName + 1), |
723 | fileName, PATH_MAX, nls_codepage, remap); | 723 | fileName, PATH_MAX, nls_codepage, remap); |
724 | name_len++; /* trailing null */ | 724 | name_len++; /* trailing null */ |
725 | name_len *= 2; | 725 | name_len *= 2; |
@@ -1141,7 +1141,7 @@ renameRetry: | |||
1141 | 1141 | ||
1142 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1142 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1143 | name_len = | 1143 | name_len = |
1144 | cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, | 1144 | cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, |
1145 | PATH_MAX, nls_codepage, remap); | 1145 | PATH_MAX, nls_codepage, remap); |
1146 | name_len++; /* trailing null */ | 1146 | name_len++; /* trailing null */ |
1147 | name_len *= 2; | 1147 | name_len *= 2; |
@@ -1149,7 +1149,7 @@ renameRetry: | |||
1149 | /* protocol requires ASCII signature byte on Unicode string */ | 1149 | /* protocol requires ASCII signature byte on Unicode string */ |
1150 | pSMB->OldFileName[name_len + 1] = 0x00; | 1150 | pSMB->OldFileName[name_len + 1] = 0x00; |
1151 | name_len2 = | 1151 | name_len2 = |
1152 | cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2], | 1152 | cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2], |
1153 | toName, PATH_MAX, nls_codepage, remap); | 1153 | toName, PATH_MAX, nls_codepage, remap); |
1154 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1154 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
1155 | name_len2 *= 2; /* convert to bytes */ | 1155 | name_len2 *= 2; /* convert to bytes */ |
@@ -1236,10 +1236,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, | |||
1236 | /* unicode only call */ | 1236 | /* unicode only call */ |
1237 | if(target_name == NULL) { | 1237 | if(target_name == NULL) { |
1238 | sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); | 1238 | sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); |
1239 | len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, | 1239 | len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, |
1240 | dummy_string, 24, nls_codepage, remap); | 1240 | dummy_string, 24, nls_codepage, remap); |
1241 | } else { | 1241 | } else { |
1242 | len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, | 1242 | len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, |
1243 | target_name, PATH_MAX, nls_codepage, remap); | 1243 | target_name, PATH_MAX, nls_codepage, remap); |
1244 | } | 1244 | } |
1245 | rename_info->target_name_len = cpu_to_le32(2 * len_of_str); | 1245 | rename_info->target_name_len = cpu_to_le32(2 * len_of_str); |
@@ -1296,7 +1296,7 @@ copyRetry: | |||
1296 | pSMB->Flags = cpu_to_le16(flags & COPY_TREE); | 1296 | pSMB->Flags = cpu_to_le16(flags & COPY_TREE); |
1297 | 1297 | ||
1298 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1298 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1299 | name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, | 1299 | name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, |
1300 | fromName, PATH_MAX, nls_codepage, | 1300 | fromName, PATH_MAX, nls_codepage, |
1301 | remap); | 1301 | remap); |
1302 | name_len++; /* trailing null */ | 1302 | name_len++; /* trailing null */ |
@@ -1304,7 +1304,7 @@ copyRetry: | |||
1304 | pSMB->OldFileName[name_len] = 0x04; /* pad */ | 1304 | pSMB->OldFileName[name_len] = 0x04; /* pad */ |
1305 | /* protocol requires ASCII signature byte on Unicode string */ | 1305 | /* protocol requires ASCII signature byte on Unicode string */ |
1306 | pSMB->OldFileName[name_len + 1] = 0x00; | 1306 | pSMB->OldFileName[name_len + 1] = 0x00; |
1307 | name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], | 1307 | name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], |
1308 | toName, PATH_MAX, nls_codepage, remap); | 1308 | toName, PATH_MAX, nls_codepage, remap); |
1309 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1309 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
1310 | name_len2 *= 2; /* convert to bytes */ | 1310 | name_len2 *= 2; /* convert to bytes */ |
@@ -1453,7 +1453,7 @@ createHardLinkRetry: | |||
1453 | return rc; | 1453 | return rc; |
1454 | 1454 | ||
1455 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1455 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1456 | name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName, | 1456 | name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName, |
1457 | PATH_MAX, nls_codepage, remap); | 1457 | PATH_MAX, nls_codepage, remap); |
1458 | name_len++; /* trailing null */ | 1458 | name_len++; /* trailing null */ |
1459 | name_len *= 2; | 1459 | name_len *= 2; |
@@ -1476,7 +1476,7 @@ createHardLinkRetry: | |||
1476 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | 1476 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; |
1477 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1477 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1478 | name_len_target = | 1478 | name_len_target = |
1479 | cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX, | 1479 | cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX, |
1480 | nls_codepage, remap); | 1480 | nls_codepage, remap); |
1481 | name_len_target++; /* trailing null */ | 1481 | name_len_target++; /* trailing null */ |
1482 | name_len_target *= 2; | 1482 | name_len_target *= 2; |
@@ -1546,14 +1546,14 @@ winCreateHardLinkRetry: | |||
1546 | 1546 | ||
1547 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1547 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1548 | name_len = | 1548 | name_len = |
1549 | cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, | 1549 | cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, |
1550 | PATH_MAX, nls_codepage, remap); | 1550 | PATH_MAX, nls_codepage, remap); |
1551 | name_len++; /* trailing null */ | 1551 | name_len++; /* trailing null */ |
1552 | name_len *= 2; | 1552 | name_len *= 2; |
1553 | pSMB->OldFileName[name_len] = 0; /* pad */ | 1553 | pSMB->OldFileName[name_len] = 0; /* pad */ |
1554 | pSMB->OldFileName[name_len + 1] = 0x04; | 1554 | pSMB->OldFileName[name_len + 1] = 0x04; |
1555 | name_len2 = | 1555 | name_len2 = |
1556 | cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], | 1556 | cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], |
1557 | toName, PATH_MAX, nls_codepage, remap); | 1557 | toName, PATH_MAX, nls_codepage, remap); |
1558 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1558 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
1559 | name_len2 *= 2; /* convert to bytes */ | 1559 | name_len2 *= 2; /* convert to bytes */ |
@@ -1939,7 +1939,7 @@ queryAclRetry: | |||
1939 | 1939 | ||
1940 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1940 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1941 | name_len = | 1941 | name_len = |
1942 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 1942 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
1943 | PATH_MAX, nls_codepage, remap); | 1943 | PATH_MAX, nls_codepage, remap); |
1944 | name_len++; /* trailing null */ | 1944 | name_len++; /* trailing null */ |
1945 | name_len *= 2; | 1945 | name_len *= 2; |
@@ -2024,7 +2024,7 @@ setAclRetry: | |||
2024 | return rc; | 2024 | return rc; |
2025 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2025 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2026 | name_len = | 2026 | name_len = |
2027 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 2027 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
2028 | PATH_MAX, nls_codepage, remap); | 2028 | PATH_MAX, nls_codepage, remap); |
2029 | name_len++; /* trailing null */ | 2029 | name_len++; /* trailing null */ |
2030 | name_len *= 2; | 2030 | name_len *= 2; |
@@ -2188,7 +2188,7 @@ QPathInfoRetry: | |||
2188 | 2188 | ||
2189 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2189 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2190 | name_len = | 2190 | name_len = |
2191 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 2191 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
2192 | PATH_MAX, nls_codepage, remap); | 2192 | PATH_MAX, nls_codepage, remap); |
2193 | name_len++; /* trailing null */ | 2193 | name_len++; /* trailing null */ |
2194 | name_len *= 2; | 2194 | name_len *= 2; |
@@ -2269,7 +2269,7 @@ UnixQPathInfoRetry: | |||
2269 | 2269 | ||
2270 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2270 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2271 | name_len = | 2271 | name_len = |
2272 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 2272 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
2273 | PATH_MAX, nls_codepage, remap); | 2273 | PATH_MAX, nls_codepage, remap); |
2274 | name_len++; /* trailing null */ | 2274 | name_len++; /* trailing null */ |
2275 | name_len *= 2; | 2275 | name_len *= 2; |
@@ -2350,7 +2350,7 @@ findUniqueRetry: | |||
2350 | 2350 | ||
2351 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2351 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2352 | name_len = | 2352 | name_len = |
2353 | cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 2353 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX |
2354 | /* find define for this maxpathcomponent */ | 2354 | /* find define for this maxpathcomponent */ |
2355 | , nls_codepage); | 2355 | , nls_codepage); |
2356 | name_len++; /* trailing null */ | 2356 | name_len++; /* trailing null */ |
@@ -2435,7 +2435,7 @@ findFirstRetry: | |||
2435 | 2435 | ||
2436 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2436 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2437 | name_len = | 2437 | name_len = |
2438 | cifsConvertToUCS((__u16 *) pSMB->FileName,searchName, | 2438 | cifsConvertToUCS((__le16 *) pSMB->FileName,searchName, |
2439 | PATH_MAX, nls_codepage, remap); | 2439 | PATH_MAX, nls_codepage, remap); |
2440 | /* We can not add the asterik earlier in case | 2440 | /* We can not add the asterik earlier in case |
2441 | it got remapped to 0xF03A as if it were part of the | 2441 | it got remapped to 0xF03A as if it were part of the |
@@ -2726,7 +2726,7 @@ GetInodeNumberRetry: | |||
2726 | 2726 | ||
2727 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2727 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
2728 | name_len = | 2728 | name_len = |
2729 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 2729 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
2730 | PATH_MAX,nls_codepage, remap); | 2730 | PATH_MAX,nls_codepage, remap); |
2731 | name_len++; /* trailing null */ | 2731 | name_len++; /* trailing null */ |
2732 | name_len *= 2; | 2732 | name_len *= 2; |
@@ -2837,7 +2837,7 @@ getDFSRetry: | |||
2837 | if (ses->capabilities & CAP_UNICODE) { | 2837 | if (ses->capabilities & CAP_UNICODE) { |
2838 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 2838 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
2839 | name_len = | 2839 | name_len = |
2840 | cifsConvertToUCS((__u16 *) pSMB->RequestFileName, | 2840 | cifsConvertToUCS((__le16 *) pSMB->RequestFileName, |
2841 | searchName, PATH_MAX, nls_codepage, remap); | 2841 | searchName, PATH_MAX, nls_codepage, remap); |
2842 | name_len++; /* trailing null */ | 2842 | name_len++; /* trailing null */ |
2843 | name_len *= 2; | 2843 | name_len *= 2; |
@@ -3369,7 +3369,7 @@ SetEOFRetry: | |||
3369 | 3369 | ||
3370 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3370 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3371 | name_len = | 3371 | name_len = |
3372 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 3372 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
3373 | PATH_MAX, nls_codepage, remap); | 3373 | PATH_MAX, nls_codepage, remap); |
3374 | name_len++; /* trailing null */ | 3374 | name_len++; /* trailing null */ |
3375 | name_len *= 2; | 3375 | name_len *= 2; |
@@ -3627,7 +3627,7 @@ SetTimesRetry: | |||
3627 | 3627 | ||
3628 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3628 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3629 | name_len = | 3629 | name_len = |
3630 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 3630 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
3631 | PATH_MAX, nls_codepage, remap); | 3631 | PATH_MAX, nls_codepage, remap); |
3632 | name_len++; /* trailing null */ | 3632 | name_len++; /* trailing null */ |
3633 | name_len *= 2; | 3633 | name_len *= 2; |
@@ -3708,7 +3708,7 @@ SetAttrLgcyRetry: | |||
3708 | 3708 | ||
3709 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3709 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3710 | name_len = | 3710 | name_len = |
3711 | ConvertToUCS((wchar_t *) pSMB->fileName, fileName, | 3711 | ConvertToUCS((__le16 *) pSMB->fileName, fileName, |
3712 | PATH_MAX, nls_codepage); | 3712 | PATH_MAX, nls_codepage); |
3713 | name_len++; /* trailing null */ | 3713 | name_len++; /* trailing null */ |
3714 | name_len *= 2; | 3714 | name_len *= 2; |
@@ -3759,7 +3759,7 @@ setPermsRetry: | |||
3759 | 3759 | ||
3760 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3760 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3761 | name_len = | 3761 | name_len = |
3762 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 3762 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
3763 | PATH_MAX, nls_codepage, remap); | 3763 | PATH_MAX, nls_codepage, remap); |
3764 | name_len++; /* trailing null */ | 3764 | name_len++; /* trailing null */ |
3765 | name_len *= 2; | 3765 | name_len *= 2; |
@@ -3904,7 +3904,7 @@ QAllEAsRetry: | |||
3904 | 3904 | ||
3905 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3905 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
3906 | name_len = | 3906 | name_len = |
3907 | cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, | 3907 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
3908 | PATH_MAX, nls_codepage, remap); | 3908 | PATH_MAX, nls_codepage, remap); |
3909 | name_len++; /* trailing null */ | 3909 | name_len++; /* trailing null */ |
3910 | name_len *= 2; | 3910 | name_len *= 2; |
@@ -4047,7 +4047,7 @@ QEARetry: | |||
4047 | 4047 | ||
4048 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 4048 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
4049 | name_len = | 4049 | name_len = |
4050 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 4050 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
4051 | PATH_MAX, nls_codepage, remap); | 4051 | PATH_MAX, nls_codepage, remap); |
4052 | name_len++; /* trailing null */ | 4052 | name_len++; /* trailing null */ |
4053 | name_len *= 2; | 4053 | name_len *= 2; |
@@ -4194,7 +4194,7 @@ SetEARetry: | |||
4194 | 4194 | ||
4195 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 4195 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
4196 | name_len = | 4196 | name_len = |
4197 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 4197 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
4198 | PATH_MAX, nls_codepage, remap); | 4198 | PATH_MAX, nls_codepage, remap); |
4199 | name_len++; /* trailing null */ | 4199 | name_len++; /* trailing null */ |
4200 | name_len *= 2; | 4200 | name_len *= 2; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e3137aa48cdd..3f3538d4a1fa 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -392,7 +392,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
392 | rc = 0; | 392 | rc = 0; |
393 | d_add(direntry, NULL); | 393 | d_add(direntry, NULL); |
394 | } else { | 394 | } else { |
395 | cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc)); | 395 | cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", |
396 | rc,full_path)); | ||
396 | /* BB special case check for Access Denied - watch security | 397 | /* BB special case check for Access Denied - watch security |
397 | exposure of returning dir info implicitly via different rc | 398 | exposure of returning dir info implicitly via different rc |
398 | if file exists or not but no access BB */ | 399 | if file exists or not but no access BB */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 670947288262..b8b78cbb34c9 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
423 | 423 | ||
424 | if (!rc) { | 424 | if (!rc) { |
425 | direntry->d_inode->i_nlink--; | 425 | if(direntry->d_inode) |
426 | direntry->d_inode->i_nlink--; | ||
426 | } else if (rc == -ENOENT) { | 427 | } else if (rc == -ENOENT) { |
427 | d_drop(direntry); | 428 | d_drop(direntry); |
428 | } else if (rc == -ETXTBSY) { | 429 | } else if (rc == -ETXTBSY) { |
@@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
440 | cifs_sb->mnt_cifs_flags & | 441 | cifs_sb->mnt_cifs_flags & |
441 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 442 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
442 | CIFSSMBClose(xid, pTcon, netfid); | 443 | CIFSSMBClose(xid, pTcon, netfid); |
443 | direntry->d_inode->i_nlink--; | 444 | if(direntry->d_inode) |
445 | direntry->d_inode->i_nlink--; | ||
444 | } | 446 | } |
445 | } else if (rc == -EACCES) { | 447 | } else if (rc == -EACCES) { |
446 | /* try only if r/o attribute set in local lookup data? */ | 448 | /* try only if r/o attribute set in local lookup data? */ |
@@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
494 | cifs_sb->mnt_cifs_flags & | 496 | cifs_sb->mnt_cifs_flags & |
495 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 497 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
496 | if (!rc) { | 498 | if (!rc) { |
497 | direntry->d_inode->i_nlink--; | 499 | if(direntry->d_inode) |
500 | direntry->d_inode->i_nlink--; | ||
498 | } else if (rc == -ETXTBSY) { | 501 | } else if (rc == -ETXTBSY) { |
499 | int oplock = FALSE; | 502 | int oplock = FALSE; |
500 | __u16 netfid; | 503 | __u16 netfid; |
@@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
514 | cifs_sb->mnt_cifs_flags & | 517 | cifs_sb->mnt_cifs_flags & |
515 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 518 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
516 | CIFSSMBClose(xid, pTcon, netfid); | 519 | CIFSSMBClose(xid, pTcon, netfid); |
517 | direntry->d_inode->i_nlink--; | 520 | if(direntry->d_inode) |
521 | direntry->d_inode->i_nlink--; | ||
518 | } | 522 | } |
519 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ | 523 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ |
520 | } | 524 | } |
521 | } | 525 | } |
522 | } | 526 | } |
523 | cifsInode = CIFS_I(direntry->d_inode); | 527 | if(direntry->d_inode) { |
524 | cifsInode->time = 0; /* will force revalidate to get info when | 528 | cifsInode = CIFS_I(direntry->d_inode); |
525 | needed */ | 529 | cifsInode->time = 0; /* will force revalidate to get info |
526 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = | 530 | when needed */ |
527 | current_fs_time(inode->i_sb); | 531 | direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); |
532 | } | ||
533 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); | ||
528 | cifsInode = CIFS_I(inode); | 534 | cifsInode = CIFS_I(inode); |
529 | cifsInode->time = 0; /* force revalidate of dir as well */ | 535 | cifsInode->time = 0; /* force revalidate of dir as well */ |
530 | 536 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index db14b503d89e..072b4ee8c53e 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -571,6 +571,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, | |||
571 | break; | 571 | break; |
572 | case UNI_LESSTHAN: | 572 | case UNI_LESSTHAN: |
573 | target[j] = '<'; | 573 | target[j] = '<'; |
574 | break; | ||
574 | default: | 575 | default: |
575 | len = cp->uni2char(src_char, &target[j], | 576 | len = cp->uni2char(src_char, &target[j], |
576 | NLS_MAX_CHARSET_SIZE); | 577 | NLS_MAX_CHARSET_SIZE); |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 14a0d339d036..4bf43ea87c46 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "kern_util.h" | 23 | #include "kern_util.h" |
24 | #include "kern.h" | 24 | #include "kern.h" |
25 | #include "user_util.h" | 25 | #include "user_util.h" |
26 | #include "2_5compat.h" | ||
27 | #include "init.h" | 26 | #include "init.h" |
28 | 27 | ||
29 | struct hostfs_inode_info { | 28 | struct hostfs_inode_info { |
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 98d830401c56..5a97e346bd95 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c | |||
@@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) | |||
188 | } else { | 188 | } else { |
189 | jbd_unlock_bh_state(bh); | 189 | jbd_unlock_bh_state(bh); |
190 | } | 190 | } |
191 | jh = next_jh; | ||
192 | } while (jh != last_jh); | 191 | } while (jh != last_jh); |
193 | 192 | ||
194 | return ret; | 193 | return ret; |
@@ -339,8 +338,10 @@ int log_do_checkpoint(journal_t *journal) | |||
339 | } | 338 | } |
340 | } while (jh != last_jh && !retry); | 339 | } while (jh != last_jh && !retry); |
341 | 340 | ||
342 | if (batch_count) | 341 | if (batch_count) { |
343 | __flush_batch(journal, bhs, &batch_count); | 342 | __flush_batch(journal, bhs, &batch_count); |
343 | retry = 1; | ||
344 | } | ||
344 | 345 | ||
345 | /* | 346 | /* |
346 | * If someone cleaned up this transaction while we slept, we're | 347 | * If someone cleaned up this transaction while we slept, we're |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 67423c696c0a..6fd57f154197 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
@@ -12,15 +12,8 @@ | |||
12 | #include <asm/uaccess.h> | 12 | #include <asm/uaccess.h> |
13 | 13 | ||
14 | #ifndef HAVE_ARCH_DEVTREE_FIXUPS | 14 | #ifndef HAVE_ARCH_DEVTREE_FIXUPS |
15 | static inline void set_node_proc_entry(struct device_node *np, struct proc_dir_entry *de) | 15 | static inline void set_node_proc_entry(struct device_node *np, |
16 | { | 16 | struct proc_dir_entry *de) |
17 | } | ||
18 | |||
19 | static void inline set_node_name_link(struct device_node *np, struct proc_dir_entry *de) | ||
20 | { | ||
21 | } | ||
22 | |||
23 | static void inline set_node_addr_link(struct device_node *np, struct proc_dir_entry *de) | ||
24 | { | 17 | { |
25 | } | 18 | } |
26 | #endif | 19 | #endif |
@@ -58,89 +51,67 @@ static int property_read_proc(char *page, char **start, off_t off, | |||
58 | /* | 51 | /* |
59 | * Process a node, adding entries for its children and its properties. | 52 | * Process a node, adding entries for its children and its properties. |
60 | */ | 53 | */ |
61 | void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *de) | 54 | void proc_device_tree_add_node(struct device_node *np, |
55 | struct proc_dir_entry *de) | ||
62 | { | 56 | { |
63 | struct property *pp; | 57 | struct property *pp; |
64 | struct proc_dir_entry *ent; | 58 | struct proc_dir_entry *ent; |
65 | struct device_node *child, *sib; | 59 | struct device_node *child; |
66 | const char *p, *at; | 60 | struct proc_dir_entry *list = NULL, **lastp; |
67 | int l; | 61 | const char *p; |
68 | struct proc_dir_entry *list, **lastp, *al; | ||
69 | 62 | ||
70 | set_node_proc_entry(np, de); | 63 | set_node_proc_entry(np, de); |
71 | lastp = &list; | 64 | lastp = &list; |
72 | for (pp = np->properties; pp != 0; pp = pp->next) { | 65 | for (child = NULL; (child = of_get_next_child(np, child));) { |
73 | /* | ||
74 | * Unfortunately proc_register puts each new entry | ||
75 | * at the beginning of the list. So we rearrange them. | ||
76 | */ | ||
77 | ent = create_proc_read_entry(pp->name, strncmp(pp->name, "security-", 9) ? | ||
78 | S_IRUGO : S_IRUSR, de, property_read_proc, pp); | ||
79 | if (ent == 0) | ||
80 | break; | ||
81 | if (!strncmp(pp->name, "security-", 9)) | ||
82 | ent->size = 0; /* don't leak number of password chars */ | ||
83 | else | ||
84 | ent->size = pp->length; | ||
85 | *lastp = ent; | ||
86 | lastp = &ent->next; | ||
87 | } | ||
88 | child = NULL; | ||
89 | while ((child = of_get_next_child(np, child))) { | ||
90 | p = strrchr(child->full_name, '/'); | 66 | p = strrchr(child->full_name, '/'); |
91 | if (!p) | 67 | if (!p) |
92 | p = child->full_name; | 68 | p = child->full_name; |
93 | else | 69 | else |
94 | ++p; | 70 | ++p; |
95 | /* chop off '@0' if the name ends with that */ | ||
96 | l = strlen(p); | ||
97 | if (l > 2 && p[l-2] == '@' && p[l-1] == '0') | ||
98 | l -= 2; | ||
99 | ent = proc_mkdir(p, de); | 71 | ent = proc_mkdir(p, de); |
100 | if (ent == 0) | 72 | if (ent == 0) |
101 | break; | 73 | break; |
102 | *lastp = ent; | 74 | *lastp = ent; |
75 | ent->next = NULL; | ||
103 | lastp = &ent->next; | 76 | lastp = &ent->next; |
104 | proc_device_tree_add_node(child, ent); | 77 | proc_device_tree_add_node(child, ent); |
105 | 78 | } | |
106 | /* | 79 | of_node_put(child); |
107 | * If we left the address part on the name, consider | 80 | for (pp = np->properties; pp != 0; pp = pp->next) { |
108 | * adding symlinks from the name and address parts. | ||
109 | */ | ||
110 | if (p[l] != 0 || (at = strchr(p, '@')) == 0) | ||
111 | continue; | ||
112 | |||
113 | /* | 81 | /* |
114 | * If this is the first node with a given name property, | 82 | * Yet another Apple device-tree bogosity: on some machines, |
115 | * add a symlink with the name property as its name. | 83 | * they have properties & nodes with the same name. Those |
84 | * properties are quite unimportant for us though, thus we | ||
85 | * simply "skip" them here, but we do have to check. | ||
116 | */ | 86 | */ |
117 | sib = NULL; | 87 | for (ent = list; ent != NULL; ent = ent->next) |
118 | while ((sib = of_get_next_child(np, sib)) && sib != child) | 88 | if (!strcmp(ent->name, pp->name)) |
119 | if (sib->name && strcmp(sib->name, child->name) == 0) | ||
120 | break; | ||
121 | if (sib == child && strncmp(p, child->name, l) != 0) { | ||
122 | al = proc_symlink(child->name, de, ent->name); | ||
123 | if (al == 0) { | ||
124 | of_node_put(sib); | ||
125 | break; | 89 | break; |
126 | } | 90 | if (ent != NULL) { |
127 | set_node_name_link(child, al); | 91 | printk(KERN_WARNING "device-tree: property \"%s\" name" |
128 | *lastp = al; | 92 | " conflicts with node in %s\n", pp->name, |
129 | lastp = &al->next; | 93 | np->full_name); |
94 | continue; | ||
130 | } | 95 | } |
131 | of_node_put(sib); | 96 | |
132 | /* | 97 | /* |
133 | * Add another directory with the @address part as its name. | 98 | * Unfortunately proc_register puts each new entry |
99 | * at the beginning of the list. So we rearrange them. | ||
134 | */ | 100 | */ |
135 | al = proc_symlink(at, de, ent->name); | 101 | ent = create_proc_read_entry(pp->name, |
136 | if (al == 0) | 102 | strncmp(pp->name, "security-", 9) |
103 | ? S_IRUGO : S_IRUSR, de, | ||
104 | property_read_proc, pp); | ||
105 | if (ent == 0) | ||
137 | break; | 106 | break; |
138 | set_node_addr_link(child, al); | 107 | if (!strncmp(pp->name, "security-", 9)) |
139 | *lastp = al; | 108 | ent->size = 0; /* don't leak number of password chars */ |
140 | lastp = &al->next; | 109 | else |
110 | ent->size = pp->length; | ||
111 | ent->next = NULL; | ||
112 | *lastp = ent; | ||
113 | lastp = &ent->next; | ||
141 | } | 114 | } |
142 | of_node_put(child); | ||
143 | *lastp = NULL; | ||
144 | de->subdir = list; | 115 | de->subdir = list; |
145 | } | 116 | } |
146 | 117 | ||
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index 457a8fe28575..85d8dbe843f1 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | /* How many days come before each month (0-12). */ | 48 | /* How many days come before each month (0-12). */ |
49 | const unsigned short int __mon_yday[2][13] = | 49 | static const unsigned short int __mon_yday[2][13] = |
50 | { | 50 | { |
51 | /* Normal years. */ | 51 | /* Normal years. */ |
52 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, | 52 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, |
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h index 40c54f69780e..c34709849839 100644 --- a/include/asm-i386/timer.h +++ b/include/asm-i386/timer.h | |||
@@ -53,6 +53,7 @@ extern struct init_timer_opts timer_cyclone_init; | |||
53 | 53 | ||
54 | extern unsigned long calibrate_tsc(void); | 54 | extern unsigned long calibrate_tsc(void); |
55 | extern void init_cpu_khz(void); | 55 | extern void init_cpu_khz(void); |
56 | extern int recalibrate_cpu_khz(void); | ||
56 | #ifdef CONFIG_HPET_TIMER | 57 | #ifdef CONFIG_HPET_TIMER |
57 | extern struct init_timer_opts timer_hpet_init; | 58 | extern struct init_timer_opts timer_hpet_init; |
58 | extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr); | 59 | extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr); |
diff --git a/include/asm-ia64/perfmon.h b/include/asm-ia64/perfmon.h index ed5416c5b1ac..7f3333dd00e4 100644 --- a/include/asm-ia64/perfmon.h +++ b/include/asm-ia64/perfmon.h | |||
@@ -177,6 +177,10 @@ typedef union { | |||
177 | 177 | ||
178 | extern long perfmonctl(int fd, int cmd, void *arg, int narg); | 178 | extern long perfmonctl(int fd, int cmd, void *arg, int narg); |
179 | 179 | ||
180 | typedef struct { | ||
181 | void (*handler)(int irq, void *arg, struct pt_regs *regs); | ||
182 | } pfm_intr_handler_desc_t; | ||
183 | |||
180 | extern void pfm_save_regs (struct task_struct *); | 184 | extern void pfm_save_regs (struct task_struct *); |
181 | extern void pfm_load_regs (struct task_struct *); | 185 | extern void pfm_load_regs (struct task_struct *); |
182 | 186 | ||
@@ -187,6 +191,10 @@ extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, | |||
187 | extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs); | 191 | extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs); |
188 | extern void pfm_init_percpu(void); | 192 | extern void pfm_init_percpu(void); |
189 | extern void pfm_handle_work(void); | 193 | extern void pfm_handle_work(void); |
194 | extern int pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *h); | ||
195 | extern int pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *h); | ||
196 | |||
197 | |||
190 | 198 | ||
191 | /* | 199 | /* |
192 | * Reset PMD register flags | 200 | * Reset PMD register flags |
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index 56d74ca76b5d..eb0395ad0d6a 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h | |||
@@ -115,6 +115,13 @@ | |||
115 | #define SAL_IROUTER_INTR_XMIT SAL_CONSOLE_INTR_XMIT | 115 | #define SAL_IROUTER_INTR_XMIT SAL_CONSOLE_INTR_XMIT |
116 | #define SAL_IROUTER_INTR_RECV SAL_CONSOLE_INTR_RECV | 116 | #define SAL_IROUTER_INTR_RECV SAL_CONSOLE_INTR_RECV |
117 | 117 | ||
118 | /* | ||
119 | * Error Handling Features | ||
120 | */ | ||
121 | #define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1 | ||
122 | #define SAL_ERR_FEAT_LOG_SBES 0x2 | ||
123 | #define SAL_ERR_FEAT_MFR_OVERRIDE 0x4 | ||
124 | #define SAL_ERR_FEAT_SBE_THRESHOLD 0xffff0000 | ||
118 | 125 | ||
119 | /* | 126 | /* |
120 | * SAL Error Codes | 127 | * SAL Error Codes |
@@ -342,6 +349,25 @@ ia64_sn_plat_cpei_handler(void) | |||
342 | } | 349 | } |
343 | 350 | ||
344 | /* | 351 | /* |
352 | * Set Error Handling Features | ||
353 | */ | ||
354 | static inline u64 | ||
355 | ia64_sn_plat_set_error_handling_features(void) | ||
356 | { | ||
357 | struct ia64_sal_retval ret_stuff; | ||
358 | |||
359 | ret_stuff.status = 0; | ||
360 | ret_stuff.v0 = 0; | ||
361 | ret_stuff.v1 = 0; | ||
362 | ret_stuff.v2 = 0; | ||
363 | SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES, | ||
364 | (SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV | SAL_ERR_FEAT_LOG_SBES), | ||
365 | 0, 0, 0, 0, 0, 0); | ||
366 | |||
367 | return ret_stuff.status; | ||
368 | } | ||
369 | |||
370 | /* | ||
345 | * Checks for console input. | 371 | * Checks for console input. |
346 | */ | 372 | */ |
347 | static inline u64 | 373 | static inline u64 |
@@ -472,7 +498,7 @@ static inline u64 | |||
472 | ia64_sn_pod_mode(void) | 498 | ia64_sn_pod_mode(void) |
473 | { | 499 | { |
474 | struct ia64_sal_retval isrv; | 500 | struct ia64_sal_retval isrv; |
475 | SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0); | 501 | SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0); |
476 | if (isrv.status) | 502 | if (isrv.status) |
477 | return 0; | 503 | return 0; |
478 | return isrv.v0; | 504 | return isrv.v0; |
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index 42fd1068cf2a..c5883dbed63f 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h | |||
@@ -1039,6 +1039,52 @@ typedef struct im_idma { | |||
1039 | #define CMXSCR_TS4CS_CLK7 0x00000006 /* SCC4 Tx Clock Source is CLK7 */ | 1039 | #define CMXSCR_TS4CS_CLK7 0x00000006 /* SCC4 Tx Clock Source is CLK7 */ |
1040 | #define CMXSCR_TS4CS_CLK8 0x00000007 /* SCC4 Tx Clock Source is CLK8 */ | 1040 | #define CMXSCR_TS4CS_CLK8 0x00000007 /* SCC4 Tx Clock Source is CLK8 */ |
1041 | 1041 | ||
1042 | /*----------------------------------------------------------------------- | ||
1043 | * SIUMCR - SIU Module Configuration Register 4-31 | ||
1044 | */ | ||
1045 | #define SIUMCR_BBD 0x80000000 /* Bus Busy Disable */ | ||
1046 | #define SIUMCR_ESE 0x40000000 /* External Snoop Enable */ | ||
1047 | #define SIUMCR_PBSE 0x20000000 /* Parity Byte Select Enable */ | ||
1048 | #define SIUMCR_CDIS 0x10000000 /* Core Disable */ | ||
1049 | #define SIUMCR_DPPC00 0x00000000 /* Data Parity Pins Configuration*/ | ||
1050 | #define SIUMCR_DPPC01 0x04000000 /* - " - */ | ||
1051 | #define SIUMCR_DPPC10 0x08000000 /* - " - */ | ||
1052 | #define SIUMCR_DPPC11 0x0c000000 /* - " - */ | ||
1053 | #define SIUMCR_L2CPC00 0x00000000 /* L2 Cache Pins Configuration */ | ||
1054 | #define SIUMCR_L2CPC01 0x01000000 /* - " - */ | ||
1055 | #define SIUMCR_L2CPC10 0x02000000 /* - " - */ | ||
1056 | #define SIUMCR_L2CPC11 0x03000000 /* - " - */ | ||
1057 | #define SIUMCR_LBPC00 0x00000000 /* Local Bus Pins Configuration */ | ||
1058 | #define SIUMCR_LBPC01 0x00400000 /* - " - */ | ||
1059 | #define SIUMCR_LBPC10 0x00800000 /* - " - */ | ||
1060 | #define SIUMCR_LBPC11 0x00c00000 /* - " - */ | ||
1061 | #define SIUMCR_APPC00 0x00000000 /* Address Parity Pins Configuration*/ | ||
1062 | #define SIUMCR_APPC01 0x00100000 /* - " - */ | ||
1063 | #define SIUMCR_APPC10 0x00200000 /* - " - */ | ||
1064 | #define SIUMCR_APPC11 0x00300000 /* - " - */ | ||
1065 | #define SIUMCR_CS10PC00 0x00000000 /* CS10 Pin Configuration */ | ||
1066 | #define SIUMCR_CS10PC01 0x00040000 /* - " - */ | ||
1067 | #define SIUMCR_CS10PC10 0x00080000 /* - " - */ | ||
1068 | #define SIUMCR_CS10PC11 0x000c0000 /* - " - */ | ||
1069 | #define SIUMCR_BCTLC00 0x00000000 /* Buffer Control Configuration */ | ||
1070 | #define SIUMCR_BCTLC01 0x00010000 /* - " - */ | ||
1071 | #define SIUMCR_BCTLC10 0x00020000 /* - " - */ | ||
1072 | #define SIUMCR_BCTLC11 0x00030000 /* - " - */ | ||
1073 | #define SIUMCR_MMR00 0x00000000 /* Mask Masters Requests */ | ||
1074 | #define SIUMCR_MMR01 0x00004000 /* - " - */ | ||
1075 | #define SIUMCR_MMR10 0x00008000 /* - " - */ | ||
1076 | #define SIUMCR_MMR11 0x0000c000 /* - " - */ | ||
1077 | #define SIUMCR_LPBSE 0x00002000 /* LocalBus Parity Byte Select Enable*/ | ||
1078 | |||
1079 | /*----------------------------------------------------------------------- | ||
1080 | * SCCR - System Clock Control Register 9-8 | ||
1081 | */ | ||
1082 | #define SCCR_PCI_MODE 0x00000100 /* PCI Mode */ | ||
1083 | #define SCCR_PCI_MODCK 0x00000080 /* Value of PCI_MODCK pin */ | ||
1084 | #define SCCR_PCIDF_MSK 0x00000078 /* PCI division factor */ | ||
1085 | #define SCCR_PCIDF_SHIFT 3 | ||
1086 | |||
1087 | |||
1042 | #endif /* __CPM2__ */ | 1088 | #endif /* __CPM2__ */ |
1043 | #endif /* __KERNEL__ */ | 1089 | #endif /* __KERNEL__ */ |
1044 | 1090 | ||
diff --git a/include/asm-ppc/m8260_pci.h b/include/asm-ppc/m8260_pci.h index 163a6b91d5b2..bf9e05dd54b5 100644 --- a/include/asm-ppc/m8260_pci.h +++ b/include/asm-ppc/m8260_pci.h | |||
@@ -19,6 +19,7 @@ | |||
19 | * Define the vendor/device ID for the MPC8265. | 19 | * Define the vendor/device ID for the MPC8265. |
20 | */ | 20 | */ |
21 | #define PCI_DEVICE_ID_MPC8265 ((0x18C0 << 16) | PCI_VENDOR_ID_MOTOROLA) | 21 | #define PCI_DEVICE_ID_MPC8265 ((0x18C0 << 16) | PCI_VENDOR_ID_MOTOROLA) |
22 | #define PCI_DEVICE_ID_MPC8272 ((0x18C1 << 16) | PCI_VENDOR_ID_MOTOROLA) | ||
22 | 23 | ||
23 | #define M8265_PCIBR0 0x101ac | 24 | #define M8265_PCIBR0 0x101ac |
24 | #define M8265_PCIBR1 0x101b0 | 25 | #define M8265_PCIBR1 0x101b0 |
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h index d820894e5991..89eb8a2ac693 100644 --- a/include/asm-ppc/mpc8260.h +++ b/include/asm-ppc/mpc8260.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #ifdef CONFIG_PCI_8260 | 43 | #ifdef CONFIG_PCI_8260 |
44 | #include <syslib/m8260_pci.h> | 44 | #include <syslib/m82xx_pci.h> |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | /* Make sure the memory translation stuff is there if PCI not used. | 47 | /* Make sure the memory translation stuff is there if PCI not used. |
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 0035efe2db2b..809c634ba1df 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h | |||
@@ -120,103 +120,18 @@ | |||
120 | 120 | ||
121 | /* Special Purpose Registers (SPRNs)*/ | 121 | /* Special Purpose Registers (SPRNs)*/ |
122 | 122 | ||
123 | #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ | ||
124 | #define SPRN_CTR 0x009 /* Count Register */ | 123 | #define SPRN_CTR 0x009 /* Count Register */ |
125 | #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ | 124 | #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ |
126 | #define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */ | 125 | #define DABR_TRANSLATION (1UL << 2) |
127 | #define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */ | ||
128 | #define SPRN_DAR 0x013 /* Data Address Register */ | 126 | #define SPRN_DAR 0x013 /* Data Address Register */ |
129 | #define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ | ||
130 | #define DBCR_EDM 0x80000000 | ||
131 | #define DBCR_IDM 0x40000000 | ||
132 | #define DBCR_RST(x) (((x) & 0x3) << 28) | ||
133 | #define DBCR_RST_NONE 0 | ||
134 | #define DBCR_RST_CORE 1 | ||
135 | #define DBCR_RST_CHIP 2 | ||
136 | #define DBCR_RST_SYSTEM 3 | ||
137 | #define DBCR_IC 0x08000000 /* Instruction Completion Debug Evnt */ | ||
138 | #define DBCR_BT 0x04000000 /* Branch Taken Debug Event */ | ||
139 | #define DBCR_EDE 0x02000000 /* Exception Debug Event */ | ||
140 | #define DBCR_TDE 0x01000000 /* TRAP Debug Event */ | ||
141 | #define DBCR_FER 0x00F80000 /* First Events Remaining Mask */ | ||
142 | #define DBCR_FT 0x00040000 /* Freeze Timers on Debug Event */ | ||
143 | #define DBCR_IA1 0x00020000 /* Instr. Addr. Compare 1 Enable */ | ||
144 | #define DBCR_IA2 0x00010000 /* Instr. Addr. Compare 2 Enable */ | ||
145 | #define DBCR_D1R 0x00008000 /* Data Addr. Compare 1 Read Enable */ | ||
146 | #define DBCR_D1W 0x00004000 /* Data Addr. Compare 1 Write Enable */ | ||
147 | #define DBCR_D1S(x) (((x) & 0x3) << 12) /* Data Adrr. Compare 1 Size */ | ||
148 | #define DAC_BYTE 0 | ||
149 | #define DAC_HALF 1 | ||
150 | #define DAC_WORD 2 | ||
151 | #define DAC_QUAD 3 | ||
152 | #define DBCR_D2R 0x00000800 /* Data Addr. Compare 2 Read Enable */ | ||
153 | #define DBCR_D2W 0x00000400 /* Data Addr. Compare 2 Write Enable */ | ||
154 | #define DBCR_D2S(x) (((x) & 0x3) << 8) /* Data Addr. Compare 2 Size */ | ||
155 | #define DBCR_SBT 0x00000040 /* Second Branch Taken Debug Event */ | ||
156 | #define DBCR_SED 0x00000020 /* Second Exception Debug Event */ | ||
157 | #define DBCR_STD 0x00000010 /* Second Trap Debug Event */ | ||
158 | #define DBCR_SIA 0x00000008 /* Second IAC Enable */ | ||
159 | #define DBCR_SDA 0x00000004 /* Second DAC Enable */ | ||
160 | #define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ | ||
161 | #define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ | ||
162 | #define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ | ||
163 | #define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ | ||
164 | #define SPRN_DBSR 0x3F0 /* Debug Status Register */ | ||
165 | #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ | ||
166 | #define DCCR_NOCACHE 0 /* Noncacheable */ | ||
167 | #define DCCR_CACHE 1 /* Cacheable */ | ||
168 | #define SPRN_DCMP 0x3D1 /* Data TLB Compare Register */ | ||
169 | #define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ | ||
170 | #define DCWR_COPY 0 /* Copy-back */ | ||
171 | #define DCWR_WRITE 1 /* Write-through */ | ||
172 | #define SPRN_DEAR 0x3D5 /* Data Error Address Register */ | ||
173 | #define SPRN_DEC 0x016 /* Decrement Register */ | 127 | #define SPRN_DEC 0x016 /* Decrement Register */ |
174 | #define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ | ||
175 | #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ | 128 | #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ |
176 | #define DSISR_NOHPTE 0x40000000 /* no translation found */ | 129 | #define DSISR_NOHPTE 0x40000000 /* no translation found */ |
177 | #define DSISR_PROTFAULT 0x08000000 /* protection fault */ | 130 | #define DSISR_PROTFAULT 0x08000000 /* protection fault */ |
178 | #define DSISR_ISSTORE 0x02000000 /* access was a store */ | 131 | #define DSISR_ISSTORE 0x02000000 /* access was a store */ |
179 | #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ | 132 | #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ |
180 | #define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ | 133 | #define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ |
181 | #define SPRN_EAR 0x11A /* External Address Register */ | ||
182 | #define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ | ||
183 | #define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */ | ||
184 | #define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */ | ||
185 | #define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ | ||
186 | #define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ | ||
187 | #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ | ||
188 | #define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ | ||
189 | #define ESR_PTR 0x02000000 /* Program Exception - Trap */ | ||
190 | #define ESR_DST 0x00800000 /* Storage Exception - Data miss */ | ||
191 | #define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */ | ||
192 | #define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */ | ||
193 | #define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ | ||
194 | #define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ | ||
195 | #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ | 134 | #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ |
196 | #define HID0_EMCP (1<<31) /* Enable Machine Check pin */ | ||
197 | #define HID0_EBA (1<<29) /* Enable Bus Address Parity */ | ||
198 | #define HID0_EBD (1<<28) /* Enable Bus Data Parity */ | ||
199 | #define HID0_SBCLK (1<<27) | ||
200 | #define HID0_EICE (1<<26) | ||
201 | #define HID0_ECLK (1<<25) | ||
202 | #define HID0_PAR (1<<24) | ||
203 | #define HID0_DOZE (1<<23) | ||
204 | #define HID0_NAP (1<<22) | ||
205 | #define HID0_SLEEP (1<<21) | ||
206 | #define HID0_DPM (1<<20) | ||
207 | #define HID0_ICE (1<<15) /* Instruction Cache Enable */ | ||
208 | #define HID0_DCE (1<<14) /* Data Cache Enable */ | ||
209 | #define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ | ||
210 | #define HID0_DLOCK (1<<12) /* Data Cache Lock */ | ||
211 | #define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ | ||
212 | #define HID0_DCI (1<<10) /* Data Cache Invalidate */ | ||
213 | #define HID0_SPD (1<<9) /* Speculative disable */ | ||
214 | #define HID0_SGE (1<<7) /* Store Gathering Enable */ | ||
215 | #define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ | ||
216 | #define HID0_BTIC (1<<5) /* Branch Target Instruction Cache Enable */ | ||
217 | #define HID0_ABE (1<<3) /* Address Broadcast Enable */ | ||
218 | #define HID0_BHTE (1<<2) /* Branch History Table Enable */ | ||
219 | #define HID0_BTCD (1<<1) /* Branch target cache disable */ | ||
220 | #define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */ | 135 | #define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */ |
221 | #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ | 136 | #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ |
222 | #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ | 137 | #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ |
@@ -225,23 +140,8 @@ | |||
225 | #define SPRN_HID5 0x3F6 /* 970 HID5 */ | 140 | #define SPRN_HID5 0x3F6 /* 970 HID5 */ |
226 | #define SPRN_TSC 0x3FD /* Thread switch control */ | 141 | #define SPRN_TSC 0x3FD /* Thread switch control */ |
227 | #define SPRN_TST 0x3FC /* Thread switch timeout */ | 142 | #define SPRN_TST 0x3FC /* Thread switch timeout */ |
228 | #define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ | ||
229 | #define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ | ||
230 | #define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ | ||
231 | #define ICCR_NOCACHE 0 /* Noncacheable */ | ||
232 | #define ICCR_CACHE 1 /* Cacheable */ | ||
233 | #define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */ | ||
234 | #define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ | ||
235 | #define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ | ||
236 | #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ | ||
237 | #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ | ||
238 | #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ | 143 | #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ |
239 | #define SPRN_LR 0x008 /* Link Register */ | 144 | #define SPRN_LR 0x008 /* Link Register */ |
240 | #define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ | ||
241 | #define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ | ||
242 | #define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ | ||
243 | #define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */ | ||
244 | #define SPRN_PID 0x3B1 /* Process ID */ | ||
245 | #define SPRN_PIR 0x3FF /* Processor Identification Register */ | 145 | #define SPRN_PIR 0x3FF /* Processor Identification Register */ |
246 | #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ | 146 | #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ |
247 | #define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */ | 147 | #define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */ |
@@ -249,9 +149,6 @@ | |||
249 | #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ | 149 | #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ |
250 | #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ | 150 | #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ |
251 | #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ | 151 | #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ |
252 | #define SPRN_SGR 0x3B9 /* Storage Guarded Register */ | ||
253 | #define SGR_NORMAL 0 | ||
254 | #define SGR_GUARDED 1 | ||
255 | #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ | 152 | #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ |
256 | #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ | 153 | #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ |
257 | #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ | 154 | #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ |
@@ -264,50 +161,12 @@ | |||
264 | #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */ | 161 | #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */ |
265 | #define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */ | 162 | #define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */ |
266 | #define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ | 163 | #define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ |
267 | #define SPRN_TCR 0x3DA /* Timer Control Register */ | ||
268 | #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ | ||
269 | #define WP_2_17 0 /* 2^17 clocks */ | ||
270 | #define WP_2_21 1 /* 2^21 clocks */ | ||
271 | #define WP_2_25 2 /* 2^25 clocks */ | ||
272 | #define WP_2_29 3 /* 2^29 clocks */ | ||
273 | #define TCR_WRC(x) (((x)&0x3)<<28) /* WDT Reset Control */ | ||
274 | #define WRC_NONE 0 /* No reset will occur */ | ||
275 | #define WRC_CORE 1 /* Core reset will occur */ | ||
276 | #define WRC_CHIP 2 /* Chip reset will occur */ | ||
277 | #define WRC_SYSTEM 3 /* System reset will occur */ | ||
278 | #define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ | ||
279 | #define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ | ||
280 | #define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */ | ||
281 | #define FP_2_9 0 /* 2^9 clocks */ | ||
282 | #define FP_2_13 1 /* 2^13 clocks */ | ||
283 | #define FP_2_17 2 /* 2^17 clocks */ | ||
284 | #define FP_2_21 3 /* 2^21 clocks */ | ||
285 | #define TCR_FIE 0x00800000 /* FIT Interrupt Enable */ | ||
286 | #define TCR_ARE 0x00400000 /* Auto Reload Enable */ | ||
287 | #define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ | ||
288 | #define THRM1_TIN (1<<0) | ||
289 | #define THRM1_TIV (1<<1) | ||
290 | #define THRM1_THRES (0x7f<<2) | ||
291 | #define THRM1_TID (1<<29) | ||
292 | #define THRM1_TIE (1<<30) | ||
293 | #define THRM1_V (1<<31) | ||
294 | #define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ | ||
295 | #define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ | ||
296 | #define THRM3_E (1<<31) | ||
297 | #define SPRN_TSR 0x3D8 /* Timer Status Register */ | ||
298 | #define TSR_ENW 0x80000000 /* Enable Next Watchdog */ | ||
299 | #define TSR_WIS 0x40000000 /* WDT Interrupt Status */ | ||
300 | #define TSR_WRS(x) (((x)&0x3)<<28) /* WDT Reset Status */ | ||
301 | #define WRS_NONE 0 /* No WDT reset occurred */ | ||
302 | #define WRS_CORE 1 /* WDT forced core reset */ | ||
303 | #define WRS_CHIP 2 /* WDT forced chip reset */ | ||
304 | #define WRS_SYSTEM 3 /* WDT forced system reset */ | ||
305 | #define TSR_PIS 0x08000000 /* PIT Interrupt Status */ | ||
306 | #define TSR_FIS 0x04000000 /* FIT Interrupt Status */ | ||
307 | #define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ | 164 | #define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ |
308 | #define SPRN_XER 0x001 /* Fixed Point Exception Register */ | 165 | #define SPRN_XER 0x001 /* Fixed Point Exception Register */ |
309 | #define SPRN_ZPR 0x3B0 /* Zone Protection Register */ | ||
310 | #define SPRN_VRSAVE 0x100 /* Vector save */ | 166 | #define SPRN_VRSAVE 0x100 /* Vector save */ |
167 | #define SPRN_CTRLF 0x088 | ||
168 | #define SPRN_CTRLT 0x098 | ||
169 | #define CTRL_RUNLATCH 0x1 | ||
311 | 170 | ||
312 | /* Performance monitor SPRs */ | 171 | /* Performance monitor SPRs */ |
313 | #define SPRN_SIAR 780 | 172 | #define SPRN_SIAR 780 |
@@ -352,28 +211,19 @@ | |||
352 | #define CTR SPRN_CTR /* Counter Register */ | 211 | #define CTR SPRN_CTR /* Counter Register */ |
353 | #define DAR SPRN_DAR /* Data Address Register */ | 212 | #define DAR SPRN_DAR /* Data Address Register */ |
354 | #define DABR SPRN_DABR /* Data Address Breakpoint Register */ | 213 | #define DABR SPRN_DABR /* Data Address Breakpoint Register */ |
355 | #define DCMP SPRN_DCMP /* Data TLB Compare Register */ | ||
356 | #define DEC SPRN_DEC /* Decrement Register */ | 214 | #define DEC SPRN_DEC /* Decrement Register */ |
357 | #define DMISS SPRN_DMISS /* Data TLB Miss Register */ | ||
358 | #define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */ | 215 | #define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */ |
359 | #define EAR SPRN_EAR /* External Address Register */ | ||
360 | #define HASH1 SPRN_HASH1 /* Primary Hash Address Register */ | ||
361 | #define HASH2 SPRN_HASH2 /* Secondary Hash Address Register */ | ||
362 | #define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ | 216 | #define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ |
363 | #define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */ | 217 | #define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */ |
364 | #define NIADORM SPRN_NIADORM /* NIA Dormant Register */ | 218 | #define NIADORM SPRN_NIADORM /* NIA Dormant Register */ |
365 | #define TSC SPRN_TSC /* Thread switch control */ | 219 | #define TSC SPRN_TSC /* Thread switch control */ |
366 | #define TST SPRN_TST /* Thread switch timeout */ | 220 | #define TST SPRN_TST /* Thread switch timeout */ |
367 | #define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ | 221 | #define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ |
368 | #define ICMP SPRN_ICMP /* Instruction TLB Compare Register */ | ||
369 | #define IMISS SPRN_IMISS /* Instruction TLB Miss Register */ | ||
370 | #define IMMR SPRN_IMMR /* PPC 860/821 Internal Memory Map Register */ | ||
371 | #define L2CR SPRN_L2CR /* PPC 750 L2 control register */ | 222 | #define L2CR SPRN_L2CR /* PPC 750 L2 control register */ |
372 | #define __LR SPRN_LR | 223 | #define __LR SPRN_LR |
373 | #define PVR SPRN_PVR /* Processor Version */ | 224 | #define PVR SPRN_PVR /* Processor Version */ |
374 | #define PIR SPRN_PIR /* Processor ID */ | 225 | #define PIR SPRN_PIR /* Processor ID */ |
375 | #define PURR SPRN_PURR /* Processor Utilization of Resource Register */ | 226 | #define PURR SPRN_PURR /* Processor Utilization of Resource Register */ |
376 | //#define RPA SPRN_RPA /* Required Physical Address Register */ | ||
377 | #define SDR1 SPRN_SDR1 /* MMU hash base register */ | 227 | #define SDR1 SPRN_SDR1 /* MMU hash base register */ |
378 | #define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */ | 228 | #define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */ |
379 | #define SPR1 SPRN_SPRG1 | 229 | #define SPR1 SPRN_SPRG1 |
@@ -389,10 +239,6 @@ | |||
389 | #define TBRU SPRN_TBRU /* Time Base Read Upper Register */ | 239 | #define TBRU SPRN_TBRU /* Time Base Read Upper Register */ |
390 | #define TBWL SPRN_TBWL /* Time Base Write Lower Register */ | 240 | #define TBWL SPRN_TBWL /* Time Base Write Lower Register */ |
391 | #define TBWU SPRN_TBWU /* Time Base Write Upper Register */ | 241 | #define TBWU SPRN_TBWU /* Time Base Write Upper Register */ |
392 | #define ICTC 1019 | ||
393 | #define THRM1 SPRN_THRM1 /* Thermal Management Register 1 */ | ||
394 | #define THRM2 SPRN_THRM2 /* Thermal Management Register 2 */ | ||
395 | #define THRM3 SPRN_THRM3 /* Thermal Management Register 3 */ | ||
396 | #define XER SPRN_XER | 242 | #define XER SPRN_XER |
397 | 243 | ||
398 | /* Processor Version Register (PVR) field extraction */ | 244 | /* Processor Version Register (PVR) field extraction */ |
@@ -436,12 +282,6 @@ | |||
436 | #define XGLUE(a,b) a##b | 282 | #define XGLUE(a,b) a##b |
437 | #define GLUE(a,b) XGLUE(a,b) | 283 | #define GLUE(a,b) XGLUE(a,b) |
438 | 284 | ||
439 | /* iSeries CTRL register (for runlatch) */ | ||
440 | |||
441 | #define CTRLT 0x098 | ||
442 | #define CTRLF 0x088 | ||
443 | #define RUNLATCH 0x0001 | ||
444 | |||
445 | #ifdef __ASSEMBLY__ | 285 | #ifdef __ASSEMBLY__ |
446 | 286 | ||
447 | #define _GLOBAL(name) \ | 287 | #define _GLOBAL(name) \ |
@@ -656,6 +496,24 @@ static inline void prefetchw(const void *x) | |||
656 | 496 | ||
657 | #define HAVE_ARCH_PICK_MMAP_LAYOUT | 497 | #define HAVE_ARCH_PICK_MMAP_LAYOUT |
658 | 498 | ||
499 | static inline void ppc64_runlatch_on(void) | ||
500 | { | ||
501 | unsigned long ctrl; | ||
502 | |||
503 | ctrl = mfspr(SPRN_CTRLF); | ||
504 | ctrl |= CTRL_RUNLATCH; | ||
505 | mtspr(SPRN_CTRLT, ctrl); | ||
506 | } | ||
507 | |||
508 | static inline void ppc64_runlatch_off(void) | ||
509 | { | ||
510 | unsigned long ctrl; | ||
511 | |||
512 | ctrl = mfspr(SPRN_CTRLF); | ||
513 | ctrl &= ~CTRL_RUNLATCH; | ||
514 | mtspr(SPRN_CTRLT, ctrl); | ||
515 | } | ||
516 | |||
659 | #endif /* __KERNEL__ */ | 517 | #endif /* __KERNEL__ */ |
660 | 518 | ||
661 | #endif /* __ASSEMBLY__ */ | 519 | #endif /* __ASSEMBLY__ */ |
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index 2440a2c90ae9..04b1a84f7ca3 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h | |||
@@ -147,9 +147,7 @@ struct device_node { | |||
147 | struct device_node *sibling; | 147 | struct device_node *sibling; |
148 | struct device_node *next; /* next device of same type */ | 148 | struct device_node *next; /* next device of same type */ |
149 | struct device_node *allnext; /* next in list of all nodes */ | 149 | struct device_node *allnext; /* next in list of all nodes */ |
150 | struct proc_dir_entry *pde; /* this node's proc directory */ | 150 | struct proc_dir_entry *pde; /* this node's proc directory */ |
151 | struct proc_dir_entry *name_link; /* name symlink */ | ||
152 | struct proc_dir_entry *addr_link; /* addr symlink */ | ||
153 | struct kref kref; | 151 | struct kref kref; |
154 | unsigned long _flags; | 152 | unsigned long _flags; |
155 | }; | 153 | }; |
@@ -174,15 +172,6 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e | |||
174 | dn->pde = de; | 172 | dn->pde = de; |
175 | } | 173 | } |
176 | 174 | ||
177 | static void inline set_node_name_link(struct device_node *dn, struct proc_dir_entry *de) | ||
178 | { | ||
179 | dn->name_link = de; | ||
180 | } | ||
181 | |||
182 | static void inline set_node_addr_link(struct device_node *dn, struct proc_dir_entry *de) | ||
183 | { | ||
184 | dn->addr_link = de; | ||
185 | } | ||
186 | 175 | ||
187 | /* OBSOLETE: Old stlye node lookup */ | 176 | /* OBSOLETE: Old stlye node lookup */ |
188 | extern struct device_node *find_devices(const char *name); | 177 | extern struct device_node *find_devices(const char *name); |
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h index 037b5e06083c..48b7900e90ec 100644 --- a/include/asm-ppc64/thread_info.h +++ b/include/asm-ppc64/thread_info.h | |||
@@ -96,7 +96,7 @@ static inline struct thread_info *current_thread_info(void) | |||
96 | #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling | 96 | #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling |
97 | TIF_NEED_RESCHED */ | 97 | TIF_NEED_RESCHED */ |
98 | #define TIF_32BIT 5 /* 32 bit binary */ | 98 | #define TIF_32BIT 5 /* 32 bit binary */ |
99 | #define TIF_RUN_LIGHT 6 /* iSeries run light */ | 99 | /* #define SPARE 6 */ |
100 | #define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */ | 100 | #define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */ |
101 | #define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */ | 101 | #define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */ |
102 | #define TIF_SINGLESTEP 9 /* singlestepping active */ | 102 | #define TIF_SINGLESTEP 9 /* singlestepping active */ |
@@ -110,7 +110,7 @@ static inline struct thread_info *current_thread_info(void) | |||
110 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 110 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
111 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 111 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
112 | #define _TIF_32BIT (1<<TIF_32BIT) | 112 | #define _TIF_32BIT (1<<TIF_32BIT) |
113 | #define _TIF_RUN_LIGHT (1<<TIF_RUN_LIGHT) | 113 | /* #define _SPARE (1<<SPARE) */ |
114 | #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) | 114 | #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) |
115 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 115 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
116 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) | 116 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) |
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index d82f883d8e6d..4bbbd9f3c37e 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h | |||
@@ -27,7 +27,7 @@ struct thread_info { | |||
27 | 27 | ||
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #define PREEMPT_ACTIVE 0x4000000 | 30 | #define PREEMPT_ACTIVE 0x10000000 |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * macros/functions for gaining access to the thread information structure | 33 | * macros/functions for gaining access to the thread information structure |
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h index e65f394da472..8a32d6bd0b79 100644 --- a/include/asm-sh64/thread_info.h +++ b/include/asm-sh64/thread_info.h | |||
@@ -73,7 +73,7 @@ static inline struct thread_info *current_thread_info(void) | |||
73 | 73 | ||
74 | #define THREAD_SIZE 8192 | 74 | #define THREAD_SIZE 8192 |
75 | 75 | ||
76 | #define PREEMPT_ACTIVE 0x4000000 | 76 | #define PREEMPT_ACTIVE 0x10000000 |
77 | 77 | ||
78 | /* thread information flags */ | 78 | /* thread information flags */ |
79 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 79 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h index 5fd16e42a045..0de7a3da79cd 100644 --- a/include/asm-sparc64/iommu.h +++ b/include/asm-sparc64/iommu.h | |||
@@ -16,4 +16,6 @@ | |||
16 | #define IOPTE_CACHE 0x0000000000000010UL /* Cached (in UPA E-cache) */ | 16 | #define IOPTE_CACHE 0x0000000000000010UL /* Cached (in UPA E-cache) */ |
17 | #define IOPTE_WRITE 0x0000000000000002UL /* Writeable */ | 17 | #define IOPTE_WRITE 0x0000000000000002UL /* Writeable */ |
18 | 18 | ||
19 | #define IOMMU_NUM_CTXS 4096 | ||
20 | |||
19 | #endif /* !(_SPARC_IOMMU_H) */ | 21 | #endif /* !(_SPARC_IOMMU_H) */ |
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 92999631c819..4c15610a2bac 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
17 | #include <asm/oplib.h> | 17 | #include <asm/oplib.h> |
18 | #include <asm/iommu.h> | ||
18 | 19 | ||
19 | /* The abstraction used here is that there are PCI controllers, | 20 | /* The abstraction used here is that there are PCI controllers, |
20 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules | 21 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules |
@@ -40,9 +41,6 @@ struct pci_iommu { | |||
40 | */ | 41 | */ |
41 | spinlock_t lock; | 42 | spinlock_t lock; |
42 | 43 | ||
43 | /* Context allocator. */ | ||
44 | unsigned int iommu_cur_ctx; | ||
45 | |||
46 | /* IOMMU page table, a linear array of ioptes. */ | 44 | /* IOMMU page table, a linear array of ioptes. */ |
47 | iopte_t *page_table; /* The page table itself. */ | 45 | iopte_t *page_table; /* The page table itself. */ |
48 | int page_table_sz_bits; /* log2 of ow many pages does it map? */ | 46 | int page_table_sz_bits; /* log2 of ow many pages does it map? */ |
@@ -87,6 +85,10 @@ struct pci_iommu { | |||
87 | u16 flush; | 85 | u16 flush; |
88 | } alloc_info[PBM_NCLUSTERS]; | 86 | } alloc_info[PBM_NCLUSTERS]; |
89 | 87 | ||
88 | /* CTX allocation. */ | ||
89 | unsigned long ctx_lowest_free; | ||
90 | unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)]; | ||
91 | |||
90 | /* Here a PCI controller driver describes the areas of | 92 | /* Here a PCI controller driver describes the areas of |
91 | * PCI memory space where DMA to/from physical memory | 93 | * PCI memory space where DMA to/from physical memory |
92 | * are addressed. Drivers interrogate the PCI layer | 94 | * are addressed. Drivers interrogate the PCI layer |
diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 504ea8e486b0..5afee8a8cdf3 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h | |||
@@ -98,7 +98,13 @@ extern unsigned long uml_physmem; | |||
98 | 98 | ||
99 | extern unsigned long to_phys(void *virt); | 99 | extern unsigned long to_phys(void *virt); |
100 | extern void *to_virt(unsigned long phys); | 100 | extern void *to_virt(unsigned long phys); |
101 | #define __pa(virt) to_phys((void *) virt) | 101 | |
102 | /* Cast to unsigned long before casting to void * to avoid a warning from | ||
103 | * mmap_kmem about cutting a long long down to a void *. Not sure that | ||
104 | * casting is the right thing, but 32-bit UML can't have 64-bit virtual | ||
105 | * addresses | ||
106 | */ | ||
107 | #define __pa(virt) to_phys((void *) (unsigned long) virt) | ||
102 | #define __va(phys) to_virt((unsigned long) phys) | 108 | #define __va(phys) to_virt((unsigned long) phys) |
103 | 109 | ||
104 | #define page_to_pfn(page) ((page) - mem_map) | 110 | #define page_to_pfn(page) ((page) - mem_map) |
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index 510e513c7f88..a88040920311 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h | |||
@@ -114,17 +114,9 @@ extern unsigned long end_iomem; | |||
114 | extern unsigned long pg0[1024]; | 114 | extern unsigned long pg0[1024]; |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * BAD_PAGETABLE is used when we need a bogus page-table, while | ||
118 | * BAD_PAGE is used for a bogus page. | ||
119 | * | ||
120 | * ZERO_PAGE is a global shared page that is always zero: used | 117 | * ZERO_PAGE is a global shared page that is always zero: used |
121 | * for zero-mapped memory areas etc.. | 118 | * for zero-mapped memory areas etc.. |
122 | */ | 119 | */ |
123 | extern pte_t __bad_page(void); | ||
124 | extern pte_t * __bad_pagetable(void); | ||
125 | |||
126 | #define BAD_PAGETABLE __bad_pagetable() | ||
127 | #define BAD_PAGE __bad_page() | ||
128 | 120 | ||
129 | #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) | 121 | #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) |
130 | 122 | ||
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h index a10ea155907e..1feaaf148ef1 100644 --- a/include/asm-um/thread_info.h +++ b/include/asm-um/thread_info.h | |||
@@ -41,18 +41,17 @@ struct thread_info { | |||
41 | #define init_thread_info (init_thread_union.thread_info) | 41 | #define init_thread_info (init_thread_union.thread_info) |
42 | #define init_stack (init_thread_union.stack) | 42 | #define init_stack (init_thread_union.stack) |
43 | 43 | ||
44 | #define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) | ||
44 | /* how to get the thread information struct from C */ | 45 | /* how to get the thread information struct from C */ |
45 | static inline struct thread_info *current_thread_info(void) | 46 | static inline struct thread_info *current_thread_info(void) |
46 | { | 47 | { |
47 | struct thread_info *ti; | 48 | struct thread_info *ti; |
48 | unsigned long mask = PAGE_SIZE * | 49 | unsigned long mask = THREAD_SIZE - 1; |
49 | (1 << CONFIG_KERNEL_STACK_ORDER) - 1; | 50 | ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); |
50 | ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); | ||
51 | return ti; | 51 | return ti; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* thread information allocation */ | 54 | /* thread information allocation */ |
55 | #define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) | ||
56 | #define alloc_thread_info(tsk) \ | 55 | #define alloc_thread_info(tsk) \ |
57 | ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL)) | 56 | ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL)) |
58 | #define free_thread_info(ti) kfree(ti) | 57 | #define free_thread_info(ti) kfree(ti) |
@@ -62,7 +61,7 @@ static inline struct thread_info *current_thread_info(void) | |||
62 | 61 | ||
63 | #endif | 62 | #endif |
64 | 63 | ||
65 | #define PREEMPT_ACTIVE 0x4000000 | 64 | #define PREEMPT_ACTIVE 0x10000000 |
66 | 65 | ||
67 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 66 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
68 | #define TIF_SIGPENDING 1 /* signal pending */ | 67 | #define TIF_SIGPENDING 1 /* signal pending */ |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index f21af067d015..927daa86c9b3 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -49,7 +49,7 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); | |||
49 | /* Frequency values here are CPU kHz so that hardware which doesn't run | 49 | /* Frequency values here are CPU kHz so that hardware which doesn't run |
50 | * with some frequencies can complain without having to guess what per | 50 | * with some frequencies can complain without having to guess what per |
51 | * cent / per mille means. | 51 | * cent / per mille means. |
52 | * Maximum transition latency is in microseconds - if it's unknown, | 52 | * Maximum transition latency is in nanoseconds - if it's unknown, |
53 | * CPUFREQ_ETERNAL shall be used. | 53 | * CPUFREQ_ETERNAL shall be used. |
54 | */ | 54 | */ |
55 | 55 | ||
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h new file mode 100644 index 000000000000..0008e2ad0c9f --- /dev/null +++ b/include/linux/dm9000.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* include/linux/dm9000.h | ||
2 | * | ||
3 | * Copyright (c) 2004 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for dm9000 platform data | ||
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 | |||
14 | #ifndef __DM9000_PLATFORM_DATA | ||
15 | #define __DM9000_PLATFORM_DATA __FILE__ | ||
16 | |||
17 | /* IO control flags */ | ||
18 | |||
19 | #define DM9000_PLATF_8BITONLY (0x0001) | ||
20 | #define DM9000_PLATF_16BITONLY (0x0002) | ||
21 | #define DM9000_PLATF_32BITONLY (0x0004) | ||
22 | |||
23 | /* platfrom data for platfrom device structure's platfrom_data field */ | ||
24 | |||
25 | struct dm9000_plat_data { | ||
26 | unsigned int flags; | ||
27 | |||
28 | /* allow replacement IO routines */ | ||
29 | |||
30 | void (*inblk)(void __iomem *reg, void *data, int len); | ||
31 | void (*outblk)(void __iomem *reg, void *data, int len); | ||
32 | void (*dumpblk)(void __iomem *reg, int len); | ||
33 | }; | ||
34 | |||
35 | #endif /* __DM9000_PLATFORM_DATA */ | ||
36 | |||
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 220748b7abea..a1478258d002 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -56,18 +56,32 @@ static inline int is_zero_ether_addr(const u8 *addr) | |||
56 | } | 56 | } |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * is_multicast_ether_addr - Determine if the given Ethernet address is a | ||
60 | * multicast address. | ||
61 | * | ||
62 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
63 | * | ||
64 | * Return true if the address is a multicast address. | ||
65 | */ | ||
66 | static inline int is_multicast_ether_addr(const u8 *addr) | ||
67 | { | ||
68 | return addr[0] & 0x01; | ||
69 | } | ||
70 | |||
71 | /** | ||
59 | * is_valid_ether_addr - Determine if the given Ethernet address is valid | 72 | * is_valid_ether_addr - Determine if the given Ethernet address is valid |
60 | * @addr: Pointer to a six-byte array containing the Ethernet address | 73 | * @addr: Pointer to a six-byte array containing the Ethernet address |
61 | * | 74 | * |
62 | * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not | 75 | * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not |
63 | * a multicast address, and is not FF:FF:FF:FF:FF:FF. The multicast | 76 | * a multicast address, and is not FF:FF:FF:FF:FF:FF. |
64 | * and FF:FF:... tests are combined into the single test "!(addr[0]&1)". | ||
65 | * | 77 | * |
66 | * Return true if the address is valid. | 78 | * Return true if the address is valid. |
67 | */ | 79 | */ |
68 | static inline int is_valid_ether_addr(const u8 *addr) | 80 | static inline int is_valid_ether_addr(const u8 *addr) |
69 | { | 81 | { |
70 | return !(addr[0]&1) && !is_zero_ether_addr(addr); | 82 | /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to |
83 | * explicitly check for it here. */ | ||
84 | return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); | ||
71 | } | 85 | } |
72 | 86 | ||
73 | /** | 87 | /** |
@@ -83,6 +97,6 @@ static inline void random_ether_addr(u8 *addr) | |||
83 | addr [0] &= 0xfe; /* clear multicast bit */ | 97 | addr [0] &= 0xfe; /* clear multicast bit */ |
84 | addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ | 98 | addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ |
85 | } | 99 | } |
86 | #endif | 100 | #endif /* __KERNEL__ */ |
87 | 101 | ||
88 | #endif /* _LINUX_ETHERDEVICE_H */ | 102 | #endif /* _LINUX_ETHERDEVICE_H */ |
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c85b210490ea..a0ab26aab450 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -256,6 +256,7 @@ struct net_device; | |||
256 | u32 ethtool_op_get_link(struct net_device *dev); | 256 | u32 ethtool_op_get_link(struct net_device *dev); |
257 | u32 ethtool_op_get_tx_csum(struct net_device *dev); | 257 | u32 ethtool_op_get_tx_csum(struct net_device *dev); |
258 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); | 258 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); |
259 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data); | ||
259 | u32 ethtool_op_get_sg(struct net_device *dev); | 260 | u32 ethtool_op_get_sg(struct net_device *dev); |
260 | int ethtool_op_set_sg(struct net_device *dev, u32 data); | 261 | int ethtool_op_set_sg(struct net_device *dev, u32 data); |
261 | u32 ethtool_op_get_tso(struct net_device *dev); | 262 | u32 ethtool_op_get_tso(struct net_device *dev); |
diff --git a/include/linux/gameport.h b/include/linux/gameport.h index b1272f822cfa..cd623eccdbea 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h | |||
@@ -67,6 +67,8 @@ int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mo | |||
67 | void gameport_close(struct gameport *gameport); | 67 | void gameport_close(struct gameport *gameport); |
68 | void gameport_rescan(struct gameport *gameport); | 68 | void gameport_rescan(struct gameport *gameport); |
69 | 69 | ||
70 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
71 | |||
70 | void __gameport_register_port(struct gameport *gameport, struct module *owner); | 72 | void __gameport_register_port(struct gameport *gameport, struct module *owner); |
71 | static inline void gameport_register_port(struct gameport *gameport) | 73 | static inline void gameport_register_port(struct gameport *gameport) |
72 | { | 74 | { |
@@ -75,6 +77,29 @@ static inline void gameport_register_port(struct gameport *gameport) | |||
75 | 77 | ||
76 | void gameport_unregister_port(struct gameport *gameport); | 78 | void gameport_unregister_port(struct gameport *gameport); |
77 | 79 | ||
80 | void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) | ||
81 | __attribute__ ((format (printf, 2, 3))); | ||
82 | |||
83 | #else | ||
84 | |||
85 | static inline void gameport_register_port(struct gameport *gameport) | ||
86 | { | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | static inline void gameport_unregister_port(struct gameport *gameport) | ||
91 | { | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | static inline void gameport_set_phys(struct gameport *gameport, | ||
96 | const char *fmt, ...) | ||
97 | { | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | #endif | ||
102 | |||
78 | static inline struct gameport *gameport_allocate_port(void) | 103 | static inline struct gameport *gameport_allocate_port(void) |
79 | { | 104 | { |
80 | struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL); | 105 | struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL); |
@@ -92,9 +117,6 @@ static inline void gameport_set_name(struct gameport *gameport, const char *name | |||
92 | strlcpy(gameport->name, name, sizeof(gameport->name)); | 117 | strlcpy(gameport->name, name, sizeof(gameport->name)); |
93 | } | 118 | } |
94 | 119 | ||
95 | void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) | ||
96 | __attribute__ ((format (printf, 2, 3))); | ||
97 | |||
98 | /* | 120 | /* |
99 | * Use the following fucntions to manipulate gameport's per-port | 121 | * Use the following fucntions to manipulate gameport's per-port |
100 | * driver-specific data. | 122 | * driver-specific data. |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index ebc712e91066..8336dba18971 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -43,13 +43,17 @@ | |||
43 | #define __IRQ_MASK(x) ((1UL << (x))-1) | 43 | #define __IRQ_MASK(x) ((1UL << (x))-1) |
44 | 44 | ||
45 | #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) | 45 | #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) |
46 | #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) | ||
47 | #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | 46 | #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) |
47 | #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) | ||
48 | 48 | ||
49 | #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) | 49 | #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) |
50 | #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) | 50 | #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) |
51 | #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) | 51 | #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) |
52 | 52 | ||
53 | #if PREEMPT_ACTIVE < (1 << (HARDIRQ_SHIFT + HARDIRQ_BITS)) | ||
54 | #error PREEMPT_ACTIVE is too low! | ||
55 | #endif | ||
56 | |||
53 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) | 57 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) |
54 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) | 58 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) |
55 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) | 59 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) |
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h index 503194e62fe1..ed2927ef1ff7 100644 --- a/include/linux/hdlc.h +++ b/include/linux/hdlc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl> | 4 | * Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
@@ -41,6 +41,7 @@ | |||
41 | #define LMI_NONE 1 /* No LMI, all PVCs are static */ | 41 | #define LMI_NONE 1 /* No LMI, all PVCs are static */ |
42 | #define LMI_ANSI 2 /* ANSI Annex D */ | 42 | #define LMI_ANSI 2 /* ANSI Annex D */ |
43 | #define LMI_CCITT 3 /* ITU-T Annex A */ | 43 | #define LMI_CCITT 3 /* ITU-T Annex A */ |
44 | #define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */ | ||
44 | 45 | ||
45 | #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ | 46 | #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ |
46 | #define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ | 47 | #define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ |
@@ -89,6 +90,7 @@ typedef struct pvc_device_struct { | |||
89 | unsigned int deleted: 1; | 90 | unsigned int deleted: 1; |
90 | unsigned int fecn: 1; | 91 | unsigned int fecn: 1; |
91 | unsigned int becn: 1; | 92 | unsigned int becn: 1; |
93 | unsigned int bandwidth; /* Cisco LMI reporting only */ | ||
92 | }state; | 94 | }state; |
93 | }pvc_device; | 95 | }pvc_device; |
94 | 96 | ||
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 0485b256d043..004e6f09a6e2 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h | |||
@@ -23,7 +23,7 @@ struct shaper | |||
23 | __u32 shapeclock; | 23 | __u32 shapeclock; |
24 | unsigned long recovery; /* Time we can next clock a packet out on | 24 | unsigned long recovery; /* Time we can next clock a packet out on |
25 | an empty queue */ | 25 | an empty queue */ |
26 | unsigned long locked; | 26 | struct semaphore sem; |
27 | struct net_device_stats stats; | 27 | struct net_device_stats stats; |
28 | struct net_device *dev; | 28 | struct net_device *dev; |
29 | int (*hard_start_xmit) (struct sk_buff *skb, | 29 | int (*hard_start_xmit) (struct sk_buff *skb, |
@@ -38,7 +38,6 @@ struct shaper | |||
38 | int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); | 38 | int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); |
39 | void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr); | 39 | void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr); |
40 | struct net_device_stats* (*get_stats)(struct net_device *dev); | 40 | struct net_device_stats* (*get_stats)(struct net_device *dev); |
41 | wait_queue_head_t wait_queue; | ||
42 | struct timer_list timer; | 41 | struct timer_list timer; |
43 | }; | 42 | }; |
44 | 43 | ||
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 6fafb27877a7..7e1e15f934f3 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h | |||
@@ -29,6 +29,7 @@ struct ipv4_devconf | |||
29 | int no_xfrm; | 29 | int no_xfrm; |
30 | int no_policy; | 30 | int no_policy; |
31 | int force_igmp_version; | 31 | int force_igmp_version; |
32 | int promote_secondaries; | ||
32 | void *sysctl; | 33 | void *sysctl; |
33 | }; | 34 | }; |
34 | 35 | ||
@@ -71,6 +72,7 @@ struct in_device | |||
71 | #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) | 72 | #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) |
72 | #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) | 73 | #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) |
73 | #define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) | 74 | #define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) |
75 | #define IN_DEV_PROMOTE_SECONDARIES(in_dev) (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries) | ||
74 | 76 | ||
75 | #define IN_DEV_RX_REDIRECTS(in_dev) \ | 77 | #define IN_DEV_RX_REDIRECTS(in_dev) \ |
76 | ((IN_DEV_FORWARD(in_dev) && \ | 78 | ((IN_DEV_FORWARD(in_dev) && \ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 1f7e2039a04e..b009f801e7c5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -410,6 +410,7 @@ extern u8 ata_chk_err(struct ata_port *ap); | |||
410 | extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); | 410 | extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); |
411 | extern int ata_port_start (struct ata_port *ap); | 411 | extern int ata_port_start (struct ata_port *ap); |
412 | extern void ata_port_stop (struct ata_port *ap); | 412 | extern void ata_port_stop (struct ata_port *ap); |
413 | extern void ata_host_stop (struct ata_host_set *host_set); | ||
413 | extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 414 | extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); |
414 | extern void ata_qc_prep(struct ata_queued_cmd *qc); | 415 | extern void ata_qc_prep(struct ata_queued_cmd *qc); |
415 | extern int ata_qc_issue_prot(struct ata_queued_cmd *qc); | 416 | extern int ata_qc_issue_prot(struct ata_queued_cmd *qc); |
@@ -466,12 +467,34 @@ static inline u8 ata_chk_status(struct ata_port *ap) | |||
466 | return ap->ops->check_status(ap); | 467 | return ap->ops->check_status(ap); |
467 | } | 468 | } |
468 | 469 | ||
470 | |||
471 | /** | ||
472 | * ata_pause - Flush writes and pause 400 nanoseconds. | ||
473 | * @ap: Port to wait for. | ||
474 | * | ||
475 | * LOCKING: | ||
476 | * Inherited from caller. | ||
477 | */ | ||
478 | |||
469 | static inline void ata_pause(struct ata_port *ap) | 479 | static inline void ata_pause(struct ata_port *ap) |
470 | { | 480 | { |
471 | ata_altstatus(ap); | 481 | ata_altstatus(ap); |
472 | ndelay(400); | 482 | ndelay(400); |
473 | } | 483 | } |
474 | 484 | ||
485 | |||
486 | /** | ||
487 | * ata_busy_wait - Wait for a port status register | ||
488 | * @ap: Port to wait for. | ||
489 | * | ||
490 | * Waits up to max*10 microseconds for the selected bits in the port's | ||
491 | * status register to be cleared. | ||
492 | * Returns final value of status register. | ||
493 | * | ||
494 | * LOCKING: | ||
495 | * Inherited from caller. | ||
496 | */ | ||
497 | |||
475 | static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, | 498 | static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, |
476 | unsigned int max) | 499 | unsigned int max) |
477 | { | 500 | { |
@@ -486,6 +509,18 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, | |||
486 | return status; | 509 | return status; |
487 | } | 510 | } |
488 | 511 | ||
512 | |||
513 | /** | ||
514 | * ata_wait_idle - Wait for a port to be idle. | ||
515 | * @ap: Port to wait for. | ||
516 | * | ||
517 | * Waits up to 10ms for port's BUSY and DRQ signals to clear. | ||
518 | * Returns final value of status register. | ||
519 | * | ||
520 | * LOCKING: | ||
521 | * Inherited from caller. | ||
522 | */ | ||
523 | |||
489 | static inline u8 ata_wait_idle(struct ata_port *ap) | 524 | static inline u8 ata_wait_idle(struct ata_port *ap) |
490 | { | 525 | { |
491 | u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); | 526 | u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); |
@@ -524,6 +559,18 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns | |||
524 | tf->device = ATA_DEVICE_OBS | ATA_DEV1; | 559 | tf->device = ATA_DEVICE_OBS | ATA_DEV1; |
525 | } | 560 | } |
526 | 561 | ||
562 | |||
563 | /** | ||
564 | * ata_irq_on - Enable interrupts on a port. | ||
565 | * @ap: Port on which interrupts are enabled. | ||
566 | * | ||
567 | * Enable interrupts on a legacy IDE device using MMIO or PIO, | ||
568 | * wait for idle, clear any pending interrupts. | ||
569 | * | ||
570 | * LOCKING: | ||
571 | * Inherited from caller. | ||
572 | */ | ||
573 | |||
527 | static inline u8 ata_irq_on(struct ata_port *ap) | 574 | static inline u8 ata_irq_on(struct ata_port *ap) |
528 | { | 575 | { |
529 | struct ata_ioports *ioaddr = &ap->ioaddr; | 576 | struct ata_ioports *ioaddr = &ap->ioaddr; |
@@ -543,6 +590,18 @@ static inline u8 ata_irq_on(struct ata_port *ap) | |||
543 | return tmp; | 590 | return tmp; |
544 | } | 591 | } |
545 | 592 | ||
593 | |||
594 | /** | ||
595 | * ata_irq_ack - Acknowledge a device interrupt. | ||
596 | * @ap: Port on which interrupts are enabled. | ||
597 | * | ||
598 | * Wait up to 10 ms for legacy IDE device to become idle (BUSY | ||
599 | * or BUSY+DRQ clear). Obtain dma status and port status from | ||
600 | * device. Clear the interrupt. Return port status. | ||
601 | * | ||
602 | * LOCKING: | ||
603 | */ | ||
604 | |||
546 | static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) | 605 | static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) |
547 | { | 606 | { |
548 | unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; | 607 | unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b25bd02720d3..ba5d1236aa17 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -204,7 +204,7 @@ struct hh_cache | |||
204 | /* cached hardware header; allow for machine alignment needs. */ | 204 | /* cached hardware header; allow for machine alignment needs. */ |
205 | #define HH_DATA_MOD 16 | 205 | #define HH_DATA_MOD 16 |
206 | #define HH_DATA_OFF(__len) \ | 206 | #define HH_DATA_OFF(__len) \ |
207 | (HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1))) | 207 | (HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1)) |
208 | #define HH_DATA_ALIGN(__len) \ | 208 | #define HH_DATA_ALIGN(__len) \ |
209 | (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1)) | 209 | (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1)) |
210 | unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]; | 210 | unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]; |
@@ -401,7 +401,7 @@ struct net_device | |||
401 | } reg_state; | 401 | } reg_state; |
402 | 402 | ||
403 | /* Net device features */ | 403 | /* Net device features */ |
404 | int features; | 404 | unsigned long features; |
405 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ | 405 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ |
406 | #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ | 406 | #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ |
407 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ | 407 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ |
@@ -913,6 +913,7 @@ extern void dev_mc_discard(struct net_device *dev); | |||
913 | extern void dev_set_promiscuity(struct net_device *dev, int inc); | 913 | extern void dev_set_promiscuity(struct net_device *dev, int inc); |
914 | extern void dev_set_allmulti(struct net_device *dev, int inc); | 914 | extern void dev_set_allmulti(struct net_device *dev, int inc); |
915 | extern void netdev_state_change(struct net_device *dev); | 915 | extern void netdev_state_change(struct net_device *dev); |
916 | extern void netdev_features_change(struct net_device *dev); | ||
916 | /* Load a device via the kmod */ | 917 | /* Load a device via the kmod */ |
917 | extern void dev_load(const char *name); | 918 | extern void dev_load(const char *name); |
918 | extern void dev_mcast_init(void); | 919 | extern void dev_mcast_init(void); |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 9303a003e9ab..5937dd6053c3 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -56,6 +56,7 @@ extern int notifier_call_chain(struct notifier_block **n, unsigned long val, voi | |||
56 | #define NETDEV_CHANGEADDR 0x0008 | 56 | #define NETDEV_CHANGEADDR 0x0008 |
57 | #define NETDEV_GOING_DOWN 0x0009 | 57 | #define NETDEV_GOING_DOWN 0x0009 |
58 | #define NETDEV_CHANGENAME 0x000A | 58 | #define NETDEV_CHANGENAME 0x000A |
59 | #define NETDEV_FEAT_CHANGE 0x000B | ||
59 | 60 | ||
60 | #define SYS_DOWN 0x0001 /* Notify of system down */ | 61 | #define SYS_DOWN 0x0001 /* Notify of system down */ |
61 | #define SYS_RESTART SYS_DOWN | 62 | #define SYS_RESTART SYS_DOWN |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7ccbc2e4272c..b0d6134e1ee6 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -1230,6 +1230,12 @@ | |||
1230 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 | 1230 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 |
1231 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 | 1231 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 |
1232 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B | 1232 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B |
1233 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 | ||
1234 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 | ||
1235 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 | ||
1236 | #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 | ||
1237 | #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 | ||
1238 | #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B | ||
1233 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 | 1239 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 |
1234 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 | 1240 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 |
1235 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 | 1241 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 772998147e3e..23032d9d6071 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -399,6 +399,7 @@ enum | |||
399 | NET_IPV4_CONF_FORCE_IGMP_VERSION=17, | 399 | NET_IPV4_CONF_FORCE_IGMP_VERSION=17, |
400 | NET_IPV4_CONF_ARP_ANNOUNCE=18, | 400 | NET_IPV4_CONF_ARP_ANNOUNCE=18, |
401 | NET_IPV4_CONF_ARP_IGNORE=19, | 401 | NET_IPV4_CONF_ARP_IGNORE=19, |
402 | NET_IPV4_CONF_PROMOTE_SECONDARIES=20, | ||
402 | __NET_IPV4_CONF_MAX | 403 | __NET_IPV4_CONF_MAX |
403 | }; | 404 | }; |
404 | 405 | ||
diff --git a/include/linux/usb.h b/include/linux/usb.h index 41d1a644c9d4..2d1ac5058534 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -796,6 +796,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); | |||
796 | * of the iso_frame_desc array, and the number of errors is reported in | 796 | * of the iso_frame_desc array, and the number of errors is reported in |
797 | * error_count. Completion callbacks for ISO transfers will normally | 797 | * error_count. Completion callbacks for ISO transfers will normally |
798 | * (re)submit URBs to ensure a constant transfer rate. | 798 | * (re)submit URBs to ensure a constant transfer rate. |
799 | * | ||
800 | * Note that even fields marked "public" should not be touched by the driver | ||
801 | * when the urb is owned by the hcd, that is, since the call to | ||
802 | * usb_submit_urb() till the entry into the completion routine. | ||
799 | */ | 803 | */ |
800 | struct urb | 804 | struct urb |
801 | { | 805 | { |
@@ -803,12 +807,12 @@ struct urb | |||
803 | struct kref kref; /* reference count of the URB */ | 807 | struct kref kref; /* reference count of the URB */ |
804 | spinlock_t lock; /* lock for the URB */ | 808 | spinlock_t lock; /* lock for the URB */ |
805 | void *hcpriv; /* private data for host controller */ | 809 | void *hcpriv; /* private data for host controller */ |
806 | struct list_head urb_list; /* list pointer to all active urbs */ | ||
807 | int bandwidth; /* bandwidth for INT/ISO request */ | 810 | int bandwidth; /* bandwidth for INT/ISO request */ |
808 | atomic_t use_count; /* concurrent submissions counter */ | 811 | atomic_t use_count; /* concurrent submissions counter */ |
809 | u8 reject; /* submissions will fail */ | 812 | u8 reject; /* submissions will fail */ |
810 | 813 | ||
811 | /* public, documented fields in the urb that can be used by drivers */ | 814 | /* public, documented fields in the urb that can be used by drivers */ |
815 | struct list_head urb_list; /* list head for use by the urb owner */ | ||
812 | struct usb_device *dev; /* (in) pointer to associated device */ | 816 | struct usb_device *dev; /* (in) pointer to associated device */ |
813 | unsigned int pipe; /* (in) pipe information */ | 817 | unsigned int pipe; /* (in) pipe information */ |
814 | int status; /* (return) non-ISO status */ | 818 | int status; /* (return) non-ISO status */ |
diff --git a/include/net/route.h b/include/net/route.h index efe92b239ef1..d34ca8fc6756 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -181,9 +181,6 @@ static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport, | |||
181 | memcpy(&fl, &(*rp)->fl, sizeof(fl)); | 181 | memcpy(&fl, &(*rp)->fl, sizeof(fl)); |
182 | fl.fl_ip_sport = sport; | 182 | fl.fl_ip_sport = sport; |
183 | fl.fl_ip_dport = dport; | 183 | fl.fl_ip_dport = dport; |
184 | #if defined(CONFIG_IP_ROUTE_MULTIPATH_CACHED) | ||
185 | fl.flags |= FLOWI_FLAG_MULTIPATHOLDROUTE; | ||
186 | #endif | ||
187 | ip_rt_put(*rp); | 184 | ip_rt_put(*rp); |
188 | *rp = NULL; | 185 | *rp = NULL; |
189 | return ip_route_output_flow(rp, &fl, sk, 0); | 186 | return ip_route_output_flow(rp, &fl, sk, 0); |
diff --git a/init/Kconfig b/init/Kconfig index d920baed109a..a7660ccc693f 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -442,7 +442,7 @@ config OBSOLETE_MODPARM | |||
442 | 442 | ||
443 | config MODVERSIONS | 443 | config MODVERSIONS |
444 | bool "Module versioning support (EXPERIMENTAL)" | 444 | bool "Module versioning support (EXPERIMENTAL)" |
445 | depends on MODULES && EXPERIMENTAL && !UML | 445 | depends on MODULES && EXPERIMENTAL |
446 | help | 446 | help |
447 | Usually, you have to use modules compiled with your kernel. | 447 | Usually, you have to use modules compiled with your kernel. |
448 | Saying Y here makes it sometimes possible to use modules | 448 | Saying Y here makes it sometimes possible to use modules |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 06b5a6323998..436c7d93c00a 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -119,8 +119,6 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
119 | */ | 119 | */ |
120 | desc->handler->ack(irq); | 120 | desc->handler->ack(irq); |
121 | action_ret = handle_IRQ_event(irq, regs, desc->action); | 121 | action_ret = handle_IRQ_event(irq, regs, desc->action); |
122 | if (!noirqdebug) | ||
123 | note_interrupt(irq, desc, action_ret); | ||
124 | desc->handler->end(irq); | 122 | desc->handler->end(irq); |
125 | return 1; | 123 | return 1; |
126 | } | 124 | } |
diff --git a/kernel/module.c b/kernel/module.c index 5734ab09d3f9..83b3d376708c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1758,6 +1758,7 @@ sys_init_module(void __user *umod, | |||
1758 | const char __user *uargs) | 1758 | const char __user *uargs) |
1759 | { | 1759 | { |
1760 | struct module *mod; | 1760 | struct module *mod; |
1761 | mm_segment_t old_fs = get_fs(); | ||
1761 | int ret = 0; | 1762 | int ret = 0; |
1762 | 1763 | ||
1763 | /* Must have permission */ | 1764 | /* Must have permission */ |
@@ -1775,6 +1776,9 @@ sys_init_module(void __user *umod, | |||
1775 | return PTR_ERR(mod); | 1776 | return PTR_ERR(mod); |
1776 | } | 1777 | } |
1777 | 1778 | ||
1779 | /* flush the icache in correct context */ | ||
1780 | set_fs(KERNEL_DS); | ||
1781 | |||
1778 | /* Flush the instruction cache, since we've played with text */ | 1782 | /* Flush the instruction cache, since we've played with text */ |
1779 | if (mod->module_init) | 1783 | if (mod->module_init) |
1780 | flush_icache_range((unsigned long)mod->module_init, | 1784 | flush_icache_range((unsigned long)mod->module_init, |
@@ -1783,6 +1787,8 @@ sys_init_module(void __user *umod, | |||
1783 | flush_icache_range((unsigned long)mod->module_core, | 1787 | flush_icache_range((unsigned long)mod->module_core, |
1784 | (unsigned long)mod->module_core + mod->core_size); | 1788 | (unsigned long)mod->module_core + mod->core_size); |
1785 | 1789 | ||
1790 | set_fs(old_fs); | ||
1791 | |||
1786 | /* Now sew it into the lists. They won't access us, since | 1792 | /* Now sew it into the lists. They won't access us, since |
1787 | strong_try_module_get() will fail. */ | 1793 | strong_try_module_get() will fail. */ |
1788 | stop_machine_run(__link_module, mod, NR_CPUS); | 1794 | stop_machine_run(__link_module, mod, NR_CPUS); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ac23847ce0e3..0c421295e613 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -151,7 +151,8 @@ config DEBUG_FS | |||
151 | 151 | ||
152 | config FRAME_POINTER | 152 | config FRAME_POINTER |
153 | bool "Compile the kernel with frame pointers" | 153 | bool "Compile the kernel with frame pointers" |
154 | depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV) | 154 | depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV || UML) |
155 | default y if DEBUG_INFO && UML | ||
155 | help | 156 | help |
156 | If you say Y here the resulting kernel image will be slightly larger | 157 | If you say Y here the resulting kernel image will be slightly larger |
157 | and slower, but it will give very useful debugging information. | 158 | and slower, but it will give very useful debugging information. |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index d9b72fde433c..f564ee99782d 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -21,10 +21,7 @@ | |||
21 | 21 | ||
22 | static struct net_device_stats *br_dev_get_stats(struct net_device *dev) | 22 | static struct net_device_stats *br_dev_get_stats(struct net_device *dev) |
23 | { | 23 | { |
24 | struct net_bridge *br; | 24 | struct net_bridge *br = netdev_priv(dev); |
25 | |||
26 | br = dev->priv; | ||
27 | |||
28 | return &br->statistics; | 25 | return &br->statistics; |
29 | } | 26 | } |
30 | 27 | ||
@@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
54 | 51 | ||
55 | static int br_dev_open(struct net_device *dev) | 52 | static int br_dev_open(struct net_device *dev) |
56 | { | 53 | { |
57 | netif_start_queue(dev); | 54 | struct net_bridge *br = netdev_priv(dev); |
58 | 55 | ||
59 | br_stp_enable_bridge(dev->priv); | 56 | br_features_recompute(br); |
57 | netif_start_queue(dev); | ||
58 | br_stp_enable_bridge(br); | ||
60 | 59 | ||
61 | return 0; | 60 | return 0; |
62 | } | 61 | } |
@@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(struct net_device *dev) | |||
67 | 66 | ||
68 | static int br_dev_stop(struct net_device *dev) | 67 | static int br_dev_stop(struct net_device *dev) |
69 | { | 68 | { |
70 | br_stp_disable_bridge(dev->priv); | 69 | br_stp_disable_bridge(netdev_priv(dev)); |
71 | 70 | ||
72 | netif_stop_queue(dev); | 71 | netif_stop_queue(dev); |
73 | 72 | ||
@@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device *dev) | |||
76 | 75 | ||
77 | static int br_change_mtu(struct net_device *dev, int new_mtu) | 76 | static int br_change_mtu(struct net_device *dev, int new_mtu) |
78 | { | 77 | { |
79 | if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv)) | 78 | if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev))) |
80 | return -EINVAL; | 79 | return -EINVAL; |
81 | 80 | ||
82 | dev->mtu = new_mtu; | 81 | dev->mtu = new_mtu; |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 69872bf3b87e..91bb895375f4 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *br) | |||
314 | return mtu; | 314 | return mtu; |
315 | } | 315 | } |
316 | 316 | ||
317 | /* | ||
318 | * Recomputes features using slave's features | ||
319 | */ | ||
320 | void br_features_recompute(struct net_bridge *br) | ||
321 | { | ||
322 | struct net_bridge_port *p; | ||
323 | unsigned long features, checksum; | ||
324 | |||
325 | features = NETIF_F_SG | NETIF_F_FRAGLIST | ||
326 | | NETIF_F_HIGHDMA | NETIF_F_TSO; | ||
327 | checksum = NETIF_F_IP_CSUM; /* least commmon subset */ | ||
328 | |||
329 | list_for_each_entry(p, &br->port_list, list) { | ||
330 | if (!(p->dev->features | ||
331 | & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM))) | ||
332 | checksum = 0; | ||
333 | features &= p->dev->features; | ||
334 | } | ||
335 | |||
336 | br->dev->features = features | checksum | NETIF_F_LLTX; | ||
337 | } | ||
338 | |||
317 | /* called with RTNL */ | 339 | /* called with RTNL */ |
318 | int br_add_if(struct net_bridge *br, struct net_device *dev) | 340 | int br_add_if(struct net_bridge *br, struct net_device *dev) |
319 | { | 341 | { |
@@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
368 | 390 | ||
369 | spin_lock_bh(&br->lock); | 391 | spin_lock_bh(&br->lock); |
370 | br_stp_recalculate_bridge_id(br); | 392 | br_stp_recalculate_bridge_id(br); |
393 | br_features_recompute(br); | ||
371 | spin_unlock_bh(&br->lock); | 394 | spin_unlock_bh(&br->lock); |
372 | 395 | ||
373 | return 0; | 396 | return 0; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 2b1cce46cab4..8f5f2e730992 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -26,7 +26,7 @@ static int br_pass_frame_up_finish(struct sk_buff *skb) | |||
26 | #ifdef CONFIG_NETFILTER_DEBUG | 26 | #ifdef CONFIG_NETFILTER_DEBUG |
27 | skb->nf_debug = 0; | 27 | skb->nf_debug = 0; |
28 | #endif | 28 | #endif |
29 | netif_rx(skb); | 29 | netif_receive_skb(skb); |
30 | 30 | ||
31 | return 0; | 31 | return 0; |
32 | } | 32 | } |
@@ -54,6 +54,9 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
54 | struct net_bridge_fdb_entry *dst; | 54 | struct net_bridge_fdb_entry *dst; |
55 | int passedup = 0; | 55 | int passedup = 0; |
56 | 56 | ||
57 | /* insert into forwarding database after filtering to avoid spoofing */ | ||
58 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | ||
59 | |||
57 | if (br->dev->flags & IFF_PROMISC) { | 60 | if (br->dev->flags & IFF_PROMISC) { |
58 | struct sk_buff *skb2; | 61 | struct sk_buff *skb2; |
59 | 62 | ||
@@ -108,8 +111,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb) | |||
108 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) | 111 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) |
109 | goto err; | 112 | goto err; |
110 | 113 | ||
111 | if (p->state == BR_STATE_LEARNING || | 114 | if (p->state == BR_STATE_LEARNING) |
112 | p->state == BR_STATE_FORWARDING) | ||
113 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | 115 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); |
114 | 116 | ||
115 | if (p->br->stp_enabled && | 117 | if (p->br->stp_enabled && |
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index f8fb49e34764..917311c6828b 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -65,6 +65,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
65 | } | 65 | } |
66 | break; | 66 | break; |
67 | 67 | ||
68 | case NETDEV_FEAT_CHANGE: | ||
69 | if (br->dev->flags & IFF_UP) | ||
70 | br_features_recompute(br); | ||
71 | |||
72 | /* could do recursive feature change notification | ||
73 | * but who would care?? | ||
74 | */ | ||
75 | break; | ||
76 | |||
68 | case NETDEV_DOWN: | 77 | case NETDEV_DOWN: |
69 | if (br->dev->flags & IFF_UP) | 78 | if (br->dev->flags & IFF_UP) |
70 | br_stp_disable_port(p); | 79 | br_stp_disable_port(p); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 54d63f1372a0..bdf95a74d8cd 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *br, | |||
174 | extern int br_del_if(struct net_bridge *br, | 174 | extern int br_del_if(struct net_bridge *br, |
175 | struct net_device *dev); | 175 | struct net_device *dev); |
176 | extern int br_min_mtu(const struct net_bridge *br); | 176 | extern int br_min_mtu(const struct net_bridge *br); |
177 | extern void br_features_recompute(struct net_bridge *br); | ||
177 | 178 | ||
178 | /* br_input.c */ | 179 | /* br_input.c */ |
179 | extern int br_handle_frame_finish(struct sk_buff *skb); | 180 | extern int br_handle_frame_finish(struct sk_buff *skb); |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index b91a875aca01..d071f1c9ad0b 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -140,6 +140,9 @@ int br_stp_handle_bpdu(struct sk_buff *skb) | |||
140 | struct net_bridge *br = p->br; | 140 | struct net_bridge *br = p->br; |
141 | unsigned char *buf; | 141 | unsigned char *buf; |
142 | 142 | ||
143 | /* insert into forwarding database after filtering to avoid spoofing */ | ||
144 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | ||
145 | |||
143 | /* need at least the 802 and STP headers */ | 146 | /* need at least the 802 and STP headers */ |
144 | if (!pskb_may_pull(skb, sizeof(header)+1) || | 147 | if (!pskb_may_pull(skb, sizeof(header)+1) || |
145 | memcmp(skb->data, header, sizeof(header))) | 148 | memcmp(skb->data, header, sizeof(header))) |
diff --git a/net/core/dev.c b/net/core/dev.c index d4d9e2680adb..f15a3ffff635 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -761,6 +761,18 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
761 | } | 761 | } |
762 | 762 | ||
763 | /** | 763 | /** |
764 | * netdev_features_change - device changes fatures | ||
765 | * @dev: device to cause notification | ||
766 | * | ||
767 | * Called to indicate a device has changed features. | ||
768 | */ | ||
769 | void netdev_features_change(struct net_device *dev) | ||
770 | { | ||
771 | notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); | ||
772 | } | ||
773 | EXPORT_SYMBOL(netdev_features_change); | ||
774 | |||
775 | /** | ||
764 | * netdev_state_change - device changes state | 776 | * netdev_state_change - device changes state |
765 | * @dev: device to cause notification | 777 | * @dev: device to cause notification |
766 | * | 778 | * |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f05fde97c43d..8ec484894d68 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -29,7 +29,7 @@ u32 ethtool_op_get_link(struct net_device *dev) | |||
29 | 29 | ||
30 | u32 ethtool_op_get_tx_csum(struct net_device *dev) | 30 | u32 ethtool_op_get_tx_csum(struct net_device *dev) |
31 | { | 31 | { |
32 | return (dev->features & NETIF_F_IP_CSUM) != 0; | 32 | return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | 35 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) |
@@ -42,6 +42,15 @@ int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | |||
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) | ||
46 | { | ||
47 | if (data) | ||
48 | dev->features |= NETIF_F_HW_CSUM; | ||
49 | else | ||
50 | dev->features &= ~NETIF_F_HW_CSUM; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
45 | u32 ethtool_op_get_sg(struct net_device *dev) | 54 | u32 ethtool_op_get_sg(struct net_device *dev) |
46 | { | 55 | { |
47 | return (dev->features & NETIF_F_SG) != 0; | 56 | return (dev->features & NETIF_F_SG) != 0; |
@@ -682,6 +691,7 @@ int dev_ethtool(struct ifreq *ifr) | |||
682 | void __user *useraddr = ifr->ifr_data; | 691 | void __user *useraddr = ifr->ifr_data; |
683 | u32 ethcmd; | 692 | u32 ethcmd; |
684 | int rc; | 693 | int rc; |
694 | unsigned long old_features; | ||
685 | 695 | ||
686 | /* | 696 | /* |
687 | * XXX: This can be pushed down into the ethtool_* handlers that | 697 | * XXX: This can be pushed down into the ethtool_* handlers that |
@@ -703,6 +713,8 @@ int dev_ethtool(struct ifreq *ifr) | |||
703 | if ((rc = dev->ethtool_ops->begin(dev)) < 0) | 713 | if ((rc = dev->ethtool_ops->begin(dev)) < 0) |
704 | return rc; | 714 | return rc; |
705 | 715 | ||
716 | old_features = dev->features; | ||
717 | |||
706 | switch (ethcmd) { | 718 | switch (ethcmd) { |
707 | case ETHTOOL_GSET: | 719 | case ETHTOOL_GSET: |
708 | rc = ethtool_get_settings(dev, useraddr); | 720 | rc = ethtool_get_settings(dev, useraddr); |
@@ -712,7 +724,6 @@ int dev_ethtool(struct ifreq *ifr) | |||
712 | break; | 724 | break; |
713 | case ETHTOOL_GDRVINFO: | 725 | case ETHTOOL_GDRVINFO: |
714 | rc = ethtool_get_drvinfo(dev, useraddr); | 726 | rc = ethtool_get_drvinfo(dev, useraddr); |
715 | |||
716 | break; | 727 | break; |
717 | case ETHTOOL_GREGS: | 728 | case ETHTOOL_GREGS: |
718 | rc = ethtool_get_regs(dev, useraddr); | 729 | rc = ethtool_get_regs(dev, useraddr); |
@@ -801,6 +812,10 @@ int dev_ethtool(struct ifreq *ifr) | |||
801 | 812 | ||
802 | if(dev->ethtool_ops->complete) | 813 | if(dev->ethtool_ops->complete) |
803 | dev->ethtool_ops->complete(dev); | 814 | dev->ethtool_ops->complete(dev); |
815 | |||
816 | if (old_features != dev->features) | ||
817 | netdev_features_change(dev); | ||
818 | |||
804 | return rc; | 819 | return rc; |
805 | 820 | ||
806 | ioctl: | 821 | ioctl: |
@@ -817,3 +832,4 @@ EXPORT_SYMBOL(ethtool_op_get_tx_csum); | |||
817 | EXPORT_SYMBOL(ethtool_op_set_sg); | 832 | EXPORT_SYMBOL(ethtool_op_set_sg); |
818 | EXPORT_SYMBOL(ethtool_op_set_tso); | 833 | EXPORT_SYMBOL(ethtool_op_set_tso); |
819 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); | 834 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); |
835 | EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); | ||
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 060f703659e8..910eb4c05a47 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #define to_net_dev(class) container_of(class, struct net_device, class_dev) | 21 | #define to_net_dev(class) container_of(class, struct net_device, class_dev) |
22 | 22 | ||
23 | static const char fmt_hex[] = "%#x\n"; | 23 | static const char fmt_hex[] = "%#x\n"; |
24 | static const char fmt_long_hex[] = "%#lx\n"; | ||
24 | static const char fmt_dec[] = "%d\n"; | 25 | static const char fmt_dec[] = "%d\n"; |
25 | static const char fmt_ulong[] = "%lu\n"; | 26 | static const char fmt_ulong[] = "%lu\n"; |
26 | 27 | ||
@@ -91,7 +92,7 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \ | |||
91 | NETDEVICE_ATTR(addr_len, fmt_dec); | 92 | NETDEVICE_ATTR(addr_len, fmt_dec); |
92 | NETDEVICE_ATTR(iflink, fmt_dec); | 93 | NETDEVICE_ATTR(iflink, fmt_dec); |
93 | NETDEVICE_ATTR(ifindex, fmt_dec); | 94 | NETDEVICE_ATTR(ifindex, fmt_dec); |
94 | NETDEVICE_ATTR(features, fmt_hex); | 95 | NETDEVICE_ATTR(features, fmt_long_hex); |
95 | NETDEVICE_ATTR(type, fmt_dec); | 96 | NETDEVICE_ATTR(type, fmt_dec); |
96 | 97 | ||
97 | /* use same locking rules as GIFHWADDR ioctl's */ | 98 | /* use same locking rules as GIFHWADDR ioctl's */ |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 3cc96730c4ed..478a30179a52 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -233,11 +233,14 @@ int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b) | |||
233 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 233 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, |
234 | int destroy) | 234 | int destroy) |
235 | { | 235 | { |
236 | struct in_ifaddr *promote = NULL; | ||
236 | struct in_ifaddr *ifa1 = *ifap; | 237 | struct in_ifaddr *ifa1 = *ifap; |
237 | 238 | ||
238 | ASSERT_RTNL(); | 239 | ASSERT_RTNL(); |
239 | 240 | ||
240 | /* 1. Deleting primary ifaddr forces deletion all secondaries */ | 241 | /* 1. Deleting primary ifaddr forces deletion all secondaries |
242 | * unless alias promotion is set | ||
243 | **/ | ||
241 | 244 | ||
242 | if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { | 245 | if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { |
243 | struct in_ifaddr *ifa; | 246 | struct in_ifaddr *ifa; |
@@ -251,11 +254,16 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
251 | continue; | 254 | continue; |
252 | } | 255 | } |
253 | 256 | ||
254 | *ifap1 = ifa->ifa_next; | 257 | if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) { |
258 | *ifap1 = ifa->ifa_next; | ||
255 | 259 | ||
256 | rtmsg_ifa(RTM_DELADDR, ifa); | 260 | rtmsg_ifa(RTM_DELADDR, ifa); |
257 | notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); | 261 | notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); |
258 | inet_free_ifa(ifa); | 262 | inet_free_ifa(ifa); |
263 | } else { | ||
264 | promote = ifa; | ||
265 | break; | ||
266 | } | ||
259 | } | 267 | } |
260 | } | 268 | } |
261 | 269 | ||
@@ -281,6 +289,13 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
281 | if (!in_dev->ifa_list) | 289 | if (!in_dev->ifa_list) |
282 | inetdev_destroy(in_dev); | 290 | inetdev_destroy(in_dev); |
283 | } | 291 | } |
292 | |||
293 | if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) { | ||
294 | /* not sure if we should send a delete notify first? */ | ||
295 | promote->ifa_flags &= ~IFA_F_SECONDARY; | ||
296 | rtmsg_ifa(RTM_NEWADDR, promote); | ||
297 | notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote); | ||
298 | } | ||
284 | } | 299 | } |
285 | 300 | ||
286 | static int inet_insert_ifa(struct in_ifaddr *ifa) | 301 | static int inet_insert_ifa(struct in_ifaddr *ifa) |
@@ -1384,6 +1399,15 @@ static struct devinet_sysctl_table { | |||
1384 | .proc_handler = &ipv4_doint_and_flush, | 1399 | .proc_handler = &ipv4_doint_and_flush, |
1385 | .strategy = &ipv4_doint_and_flush_strategy, | 1400 | .strategy = &ipv4_doint_and_flush_strategy, |
1386 | }, | 1401 | }, |
1402 | { | ||
1403 | .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES, | ||
1404 | .procname = "promote_secondaries", | ||
1405 | .data = &ipv4_devconf.promote_secondaries, | ||
1406 | .maxlen = sizeof(int), | ||
1407 | .mode = 0644, | ||
1408 | .proc_handler = &ipv4_doint_and_flush, | ||
1409 | .strategy = &ipv4_doint_and_flush_strategy, | ||
1410 | }, | ||
1387 | }, | 1411 | }, |
1388 | .devinet_dev = { | 1412 | .devinet_dev = { |
1389 | { | 1413 | { |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 053a883247ba..eae84cc39d3f 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -478,7 +478,7 @@ static int __init esp4_init(void) | |||
478 | { | 478 | { |
479 | struct xfrm_decap_state decap; | 479 | struct xfrm_decap_state decap; |
480 | 480 | ||
481 | if (sizeof(struct esp_decap_data) < | 481 | if (sizeof(struct esp_decap_data) > |
482 | sizeof(decap.decap_data)) { | 482 | sizeof(decap.decap_data)) { |
483 | extern void decap_data_too_small(void); | 483 | extern void decap_data_too_small(void); |
484 | 484 | ||
diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile index a788461a40c9..30e85de9ffff 100644 --- a/net/ipv4/ipvs/Makefile +++ b/net/ipv4/ipvs/Makefile | |||
@@ -11,7 +11,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o | |||
11 | 11 | ||
12 | ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ | 12 | ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ |
13 | ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ | 13 | ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ |
14 | ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o \ | 14 | ip_vs_est.o ip_vs_proto.o \ |
15 | $(ip_vs_proto-objs-y) | 15 | $(ip_vs_proto-objs-y) |
16 | 16 | ||
17 | 17 | ||
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c index 253c46252bd5..867d4e9c6594 100644 --- a/net/ipv4/ipvs/ip_vs_proto.c +++ b/net/ipv4/ipvs/ip_vs_proto.c | |||
@@ -216,9 +216,6 @@ int ip_vs_protocol_init(void) | |||
216 | #ifdef CONFIG_IP_VS_PROTO_UDP | 216 | #ifdef CONFIG_IP_VS_PROTO_UDP |
217 | REGISTER_PROTOCOL(&ip_vs_protocol_udp); | 217 | REGISTER_PROTOCOL(&ip_vs_protocol_udp); |
218 | #endif | 218 | #endif |
219 | #ifdef CONFIG_IP_VS_PROTO_ICMP | ||
220 | REGISTER_PROTOCOL(&ip_vs_protocol_icmp); | ||
221 | #endif | ||
222 | #ifdef CONFIG_IP_VS_PROTO_AH | 219 | #ifdef CONFIG_IP_VS_PROTO_AH |
223 | REGISTER_PROTOCOL(&ip_vs_protocol_ah); | 220 | REGISTER_PROTOCOL(&ip_vs_protocol_ah); |
224 | #endif | 221 | #endif |
diff --git a/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c deleted file mode 100644 index 191e94aa1c1f..000000000000 --- a/net/ipv4/ipvs/ip_vs_proto_icmp.c +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | /* | ||
2 | * ip_vs_proto_icmp.c: ICMP load balancing support for IP Virtual Server | ||
3 | * | ||
4 | * Authors: Julian Anastasov <ja@ssi.bg>, March 2002 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation; | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/icmp.h> | ||
15 | #include <linux/netfilter.h> | ||
16 | #include <linux/netfilter_ipv4.h> | ||
17 | |||
18 | #include <net/ip_vs.h> | ||
19 | |||
20 | |||
21 | static int icmp_timeouts[1] = { 1*60*HZ }; | ||
22 | |||
23 | static char * icmp_state_name_table[1] = { "ICMP" }; | ||
24 | |||
25 | static struct ip_vs_conn * | ||
26 | icmp_conn_in_get(const struct sk_buff *skb, | ||
27 | struct ip_vs_protocol *pp, | ||
28 | const struct iphdr *iph, | ||
29 | unsigned int proto_off, | ||
30 | int inverse) | ||
31 | { | ||
32 | #if 0 | ||
33 | struct ip_vs_conn *cp; | ||
34 | |||
35 | if (likely(!inverse)) { | ||
36 | cp = ip_vs_conn_in_get(iph->protocol, | ||
37 | iph->saddr, 0, | ||
38 | iph->daddr, 0); | ||
39 | } else { | ||
40 | cp = ip_vs_conn_in_get(iph->protocol, | ||
41 | iph->daddr, 0, | ||
42 | iph->saddr, 0); | ||
43 | } | ||
44 | |||
45 | return cp; | ||
46 | |||
47 | #else | ||
48 | return NULL; | ||
49 | #endif | ||
50 | } | ||
51 | |||
52 | static struct ip_vs_conn * | ||
53 | icmp_conn_out_get(const struct sk_buff *skb, | ||
54 | struct ip_vs_protocol *pp, | ||
55 | const struct iphdr *iph, | ||
56 | unsigned int proto_off, | ||
57 | int inverse) | ||
58 | { | ||
59 | #if 0 | ||
60 | struct ip_vs_conn *cp; | ||
61 | |||
62 | if (likely(!inverse)) { | ||
63 | cp = ip_vs_conn_out_get(iph->protocol, | ||
64 | iph->saddr, 0, | ||
65 | iph->daddr, 0); | ||
66 | } else { | ||
67 | cp = ip_vs_conn_out_get(IPPROTO_UDP, | ||
68 | iph->daddr, 0, | ||
69 | iph->saddr, 0); | ||
70 | } | ||
71 | |||
72 | return cp; | ||
73 | #else | ||
74 | return NULL; | ||
75 | #endif | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | icmp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp, | ||
80 | int *verdict, struct ip_vs_conn **cpp) | ||
81 | { | ||
82 | *verdict = NF_ACCEPT; | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int | ||
87 | icmp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) | ||
88 | { | ||
89 | if (!(skb->nh.iph->frag_off & __constant_htons(IP_OFFSET))) { | ||
90 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) { | ||
91 | if (ip_vs_checksum_complete(skb, skb->nh.iph->ihl * 4)) { | ||
92 | IP_VS_DBG_RL_PKT(0, pp, skb, 0, "Failed checksum for"); | ||
93 | return 0; | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | static void | ||
101 | icmp_debug_packet(struct ip_vs_protocol *pp, | ||
102 | const struct sk_buff *skb, | ||
103 | int offset, | ||
104 | const char *msg) | ||
105 | { | ||
106 | char buf[256]; | ||
107 | struct iphdr _iph, *ih; | ||
108 | |||
109 | ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); | ||
110 | if (ih == NULL) | ||
111 | sprintf(buf, "%s TRUNCATED", pp->name); | ||
112 | else if (ih->frag_off & __constant_htons(IP_OFFSET)) | ||
113 | sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag", | ||
114 | pp->name, NIPQUAD(ih->saddr), | ||
115 | NIPQUAD(ih->daddr)); | ||
116 | else { | ||
117 | struct icmphdr _icmph, *ic; | ||
118 | |||
119 | ic = skb_header_pointer(skb, offset + ih->ihl*4, | ||
120 | sizeof(_icmph), &_icmph); | ||
121 | if (ic == NULL) | ||
122 | sprintf(buf, "%s TRUNCATED to %u bytes\n", | ||
123 | pp->name, skb->len - offset); | ||
124 | else | ||
125 | sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u T:%d C:%d", | ||
126 | pp->name, NIPQUAD(ih->saddr), | ||
127 | NIPQUAD(ih->daddr), | ||
128 | ic->type, ic->code); | ||
129 | } | ||
130 | printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf); | ||
131 | } | ||
132 | |||
133 | static int | ||
134 | icmp_state_transition(struct ip_vs_conn *cp, int direction, | ||
135 | const struct sk_buff *skb, | ||
136 | struct ip_vs_protocol *pp) | ||
137 | { | ||
138 | cp->timeout = pp->timeout_table[IP_VS_ICMP_S_NORMAL]; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | static int | ||
143 | icmp_set_state_timeout(struct ip_vs_protocol *pp, char *sname, int to) | ||
144 | { | ||
145 | int num; | ||
146 | char **names; | ||
147 | |||
148 | num = IP_VS_ICMP_S_LAST; | ||
149 | names = icmp_state_name_table; | ||
150 | return ip_vs_set_state_timeout(pp->timeout_table, num, names, sname, to); | ||
151 | } | ||
152 | |||
153 | |||
154 | static void icmp_init(struct ip_vs_protocol *pp) | ||
155 | { | ||
156 | pp->timeout_table = icmp_timeouts; | ||
157 | } | ||
158 | |||
159 | static void icmp_exit(struct ip_vs_protocol *pp) | ||
160 | { | ||
161 | } | ||
162 | |||
163 | struct ip_vs_protocol ip_vs_protocol_icmp = { | ||
164 | .name = "ICMP", | ||
165 | .protocol = IPPROTO_ICMP, | ||
166 | .dont_defrag = 0, | ||
167 | .init = icmp_init, | ||
168 | .exit = icmp_exit, | ||
169 | .conn_schedule = icmp_conn_schedule, | ||
170 | .conn_in_get = icmp_conn_in_get, | ||
171 | .conn_out_get = icmp_conn_out_get, | ||
172 | .snat_handler = NULL, | ||
173 | .dnat_handler = NULL, | ||
174 | .csum_check = icmp_csum_check, | ||
175 | .state_transition = icmp_state_transition, | ||
176 | .register_app = NULL, | ||
177 | .unregister_app = NULL, | ||
178 | .app_conn_bind = NULL, | ||
179 | .debug_packet = icmp_debug_packet, | ||
180 | .timeout_change = NULL, | ||
181 | .set_state_timeout = icmp_set_state_timeout, | ||
182 | }; | ||
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c index 9349686131fc..cf2e6bcf7973 100644 --- a/net/ipv4/multipath_drr.c +++ b/net/ipv4/multipath_drr.c | |||
@@ -57,7 +57,6 @@ struct multipath_device { | |||
57 | 57 | ||
58 | static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES]; | 58 | static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES]; |
59 | static DEFINE_SPINLOCK(state_lock); | 59 | static DEFINE_SPINLOCK(state_lock); |
60 | static struct rtable *last_selection = NULL; | ||
61 | 60 | ||
62 | static int inline __multipath_findslot(void) | 61 | static int inline __multipath_findslot(void) |
63 | { | 62 | { |
@@ -111,11 +110,6 @@ struct notifier_block drr_dev_notifier = { | |||
111 | .notifier_call = drr_dev_event, | 110 | .notifier_call = drr_dev_event, |
112 | }; | 111 | }; |
113 | 112 | ||
114 | static void drr_remove(struct rtable *rt) | ||
115 | { | ||
116 | if (last_selection == rt) | ||
117 | last_selection = NULL; | ||
118 | } | ||
119 | 113 | ||
120 | static void drr_safe_inc(atomic_t *usecount) | 114 | static void drr_safe_inc(atomic_t *usecount) |
121 | { | 115 | { |
@@ -144,14 +138,6 @@ static void drr_select_route(const struct flowi *flp, | |||
144 | int devidx = -1; | 138 | int devidx = -1; |
145 | int cur_min_devidx = -1; | 139 | int cur_min_devidx = -1; |
146 | 140 | ||
147 | /* if necessary and possible utilize the old alternative */ | ||
148 | if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 && | ||
149 | last_selection != NULL) { | ||
150 | result = last_selection; | ||
151 | *rp = result; | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | /* 1. make sure all alt. nexthops have the same GC related data */ | 141 | /* 1. make sure all alt. nexthops have the same GC related data */ |
156 | /* 2. determine the new candidate to be returned */ | 142 | /* 2. determine the new candidate to be returned */ |
157 | result = NULL; | 143 | result = NULL; |
@@ -229,12 +215,10 @@ static void drr_select_route(const struct flowi *flp, | |||
229 | } | 215 | } |
230 | 216 | ||
231 | *rp = result; | 217 | *rp = result; |
232 | last_selection = result; | ||
233 | } | 218 | } |
234 | 219 | ||
235 | static struct ip_mp_alg_ops drr_ops = { | 220 | static struct ip_mp_alg_ops drr_ops = { |
236 | .mp_alg_select_route = drr_select_route, | 221 | .mp_alg_select_route = drr_select_route, |
237 | .mp_alg_remove = drr_remove, | ||
238 | }; | 222 | }; |
239 | 223 | ||
240 | static int __init drr_init(void) | 224 | static int __init drr_init(void) |
@@ -244,7 +228,7 @@ static int __init drr_init(void) | |||
244 | if (err) | 228 | if (err) |
245 | return err; | 229 | return err; |
246 | 230 | ||
247 | err = multipath_alg_register(&drr_ops, IP_MP_ALG_RR); | 231 | err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR); |
248 | if (err) | 232 | if (err) |
249 | goto fail; | 233 | goto fail; |
250 | 234 | ||
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c index 554a82568160..061b6b253982 100644 --- a/net/ipv4/multipath_rr.c +++ b/net/ipv4/multipath_rr.c | |||
@@ -47,29 +47,12 @@ | |||
47 | #include <net/checksum.h> | 47 | #include <net/checksum.h> |
48 | #include <net/ip_mp_alg.h> | 48 | #include <net/ip_mp_alg.h> |
49 | 49 | ||
50 | #define MULTIPATH_MAX_CANDIDATES 40 | ||
51 | |||
52 | static struct rtable* last_used = NULL; | ||
53 | |||
54 | static void rr_remove(struct rtable *rt) | ||
55 | { | ||
56 | if (last_used == rt) | ||
57 | last_used = NULL; | ||
58 | } | ||
59 | |||
60 | static void rr_select_route(const struct flowi *flp, | 50 | static void rr_select_route(const struct flowi *flp, |
61 | struct rtable *first, struct rtable **rp) | 51 | struct rtable *first, struct rtable **rp) |
62 | { | 52 | { |
63 | struct rtable *nh, *result, *min_use_cand = NULL; | 53 | struct rtable *nh, *result, *min_use_cand = NULL; |
64 | int min_use = -1; | 54 | int min_use = -1; |
65 | 55 | ||
66 | /* if necessary and possible utilize the old alternative */ | ||
67 | if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 && | ||
68 | last_used != NULL) { | ||
69 | result = last_used; | ||
70 | goto out; | ||
71 | } | ||
72 | |||
73 | /* 1. make sure all alt. nexthops have the same GC related data | 56 | /* 1. make sure all alt. nexthops have the same GC related data |
74 | * 2. determine the new candidate to be returned | 57 | * 2. determine the new candidate to be returned |
75 | */ | 58 | */ |
@@ -90,15 +73,12 @@ static void rr_select_route(const struct flowi *flp, | |||
90 | if (!result) | 73 | if (!result) |
91 | result = first; | 74 | result = first; |
92 | 75 | ||
93 | out: | ||
94 | last_used = result; | ||
95 | result->u.dst.__use++; | 76 | result->u.dst.__use++; |
96 | *rp = result; | 77 | *rp = result; |
97 | } | 78 | } |
98 | 79 | ||
99 | static struct ip_mp_alg_ops rr_ops = { | 80 | static struct ip_mp_alg_ops rr_ops = { |
100 | .mp_alg_select_route = rr_select_route, | 81 | .mp_alg_select_route = rr_select_route, |
101 | .mp_alg_remove = rr_remove, | ||
102 | }; | 82 | }; |
103 | 83 | ||
104 | static int __init rr_init(void) | 84 | static int __init rr_init(void) |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index e5746b674413..eda1fba431a4 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * communicating with userspace via netlink. | 3 | * communicating with userspace via netlink. |
4 | * | 4 | * |
5 | * (C) 2000-2002 James Morris <jmorris@intercode.com.au> | 5 | * (C) 2000-2002 James Morris <jmorris@intercode.com.au> |
6 | * (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.org> | ||
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 |
@@ -17,6 +18,7 @@ | |||
17 | * 2005-01-10: Added /proc counter for dropped packets; fixed so | 18 | * 2005-01-10: Added /proc counter for dropped packets; fixed so |
18 | * packets aren't delivered to user space if they're going | 19 | * packets aren't delivered to user space if they're going |
19 | * to be dropped. | 20 | * to be dropped. |
21 | * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte) | ||
20 | * | 22 | * |
21 | */ | 23 | */ |
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -71,7 +73,15 @@ static DECLARE_MUTEX(ipqnl_sem); | |||
71 | static void | 73 | static void |
72 | ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) | 74 | ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) |
73 | { | 75 | { |
76 | /* TCP input path (and probably other bits) assume to be called | ||
77 | * from softirq context, not from syscall, like ipq_issue_verdict is | ||
78 | * called. TCP input path deadlocks with locks taken from timer | ||
79 | * softirq, e.g. We therefore emulate this by local_bh_disable() */ | ||
80 | |||
81 | local_bh_disable(); | ||
74 | nf_reinject(entry->skb, entry->info, verdict); | 82 | nf_reinject(entry->skb, entry->info, verdict); |
83 | local_bh_enable(); | ||
84 | |||
75 | kfree(entry); | 85 | kfree(entry); |
76 | } | 86 | } |
77 | 87 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 4a6952e3fee9..7c24e64b443f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
738 | unsigned long amount; | 738 | unsigned long amount; |
739 | 739 | ||
740 | amount = 0; | 740 | amount = 0; |
741 | spin_lock_irq(&sk->sk_receive_queue.lock); | 741 | spin_lock_bh(&sk->sk_receive_queue.lock); |
742 | skb = skb_peek(&sk->sk_receive_queue); | 742 | skb = skb_peek(&sk->sk_receive_queue); |
743 | if (skb != NULL) { | 743 | if (skb != NULL) { |
744 | /* | 744 | /* |
@@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
748 | */ | 748 | */ |
749 | amount = skb->len - sizeof(struct udphdr); | 749 | amount = skb->len - sizeof(struct udphdr); |
750 | } | 750 | } |
751 | spin_unlock_irq(&sk->sk_receive_queue.lock); | 751 | spin_unlock_bh(&sk->sk_receive_queue.lock); |
752 | return put_user(amount, (int __user *)arg); | 752 | return put_user(amount, (int __user *)arg); |
753 | } | 753 | } |
754 | 754 | ||
@@ -848,12 +848,12 @@ csum_copy_err: | |||
848 | /* Clear queue. */ | 848 | /* Clear queue. */ |
849 | if (flags&MSG_PEEK) { | 849 | if (flags&MSG_PEEK) { |
850 | int clear = 0; | 850 | int clear = 0; |
851 | spin_lock_irq(&sk->sk_receive_queue.lock); | 851 | spin_lock_bh(&sk->sk_receive_queue.lock); |
852 | if (skb == skb_peek(&sk->sk_receive_queue)) { | 852 | if (skb == skb_peek(&sk->sk_receive_queue)) { |
853 | __skb_unlink(skb, &sk->sk_receive_queue); | 853 | __skb_unlink(skb, &sk->sk_receive_queue); |
854 | clear = 1; | 854 | clear = 1; |
855 | } | 855 | } |
856 | spin_unlock_irq(&sk->sk_receive_queue.lock); | 856 | spin_unlock_bh(&sk->sk_receive_queue.lock); |
857 | if (clear) | 857 | if (clear) |
858 | kfree_skb(skb); | 858 | kfree_skb(skb); |
859 | } | 859 | } |
@@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
1334 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; | 1334 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; |
1335 | struct sk_buff *skb; | 1335 | struct sk_buff *skb; |
1336 | 1336 | ||
1337 | spin_lock_irq(&rcvq->lock); | 1337 | spin_lock_bh(&rcvq->lock); |
1338 | while ((skb = skb_peek(rcvq)) != NULL) { | 1338 | while ((skb = skb_peek(rcvq)) != NULL) { |
1339 | if (udp_checksum_complete(skb)) { | 1339 | if (udp_checksum_complete(skb)) { |
1340 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); | 1340 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); |
@@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
1345 | break; | 1345 | break; |
1346 | } | 1346 | } |
1347 | } | 1347 | } |
1348 | spin_unlock_irq(&rcvq->lock); | 1348 | spin_unlock_bh(&rcvq->lock); |
1349 | 1349 | ||
1350 | /* nothing to see, move along */ | 1350 | /* nothing to see, move along */ |
1351 | if (skb == NULL) | 1351 | if (skb == NULL) |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index a93f6dc51979..0e5f7499debb 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -535,10 +535,12 @@ release: | |||
535 | if (err) | 535 | if (err) |
536 | goto done; | 536 | goto done; |
537 | 537 | ||
538 | /* Do not check for fault */ | 538 | if (!freq.flr_label) { |
539 | if (!freq.flr_label) | 539 | if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, |
540 | copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, | 540 | &fl->label, sizeof(fl->label))) { |
541 | &fl->label, sizeof(fl->label)); | 541 | /* Intentionally ignore fault. */ |
542 | } | ||
543 | } | ||
542 | 544 | ||
543 | sfl1->fl = fl; | 545 | sfl1->fl = fl; |
544 | sfl1->next = np->ipv6_fl_list; | 546 | sfl1->next = np->ipv6_fl_list; |
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 2f4c91ddc9a3..5ade5a5d1990 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c | |||
@@ -37,5 +37,4 @@ EXPORT_SYMBOL(in6_dev_finish_destroy); | |||
37 | EXPORT_SYMBOL(xfrm6_rcv); | 37 | EXPORT_SYMBOL(xfrm6_rcv); |
38 | #endif | 38 | #endif |
39 | EXPORT_SYMBOL(rt6_lookup); | 39 | EXPORT_SYMBOL(rt6_lookup); |
40 | EXPORT_SYMBOL(fl6_sock_lookup); | ||
41 | EXPORT_SYMBOL(ipv6_push_nfrag_opts); | 40 | EXPORT_SYMBOL(ipv6_push_nfrag_opts); |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 8a3db9d95bab..d8bd2a569c7c 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/byteorder.h> | 18 | #include <asm/byteorder.h> |
19 | 19 | ||
20 | 20 | ||
21 | #if 1 /* control */ | 21 | #if 0 /* control */ |
22 | #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) | 22 | #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) |
23 | #else | 23 | #else |
24 | #define DPRINTK(format,args...) | 24 | #define DPRINTK(format,args...) |
@@ -73,8 +73,13 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg, | |||
73 | 73 | ||
74 | DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, | 74 | DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, |
75 | old); | 75 | old); |
76 | if (!new) | 76 | |
77 | new = &noop_qdisc; | 77 | if (new == NULL) { |
78 | new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); | ||
79 | if (new == NULL) | ||
80 | new = &noop_qdisc; | ||
81 | } | ||
82 | |||
78 | sch_tree_lock(sch); | 83 | sch_tree_lock(sch); |
79 | *old = xchg(&p->q,new); | 84 | *old = xchg(&p->q,new); |
80 | if (*old) | 85 | if (*old) |
@@ -163,14 +168,15 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) | |||
163 | return; | 168 | return; |
164 | for (i = 0; i < p->indices; i++) { | 169 | for (i = 0; i < p->indices; i++) { |
165 | if (p->mask[i] == 0xff && !p->value[i]) | 170 | if (p->mask[i] == 0xff && !p->value[i]) |
166 | continue; | 171 | goto ignore; |
167 | if (walker->count >= walker->skip) { | 172 | if (walker->count >= walker->skip) { |
168 | if (walker->fn(sch, i+1, walker) < 0) { | 173 | if (walker->fn(sch, i+1, walker) < 0) { |
169 | walker->stop = 1; | 174 | walker->stop = 1; |
170 | break; | 175 | break; |
171 | } | 176 | } |
172 | } | 177 | } |
173 | walker->count++; | 178 | ignore: |
179 | walker->count++; | ||
174 | } | 180 | } |
175 | } | 181 | } |
176 | 182 | ||
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index a9602f89d6b1..e537bd66a707 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -112,7 +112,7 @@ config SOUND_BCM_CS4297A | |||
112 | 112 | ||
113 | config SOUND_ES1370 | 113 | config SOUND_ES1370 |
114 | tristate "Ensoniq AudioPCI (ES1370)" | 114 | tristate "Ensoniq AudioPCI (ES1370)" |
115 | depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT | 115 | depends on SOUND_PRIME!=n && SOUND && PCI |
116 | help | 116 | help |
117 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 117 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
118 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find | 118 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find |
@@ -125,7 +125,7 @@ config SOUND_ES1370 | |||
125 | 125 | ||
126 | config SOUND_ES1371 | 126 | config SOUND_ES1371 |
127 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" | 127 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" |
128 | depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT | 128 | depends on SOUND_PRIME!=n && SOUND && PCI |
129 | help | 129 | help |
130 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 130 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
131 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if | 131 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if |
@@ -138,7 +138,7 @@ config SOUND_ES1371 | |||
138 | 138 | ||
139 | config SOUND_ESSSOLO1 | 139 | config SOUND_ESSSOLO1 |
140 | tristate "ESS Technology Solo1" | 140 | tristate "ESS Technology Solo1" |
141 | depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT && PCI | 141 | depends on SOUND_PRIME!=n && SOUND && PCI |
142 | help | 142 | help |
143 | Say Y or M if you have a PCI sound card utilizing the ESS Technology | 143 | Say Y or M if you have a PCI sound card utilizing the ESS Technology |
144 | Solo1 chip. To find out if your sound card uses a | 144 | Solo1 chip. To find out if your sound card uses a |
@@ -179,7 +179,7 @@ config SOUND_HARMONY | |||
179 | 179 | ||
180 | config SOUND_SONICVIBES | 180 | config SOUND_SONICVIBES |
181 | tristate "S3 SonicVibes" | 181 | tristate "S3 SonicVibes" |
182 | depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT | 182 | depends on SOUND_PRIME!=n && SOUND |
183 | help | 183 | help |
184 | Say Y or M if you have a PCI sound card utilizing the S3 | 184 | Say Y or M if you have a PCI sound card utilizing the S3 |
185 | SonicVibes chipset. To find out if your sound card uses a | 185 | SonicVibes chipset. To find out if your sound card uses a |
@@ -226,7 +226,7 @@ config SOUND_AU1550_AC97 | |||
226 | 226 | ||
227 | config SOUND_TRIDENT | 227 | config SOUND_TRIDENT |
228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" | 228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" |
229 | depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT | 229 | depends on SOUND_PRIME!=n && SOUND |
230 | ---help--- | 230 | ---help--- |
231 | Say Y or M if you have a PCI sound card utilizing the Trident | 231 | Say Y or M if you have a PCI sound card utilizing the Trident |
232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 | 232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 |
@@ -739,7 +739,7 @@ config SOUND_NM256 | |||
739 | 739 | ||
740 | config SOUND_MAD16 | 740 | config SOUND_MAD16 |
741 | tristate "OPTi MAD16 and/or Mozart based cards" | 741 | tristate "OPTi MAD16 and/or Mozart based cards" |
742 | depends on SOUND_OSS && SOUND_GAMEPORT | 742 | depends on SOUND_OSS |
743 | ---help--- | 743 | ---help--- |
744 | Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi | 744 | Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi |
745 | 82C928 or 82C929 or 82C931) audio interface chip. These chips are | 745 | 82C928 or 82C929 or 82C931) audio interface chip. These chips are |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 32d94754acf8..080ef3928465 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -876,7 +876,7 @@ static void __init detect_byte_swap(pmac_t *chip) | |||
876 | */ | 876 | */ |
877 | static int __init snd_pmac_detect(pmac_t *chip) | 877 | static int __init snd_pmac_detect(pmac_t *chip) |
878 | { | 878 | { |
879 | struct device_node *sound; | 879 | struct device_node *sound = NULL; |
880 | unsigned int *prop, l; | 880 | unsigned int *prop, l; |
881 | struct macio_chip* macio; | 881 | struct macio_chip* macio; |
882 | 882 | ||
@@ -906,20 +906,22 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
906 | chip->is_pbook_G3 = 1; | 906 | chip->is_pbook_G3 = 1; |
907 | chip->node = find_devices("awacs"); | 907 | chip->node = find_devices("awacs"); |
908 | if (chip->node) | 908 | if (chip->node) |
909 | return 0; /* ok */ | 909 | sound = chip->node; |
910 | 910 | ||
911 | /* | 911 | /* |
912 | * powermac G3 models have a node called "davbus" | 912 | * powermac G3 models have a node called "davbus" |
913 | * with a child called "sound". | 913 | * with a child called "sound". |
914 | */ | 914 | */ |
915 | chip->node = find_devices("davbus"); | 915 | if (!chip->node) |
916 | chip->node = find_devices("davbus"); | ||
916 | /* | 917 | /* |
917 | * if we didn't find a davbus device, try 'i2s-a' since | 918 | * if we didn't find a davbus device, try 'i2s-a' since |
918 | * this seems to be what iBooks have | 919 | * this seems to be what iBooks have |
919 | */ | 920 | */ |
920 | if (! chip->node) { | 921 | if (! chip->node) { |
921 | chip->node = find_devices("i2s-a"); | 922 | chip->node = find_devices("i2s-a"); |
922 | if (chip->node && chip->node->parent && chip->node->parent->parent) { | 923 | if (chip->node && chip->node->parent && |
924 | chip->node->parent->parent) { | ||
923 | if (device_is_compatible(chip->node->parent->parent, | 925 | if (device_is_compatible(chip->node->parent->parent, |
924 | "K2-Keylargo")) | 926 | "K2-Keylargo")) |
925 | chip->is_k2 = 1; | 927 | chip->is_k2 = 1; |
@@ -928,9 +930,11 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
928 | if (! chip->node) | 930 | if (! chip->node) |
929 | return -ENODEV; | 931 | return -ENODEV; |
930 | 932 | ||
931 | sound = find_devices("sound"); | 933 | if (!sound) { |
932 | while (sound && sound->parent != chip->node) | 934 | sound = find_devices("sound"); |
933 | sound = sound->next; | 935 | while (sound && sound->parent != chip->node) |
936 | sound = sound->next; | ||
937 | } | ||
934 | if (! sound) | 938 | if (! sound) |
935 | return -ENODEV; | 939 | return -ENODEV; |
936 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); | 940 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); |
@@ -1019,7 +1023,8 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
1019 | } | 1023 | } |
1020 | } | 1024 | } |
1021 | if (chip->pdev == NULL) | 1025 | if (chip->pdev == NULL) |
1022 | printk(KERN_WARNING "snd-powermac: can't locate macio PCI device !\n"); | 1026 | printk(KERN_WARNING "snd-powermac: can't locate macio PCI" |
1027 | " device !\n"); | ||
1023 | 1028 | ||
1024 | detect_byte_swap(chip); | 1029 | detect_byte_swap(chip); |
1025 | 1030 | ||
@@ -1027,7 +1032,8 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
1027 | are available */ | 1032 | are available */ |
1028 | prop = (unsigned int *) get_property(sound, "sample-rates", &l); | 1033 | prop = (unsigned int *) get_property(sound, "sample-rates", &l); |
1029 | if (! prop) | 1034 | if (! prop) |
1030 | prop = (unsigned int *) get_property(sound, "output-frame-rates", &l); | 1035 | prop = (unsigned int *) get_property(sound, |
1036 | "output-frame-rates", &l); | ||
1031 | if (prop) { | 1037 | if (prop) { |
1032 | int i; | 1038 | int i; |
1033 | chip->freqs_ok = 0; | 1039 | chip->freqs_ok = 0; |
@@ -1054,7 +1060,8 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
1054 | /* | 1060 | /* |
1055 | * exported - boolean info callbacks for ease of programming | 1061 | * exported - boolean info callbacks for ease of programming |
1056 | */ | 1062 | */ |
1057 | int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | 1063 | int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, |
1064 | snd_ctl_elem_info_t *uinfo) | ||
1058 | { | 1065 | { |
1059 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1066 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1060 | uinfo->count = 2; | 1067 | uinfo->count = 2; |
@@ -1063,7 +1070,8 @@ int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * | |||
1063 | return 0; | 1070 | return 0; |
1064 | } | 1071 | } |
1065 | 1072 | ||
1066 | int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | 1073 | int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, |
1074 | snd_ctl_elem_info_t *uinfo) | ||
1067 | { | 1075 | { |
1068 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1076 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1069 | uinfo->count = 1; | 1077 | uinfo->count = 1; |