diff options
author | Tony Luck <tony.luck@intel.com> | 2005-06-29 18:21:41 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-06-29 18:21:41 -0400 |
commit | d18bfacff20f08aecf01bb971b110ca108eef3c7 (patch) | |
tree | 255f862839c593c796e609328575b611e3f56cf3 | |
parent | a68db763af9b676590c3fe9ec3f17bf18015eb2f (diff) | |
parent | fd782a4a99d2d3e818b9465c427b10f7f027d7da (diff) |
Auto merge with /home/aegl/GIT/linus
221 files changed, 4051 insertions, 4407 deletions
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 6df1dfd18b65..375ae760dc1e 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl | |||
@@ -84,6 +84,14 @@ void (*port_disable) (struct ata_port *); | |||
84 | Called from ata_bus_probe() and ata_bus_reset() error paths, | 84 | Called from ata_bus_probe() and ata_bus_reset() error paths, |
85 | as well as when unregistering from the SCSI module (rmmod, hot | 85 | as well as when unregistering from the SCSI module (rmmod, hot |
86 | unplug). | 86 | unplug). |
87 | This function should do whatever needs to be done to take the | ||
88 | port out of use. In most cases, ata_port_disable() can be used | ||
89 | as this hook. | ||
90 | </para> | ||
91 | <para> | ||
92 | Called from ata_bus_probe() on a failed probe. | ||
93 | Called from ata_bus_reset() on a failed bus reset. | ||
94 | Called from ata_scsi_release(). | ||
87 | </para> | 95 | </para> |
88 | 96 | ||
89 | </sect2> | 97 | </sect2> |
@@ -98,6 +106,13 @@ void (*dev_config) (struct ata_port *, struct ata_device *); | |||
98 | found. Typically used to apply device-specific fixups prior to | 106 | found. Typically used to apply device-specific fixups prior to |
99 | issue of SET FEATURES - XFER MODE, and prior to operation. | 107 | issue of SET FEATURES - XFER MODE, and prior to operation. |
100 | </para> | 108 | </para> |
109 | <para> | ||
110 | Called by ata_device_add() after ata_dev_identify() determines | ||
111 | a device is present. | ||
112 | </para> | ||
113 | <para> | ||
114 | This entry may be specified as NULL in ata_port_operations. | ||
115 | </para> | ||
101 | 116 | ||
102 | </sect2> | 117 | </sect2> |
103 | 118 | ||
@@ -135,6 +150,8 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); | |||
135 | registers / DMA buffers. ->tf_read() is called to read the | 150 | registers / DMA buffers. ->tf_read() is called to read the |
136 | hardware registers / DMA buffers, to obtain the current set of | 151 | hardware registers / DMA buffers, to obtain the current set of |
137 | taskfile register values. | 152 | taskfile register values. |
153 | Most drivers for taskfile-based hardware (PIO or MMIO) use | ||
154 | ata_tf_load() and ata_tf_read() for these hooks. | ||
138 | </para> | 155 | </para> |
139 | 156 | ||
140 | </sect2> | 157 | </sect2> |
@@ -147,6 +164,8 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); | |||
147 | <para> | 164 | <para> |
148 | causes an ATA command, previously loaded with | 165 | causes an ATA command, previously loaded with |
149 | ->tf_load(), to be initiated in hardware. | 166 | ->tf_load(), to be initiated in hardware. |
167 | Most drivers for taskfile-based hardware use ata_exec_command() | ||
168 | for this hook. | ||
150 | </para> | 169 | </para> |
151 | 170 | ||
152 | </sect2> | 171 | </sect2> |
@@ -161,6 +180,10 @@ 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 | 180 | indicating whether or not it is OK to use DMA for the supplied PACKET |
162 | command. | 181 | command. |
163 | </para> | 182 | </para> |
183 | <para> | ||
184 | This hook may be specified as NULL, in which case libata will | ||
185 | assume that atapi dma can be supported. | ||
186 | </para> | ||
164 | 187 | ||
165 | </sect2> | 188 | </sect2> |
166 | 189 | ||
@@ -175,6 +198,14 @@ u8 (*check_err)(struct ata_port *ap); | |||
175 | Reads the Status/AltStatus/Error ATA shadow register from | 198 | Reads the Status/AltStatus/Error ATA shadow register from |
176 | hardware. On some hardware, reading the Status register has | 199 | hardware. On some hardware, reading the Status register has |
177 | the side effect of clearing the interrupt condition. | 200 | the side effect of clearing the interrupt condition. |
201 | Most drivers for taskfile-based hardware use | ||
202 | ata_check_status() for this hook. | ||
203 | </para> | ||
204 | <para> | ||
205 | Note that because this is called from ata_device_add(), at | ||
206 | least a dummy function that clears device interrupts must be | ||
207 | provided for all drivers, even if the controller doesn't | ||
208 | actually have a taskfile status register. | ||
178 | </para> | 209 | </para> |
179 | 210 | ||
180 | </sect2> | 211 | </sect2> |
@@ -188,7 +219,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); | |||
188 | Issues the low-level hardware command(s) that causes one of N | 219 | Issues the low-level hardware command(s) that causes one of N |
189 | hardware devices to be considered 'selected' (active and | 220 | hardware devices to be considered 'selected' (active and |
190 | available for use) on the ATA bus. This generally has no | 221 | available for use) on the ATA bus. This generally has no |
191 | meaning on FIS-based devices. | 222 | meaning on FIS-based devices. |
223 | </para> | ||
224 | <para> | ||
225 | Most drivers for taskfile-based hardware use | ||
226 | ata_std_dev_select() for this hook. Controllers which do not | ||
227 | support second drives on a port (such as SATA contollers) will | ||
228 | use ata_noop_dev_select(). | ||
192 | </para> | 229 | </para> |
193 | 230 | ||
194 | </sect2> | 231 | </sect2> |
@@ -204,6 +241,8 @@ void (*phy_reset) (struct ata_port *ap); | |||
204 | for device presence (PATA and SATA), typically a soft reset | 241 | for device presence (PATA and SATA), typically a soft reset |
205 | (SRST) will be performed. Drivers typically use the helper | 242 | (SRST) will be performed. Drivers typically use the helper |
206 | functions ata_bus_reset() or sata_phy_reset() for this hook. | 243 | functions ata_bus_reset() or sata_phy_reset() for this hook. |
244 | Many SATA drivers use sata_phy_reset() or call it from within | ||
245 | their own phy_reset() functions. | ||
207 | </para> | 246 | </para> |
208 | 247 | ||
209 | </sect2> | 248 | </sect2> |
@@ -227,6 +266,25 @@ PCI IDE DMA Status register. | |||
227 | These hooks are typically either no-ops, or simply not implemented, in | 266 | These hooks are typically either no-ops, or simply not implemented, in |
228 | FIS-based drivers. | 267 | FIS-based drivers. |
229 | </para> | 268 | </para> |
269 | <para> | ||
270 | Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup() | ||
271 | hook. ata_bmdma_setup() will write the pointer to the PRD table to | ||
272 | the IDE PRD Table Address register, enable DMA in the DMA Command | ||
273 | register, and call exec_command() to begin the transfer. | ||
274 | </para> | ||
275 | <para> | ||
276 | Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start() | ||
277 | hook. ata_bmdma_start() will write the ATA_DMA_START flag to the DMA | ||
278 | Command register. | ||
279 | </para> | ||
280 | <para> | ||
281 | Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop() | ||
282 | hook. ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA | ||
283 | command register. | ||
284 | </para> | ||
285 | <para> | ||
286 | Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook. | ||
287 | </para> | ||
230 | 288 | ||
231 | </sect2> | 289 | </sect2> |
232 | 290 | ||
@@ -250,6 +308,10 @@ int (*qc_issue) (struct ata_queued_cmd *qc); | |||
250 | helper function ata_qc_issue_prot() for taskfile protocol-based | 308 | helper function ata_qc_issue_prot() for taskfile protocol-based |
251 | dispatch. More advanced drivers implement their own ->qc_issue. | 309 | dispatch. More advanced drivers implement their own ->qc_issue. |
252 | </para> | 310 | </para> |
311 | <para> | ||
312 | ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and | ||
313 | ->bmdma_start() as necessary to initiate a transfer. | ||
314 | </para> | ||
253 | 315 | ||
254 | </sect2> | 316 | </sect2> |
255 | 317 | ||
@@ -279,6 +341,21 @@ void (*irq_clear) (struct ata_port *); | |||
279 | before the interrupt handler is registered, to be sure hardware | 341 | before the interrupt handler is registered, to be sure hardware |
280 | is quiet. | 342 | is quiet. |
281 | </para> | 343 | </para> |
344 | <para> | ||
345 | The second argument, dev_instance, should be cast to a pointer | ||
346 | to struct ata_host_set. | ||
347 | </para> | ||
348 | <para> | ||
349 | Most legacy IDE drivers use ata_interrupt() for the | ||
350 | irq_handler hook, which scans all ports in the host_set, | ||
351 | determines which queued command was active (if any), and calls | ||
352 | ata_host_intr(ap,qc). | ||
353 | </para> | ||
354 | <para> | ||
355 | Most legacy IDE drivers use ata_bmdma_irq_clear() for the | ||
356 | irq_clear() hook, which simply clears the interrupt and error | ||
357 | flags in the DMA status register. | ||
358 | </para> | ||
282 | 359 | ||
283 | </sect2> | 360 | </sect2> |
284 | 361 | ||
@@ -292,6 +369,7 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | |||
292 | <para> | 369 | <para> |
293 | Read and write standard SATA phy registers. Currently only used | 370 | Read and write standard SATA phy registers. Currently only used |
294 | if ->phy_reset hook called the sata_phy_reset() helper function. | 371 | if ->phy_reset hook called the sata_phy_reset() helper function. |
372 | sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE. | ||
295 | </para> | 373 | </para> |
296 | 374 | ||
297 | </sect2> | 375 | </sect2> |
@@ -307,17 +385,29 @@ void (*host_stop) (struct ata_host_set *host_set); | |||
307 | ->port_start() is called just after the data structures for each | 385 | ->port_start() is called just after the data structures for each |
308 | port are initialized. Typically this is used to alloc per-port | 386 | port are initialized. Typically this is used to alloc per-port |
309 | DMA buffers / tables / rings, enable DMA engines, and similar | 387 | DMA buffers / tables / rings, enable DMA engines, and similar |
310 | tasks. | 388 | tasks. Some drivers also use this entry point as a chance to |
389 | allocate driver-private memory for ap->private_data. | ||
390 | </para> | ||
391 | <para> | ||
392 | Many drivers use ata_port_start() as this hook or call | ||
393 | it from their own port_start() hooks. ata_port_start() | ||
394 | allocates space for a legacy IDE PRD table and returns. | ||
311 | </para> | 395 | </para> |
312 | <para> | 396 | <para> |
313 | ->port_stop() is called after ->host_stop(). It's sole function | 397 | ->port_stop() is called after ->host_stop(). It's sole function |
314 | is to release DMA/memory resources, now that they are no longer | 398 | is to release DMA/memory resources, now that they are no longer |
315 | actively being used. | 399 | actively being used. Many drivers also free driver-private |
400 | data from port at this time. | ||
401 | </para> | ||
402 | <para> | ||
403 | Many drivers use ata_port_stop() as this hook, which frees the | ||
404 | PRD table. | ||
316 | </para> | 405 | </para> |
317 | <para> | 406 | <para> |
318 | ->host_stop() is called after all ->port_stop() calls | 407 | ->host_stop() is called after all ->port_stop() calls |
319 | have completed. The hook must finalize hardware shutdown, release DMA | 408 | have completed. The hook must finalize hardware shutdown, release DMA |
320 | and other resources, etc. | 409 | and other resources, etc. |
410 | This hook may be specified as NULL, in which case it is not called. | ||
321 | </para> | 411 | </para> |
322 | 412 | ||
323 | </sect2> | 413 | </sect2> |
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers index de3b252e717d..c3cca924e94b 100644 --- a/Documentation/SubmittingDrivers +++ b/Documentation/SubmittingDrivers | |||
@@ -13,13 +13,14 @@ Allocating Device Numbers | |||
13 | ------------------------- | 13 | ------------------------- |
14 | 14 | ||
15 | Major and minor numbers for block and character devices are allocated | 15 | Major and minor numbers for block and character devices are allocated |
16 | by the Linux assigned name and number authority (currently better | 16 | by the Linux assigned name and number authority (currently this is |
17 | known as H Peter Anvin). The site is http://www.lanana.org/. This | 17 | Torben Mathiasen). The site is http://www.lanana.org/. This |
18 | also deals with allocating numbers for devices that are not going to | 18 | also deals with allocating numbers for devices that are not going to |
19 | be submitted to the mainstream kernel. | 19 | be submitted to the mainstream kernel. |
20 | See Documentation/devices.txt for more information on this. | ||
20 | 21 | ||
21 | If you don't use assigned numbers then when you device is submitted it will | 22 | If you don't use assigned numbers then when your device is submitted it will |
22 | get given an assigned number even if that is different from values you may | 23 | be given an assigned number even if that is different from values you may |
23 | have shipped to customers before. | 24 | have shipped to customers before. |
24 | 25 | ||
25 | Who To Submit Drivers To | 26 | Who To Submit Drivers To |
@@ -32,7 +33,8 @@ Linux 2.2: | |||
32 | If the code area has a general maintainer then please submit it to | 33 | If the code area has a general maintainer then please submit it to |
33 | the maintainer listed in MAINTAINERS in the kernel file. If the | 34 | the maintainer listed in MAINTAINERS in the kernel file. If the |
34 | maintainer does not respond or you cannot find the appropriate | 35 | maintainer does not respond or you cannot find the appropriate |
35 | maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk> | 36 | maintainer then please contact the 2.2 kernel maintainer: |
37 | Marc-Christian Petersen <m.c.p@wolk-project.de>. | ||
36 | 38 | ||
37 | Linux 2.4: | 39 | Linux 2.4: |
38 | The same rules apply as 2.2. The final contact point for Linux 2.4 | 40 | The same rules apply as 2.2. The final contact point for Linux 2.4 |
@@ -48,7 +50,7 @@ What Criteria Determine Acceptance | |||
48 | 50 | ||
49 | Licensing: The code must be released to us under the | 51 | Licensing: The code must be released to us under the |
50 | GNU General Public License. We don't insist on any kind | 52 | GNU General Public License. We don't insist on any kind |
51 | of exclusively GPL licensing, and if you wish the driver | 53 | of exclusive GPL licensing, and if you wish the driver |
52 | to be useful to other communities such as BSD you may well | 54 | to be useful to other communities such as BSD you may well |
53 | wish to release under multiple licenses. | 55 | wish to release under multiple licenses. |
54 | 56 | ||
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 4d1f41b84ebc..6761a7b241a5 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches | |||
@@ -35,7 +35,7 @@ not in any lower subdirectory. | |||
35 | 35 | ||
36 | To create a patch for a single file, it is often sufficient to do: | 36 | To create a patch for a single file, it is often sufficient to do: |
37 | 37 | ||
38 | SRCTREE= linux-2.4 | 38 | SRCTREE= linux-2.6 |
39 | MYFILE= drivers/net/mydriver.c | 39 | MYFILE= drivers/net/mydriver.c |
40 | 40 | ||
41 | cd $SRCTREE | 41 | cd $SRCTREE |
@@ -48,17 +48,18 @@ To create a patch for multiple files, you should unpack a "vanilla", | |||
48 | or unmodified kernel source tree, and generate a diff against your | 48 | or unmodified kernel source tree, and generate a diff against your |
49 | own source tree. For example: | 49 | own source tree. For example: |
50 | 50 | ||
51 | MYSRC= /devel/linux-2.4 | 51 | MYSRC= /devel/linux-2.6 |
52 | 52 | ||
53 | tar xvfz linux-2.4.0-test11.tar.gz | 53 | tar xvfz linux-2.6.12.tar.gz |
54 | mv linux linux-vanilla | 54 | mv linux-2.6.12 linux-2.6.12-vanilla |
55 | wget http://www.moses.uklinux.net/patches/dontdiff | 55 | diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \ |
56 | diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch | 56 | linux-2.6.12-vanilla $MYSRC > /tmp/patch |
57 | rm -f dontdiff | ||
58 | 57 | ||
59 | "dontdiff" is a list of files which are generated by the kernel during | 58 | "dontdiff" is a list of files which are generated by the kernel during |
60 | the build process, and should be ignored in any diff(1)-generated | 59 | the build process, and should be ignored in any diff(1)-generated |
61 | patch. dontdiff is maintained by Tigran Aivazian <tigran@veritas.com> | 60 | patch. The "dontdiff" file is included in the kernel tree in |
61 | 2.6.12 and later. For earlier kernel versions, you can get it | ||
62 | from <http://www.xenotime.net/linux/doc/dontdiff>. | ||
62 | 63 | ||
63 | Make sure your patch does not include any extra files which do not | 64 | Make sure your patch does not include any extra files which do not |
64 | belong in a patch submission. Make sure to review your patch -after- | 65 | belong in a patch submission. Make sure to review your patch -after- |
@@ -66,18 +67,20 @@ generated it with diff(1), to ensure accuracy. | |||
66 | 67 | ||
67 | If your changes produce a lot of deltas, you may want to look into | 68 | If your changes produce a lot of deltas, you may want to look into |
68 | splitting them into individual patches which modify things in | 69 | splitting them into individual patches which modify things in |
69 | logical stages, this will facilitate easier reviewing by other | 70 | logical stages. This will facilitate easier reviewing by other |
70 | kernel developers, very important if you want your patch accepted. | 71 | kernel developers, very important if you want your patch accepted. |
71 | There are a number of scripts which can aid in this; | 72 | There are a number of scripts which can aid in this: |
72 | 73 | ||
73 | Quilt: | 74 | Quilt: |
74 | http://savannah.nongnu.org/projects/quilt | 75 | http://savannah.nongnu.org/projects/quilt |
75 | 76 | ||
76 | Randy Dunlap's patch scripts: | 77 | Randy Dunlap's patch scripts: |
77 | http://developer.osdl.org/rddunlap/scripts/patching-scripts.tgz | 78 | http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz |
78 | 79 | ||
79 | Andrew Morton's patch scripts: | 80 | Andrew Morton's patch scripts: |
80 | http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.16 | 81 | http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20 |
82 | |||
83 | |||
81 | 84 | ||
82 | 2) Describe your changes. | 85 | 2) Describe your changes. |
83 | 86 | ||
@@ -163,6 +166,8 @@ patches. Trivial patches must qualify for one of the following rules: | |||
163 | since people copy, as long as it's trivial) | 166 | since people copy, as long as it's trivial) |
164 | Any fix by the author/maintainer of the file. (ie. patch monkey | 167 | Any fix by the author/maintainer of the file. (ie. patch monkey |
165 | in re-transmission mode) | 168 | in re-transmission mode) |
169 | URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/> | ||
170 | |||
166 | 171 | ||
167 | 172 | ||
168 | 173 | ||
@@ -291,6 +296,17 @@ now, but you can do this to mark internal company procedures or just | |||
291 | point out some special detail about the sign-off. | 296 | point out some special detail about the sign-off. |
292 | 297 | ||
293 | 298 | ||
299 | |||
300 | 12) More references for submitting patches | ||
301 | |||
302 | Andrew Morton, "The perfect patch" (tpp). | ||
303 | <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt> | ||
304 | |||
305 | Jeff Garzik, "Linux kernel patch submission format." | ||
306 | <http://linux.yyz.us/patch-format.html> | ||
307 | |||
308 | |||
309 | |||
294 | ----------------------------------- | 310 | ----------------------------------- |
295 | SECTION 2 - HINTS, TIPS, AND TRICKS | 311 | SECTION 2 - HINTS, TIPS, AND TRICKS |
296 | ----------------------------------- | 312 | ----------------------------------- |
@@ -359,7 +375,5 @@ and 'extern __inline__'. | |||
359 | 4) Don't over-design. | 375 | 4) Don't over-design. |
360 | 376 | ||
361 | Don't try to anticipate nebulous future cases which may or may not | 377 | Don't try to anticipate nebulous future cases which may or may not |
362 | be useful: "Make it as simple as you can, and no simpler" | 378 | be useful: "Make it as simple as you can, and no simpler." |
363 | |||
364 | |||
365 | 379 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 89cd417651e0..4ec75c06bca4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -622,6 +622,17 @@ running once the system is up. | |||
622 | ips= [HW,SCSI] Adaptec / IBM ServeRAID controller | 622 | ips= [HW,SCSI] Adaptec / IBM ServeRAID controller |
623 | See header of drivers/scsi/ips.c. | 623 | See header of drivers/scsi/ips.c. |
624 | 624 | ||
625 | irqfixup [HW] | ||
626 | When an interrupt is not handled search all handlers | ||
627 | for it. Intended to get systems with badly broken | ||
628 | firmware running. | ||
629 | |||
630 | irqpoll [HW] | ||
631 | When an interrupt is not handled search all handlers | ||
632 | for it. Also check all handlers each timer | ||
633 | interrupt. Intended to get systems with badly broken | ||
634 | firmware running. | ||
635 | |||
625 | isapnp= [ISAPNP] | 636 | isapnp= [ISAPNP] |
626 | Format: <RDP>, <reset>, <pci_scan>, <verbosity> | 637 | Format: <RDP>, <reset>, <pci_scan>, <verbosity> |
627 | 638 | ||
@@ -1030,6 +1041,10 @@ running once the system is up. | |||
1030 | irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned | 1041 | irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned |
1031 | automatically to PCI devices. You can make the kernel | 1042 | automatically to PCI devices. You can make the kernel |
1032 | exclude IRQs of your ISA cards this way. | 1043 | exclude IRQs of your ISA cards this way. |
1044 | pirqaddr=0xAAAAA [IA-32] Specify the physical address | ||
1045 | of the PIRQ table (normally generated | ||
1046 | by the BIOS) if it is outside the | ||
1047 | F0000h-100000h range. | ||
1033 | lastbus=N [IA-32] Scan all buses till bus #N. Can be useful | 1048 | lastbus=N [IA-32] Scan all buses till bus #N. Can be useful |
1034 | if the kernel is unable to find your secondary buses | 1049 | if the kernel is unable to find your secondary buses |
1035 | and you want to tell it explicitly which ones they are. | 1050 | and you want to tell it explicitly which ones they are. |
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html index 4b3d8f640a4a..441407b12a9f 100644 --- a/Documentation/video4linux/API.html +++ b/Documentation/video4linux/API.html | |||
@@ -1,399 +1,16 @@ | |||
1 | <HTML><HEAD> | 1 | <TITLE>V4L API</TITLE> |
2 | <TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE> | 2 | <H1>Video For Linux APIs</H1> |
3 | </HEAD> | 3 | <table border=0> |
4 | <! Revision History: > | 4 | <tr> |
5 | <! 4/30/1999 - Fred Gleason (fredg@wava.com)> | 5 | <td> |
6 | <! Documented extensions for the Radio Data System (RDS) extensions > | 6 | <A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html> |
7 | <BODY bgcolor="#ffffff"> | 7 | V4L original API</a> |
8 | <H3>Devices</H3> | 8 | </td><td> |
9 | Video4Linux provides the following sets of device files. These live on the | 9 | Obsoleted by V4L2 API |
10 | character device formerly known as "/dev/bttv". /dev/bttv should be a | 10 | </td></tr><tr><td> |
11 | symlink to /dev/video0 for most people. | 11 | <A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html> |
12 | <P> | 12 | V4L2 API</a> |
13 | <TABLE> | 13 | </td><td> |
14 | <TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH> | 14 | Should be used for new projects |
15 | <TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD> | 15 | </td></tr> |
16 | <TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD> | 16 | </table> |
17 | <TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD> | ||
18 | <TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD> | ||
19 | </TABLE> | ||
20 | <P> | ||
21 | Video4Linux programs open and scan the devices to find what they are looking | ||
22 | for. Capability queries define what each interface supports. The | ||
23 | described API is only defined for video capture cards. The relevant subset | ||
24 | applies to radio cards. Teletext interfaces talk the existing VTX API. | ||
25 | <P> | ||
26 | <H3>Capability Query Ioctl</H3> | ||
27 | The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability | ||
28 | information for a video device. The <b>struct video_capability</b> object | ||
29 | passed to the ioctl is completed and returned. It contains the following | ||
30 | information | ||
31 | <P> | ||
32 | <TABLE> | ||
33 | <TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD> | ||
34 | <TR><TD><b>type</b><TD>Type of interface</TD> | ||
35 | <TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD> | ||
36 | <TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD> | ||
37 | <TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD> | ||
38 | <TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD> | ||
39 | <TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD> | ||
40 | <TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD> | ||
41 | </TABLE> | ||
42 | <P> | ||
43 | The type field lists the capability flags for the device. These are | ||
44 | as follows | ||
45 | <P> | ||
46 | <TABLE> | ||
47 | <TR><TH>Name</TH><TH>Description</TH> | ||
48 | <TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD> | ||
49 | <TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD> | ||
50 | <TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD> | ||
51 | <TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD> | ||
52 | <TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD> | ||
53 | <TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD> | ||
54 | <TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD> | ||
55 | <TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD> | ||
56 | <TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD> | ||
57 | <TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD> | ||
58 | </TABLE> | ||
59 | <P> | ||
60 | The minimum and maximum sizes listed for a capture device do not imply all | ||
61 | that all height/width ratios or sizes within the range are possible. A | ||
62 | request to set a size will be honoured by the largest available capture | ||
63 | size whose capture is no large than the requested rectangle in either | ||
64 | direction. For example the quickcam has 3 fixed settings. | ||
65 | <P> | ||
66 | <H3>Frame Buffer</H3> | ||
67 | Capture cards that drop data directly onto the frame buffer must be told the | ||
68 | base address of the frame buffer, its size and organisation. This is a | ||
69 | privileged ioctl and one that eventually X itself should set. | ||
70 | <P> | ||
71 | The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture | ||
72 | card. If the card does not do direct writes to the frame buffer then this | ||
73 | ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the | ||
74 | currently used parameters. The structure used in both cases is a | ||
75 | <b>struct video_buffer</b>. | ||
76 | <P> | ||
77 | <TABLE> | ||
78 | <TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD> | ||
79 | <TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD> | ||
80 | <TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD> | ||
81 | <TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD> | ||
82 | <TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD> | ||
83 | </TABLE> | ||
84 | <P> | ||
85 | Note that these values reflect the physical layout of the frame buffer. | ||
86 | The visible area may be smaller. In fact under XFree86 this is commonly the | ||
87 | case. XFree86 DGA can provide the parameters required to set up this ioctl. | ||
88 | Setting the base address to NULL indicates there is no physical frame buffer | ||
89 | access. | ||
90 | <P> | ||
91 | <H3>Capture Windows</H3> | ||
92 | The capture area is described by a <b>struct video_window</b>. This defines | ||
93 | a capture area and the clipping information if relevant. The | ||
94 | <b>VIDIOCGWIN</b> ioctl recovers the current settings and the | ||
95 | <b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b> | ||
96 | indicates that a suitable set of parameters have been chosen. They do not | ||
97 | indicate that exactly what was requested was granted. The program should | ||
98 | call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The | ||
99 | <b>struct video_window</b> contains the following fields. | ||
100 | <P> | ||
101 | <TABLE> | ||
102 | <TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD> | ||
103 | <TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD> | ||
104 | <TR><TD><b>width</b><TD>The width of the image capture.</TD> | ||
105 | <TR><TD><b>height</b><TD>The height of the image capture.</TD> | ||
106 | <TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD> | ||
107 | <TR><TD><b>flags</b><TD>Additional capture flags.</TD> | ||
108 | <TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD> | ||
109 | <TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD> | ||
110 | </TABLE> | ||
111 | <P> | ||
112 | Clipping rectangles are passed as an array. Each clip consists of the following | ||
113 | fields available to the user. | ||
114 | <P> | ||
115 | <TABLE> | ||
116 | <TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD> | ||
117 | <TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD> | ||
118 | <TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD> | ||
119 | <TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD> | ||
120 | </TABLE> | ||
121 | <P> | ||
122 | Merely setting the window does not enable capturing. Overlay capturing | ||
123 | (i.e. PCI-PCI transfer to the frame buffer of the video card) | ||
124 | is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and | ||
125 | disabled by passing it a value of 0. | ||
126 | <P> | ||
127 | Some capture devices can capture a subfield of the image they actually see. | ||
128 | This is indicated when VIDEO_TYPE_SUBCAPTURE is defined. | ||
129 | The video_capture describes the time and special subfields to capture. | ||
130 | The video_capture structure contains the following fields. | ||
131 | <P> | ||
132 | <TABLE> | ||
133 | <TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD> | ||
134 | <TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD> | ||
135 | <TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD> | ||
136 | <TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD> | ||
137 | <TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD> | ||
138 | <TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD> | ||
139 | </TABLE> | ||
140 | The available flags are | ||
141 | <P> | ||
142 | <TABLE> | ||
143 | <TR><TH>Name</TH><TH>Description</TH> | ||
144 | <TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD> | ||
145 | <TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD> | ||
146 | </TABLE> | ||
147 | <P> | ||
148 | <H3>Video Sources</H3> | ||
149 | Each video4linux video or audio device captures from one or more | ||
150 | source <b>channels</b>. Each channel can be queries with the | ||
151 | <b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller | ||
152 | must set the channel field to the channel that is being queried. On return | ||
153 | the <b>struct video_channel</b> is filled in with information about the | ||
154 | nature of the channel itself. | ||
155 | <P> | ||
156 | The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the | ||
157 | capture to this input. It is not defined whether parameters such as colour | ||
158 | settings or tuning are maintained across a channel switch. The caller should | ||
159 | maintain settings as desired for each channel. (This is reasonable as | ||
160 | different video inputs may have different properties). | ||
161 | <P> | ||
162 | The <b>struct video_channel</b> consists of the following | ||
163 | <P> | ||
164 | <TABLE> | ||
165 | <TR><TD><b>channel</b></TD><TD>The channel number</TD> | ||
166 | <TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label | ||
167 | on the card input itself</TD> | ||
168 | <TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD> | ||
169 | <TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD> | ||
170 | <TR><TD><b>type</b></TD><TD>Input type (if known)</TD> | ||
171 | <TR><TD><b>norm</b><TD>The norm for this channel</TD> | ||
172 | </TABLE> | ||
173 | <P> | ||
174 | The flags defined are | ||
175 | <P> | ||
176 | <TABLE> | ||
177 | <TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD> | ||
178 | <TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD> | ||
179 | <TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD> | ||
180 | </TABLE> | ||
181 | <P> | ||
182 | The types defined are | ||
183 | <P> | ||
184 | <TABLE> | ||
185 | <TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD> | ||
186 | <TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD> | ||
187 | </TABLE> | ||
188 | <P> | ||
189 | <H3>Image Properties</H3> | ||
190 | The image properties of the picture can be queried with the <b>VIDIOCGPICT</b> | ||
191 | ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b> | ||
192 | ioctl allows values to be changed. All values except for the palette type | ||
193 | are scaled between 0-65535. | ||
194 | <P> | ||
195 | The <b>struct video_picture</b> consists of the following fields | ||
196 | <P> | ||
197 | <TABLE> | ||
198 | <TR><TD><b>brightness</b><TD>Picture brightness</TD> | ||
199 | <TR><TD><b>hue</b><TD>Picture hue (colour only)</TD> | ||
200 | <TR><TD><b>colour</b><TD>Picture colour (colour only)</TD> | ||
201 | <TR><TD><b>contrast</b><TD>Picture contrast</TD> | ||
202 | <TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD> | ||
203 | <TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD> | ||
204 | <TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD> | ||
205 | </TABLE> | ||
206 | <P> | ||
207 | The following palettes are defined | ||
208 | <P> | ||
209 | <TABLE> | ||
210 | <TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD> | ||
211 | <TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD> | ||
212 | <TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD> | ||
213 | <TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD> | ||
214 | <TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD> | ||
215 | <TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD> | ||
216 | <TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD> | ||
217 | <TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD> | ||
218 | <TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD> | ||
219 | <TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD> | ||
220 | <TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD> | ||
221 | <TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD> | ||
222 | <TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD> | ||
223 | <TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD> | ||
224 | </TABLE> | ||
225 | <P> | ||
226 | <H3>Tuning</H3> | ||
227 | Each video input channel can have one or more tuners associated with it. Many | ||
228 | devices will not have tuners. TV cards and radio cards will have one or more | ||
229 | tuners attached. | ||
230 | <P> | ||
231 | Tuners are described by a <b>struct video_tuner</b> which can be obtained by | ||
232 | the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure | ||
233 | then pass the structure to the ioctl to have the data filled in. The | ||
234 | tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument | ||
235 | giving the tuner to use. A struct tuner has the following fields | ||
236 | <P> | ||
237 | <TABLE> | ||
238 | <TR><TD><b>tuner</b><TD>Number of the tuner</TD> | ||
239 | <TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD> | ||
240 | <TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD> | ||
241 | <TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD> | ||
242 | <TR><TD><b>flags</b><TD>Flags describing the tuner</TD> | ||
243 | <TR><TD><b>mode</b><TD>The video signal mode if relevant</TD> | ||
244 | <TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD> | ||
245 | </TABLE> | ||
246 | <P> | ||
247 | The following flags exist | ||
248 | <P> | ||
249 | <TABLE> | ||
250 | <TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD> | ||
251 | <TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD> | ||
252 | <TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD> | ||
253 | <TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD> | ||
254 | <TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD> | ||
255 | <TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD> | ||
256 | <TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD> | ||
257 | <TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD> | ||
258 | </TABLE> | ||
259 | <P> | ||
260 | The following modes are defined | ||
261 | <P> | ||
262 | <TABLE> | ||
263 | <TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD> | ||
264 | <TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD> | ||
265 | <TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD> | ||
266 | <TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD> | ||
267 | </TABLE> | ||
268 | <P> | ||
269 | Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the | ||
270 | <b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current | ||
271 | frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and | ||
272 | set by the <b>VIDIOCSFREQ</b> ioctl. | ||
273 | <P> | ||
274 | <H3>Audio</H3> | ||
275 | TV and Radio devices have one or more audio inputs that may be selected. | ||
276 | The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The | ||
277 | <b>VIDIOCSAUDIO</b> ioctl sets audio properties. | ||
278 | <P> | ||
279 | The structure contains the following fields | ||
280 | <P> | ||
281 | <TABLE> | ||
282 | <TR><TD><b>audio</b><TD>The channel number</TD> | ||
283 | <TR><TD><b>volume</b><TD>The volume level</TD> | ||
284 | <TR><TD><b>bass</b><TD>The bass level</TD> | ||
285 | <TR><TD><b>treble</b><TD>The treble level</TD> | ||
286 | <TR><TD><b>flags</b><TD>Flags describing the audio channel</TD> | ||
287 | <TR><TD><b>name</b><TD>Canonical name for the audio input</TD> | ||
288 | <TR><TD><b>mode</b><TD>The mode the audio input is in</TD> | ||
289 | <TR><TD><b>balance</b><TD>The left/right balance</TD> | ||
290 | <TR><TD><b>step</b><TD>Actual step used by the hardware</TD> | ||
291 | </TABLE> | ||
292 | <P> | ||
293 | The following flags are defined | ||
294 | <P> | ||
295 | <TABLE> | ||
296 | <TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD> | ||
297 | <TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD> | ||
298 | <TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD> | ||
299 | <TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD> | ||
300 | <TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD> | ||
301 | <TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD> | ||
302 | </TABLE> | ||
303 | <P> | ||
304 | The following decoding modes are defined | ||
305 | <P> | ||
306 | <TABLE> | ||
307 | <TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD> | ||
308 | <TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD> | ||
309 | <TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD> | ||
310 | <TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD> | ||
311 | </TABLE> | ||
312 | <P> | ||
313 | <H3>Reading Images</H3> | ||
314 | Each call to the <b>read</b> syscall returns the next available image | ||
315 | from the device. It is up to the caller to set format and size (using | ||
316 | the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable | ||
317 | size buffer and length to the function. Not all devices will support | ||
318 | read operations. | ||
319 | <P> | ||
320 | A second way to handle image capture is via the mmap interface if supported. | ||
321 | To use the mmap interface a user first sets the desired image size and depth | ||
322 | properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size | ||
323 | of buffer to mmap and the offset within the buffer for each frame. The | ||
324 | number of frames supported is device dependent and may only be one. | ||
325 | <P> | ||
326 | The video_mbuf structure contains the following fields | ||
327 | <P> | ||
328 | <TABLE> | ||
329 | <TR><TD><b>size</b><TD>The number of bytes to map</TD> | ||
330 | <TR><TD><b>frames</b><TD>The number of frames</TD> | ||
331 | <TR><TD><b>offsets</b><TD>The offset of each frame</TD> | ||
332 | </TABLE> | ||
333 | <P> | ||
334 | Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the | ||
335 | capture to a frame using the format and image size specified in the | ||
336 | video_mmap (which should match or be below the initial query size). | ||
337 | When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em> | ||
338 | captured yet, the driver just instructed the hardware to start the | ||
339 | capture. The application has to use the VIDIOCSYNC ioctl to wait | ||
340 | until the capture of a frame is finished. VIDIOCSYNC takes the frame | ||
341 | number you want to wait for as argument. | ||
342 | <p> | ||
343 | It is allowed to call VIDIOCMCAPTURE multiple times (with different | ||
344 | frame numbers in video_mmap->frame of course) and thus have multiple | ||
345 | outstanding capture requests. A simple way do to double-buffering | ||
346 | using this feature looks like this: | ||
347 | <pre> | ||
348 | /* setup everything */ | ||
349 | VIDIOCMCAPTURE(0) | ||
350 | while (whatever) { | ||
351 | VIDIOCMCAPTURE(1) | ||
352 | VIDIOCSYNC(0) | ||
353 | /* process frame 0 while the hardware captures frame 1 */ | ||
354 | VIDIOCMCAPTURE(0) | ||
355 | VIDIOCSYNC(1) | ||
356 | /* process frame 1 while the hardware captures frame 0 */ | ||
357 | } | ||
358 | </pre> | ||
359 | Note that you are <em>not</em> limited to only two frames. The API | ||
360 | allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of | ||
361 | frames the driver granted. Thus it is possible to build deeper queues | ||
362 | to avoid loosing frames on load peaks. | ||
363 | <p> | ||
364 | While capturing to memory the driver will make a "best effort" attempt | ||
365 | to capture to screen as well if requested. This normally means all | ||
366 | frames that "miss" memory mapped capture will go to the display. | ||
367 | <P> | ||
368 | A final ioctl exists to allow a device to obtain related devices if a | ||
369 | driver has multiple components (for example video0 may not be associated | ||
370 | with vbi0 which would cause an intercast display program to make a bad | ||
371 | mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated | ||
372 | devices if any exist. The video_unit structure has the following fields. | ||
373 | <P> | ||
374 | <TABLE> | ||
375 | <TR><TD><b>video</b><TD>Video capture device</TD> | ||
376 | <TR><TD><b>vbi</b><TD>VBI capture device</TD> | ||
377 | <TR><TD><b>radio</b><TD>Radio device</TD> | ||
378 | <TR><TD><b>audio</b><TD>Audio mixer</TD> | ||
379 | <TR><TD><b>teletext</b><TD>Teletext device</TD> | ||
380 | </TABLE> | ||
381 | <P> | ||
382 | <H3>RDS Datastreams</H3> | ||
383 | For radio devices that support it, it is possible to receive Radio Data | ||
384 | System (RDS) data by means of a read() on the device. The data is packed in | ||
385 | groups of three, as follows: | ||
386 | <TABLE> | ||
387 | <TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR> | ||
388 | <TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block | ||
389 | <TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit. Indicates that | ||
390 | an uncorrectable error occurred during reception of this block.</TD></TR> | ||
391 | <TR><TD> </TD><TD>Bit 6:</TD><TD>Corrected bit. Indicates that | ||
392 | an error was corrected for this data block.</TD></TR> | ||
393 | <TR><TD> </TD><TD>Bits 5-3:</TD><TD>Received Offset. Indicates the | ||
394 | offset received by the sync system.</TD></TR> | ||
395 | <TR><TD> </TD><TD>Bits 2-0:</TD><TD>Offset Name. Indicates the | ||
396 | offset applied to this data.</TD></TR> | ||
397 | </TABLE> | ||
398 | </BODY> | ||
399 | </HTML> | ||
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 216f705495cc..4377aa11f567 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 | |||
@@ -13,17 +13,17 @@ card=11 - Prolink PlayTV PVR | |||
13 | card=12 - ASUS PVR-416 | 13 | card=12 - ASUS PVR-416 |
14 | card=13 - MSI TV-@nywhere | 14 | card=13 - MSI TV-@nywhere |
15 | card=14 - KWorld/VStream XPert DVB-T | 15 | card=14 - KWorld/VStream XPert DVB-T |
16 | card=15 - DVICO FusionHDTV DVB-T1 | 16 | card=15 - DViCO FusionHDTV DVB-T1 |
17 | card=16 - KWorld LTV883RF | 17 | card=16 - KWorld LTV883RF |
18 | card=17 - DViCO - FusionHDTV 3 Gold | 18 | card=17 - DViCO FusionHDTV 3 Gold-Q |
19 | card=18 - Hauppauge Nova-T DVB-T | 19 | card=18 - Hauppauge Nova-T DVB-T |
20 | card=19 - Conexant DVB-T reference design | 20 | card=19 - Conexant DVB-T reference design |
21 | card=20 - Provideo PV259 | 21 | card=20 - Provideo PV259 |
22 | card=21 - DVICO FusionHDTV DVB-T Plus | 22 | card=21 - DViCO FusionHDTV DVB-T Plus |
23 | card=22 - digitalnow DNTV Live! DVB-T | 23 | card=22 - digitalnow DNTV Live! DVB-T |
24 | card=23 - pcHDTV HD3000 HDTV | 24 | card=23 - pcHDTV HD3000 HDTV |
25 | card=24 - Hauppauge WinTV 28xxx (Roslyn) models | 25 | card=24 - Hauppauge WinTV 28xxx (Roslyn) models |
26 | card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) | 26 | card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) |
27 | card=26 - IODATA GV/BCTV7E | 27 | card=26 - IODATA GV/BCTV7E |
28 | card=27 - PixelView PlayTV Ultra Pro (Stereo) | 28 | card=27 - PixelView PlayTV Ultra Pro (Stereo) |
29 | card=28 - DViCO - FusionHDTV 3 Gold-T | 29 | card=28 - DViCO FusionHDTV 3 Gold-T |
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index d5ed95d28500..735e8ba02d9f 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 | |||
@@ -54,3 +54,9 @@ | |||
54 | 55 -> LifeView FlyDVB-T DUO [5168:0306] | 54 | 55 -> LifeView FlyDVB-T DUO [5168:0306] |
55 | 56 -> Avermedia AVerTV 307 [1461:a70a] | 55 | 56 -> Avermedia AVerTV 307 [1461:a70a] |
56 | 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] | 56 | 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] |
57 | 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370] | ||
58 | 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 | ||
59 | 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus | ||
60 | 61 -> Philips TOUGH DVB-T reference design | ||
61 | 62 -> Compro VideoMate TV Gold+II | ||
62 | 63 -> Kworld Xpert TV PVR7134 | ||
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index aeb8df8ce890..e78020f68b2e 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner | |||
@@ -59,3 +59,6 @@ tuner=57 - Philips FQ1236A MK4 | |||
59 | tuner=58 - Ymec TVision TVF-8531MF | 59 | tuner=58 - Ymec TVision TVF-8531MF |
60 | tuner=59 - Ymec TVision TVF-5533MF | 60 | tuner=59 - Ymec TVision TVF-5533MF |
61 | tuner=60 - Thomson DDT 7611 (ATSC/NTSC) | 61 | tuner=60 - Thomson DDT 7611 (ATSC/NTSC) |
62 | tuner=61 - Tena TNF9533-D/IF | ||
63 | tuner=62 - Philips TEA5767HN FM Radio | ||
64 | tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner | ||
diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134 index 1a446c65365e..1f788e498eff 100644 --- a/Documentation/video4linux/README.saa7134 +++ b/Documentation/video4linux/README.saa7134 | |||
@@ -57,6 +57,15 @@ Cards can use either of these two crystals (xtal): | |||
57 | - 24.576MHz -> .audio_clock=0x200000 | 57 | - 24.576MHz -> .audio_clock=0x200000 |
58 | (xtal * .audio_clock = 51539600) | 58 | (xtal * .audio_clock = 51539600) |
59 | 59 | ||
60 | Some details about 30/34/35: | ||
61 | |||
62 | - saa7130 - low-price chip, doesn't have mute, that is why all those | ||
63 | cards should have .mute field defined in their tuner structure. | ||
64 | |||
65 | - saa7134 - usual chip | ||
66 | |||
67 | - saa7133/35 - saa7135 is probably a marketing decision, since all those | ||
68 | chips identifies itself as 33 on pci. | ||
60 | 69 | ||
61 | Credits | 70 | Credits |
62 | ======= | 71 | ======= |
diff --git a/MAINTAINERS b/MAINTAINERS index 4db63de9652a..19a9a1c53037 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -512,11 +512,11 @@ W: http://linuxppc64.org | |||
512 | S: Supported | 512 | S: Supported |
513 | 513 | ||
514 | BTTV VIDEO4LINUX DRIVER | 514 | BTTV VIDEO4LINUX DRIVER |
515 | P: Gerd Knorr | 515 | P: Mauro Carvalho Chehab |
516 | M: kraxel@bytesex.org | 516 | M: mchehab@brturbo.com.br |
517 | L: video4linux-list@redhat.com | 517 | L: video4linux-list@redhat.com |
518 | W: http://bytesex.org/bttv/ | 518 | W: http://linuxtv.org |
519 | S: Orphan | 519 | S: Maintained |
520 | 520 | ||
521 | BUSLOGIC SCSI DRIVER | 521 | BUSLOGIC SCSI DRIVER |
522 | P: Leonard N. Zubkoff | 522 | P: Leonard N. Zubkoff |
@@ -2625,10 +2625,11 @@ W: http://rio500.sourceforge.net | |||
2625 | S: Maintained | 2625 | S: Maintained |
2626 | 2626 | ||
2627 | VIDEO FOR LINUX | 2627 | VIDEO FOR LINUX |
2628 | P: Gerd Knorr | 2628 | P: Mauro Carvalho Chehab |
2629 | M: kraxel@bytesex.org | 2629 | M: mchehab@brturbo.com.br |
2630 | L: video4linux-list@redhat.com | 2630 | L: video4linux-list@redhat.com |
2631 | S: Orphan | 2631 | W: http://linuxtv.org |
2632 | S: Maintained | ||
2632 | 2633 | ||
2633 | W1 DALLAS'S 1-WIRE BUS | 2634 | W1 DALLAS'S 1-WIRE BUS |
2634 | P: Evgeniy Polyakov | 2635 | P: Evgeniy Polyakov |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 12 | 3 | SUBLEVEL = 13 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION =-rc1 |
5 | NAME=Woozy Numbat | 5 | NAME=Woozy Numbat |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8d94dcd8ef7..620f2ca94ed2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -361,6 +361,11 @@ config NO_IDLE_HZ | |||
361 | Alternatively, if you want dynamic tick automatically enabled | 361 | Alternatively, if you want dynamic tick automatically enabled |
362 | during boot, pass "dyntick=enable" via the kernel command string. | 362 | during boot, pass "dyntick=enable" via the kernel command string. |
363 | 363 | ||
364 | Please note that dynamic tick may affect the accuracy of | ||
365 | timekeeping on some platforms depending on the implementation. | ||
366 | Currently at least OMAP platform is known to have accurate | ||
367 | timekeeping with dynamic tick. | ||
368 | |||
364 | config ARCH_DISCONTIGMEM_ENABLE | 369 | config ARCH_DISCONTIGMEM_ENABLE |
365 | bool | 370 | bool |
366 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 371 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index b668c48f4399..cf9f46d88061 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
@@ -40,8 +40,11 @@ | |||
40 | * 04-Nov-2004 Ben Dooks | 40 | * 04-Nov-2004 Ben Dooks |
41 | * Fix standard IRQ wake for EINT0..4 and RTC | 41 | * Fix standard IRQ wake for EINT0..4 and RTC |
42 | * | 42 | * |
43 | * 22-Feb-2004 Ben Dooks | 43 | * 22-Feb-2005 Ben Dooks |
44 | * Fixed edge-triggering on ADC IRQ | 44 | * Fixed edge-triggering on ADC IRQ |
45 | * | ||
46 | * 28-Jun-2005 Ben Dooks | ||
47 | * Mark IRQ_LCD valid | ||
45 | */ | 48 | */ |
46 | 49 | ||
47 | #include <linux/init.h> | 50 | #include <linux/init.h> |
@@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { | |||
366 | #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) | 369 | #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) |
367 | #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) | 370 | #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) |
368 | #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) | 371 | #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) |
369 | #define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) | ||
370 | 372 | ||
371 | static inline void | 373 | static inline void |
372 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, | 374 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, |
@@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void) | |||
716 | case IRQ_UART0: | 718 | case IRQ_UART0: |
717 | case IRQ_UART1: | 719 | case IRQ_UART1: |
718 | case IRQ_UART2: | 720 | case IRQ_UART2: |
719 | case IRQ_LCD: | ||
720 | case IRQ_ADCPARENT: | 721 | case IRQ_ADCPARENT: |
721 | set_irq_chip(irqno, &s3c_irq_level_chip); | 722 | set_irq_chip(irqno, &s3c_irq_level_chip); |
722 | set_irq_handler(irqno, do_level_IRQ); | 723 | set_irq_handler(irqno, do_level_IRQ); |
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index ba1a6e9f2b28..8ffb523e6c77 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile | |||
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | |||
6 | oprofilefs.o oprofile_stats.o \ | 6 | oprofilefs.o oprofile_stats.o \ |
7 | timer_int.o ) | 7 | timer_int.o ) |
8 | 8 | ||
9 | oprofile-y := $(DRIVER_OBJS) init.o | 9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o |
10 | oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o | 10 | oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o |
11 | 11 | ||
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c new file mode 100644 index 000000000000..ec58d3e2eb8b --- /dev/null +++ b/arch/arm/oprofile/backtrace.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Arm specific backtracing code for oprofile | ||
3 | * | ||
4 | * Copyright 2005 Openedhand Ltd. | ||
5 | * | ||
6 | * Author: Richard Purdie <rpurdie@openedhand.com> | ||
7 | * | ||
8 | * Based on i386 oprofile backtrace code by John Levon, David Smith | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/oprofile.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <asm/ptrace.h> | ||
20 | #include <asm/uaccess.h> | ||
21 | |||
22 | |||
23 | /* | ||
24 | * The registers we're interested in are at the end of the variable | ||
25 | * length saved register structure. The fp points at the end of this | ||
26 | * structure so the address of this struct is: | ||
27 | * (struct frame_tail *)(xxx->fp)-1 | ||
28 | */ | ||
29 | struct frame_tail { | ||
30 | struct frame_tail *fp; | ||
31 | unsigned long sp; | ||
32 | unsigned long lr; | ||
33 | } __attribute__((packed)); | ||
34 | |||
35 | |||
36 | #ifdef CONFIG_FRAME_POINTER | ||
37 | static struct frame_tail* kernel_backtrace(struct frame_tail *tail) | ||
38 | { | ||
39 | oprofile_add_trace(tail->lr); | ||
40 | |||
41 | /* frame pointers should strictly progress back up the stack | ||
42 | * (towards higher addresses) */ | ||
43 | if (tail >= tail->fp) | ||
44 | return NULL; | ||
45 | |||
46 | return tail->fp-1; | ||
47 | } | ||
48 | #endif | ||
49 | |||
50 | static struct frame_tail* user_backtrace(struct frame_tail *tail) | ||
51 | { | ||
52 | struct frame_tail buftail; | ||
53 | |||
54 | /* hardware pte might not be valid due to dirty/accessed bit emulation | ||
55 | * so we use copy_from_user and benefit from exception fixups */ | ||
56 | if (copy_from_user(&buftail, tail, sizeof(struct frame_tail))) | ||
57 | return NULL; | ||
58 | |||
59 | oprofile_add_trace(buftail.lr); | ||
60 | |||
61 | /* frame pointers should strictly progress back up the stack | ||
62 | * (towards higher addresses) */ | ||
63 | if (tail >= buftail.fp) | ||
64 | return NULL; | ||
65 | |||
66 | return buftail.fp-1; | ||
67 | } | ||
68 | |||
69 | /* Compare two addresses and see if they're on the same page */ | ||
70 | #define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \ | ||
71 | == ((((unsigned long) y) + offset) >> PAGE_SHIFT)) | ||
72 | |||
73 | /* check that the page(s) containing the frame tail are present */ | ||
74 | static int pages_present(struct frame_tail *tail) | ||
75 | { | ||
76 | struct mm_struct * mm = current->mm; | ||
77 | |||
78 | if (!check_user_page_readable(mm, (unsigned long)tail)) | ||
79 | return 0; | ||
80 | |||
81 | if (CMP_ADDR_EQUAL(tail, tail, 8)) | ||
82 | return 1; | ||
83 | |||
84 | if (!check_user_page_readable(mm, ((unsigned long)tail) + 8)) | ||
85 | return 0; | ||
86 | |||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * | | /\ Higher addresses | ||
92 | * | | | ||
93 | * --------------- stack base (address of current_thread_info) | ||
94 | * | thread info | | ||
95 | * . . | ||
96 | * | stack | | ||
97 | * --------------- saved regs->ARM_fp value if valid (frame_tail address) | ||
98 | * . . | ||
99 | * --------------- struct pt_regs stored on stack (struct pt_regs *) | ||
100 | * | | | ||
101 | * . . | ||
102 | * | | | ||
103 | * --------------- %esp | ||
104 | * | | | ||
105 | * | | \/ Lower addresses | ||
106 | * | ||
107 | * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values | ||
108 | */ | ||
109 | static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) | ||
110 | { | ||
111 | unsigned long tailaddr = (unsigned long)tail; | ||
112 | unsigned long stack = (unsigned long)regs; | ||
113 | unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; | ||
114 | |||
115 | return (tailaddr > stack) && (tailaddr < stack_base); | ||
116 | } | ||
117 | |||
118 | void arm_backtrace(struct pt_regs const *regs, unsigned int depth) | ||
119 | { | ||
120 | struct frame_tail *tail; | ||
121 | unsigned long last_address = 0; | ||
122 | |||
123 | tail = ((struct frame_tail *) regs->ARM_fp) - 1; | ||
124 | |||
125 | if (!user_mode(regs)) { | ||
126 | |||
127 | #ifdef CONFIG_FRAME_POINTER | ||
128 | while (depth-- && tail && valid_kernel_stack(tail, regs)) { | ||
129 | tail = kernel_backtrace(tail); | ||
130 | } | ||
131 | #endif | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | while (depth-- && tail && !((unsigned long) tail & 3)) { | ||
136 | if ((!CMP_ADDR_EQUAL(last_address, tail, 0) | ||
137 | || !CMP_ADDR_EQUAL(last_address, tail, 8)) | ||
138 | && !pages_present(tail)) | ||
139 | return; | ||
140 | last_address = (unsigned long) tail; | ||
141 | tail = user_backtrace(tail); | ||
142 | } | ||
143 | } | ||
144 | |||
diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index cce3d3015eb7..d315a3a86c86 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c | |||
@@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
20 | ret = pmu_init(ops, &op_xscale_spec); | 20 | ret = pmu_init(ops, &op_xscale_spec); |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | ops->backtrace = arm_backtrace; | ||
24 | |||
23 | return ret; | 25 | return ret; |
24 | } | 26 | } |
25 | 27 | ||
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2d4caf4781ad..2148d07484b7 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h | |||
@@ -24,6 +24,8 @@ struct op_arm_model_spec { | |||
24 | extern struct op_arm_model_spec op_xscale_spec; | 24 | extern struct op_arm_model_spec op_xscale_spec; |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
28 | |||
27 | extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); | 29 | extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); |
28 | extern void pmu_exit(void); | 30 | extern void pmu_exit(void); |
29 | #endif /* OP_ARM_MODEL_H */ | 31 | #endif /* OP_ARM_MODEL_H */ |
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956512e1..6835f6d47c31 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -70,7 +70,8 @@ void usage(void) | |||
70 | 70 | ||
71 | int main(int argc, char ** argv) | 71 | int main(int argc, char ** argv) |
72 | { | 72 | { |
73 | unsigned int i, c, sz, setup_sectors; | 73 | unsigned int i, sz, setup_sectors; |
74 | int c; | ||
74 | u32 sys_size; | 75 | u32 sys_size; |
75 | byte major_root, minor_root; | 76 | byte major_root, minor_root; |
76 | struct stat sb; | 77 | struct stat sb; |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0f404b..b7808a89d945 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) | |||
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | #ifdef CONFIG_PCI_MMCONFIG | 161 | #ifdef CONFIG_PCI_MMCONFIG |
162 | static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | 162 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ |
163 | struct acpi_table_mcfg_config *pci_mmcfg_config; | ||
164 | int pci_mmcfg_config_num; | ||
165 | |||
166 | int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | ||
163 | { | 167 | { |
164 | struct acpi_table_mcfg *mcfg; | 168 | struct acpi_table_mcfg *mcfg; |
169 | unsigned long i; | ||
170 | int config_size; | ||
165 | 171 | ||
166 | if (!phys_addr || !size) | 172 | if (!phys_addr || !size) |
167 | return -EINVAL; | 173 | return -EINVAL; |
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
172 | return -ENODEV; | 178 | return -ENODEV; |
173 | } | 179 | } |
174 | 180 | ||
175 | if (mcfg->base_reserved) { | 181 | /* how many config structures do we have */ |
176 | printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); | 182 | pci_mmcfg_config_num = 0; |
183 | i = size - sizeof(struct acpi_table_mcfg); | ||
184 | while (i >= sizeof(struct acpi_table_mcfg_config)) { | ||
185 | ++pci_mmcfg_config_num; | ||
186 | i -= sizeof(struct acpi_table_mcfg_config); | ||
187 | }; | ||
188 | if (pci_mmcfg_config_num == 0) { | ||
189 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); | ||
177 | return -ENODEV; | 190 | return -ENODEV; |
178 | } | 191 | } |
179 | 192 | ||
180 | pci_mmcfg_base_addr = mcfg->base_address; | 193 | config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); |
194 | pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); | ||
195 | if (!pci_mmcfg_config) { | ||
196 | printk(KERN_WARNING PREFIX | ||
197 | "No memory for MCFG config tables\n"); | ||
198 | return -ENOMEM; | ||
199 | } | ||
200 | |||
201 | memcpy(pci_mmcfg_config, &mcfg->config, config_size); | ||
202 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
203 | if (mcfg->config[i].base_reserved) { | ||
204 | printk(KERN_ERR PREFIX | ||
205 | "MMCONFIG not in low 4GB of memory\n"); | ||
206 | return -ENODEV; | ||
207 | } | ||
208 | } | ||
181 | 209 | ||
182 | return 0; | 210 | return 0; |
183 | } | 211 | } |
184 | #else | 212 | #endif /* CONFIG_PCI_MMCONFIG */ |
185 | #define acpi_parse_mcfg NULL | ||
186 | #endif /* !CONFIG_PCI_MMCONFIG */ | ||
187 | 213 | ||
188 | #ifdef CONFIG_X86_LOCAL_APIC | 214 | #ifdef CONFIG_X86_LOCAL_APIC |
189 | static int __init | 215 | static int __init |
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) | |||
507 | EXPORT_SYMBOL(acpi_unmap_lsapic); | 533 | EXPORT_SYMBOL(acpi_unmap_lsapic); |
508 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 534 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
509 | 535 | ||
536 | int | ||
537 | acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) | ||
538 | { | ||
539 | /* TBD */ | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | EXPORT_SYMBOL(acpi_register_ioapic); | ||
543 | |||
544 | int | ||
545 | acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) | ||
546 | { | ||
547 | /* TBD */ | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | EXPORT_SYMBOL(acpi_unregister_ioapic); | ||
551 | |||
510 | static unsigned long __init | 552 | static unsigned long __init |
511 | acpi_scan_rsdp ( | 553 | acpi_scan_rsdp ( |
512 | unsigned long start, | 554 | unsigned long start, |
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) | |||
1123 | acpi_process_madt(); | 1165 | acpi_process_madt(); |
1124 | 1166 | ||
1125 | acpi_table_parse(ACPI_HPET, acpi_parse_hpet); | 1167 | acpi_table_parse(ACPI_HPET, acpi_parse_hpet); |
1126 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
1127 | 1168 | ||
1128 | return 0; | 1169 | return 0; |
1129 | } | 1170 | } |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e1af50..87325263cd4f 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | |||
25 | 25 | ||
26 | int pci_routeirq; | 26 | int pci_routeirq; |
27 | int pcibios_last_bus = -1; | 27 | int pcibios_last_bus = -1; |
28 | struct pci_bus *pci_root_bus = NULL; | 28 | unsigned long pirq_table_addr; |
29 | struct pci_bus *pci_root_bus; | ||
29 | struct pci_raw_ops *raw_pci_ops; | 30 | struct pci_raw_ops *raw_pci_ops; |
30 | 31 | ||
31 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) | 32 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) |
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
133 | 134 | ||
134 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); | 135 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); |
135 | 136 | ||
136 | return pci_scan_bus(busnum, &pci_root_ops, NULL); | 137 | return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); |
137 | } | 138 | } |
138 | 139 | ||
139 | extern u8 pci_cache_line_size; | 140 | extern u8 pci_cache_line_size; |
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str) | |||
188 | } else if (!strcmp(str, "biosirq")) { | 189 | } else if (!strcmp(str, "biosirq")) { |
189 | pci_probe |= PCI_BIOS_IRQ_SCAN; | 190 | pci_probe |= PCI_BIOS_IRQ_SCAN; |
190 | return NULL; | 191 | return NULL; |
192 | } else if (!strncmp(str, "pirqaddr=", 9)) { | ||
193 | pirq_table_addr = simple_strtoul(str+9, NULL, 0); | ||
194 | return NULL; | ||
191 | } | 195 | } |
192 | #endif | 196 | #endif |
193 | #ifdef CONFIG_PCI_DIRECT | 197 | #ifdef CONFIG_PCI_DIRECT |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f81e661..78ca1ecbb907 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -58,6 +58,35 @@ struct irq_router_handler { | |||
58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; | 58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Check passed address for the PCI IRQ Routing Table signature | ||
62 | * and perform checksum verification. | ||
63 | */ | ||
64 | |||
65 | static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) | ||
66 | { | ||
67 | struct irq_routing_table *rt; | ||
68 | int i; | ||
69 | u8 sum; | ||
70 | |||
71 | rt = (struct irq_routing_table *) addr; | ||
72 | if (rt->signature != PIRQ_SIGNATURE || | ||
73 | rt->version != PIRQ_VERSION || | ||
74 | rt->size % 16 || | ||
75 | rt->size < sizeof(struct irq_routing_table)) | ||
76 | return NULL; | ||
77 | sum = 0; | ||
78 | for (i=0; i < rt->size; i++) | ||
79 | sum += addr[i]; | ||
80 | if (!sum) { | ||
81 | DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); | ||
82 | return rt; | ||
83 | } | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
61 | * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. | 90 | * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. |
62 | */ | 91 | */ |
63 | 92 | ||
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) | |||
65 | { | 94 | { |
66 | u8 *addr; | 95 | u8 *addr; |
67 | struct irq_routing_table *rt; | 96 | struct irq_routing_table *rt; |
68 | int i; | ||
69 | u8 sum; | ||
70 | 97 | ||
98 | if (pirq_table_addr) { | ||
99 | rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); | ||
100 | if (rt) | ||
101 | return rt; | ||
102 | printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); | ||
103 | } | ||
71 | for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { | 104 | for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { |
72 | rt = (struct irq_routing_table *) addr; | 105 | rt = pirq_check_routing_table(addr); |
73 | if (rt->signature != PIRQ_SIGNATURE || | 106 | if (rt) |
74 | rt->version != PIRQ_VERSION || | ||
75 | rt->size % 16 || | ||
76 | rt->size < sizeof(struct irq_routing_table)) | ||
77 | continue; | ||
78 | sum = 0; | ||
79 | for(i=0; i<rt->size; i++) | ||
80 | sum += addr[i]; | ||
81 | if (!sum) { | ||
82 | DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); | ||
83 | return rt; | 107 | return rt; |
84 | } | ||
85 | } | 108 | } |
86 | return NULL; | 109 | return NULL; |
87 | } | 110 | } |
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e3753869..149a9588c256 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c | |||
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) | |||
45 | 45 | ||
46 | printk("PCI: Probing PCI hardware\n"); | 46 | printk("PCI: Probing PCI hardware\n"); |
47 | pci_root_bus = pcibios_scan_root(0); | 47 | pci_root_bus = pcibios_scan_root(0); |
48 | if (pci_root_bus) | ||
49 | pci_bus_add_devices(pci_root_bus); | ||
48 | 50 | ||
49 | pcibios_fixup_peer_bridges(); | 51 | pcibios_fixup_peer_bridges(); |
50 | 52 | ||
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50aa51f4..60f0e7a1162a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -11,11 +11,9 @@ | |||
11 | 11 | ||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | ||
14 | #include "pci.h" | 15 | #include "pci.h" |
15 | 16 | ||
16 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | ||
17 | u32 pci_mmcfg_base_addr; | ||
18 | |||
19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 17 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
20 | 18 | ||
21 | /* The base address of the last MMCONFIG device accessed */ | 19 | /* The base address of the last MMCONFIG device accessed */ |
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device; | |||
24 | /* | 22 | /* |
25 | * Functions for accessing PCI configuration space with MMCONFIG accesses | 23 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
26 | */ | 24 | */ |
25 | static u32 get_base_addr(unsigned int seg, int bus) | ||
26 | { | ||
27 | int cfg_num = -1; | ||
28 | struct acpi_table_mcfg_config *cfg; | ||
29 | |||
30 | while (1) { | ||
31 | ++cfg_num; | ||
32 | if (cfg_num >= pci_mmcfg_config_num) { | ||
33 | /* something bad is going on, no cfg table is found. */ | ||
34 | /* so we fall back to the old way we used to do this */ | ||
35 | /* and just rely on the first entry to be correct. */ | ||
36 | return pci_mmcfg_config[0].base_address; | ||
37 | } | ||
38 | cfg = &pci_mmcfg_config[cfg_num]; | ||
39 | if (cfg->pci_segment_group_number != seg) | ||
40 | continue; | ||
41 | if ((cfg->start_bus_number <= bus) && | ||
42 | (cfg->end_bus_number >= bus)) | ||
43 | return cfg->base_address; | ||
44 | } | ||
45 | } | ||
27 | 46 | ||
28 | static inline void pci_exp_set_dev_base(int bus, int devfn) | 47 | static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) |
29 | { | 48 | { |
30 | u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); | 49 | u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); |
31 | if (dev_base != mmcfg_last_accessed_device) { | 50 | if (dev_base != mmcfg_last_accessed_device) { |
32 | mmcfg_last_accessed_device = dev_base; | 51 | mmcfg_last_accessed_device = dev_base; |
33 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); | 52 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); |
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
44 | 63 | ||
45 | spin_lock_irqsave(&pci_config_lock, flags); | 64 | spin_lock_irqsave(&pci_config_lock, flags); |
46 | 65 | ||
47 | pci_exp_set_dev_base(bus, devfn); | 66 | pci_exp_set_dev_base(seg, bus, devfn); |
48 | 67 | ||
49 | switch (len) { | 68 | switch (len) { |
50 | case 1: | 69 | case 1: |
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
73 | 92 | ||
74 | spin_lock_irqsave(&pci_config_lock, flags); | 93 | spin_lock_irqsave(&pci_config_lock, flags); |
75 | 94 | ||
76 | pci_exp_set_dev_base(bus, devfn); | 95 | pci_exp_set_dev_base(seg, bus, devfn); |
77 | 96 | ||
78 | switch (len) { | 97 | switch (len) { |
79 | case 1: | 98 | case 1: |
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void) | |||
101 | { | 120 | { |
102 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 121 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
103 | goto out; | 122 | goto out; |
104 | if (!pci_mmcfg_base_addr) | 123 | |
124 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
125 | if ((pci_mmcfg_config_num == 0) || | ||
126 | (pci_mmcfg_config == NULL) || | ||
127 | (pci_mmcfg_config[0].base_address == 0)) | ||
105 | goto out; | 128 | goto out; |
106 | 129 | ||
107 | /* Kludge for now. Don't use mmconfig on AMD systems because | 130 | /* Kludge for now. Don't use mmconfig on AMD systems because |
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e3695461899..adbe17a38f6f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c | |||
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void) | |||
115 | return 0; | 115 | return 0; |
116 | 116 | ||
117 | pci_root_bus = pcibios_scan_root(0); | 117 | pci_root_bus = pcibios_scan_root(0); |
118 | if (pci_root_bus) | ||
119 | pci_bus_add_devices(pci_root_bus); | ||
118 | if (num_online_nodes() > 1) | 120 | if (num_online_nodes() > 1) |
119 | for_each_online_node(quad) { | 121 | for_each_online_node(quad) { |
120 | if (quad == 0) | 122 | if (quad == 0) |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80ca69f3..a80f0f55ff51 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 | 27 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 |
28 | 28 | ||
29 | extern unsigned int pci_probe; | 29 | extern unsigned int pci_probe; |
30 | extern unsigned long pirq_table_addr; | ||
30 | 31 | ||
31 | /* pci-i386.c */ | 32 | /* pci-i386.c */ |
32 | 33 | ||
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 72dfd9e7de0f..cda06f88c66e 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) | |||
236 | if (BAD_MADT_ENTRY(iosapic, end)) | 236 | if (BAD_MADT_ENTRY(iosapic, end)) |
237 | return -EINVAL; | 237 | return -EINVAL; |
238 | 238 | ||
239 | iosapic_init(iosapic->address, iosapic->global_irq_base); | 239 | return iosapic_init(iosapic->address, iosapic->global_irq_base); |
240 | |||
241 | return 0; | ||
242 | } | 240 | } |
243 | 241 | ||
244 | 242 | ||
@@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); | |||
772 | 770 | ||
773 | 771 | ||
774 | #ifdef CONFIG_ACPI_NUMA | 772 | #ifdef CONFIG_ACPI_NUMA |
775 | acpi_status __init | 773 | acpi_status __devinit |
776 | acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | 774 | acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) |
777 | { | 775 | { |
778 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 776 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
@@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | |||
825 | return AE_OK; | 823 | return AE_OK; |
826 | } | 824 | } |
827 | #endif /* CONFIG_NUMA */ | 825 | #endif /* CONFIG_NUMA */ |
826 | |||
827 | int | ||
828 | acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) | ||
829 | { | ||
830 | int err; | ||
831 | |||
832 | if ((err = iosapic_init(phys_addr, gsi_base))) | ||
833 | return err; | ||
834 | |||
835 | #if CONFIG_ACPI_NUMA | ||
836 | acpi_map_iosapic(handle, 0, NULL, NULL); | ||
837 | #endif /* CONFIG_ACPI_NUMA */ | ||
838 | |||
839 | return 0; | ||
840 | } | ||
841 | EXPORT_SYMBOL(acpi_register_ioapic); | ||
842 | |||
843 | int | ||
844 | acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) | ||
845 | { | ||
846 | return iosapic_remove(gsi_base); | ||
847 | } | ||
848 | EXPORT_SYMBOL(acpi_unregister_ioapic); | ||
849 | |||
828 | #endif /* CONFIG_ACPI_BOOT */ | 850 | #endif /* CONFIG_ACPI_BOOT */ |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 88b014381df5..c170be095ccd 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -129,14 +129,13 @@ static struct iosapic { | |||
129 | char __iomem *addr; /* base address of IOSAPIC */ | 129 | char __iomem *addr; /* base address of IOSAPIC */ |
130 | unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ | 130 | unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ |
131 | unsigned short num_rte; /* number of RTE in this IOSAPIC */ | 131 | unsigned short num_rte; /* number of RTE in this IOSAPIC */ |
132 | int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ | ||
132 | #ifdef CONFIG_NUMA | 133 | #ifdef CONFIG_NUMA |
133 | unsigned short node; /* numa node association via pxm */ | 134 | unsigned short node; /* numa node association via pxm */ |
134 | #endif | 135 | #endif |
135 | } iosapic_lists[NR_IOSAPICS]; | 136 | } iosapic_lists[NR_IOSAPICS]; |
136 | 137 | ||
137 | static int num_iosapic; | 138 | static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ |
138 | |||
139 | static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ | ||
140 | 139 | ||
141 | static int iosapic_kmalloc_ok; | 140 | static int iosapic_kmalloc_ok; |
142 | static LIST_HEAD(free_rte_list); | 141 | static LIST_HEAD(free_rte_list); |
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi) | |||
149 | { | 148 | { |
150 | int i; | 149 | int i; |
151 | 150 | ||
152 | for (i = 0; i < num_iosapic; i++) { | 151 | for (i = 0; i < NR_IOSAPICS; i++) { |
153 | if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) | 152 | if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) |
154 | return i; | 153 | return i; |
155 | } | 154 | } |
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, | |||
598 | rte->refcnt++; | 597 | rte->refcnt++; |
599 | list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); | 598 | list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); |
600 | iosapic_intr_info[vector].count++; | 599 | iosapic_intr_info[vector].count++; |
600 | iosapic_lists[index].rtes_inuse++; | ||
601 | } | 601 | } |
602 | else if (vector_is_shared(vector)) { | 602 | else if (vector_is_shared(vector)) { |
603 | struct iosapic_intr_info *info = &iosapic_intr_info[vector]; | 603 | struct iosapic_intr_info *info = &iosapic_intr_info[vector]; |
@@ -778,7 +778,7 @@ void | |||
778 | iosapic_unregister_intr (unsigned int gsi) | 778 | iosapic_unregister_intr (unsigned int gsi) |
779 | { | 779 | { |
780 | unsigned long flags; | 780 | unsigned long flags; |
781 | int irq, vector; | 781 | int irq, vector, index; |
782 | irq_desc_t *idesc; | 782 | irq_desc_t *idesc; |
783 | u32 low32; | 783 | u32 low32; |
784 | unsigned long trigger, polarity; | 784 | unsigned long trigger, polarity; |
@@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi) | |||
819 | list_del(&rte->rte_list); | 819 | list_del(&rte->rte_list); |
820 | iosapic_intr_info[vector].count--; | 820 | iosapic_intr_info[vector].count--; |
821 | iosapic_free_rte(rte); | 821 | iosapic_free_rte(rte); |
822 | index = find_iosapic(gsi); | ||
823 | iosapic_lists[index].rtes_inuse--; | ||
824 | WARN_ON(iosapic_lists[index].rtes_inuse < 0); | ||
822 | 825 | ||
823 | trigger = iosapic_intr_info[vector].trigger; | 826 | trigger = iosapic_intr_info[vector].trigger; |
824 | polarity = iosapic_intr_info[vector].polarity; | 827 | polarity = iosapic_intr_info[vector].polarity; |
@@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat) | |||
952 | } | 955 | } |
953 | } | 956 | } |
954 | 957 | ||
955 | void __init | 958 | static inline int |
959 | iosapic_alloc (void) | ||
960 | { | ||
961 | int index; | ||
962 | |||
963 | for (index = 0; index < NR_IOSAPICS; index++) | ||
964 | if (!iosapic_lists[index].addr) | ||
965 | return index; | ||
966 | |||
967 | printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); | ||
968 | return -1; | ||
969 | } | ||
970 | |||
971 | static inline void | ||
972 | iosapic_free (int index) | ||
973 | { | ||
974 | memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); | ||
975 | } | ||
976 | |||
977 | static inline int | ||
978 | iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) | ||
979 | { | ||
980 | int index; | ||
981 | unsigned int gsi_end, base, end; | ||
982 | |||
983 | /* check gsi range */ | ||
984 | gsi_end = gsi_base + ((ver >> 16) & 0xff); | ||
985 | for (index = 0; index < NR_IOSAPICS; index++) { | ||
986 | if (!iosapic_lists[index].addr) | ||
987 | continue; | ||
988 | |||
989 | base = iosapic_lists[index].gsi_base; | ||
990 | end = base + iosapic_lists[index].num_rte - 1; | ||
991 | |||
992 | if (gsi_base < base && gsi_end < base) | ||
993 | continue;/* OK */ | ||
994 | |||
995 | if (gsi_base > end && gsi_end > end) | ||
996 | continue; /* OK */ | ||
997 | |||
998 | return -EBUSY; | ||
999 | } | ||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | int __devinit | ||
956 | iosapic_init (unsigned long phys_addr, unsigned int gsi_base) | 1004 | iosapic_init (unsigned long phys_addr, unsigned int gsi_base) |
957 | { | 1005 | { |
958 | int num_rte; | 1006 | int num_rte, err, index; |
959 | unsigned int isa_irq, ver; | 1007 | unsigned int isa_irq, ver; |
960 | char __iomem *addr; | 1008 | char __iomem *addr; |
1009 | unsigned long flags; | ||
1010 | |||
1011 | spin_lock_irqsave(&iosapic_lock, flags); | ||
1012 | { | ||
1013 | addr = ioremap(phys_addr, 0); | ||
1014 | ver = iosapic_version(addr); | ||
961 | 1015 | ||
962 | addr = ioremap(phys_addr, 0); | 1016 | if ((err = iosapic_check_gsi_range(gsi_base, ver))) { |
963 | ver = iosapic_version(addr); | 1017 | iounmap(addr); |
1018 | spin_unlock_irqrestore(&iosapic_lock, flags); | ||
1019 | return err; | ||
1020 | } | ||
964 | 1021 | ||
965 | /* | 1022 | /* |
966 | * The MAX_REDIR register holds the highest input pin | 1023 | * The MAX_REDIR register holds the highest input pin |
967 | * number (starting from 0). | 1024 | * number (starting from 0). |
968 | * We add 1 so that we can use it for number of pins (= RTEs) | 1025 | * We add 1 so that we can use it for number of pins (= RTEs) |
969 | */ | 1026 | */ |
970 | num_rte = ((ver >> 16) & 0xff) + 1; | 1027 | num_rte = ((ver >> 16) & 0xff) + 1; |
971 | 1028 | ||
972 | iosapic_lists[num_iosapic].addr = addr; | 1029 | index = iosapic_alloc(); |
973 | iosapic_lists[num_iosapic].gsi_base = gsi_base; | 1030 | iosapic_lists[index].addr = addr; |
974 | iosapic_lists[num_iosapic].num_rte = num_rte; | 1031 | iosapic_lists[index].gsi_base = gsi_base; |
1032 | iosapic_lists[index].num_rte = num_rte; | ||
975 | #ifdef CONFIG_NUMA | 1033 | #ifdef CONFIG_NUMA |
976 | iosapic_lists[num_iosapic].node = MAX_NUMNODES; | 1034 | iosapic_lists[index].node = MAX_NUMNODES; |
977 | #endif | 1035 | #endif |
978 | num_iosapic++; | 1036 | } |
1037 | spin_unlock_irqrestore(&iosapic_lock, flags); | ||
979 | 1038 | ||
980 | if ((gsi_base == 0) && pcat_compat) { | 1039 | if ((gsi_base == 0) && pcat_compat) { |
981 | /* | 1040 | /* |
@@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) | |||
986 | for (isa_irq = 0; isa_irq < 16; ++isa_irq) | 1045 | for (isa_irq = 0; isa_irq < 16; ++isa_irq) |
987 | iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); | 1046 | iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); |
988 | } | 1047 | } |
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | #ifdef CONFIG_HOTPLUG | ||
1052 | int | ||
1053 | iosapic_remove (unsigned int gsi_base) | ||
1054 | { | ||
1055 | int index, err = 0; | ||
1056 | unsigned long flags; | ||
1057 | |||
1058 | spin_lock_irqsave(&iosapic_lock, flags); | ||
1059 | { | ||
1060 | index = find_iosapic(gsi_base); | ||
1061 | if (index < 0) { | ||
1062 | printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", | ||
1063 | __FUNCTION__, gsi_base); | ||
1064 | goto out; | ||
1065 | } | ||
1066 | |||
1067 | if (iosapic_lists[index].rtes_inuse) { | ||
1068 | err = -EBUSY; | ||
1069 | printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", | ||
1070 | __FUNCTION__, gsi_base); | ||
1071 | goto out; | ||
1072 | } | ||
1073 | |||
1074 | iounmap(iosapic_lists[index].addr); | ||
1075 | iosapic_free(index); | ||
1076 | } | ||
1077 | out: | ||
1078 | spin_unlock_irqrestore(&iosapic_lock, flags); | ||
1079 | return err; | ||
989 | } | 1080 | } |
1081 | #endif /* CONFIG_HOTPLUG */ | ||
990 | 1082 | ||
991 | #ifdef CONFIG_NUMA | 1083 | #ifdef CONFIG_NUMA |
992 | void __init | 1084 | void __devinit |
993 | map_iosapic_to_node(unsigned int gsi_base, int node) | 1085 | map_iosapic_to_node(unsigned int gsi_base, int node) |
994 | { | 1086 | { |
995 | int index; | 1087 | int index; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea113..720a861f88be 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, | 312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, |
313 | &info); | 313 | &info); |
314 | 314 | ||
315 | pbus = pci_scan_bus(bus, &pci_root_ops, controller); | 315 | pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); |
316 | if (pbus) | 316 | if (pbus) |
317 | pcibios_setup_root_windows(pbus, controller); | 317 | pcibios_setup_root_windows(pbus, controller); |
318 | 318 | ||
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, | |||
373 | res->end = region->end + offset; | 373 | res->end = region->end + offset; |
374 | } | 374 | } |
375 | 375 | ||
376 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | ||
377 | { | ||
378 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
379 | struct resource *devr = &dev->resource[idx]; | ||
380 | |||
381 | if (!dev->bus) | ||
382 | return 0; | ||
383 | for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { | ||
384 | struct resource *busr = dev->bus->resource[i]; | ||
385 | |||
386 | if (!busr || ((busr->flags ^ devr->flags) & type_mask)) | ||
387 | continue; | ||
388 | if ((devr->start) && (devr->start >= busr->start) && | ||
389 | (devr->end <= busr->end)) | ||
390 | return 1; | ||
391 | } | ||
392 | return 0; | ||
393 | } | ||
394 | |||
376 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 395 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
377 | { | 396 | { |
378 | struct pci_bus_region region; | 397 | struct pci_bus_region region; |
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
386 | region.start = dev->resource[i].start; | 405 | region.start = dev->resource[i].start; |
387 | region.end = dev->resource[i].end; | 406 | region.end = dev->resource[i].end; |
388 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | 407 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); |
389 | pci_claim_resource(dev, i); | 408 | if ((is_valid_resource(dev, i))) |
409 | pci_claim_resource(dev, i); | ||
390 | } | 410 | } |
391 | } | 411 | } |
392 | 412 | ||
@@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b) | |||
398 | { | 418 | { |
399 | struct pci_dev *dev; | 419 | struct pci_dev *dev; |
400 | 420 | ||
421 | if (b->self) { | ||
422 | pci_read_bridge_bases(b); | ||
423 | pcibios_fixup_device_resources(b->self); | ||
424 | } | ||
401 | list_for_each_entry(dev, &b->devices, bus_list) | 425 | list_for_each_entry(dev, &b->devices, bus_list) |
402 | pcibios_fixup_device_resources(dev); | 426 | pcibios_fixup_device_resources(dev); |
403 | 427 | ||
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
418 | u16 cmd, old_cmd; | 442 | u16 cmd, old_cmd; |
419 | int idx; | 443 | int idx; |
420 | struct resource *r; | 444 | struct resource *r; |
445 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
421 | 446 | ||
422 | if (!dev) | 447 | if (!dev) |
423 | return -EINVAL; | 448 | return -EINVAL; |
424 | 449 | ||
425 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 450 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
426 | old_cmd = cmd; | 451 | old_cmd = cmd; |
427 | for (idx=0; idx<6; idx++) { | 452 | for (idx=0; idx<PCI_NUM_RESOURCES; idx++) { |
428 | /* Only set up the desired resources. */ | 453 | /* Only set up the desired resources. */ |
429 | if (!(mask & (1 << idx))) | 454 | if (!(mask & (1 << idx))) |
430 | continue; | 455 | continue; |
431 | 456 | ||
432 | r = &dev->resource[idx]; | 457 | r = &dev->resource[idx]; |
458 | if (!(r->flags & type_mask)) | ||
459 | continue; | ||
460 | if ((idx == PCI_ROM_RESOURCE) && | ||
461 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
462 | continue; | ||
433 | if (!r->start && r->end) { | 463 | if (!r->start && r->end) { |
434 | printk(KERN_ERR | 464 | printk(KERN_ERR |
435 | "PCI: Device %s not available because of resource collisions\n", | 465 | "PCI: Device %s not available because of resource collisions\n", |
@@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
441 | if (r->flags & IORESOURCE_MEM) | 471 | if (r->flags & IORESOURCE_MEM) |
442 | cmd |= PCI_COMMAND_MEMORY; | 472 | cmd |= PCI_COMMAND_MEMORY; |
443 | } | 473 | } |
444 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
445 | cmd |= PCI_COMMAND_MEMORY; | ||
446 | if (cmd != old_cmd) { | 474 | if (cmd != old_cmd) { |
447 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | 475 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); |
448 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 476 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d7b92d72458..70cfb6ffd877 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c | |||
@@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
1495 | *offset += hose->pci_mem_offset; | 1495 | *offset += hose->pci_mem_offset; |
1496 | res_bit = IORESOURCE_MEM; | 1496 | res_bit = IORESOURCE_MEM; |
1497 | } else { | 1497 | } else { |
1498 | io_offset = (unsigned long)hose->io_base_virt; | 1498 | io_offset = hose->io_base_virt - ___IO_BASE; |
1499 | *offset += io_offset; | 1499 | *offset += io_offset; |
1500 | res_bit = IORESOURCE_IO; | 1500 | res_bit = IORESOURCE_IO; |
1501 | } | 1501 | } |
@@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
1522 | 1522 | ||
1523 | /* found it! construct the final physical address */ | 1523 | /* found it! construct the final physical address */ |
1524 | if (mmap_state == pci_mmap_io) | 1524 | if (mmap_state == pci_mmap_io) |
1525 | *offset += hose->io_base_phys - _IO_BASE; | 1525 | *offset += hose->io_base_phys - io_offset; |
1526 | return rp; | 1526 | return rp; |
1527 | } | 1527 | } |
1528 | 1528 | ||
@@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
1739 | return result; | 1739 | return result; |
1740 | } | 1740 | } |
1741 | 1741 | ||
1742 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1743 | const struct resource *rsrc, | ||
1744 | u64 *start, u64 *end) | ||
1745 | { | ||
1746 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
1747 | unsigned long offset = 0; | ||
1748 | |||
1749 | if (hose == NULL) | ||
1750 | return; | ||
1751 | |||
1752 | if (rsrc->flags & IORESOURCE_IO) | ||
1753 | offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; | ||
1754 | |||
1755 | *start = rsrc->start + offset; | ||
1756 | *end = rsrc->end + offset; | ||
1757 | } | ||
1758 | |||
1742 | void __init | 1759 | void __init |
1743 | pci_init_resource(struct resource *res, unsigned long start, unsigned long end, | 1760 | pci_init_resource(struct resource *res, unsigned long start, unsigned long end, |
1744 | int flags, char *name) | 1761 | int flags, char *name) |
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c33adf..ffe300611f00 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c | |||
@@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) | |||
245 | 245 | ||
246 | spin_lock(&desc->lock); | 246 | spin_lock(&desc->lock); |
247 | if (!noirqdebug) | 247 | if (!noirqdebug) |
248 | note_interrupt(irq, desc, action_ret); | 248 | note_interrupt(irq, desc, action_ret, regs); |
249 | if (likely(!(desc->status & IRQ_PENDING))) | 249 | if (likely(!(desc->status & IRQ_PENDING))) |
250 | break; | 250 | break; |
251 | desc->status &= ~IRQ_PENDING; | 251 | desc->status &= ~IRQ_PENDING; |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 580676f87d23..ae6f579d3fa0 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
351 | *offset += hose->pci_mem_offset; | 351 | *offset += hose->pci_mem_offset; |
352 | res_bit = IORESOURCE_MEM; | 352 | res_bit = IORESOURCE_MEM; |
353 | } else { | 353 | } else { |
354 | io_offset = (unsigned long)hose->io_base_virt; | 354 | io_offset = (unsigned long)hose->io_base_virt - pci_io_base; |
355 | *offset += io_offset; | 355 | *offset += io_offset; |
356 | res_bit = IORESOURCE_IO; | 356 | res_bit = IORESOURCE_IO; |
357 | } | 357 | } |
@@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
378 | 378 | ||
379 | /* found it! construct the final physical address */ | 379 | /* found it! construct the final physical address */ |
380 | if (mmap_state == pci_mmap_io) | 380 | if (mmap_state == pci_mmap_io) |
381 | *offset += hose->io_base_phys - io_offset; | 381 | *offset += hose->io_base_phys - io_offset; |
382 | return rp; | 382 | return rp; |
383 | } | 383 | } |
384 | 384 | ||
@@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
944 | } | 944 | } |
945 | EXPORT_SYMBOL(pci_read_irq_line); | 945 | EXPORT_SYMBOL(pci_read_irq_line); |
946 | 946 | ||
947 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
948 | const struct resource *rsrc, | ||
949 | u64 *start, u64 *end) | ||
950 | { | ||
951 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
952 | unsigned long offset = 0; | ||
953 | |||
954 | if (hose == NULL) | ||
955 | return; | ||
956 | |||
957 | if (rsrc->flags & IORESOURCE_IO) | ||
958 | offset = pci_io_base - (unsigned long)hose->io_base_virt + | ||
959 | hose->io_base_phys; | ||
960 | |||
961 | *start = rsrc->start + offset; | ||
962 | *end = rsrc->end + offset; | ||
963 | } | ||
964 | |||
947 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 965 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 262e13d086fe..7a117ef473c5 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -270,66 +270,10 @@ endmenu | |||
270 | 270 | ||
271 | source "drivers/Kconfig" | 271 | source "drivers/Kconfig" |
272 | 272 | ||
273 | config PRINTER | ||
274 | tristate "Parallel printer support" | ||
275 | depends on PARPORT | ||
276 | ---help--- | ||
277 | If you intend to attach a printer to the parallel port of your Linux | ||
278 | box (as opposed to using a serial printer; if the connector at the | ||
279 | printer has 9 or 25 holes ["female"], then it's serial), say Y. | ||
280 | Also read the Printing-HOWTO, available from | ||
281 | <http://www.tldp.org/docs.html#howto>. | ||
282 | |||
283 | It is possible to share one parallel port among several devices | ||
284 | (e.g. printer and ZIP drive) and it is safe to compile the | ||
285 | corresponding drivers into the kernel. If you want to compile this | ||
286 | driver as a module however, choose M here and read | ||
287 | <file:Documentation/parport.txt>. The module will be called lp. | ||
288 | |||
289 | If you have several parallel ports, you can specify which ports to | ||
290 | use with the "lp" kernel command line option. (Try "man bootparam" | ||
291 | or see the documentation of your boot loader (silo) about how to pass | ||
292 | options to the kernel at boot time.) The syntax of the "lp" command | ||
293 | line option can be found in <file:drivers/char/lp.c>. | ||
294 | |||
295 | If you have more than 8 printers, you need to increase the LP_NO | ||
296 | macro in lp.c and the PARPORT_MAX macro in parport.h. | ||
297 | |||
298 | source "mm/Kconfig" | ||
299 | |||
300 | endmenu | ||
301 | |||
302 | source "drivers/base/Kconfig" | ||
303 | |||
304 | source "drivers/video/Kconfig" | ||
305 | |||
306 | source "drivers/mtd/Kconfig" | ||
307 | |||
308 | source "drivers/serial/Kconfig" | ||
309 | |||
310 | if !SUN4 | 273 | if !SUN4 |
311 | source "drivers/sbus/char/Kconfig" | 274 | source "drivers/sbus/char/Kconfig" |
312 | endif | 275 | endif |
313 | 276 | ||
314 | source "drivers/block/Kconfig" | ||
315 | |||
316 | # Don't frighten a common SBus user | ||
317 | if PCI | ||
318 | |||
319 | source "drivers/ide/Kconfig" | ||
320 | |||
321 | endif | ||
322 | |||
323 | source "drivers/isdn/Kconfig" | ||
324 | |||
325 | source "drivers/scsi/Kconfig" | ||
326 | |||
327 | source "drivers/fc4/Kconfig" | ||
328 | |||
329 | source "drivers/md/Kconfig" | ||
330 | |||
331 | source "net/Kconfig" | ||
332 | |||
333 | # This one must be before the filesystem configs. -DaveM | 277 | # This one must be before the filesystem configs. -DaveM |
334 | 278 | ||
335 | menu "Unix98 PTY support" | 279 | menu "Unix98 PTY support" |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b693c232fd07..657e88aa0902 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -7,25 +7,50 @@ | |||
7 | 7 | ||
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | ||
10 | #include "pci.h" | 11 | #include "pci.h" |
11 | 12 | ||
12 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 13 | #define MMCONFIG_APER_SIZE (256*1024*1024) |
13 | 14 | ||
14 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | ||
15 | u32 pci_mmcfg_base_addr; | ||
16 | |||
17 | /* Static virtual mapping of the MMCONFIG aperture */ | 15 | /* Static virtual mapping of the MMCONFIG aperture */ |
18 | char *pci_mmcfg_virt; | 16 | struct mmcfg_virt { |
17 | struct acpi_table_mcfg_config *cfg; | ||
18 | char *virt; | ||
19 | }; | ||
20 | static struct mmcfg_virt *pci_mmcfg_virt; | ||
19 | 21 | ||
20 | static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) | 22 | static char *get_virt(unsigned int seg, int bus) |
21 | { | 23 | { |
22 | return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); | 24 | int cfg_num = -1; |
25 | struct acpi_table_mcfg_config *cfg; | ||
26 | |||
27 | while (1) { | ||
28 | ++cfg_num; | ||
29 | if (cfg_num >= pci_mmcfg_config_num) { | ||
30 | /* something bad is going on, no cfg table is found. */ | ||
31 | /* so we fall back to the old way we used to do this */ | ||
32 | /* and just rely on the first entry to be correct. */ | ||
33 | return pci_mmcfg_virt[0].virt; | ||
34 | } | ||
35 | cfg = pci_mmcfg_virt[cfg_num].cfg; | ||
36 | if (cfg->pci_segment_group_number != seg) | ||
37 | continue; | ||
38 | if ((cfg->start_bus_number <= bus) && | ||
39 | (cfg->end_bus_number >= bus)) | ||
40 | return pci_mmcfg_virt[cfg_num].virt; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | ||
45 | { | ||
46 | |||
47 | return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); | ||
23 | } | 48 | } |
24 | 49 | ||
25 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | 50 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, |
26 | unsigned int devfn, int reg, int len, u32 *value) | 51 | unsigned int devfn, int reg, int len, u32 *value) |
27 | { | 52 | { |
28 | char *addr = pci_dev_base(bus, devfn); | 53 | char *addr = pci_dev_base(seg, bus, devfn); |
29 | 54 | ||
30 | if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) | 55 | if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) |
31 | return -EINVAL; | 56 | return -EINVAL; |
@@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
48 | static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | 73 | static int pci_mmcfg_write(unsigned int seg, unsigned int bus, |
49 | unsigned int devfn, int reg, int len, u32 value) | 74 | unsigned int devfn, int reg, int len, u32 value) |
50 | { | 75 | { |
51 | char *addr = pci_dev_base(bus,devfn); | 76 | char *addr = pci_dev_base(seg, bus, devfn); |
52 | 77 | ||
53 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) | 78 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) |
54 | return -EINVAL; | 79 | return -EINVAL; |
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = { | |||
75 | 100 | ||
76 | static int __init pci_mmcfg_init(void) | 101 | static int __init pci_mmcfg_init(void) |
77 | { | 102 | { |
103 | int i; | ||
104 | |||
78 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 105 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
79 | return 0; | 106 | return 0; |
80 | if (!pci_mmcfg_base_addr) | 107 | |
108 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
109 | if ((pci_mmcfg_config_num == 0) || | ||
110 | (pci_mmcfg_config == NULL) || | ||
111 | (pci_mmcfg_config[0].base_address == 0)) | ||
81 | return 0; | 112 | return 0; |
82 | 113 | ||
83 | /* Kludge for now. Don't use mmconfig on AMD systems because | 114 | /* Kludge for now. Don't use mmconfig on AMD systems because |
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void) | |||
88 | return 0; | 119 | return 0; |
89 | 120 | ||
90 | /* RED-PEN i386 doesn't do _nocache right now */ | 121 | /* RED-PEN i386 doesn't do _nocache right now */ |
91 | pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); | 122 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); |
92 | if (!pci_mmcfg_virt) { | 123 | if (pci_mmcfg_virt == NULL) { |
93 | printk("PCI: Cannot map mmconfig aperture\n"); | 124 | printk("PCI: Can not allocate memory for mmconfig structures\n"); |
94 | return 0; | 125 | return 0; |
95 | } | 126 | } |
127 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
128 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; | ||
129 | pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); | ||
130 | if (!pci_mmcfg_virt[i].virt) { | ||
131 | printk("PCI: Cannot map mmconfig aperture for segment %d\n", | ||
132 | pci_mmcfg_config[i].pci_segment_group_number); | ||
133 | return 0; | ||
134 | } | ||
135 | printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); | ||
136 | } | ||
96 | 137 | ||
97 | printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); | ||
98 | raw_pci_ops = &pci_mmcfg; | 138 | raw_pci_ops = &pci_mmcfg; |
99 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 139 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
100 | 140 | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 5a0adbf8bc04..97013ddfa202 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle) | |||
153 | return_VALUE(-ENODEV); | 153 | return_VALUE(-ENODEV); |
154 | } | 154 | } |
155 | 155 | ||
156 | result = acpi_bus_scan(*device); | 156 | result = acpi_bus_start(*device); |
157 | 157 | ||
158 | return_VALUE(result); | 158 | return_VALUE(result); |
159 | } | 159 | } |
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 5d19b39e9e2b..5148f3c10b5c 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -61,15 +61,14 @@ acpi_pci_data_handler ( | |||
61 | 61 | ||
62 | 62 | ||
63 | /** | 63 | /** |
64 | * acpi_os_get_pci_id | 64 | * acpi_get_pci_id |
65 | * ------------------ | 65 | * ------------------ |
66 | * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) | 66 | * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) |
67 | * to resolve PCI information for ACPI-PCI devices defined in the namespace. | 67 | * to resolve PCI information for ACPI-PCI devices defined in the namespace. |
68 | * This typically occurs when resolving PCI operation region information. | 68 | * This typically occurs when resolving PCI operation region information. |
69 | */ | 69 | */ |
70 | #ifdef ACPI_FUTURE_USAGE | ||
71 | acpi_status | 70 | acpi_status |
72 | acpi_os_get_pci_id ( | 71 | acpi_get_pci_id ( |
73 | acpi_handle handle, | 72 | acpi_handle handle, |
74 | struct acpi_pci_id *id) | 73 | struct acpi_pci_id *id) |
75 | { | 74 | { |
@@ -78,7 +77,7 @@ acpi_os_get_pci_id ( | |||
78 | struct acpi_device *device = NULL; | 77 | struct acpi_device *device = NULL; |
79 | struct acpi_pci_data *data = NULL; | 78 | struct acpi_pci_data *data = NULL; |
80 | 79 | ||
81 | ACPI_FUNCTION_TRACE("acpi_os_get_pci_id"); | 80 | ACPI_FUNCTION_TRACE("acpi_get_pci_id"); |
82 | 81 | ||
83 | if (!id) | 82 | if (!id) |
84 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 83 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
@@ -92,7 +91,7 @@ acpi_os_get_pci_id ( | |||
92 | } | 91 | } |
93 | 92 | ||
94 | status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); | 93 | status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); |
95 | if (ACPI_FAILURE(status) || !data || !data->dev) { | 94 | if (ACPI_FAILURE(status) || !data) { |
96 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 95 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
97 | "Invalid ACPI-PCI context for device %s\n", | 96 | "Invalid ACPI-PCI context for device %s\n", |
98 | acpi_device_bid(device))); | 97 | acpi_device_bid(device))); |
@@ -115,7 +114,7 @@ acpi_os_get_pci_id ( | |||
115 | 114 | ||
116 | return_ACPI_STATUS(AE_OK); | 115 | return_ACPI_STATUS(AE_OK); |
117 | } | 116 | } |
118 | #endif /* ACPI_FUTURE_USAGE */ | 117 | EXPORT_SYMBOL(acpi_get_pci_id); |
119 | 118 | ||
120 | 119 | ||
121 | int | 120 | int |
@@ -129,6 +128,8 @@ acpi_pci_bind ( | |||
129 | char *pathname = NULL; | 128 | char *pathname = NULL; |
130 | struct acpi_buffer buffer = {0, NULL}; | 129 | struct acpi_buffer buffer = {0, NULL}; |
131 | acpi_handle handle = NULL; | 130 | acpi_handle handle = NULL; |
131 | struct pci_dev *dev; | ||
132 | struct pci_bus *bus; | ||
132 | 133 | ||
133 | ACPI_FUNCTION_TRACE("acpi_pci_bind"); | 134 | ACPI_FUNCTION_TRACE("acpi_pci_bind"); |
134 | 135 | ||
@@ -193,8 +194,20 @@ acpi_pci_bind ( | |||
193 | * Locate matching device in PCI namespace. If it doesn't exist | 194 | * Locate matching device in PCI namespace. If it doesn't exist |
194 | * this typically means that the device isn't currently inserted | 195 | * this typically means that the device isn't currently inserted |
195 | * (e.g. docking station, port replicator, etc.). | 196 | * (e.g. docking station, port replicator, etc.). |
197 | * We cannot simply search the global pci device list, since | ||
198 | * PCI devices are added to the global pci list when the root | ||
199 | * bridge start ops are run, which may not have happened yet. | ||
196 | */ | 200 | */ |
197 | data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); | 201 | bus = pci_find_bus(data->id.segment, data->id.bus); |
202 | if (bus) { | ||
203 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
204 | if (dev->devfn == PCI_DEVFN(data->id.device, | ||
205 | data->id.function)) { | ||
206 | data->dev = dev; | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | } | ||
198 | if (!data->dev) { | 211 | if (!data->dev) { |
199 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 212 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
200 | "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", | 213 | "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7e6b8e3b2ed4..5d2f77fcd50c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root") | |||
46 | 46 | ||
47 | static int acpi_pci_root_add (struct acpi_device *device); | 47 | static int acpi_pci_root_add (struct acpi_device *device); |
48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); | 48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); |
49 | static int acpi_pci_root_start (struct acpi_device *device); | ||
49 | 50 | ||
50 | static struct acpi_driver acpi_pci_root_driver = { | 51 | static struct acpi_driver acpi_pci_root_driver = { |
51 | .name = ACPI_PCI_ROOT_DRIVER_NAME, | 52 | .name = ACPI_PCI_ROOT_DRIVER_NAME, |
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
54 | .ops = { | 55 | .ops = { |
55 | .add = acpi_pci_root_add, | 56 | .add = acpi_pci_root_add, |
56 | .remove = acpi_pci_root_remove, | 57 | .remove = acpi_pci_root_remove, |
58 | .start = acpi_pci_root_start, | ||
57 | }, | 59 | }, |
58 | }; | 60 | }; |
59 | 61 | ||
@@ -169,6 +171,7 @@ acpi_pci_root_add ( | |||
169 | if (!root) | 171 | if (!root) |
170 | return_VALUE(-ENOMEM); | 172 | return_VALUE(-ENOMEM); |
171 | memset(root, 0, sizeof(struct acpi_pci_root)); | 173 | memset(root, 0, sizeof(struct acpi_pci_root)); |
174 | INIT_LIST_HEAD(&root->node); | ||
172 | 175 | ||
173 | root->handle = device->handle; | 176 | root->handle = device->handle; |
174 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 177 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
@@ -298,12 +301,31 @@ acpi_pci_root_add ( | |||
298 | root->id.bus); | 301 | root->id.bus); |
299 | 302 | ||
300 | end: | 303 | end: |
301 | if (result) | 304 | if (result) { |
305 | if (!list_empty(&root->node)) | ||
306 | list_del(&root->node); | ||
302 | kfree(root); | 307 | kfree(root); |
308 | } | ||
303 | 309 | ||
304 | return_VALUE(result); | 310 | return_VALUE(result); |
305 | } | 311 | } |
306 | 312 | ||
313 | static int | ||
314 | acpi_pci_root_start ( | ||
315 | struct acpi_device *device) | ||
316 | { | ||
317 | struct acpi_pci_root *root; | ||
318 | |||
319 | ACPI_FUNCTION_TRACE("acpi_pci_root_start"); | ||
320 | |||
321 | list_for_each_entry(root, &acpi_pci_roots, node) { | ||
322 | if (root->handle == device->handle) { | ||
323 | pci_bus_add_devices(root->bus); | ||
324 | return_VALUE(0); | ||
325 | } | ||
326 | } | ||
327 | return_VALUE(-ENODEV); | ||
328 | } | ||
307 | 329 | ||
308 | static int | 330 | static int |
309 | acpi_pci_root_remove ( | 331 | acpi_pci_root_remove ( |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index f4778747e889..76156ac91bd3 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -723,7 +723,7 @@ int acpi_processor_device_add( | |||
723 | return_VALUE(-ENODEV); | 723 | return_VALUE(-ENODEV); |
724 | } | 724 | } |
725 | 725 | ||
726 | acpi_bus_scan(*device); | 726 | acpi_bus_start(*device); |
727 | 727 | ||
728 | pr = acpi_driver_data(*device); | 728 | pr = acpi_driver_data(*device); |
729 | if (!pr) | 729 | if (!pr) |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e85885593280..337d49b5564b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -553,20 +553,29 @@ acpi_bus_driver_init ( | |||
553 | * upon possible configuration and currently allocated resources. | 553 | * upon possible configuration and currently allocated resources. |
554 | */ | 554 | */ |
555 | 555 | ||
556 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); | ||
557 | return_VALUE(0); | ||
558 | } | ||
559 | |||
560 | int | ||
561 | acpi_start_single_object ( | ||
562 | struct acpi_device *device) | ||
563 | { | ||
564 | int result = 0; | ||
565 | struct acpi_driver *driver; | ||
566 | |||
567 | ACPI_FUNCTION_TRACE("acpi_start_single_object"); | ||
568 | |||
569 | if (!(driver = device->driver)) | ||
570 | return_VALUE(0); | ||
571 | |||
556 | if (driver->ops.start) { | 572 | if (driver->ops.start) { |
557 | result = driver->ops.start(device); | 573 | result = driver->ops.start(device); |
558 | if (result && driver->ops.remove) | 574 | if (result && driver->ops.remove) |
559 | driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); | 575 | driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); |
560 | return_VALUE(result); | ||
561 | } | 576 | } |
562 | 577 | ||
563 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); | 578 | return_VALUE(result); |
564 | |||
565 | if (driver->ops.scan) { | ||
566 | driver->ops.scan(device); | ||
567 | } | ||
568 | |||
569 | return_VALUE(0); | ||
570 | } | 579 | } |
571 | 580 | ||
572 | static int acpi_driver_attach(struct acpi_driver * drv) | 581 | static int acpi_driver_attach(struct acpi_driver * drv) |
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv) | |||
586 | 595 | ||
587 | if (!acpi_bus_match(dev, drv)) { | 596 | if (!acpi_bus_match(dev, drv)) { |
588 | if (!acpi_bus_driver_init(dev, drv)) { | 597 | if (!acpi_bus_driver_init(dev, drv)) { |
598 | acpi_start_single_object(dev); | ||
589 | atomic_inc(&drv->references); | 599 | atomic_inc(&drv->references); |
590 | count++; | 600 | count++; |
591 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", | 601 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", |
@@ -1009,8 +1019,8 @@ acpi_bus_remove ( | |||
1009 | } | 1019 | } |
1010 | 1020 | ||
1011 | 1021 | ||
1012 | int | 1022 | static int |
1013 | acpi_bus_add ( | 1023 | acpi_add_single_object ( |
1014 | struct acpi_device **child, | 1024 | struct acpi_device **child, |
1015 | struct acpi_device *parent, | 1025 | struct acpi_device *parent, |
1016 | acpi_handle handle, | 1026 | acpi_handle handle, |
@@ -1019,7 +1029,7 @@ acpi_bus_add ( | |||
1019 | int result = 0; | 1029 | int result = 0; |
1020 | struct acpi_device *device = NULL; | 1030 | struct acpi_device *device = NULL; |
1021 | 1031 | ||
1022 | ACPI_FUNCTION_TRACE("acpi_bus_add"); | 1032 | ACPI_FUNCTION_TRACE("acpi_add_single_object"); |
1023 | 1033 | ||
1024 | if (!child) | 1034 | if (!child) |
1025 | return_VALUE(-EINVAL); | 1035 | return_VALUE(-EINVAL); |
@@ -1140,7 +1150,7 @@ acpi_bus_add ( | |||
1140 | * | 1150 | * |
1141 | * TBD: Assumes LDM provides driver hot-plug capability. | 1151 | * TBD: Assumes LDM provides driver hot-plug capability. |
1142 | */ | 1152 | */ |
1143 | acpi_bus_find_driver(device); | 1153 | result = acpi_bus_find_driver(device); |
1144 | 1154 | ||
1145 | end: | 1155 | end: |
1146 | if (!result) | 1156 | if (!result) |
@@ -1153,10 +1163,10 @@ end: | |||
1153 | 1163 | ||
1154 | return_VALUE(result); | 1164 | return_VALUE(result); |
1155 | } | 1165 | } |
1156 | EXPORT_SYMBOL(acpi_bus_add); | ||
1157 | 1166 | ||
1158 | 1167 | ||
1159 | int acpi_bus_scan (struct acpi_device *start) | 1168 | static int acpi_bus_scan (struct acpi_device *start, |
1169 | struct acpi_bus_ops *ops) | ||
1160 | { | 1170 | { |
1161 | acpi_status status = AE_OK; | 1171 | acpi_status status = AE_OK; |
1162 | struct acpi_device *parent = NULL; | 1172 | struct acpi_device *parent = NULL; |
@@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start) | |||
1229 | continue; | 1239 | continue; |
1230 | } | 1240 | } |
1231 | 1241 | ||
1232 | status = acpi_bus_add(&child, parent, chandle, type); | 1242 | if (ops->acpi_op_add) |
1233 | if (ACPI_FAILURE(status)) | 1243 | status = acpi_add_single_object(&child, parent, |
1234 | continue; | 1244 | chandle, type); |
1245 | else | ||
1246 | status = acpi_bus_get_device(chandle, &child); | ||
1247 | |||
1248 | if (ACPI_FAILURE(status)) | ||
1249 | continue; | ||
1250 | |||
1251 | if (ops->acpi_op_start) { | ||
1252 | status = acpi_start_single_object(child); | ||
1253 | if (ACPI_FAILURE(status)) | ||
1254 | continue; | ||
1255 | } | ||
1235 | 1256 | ||
1236 | /* | 1257 | /* |
1237 | * If the device is present, enabled, and functioning then | 1258 | * If the device is present, enabled, and functioning then |
@@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start) | |||
1257 | 1278 | ||
1258 | return_VALUE(0); | 1279 | return_VALUE(0); |
1259 | } | 1280 | } |
1260 | EXPORT_SYMBOL(acpi_bus_scan); | ||
1261 | 1281 | ||
1282 | int | ||
1283 | acpi_bus_add ( | ||
1284 | struct acpi_device **child, | ||
1285 | struct acpi_device *parent, | ||
1286 | acpi_handle handle, | ||
1287 | int type) | ||
1288 | { | ||
1289 | int result; | ||
1290 | struct acpi_bus_ops ops; | ||
1291 | |||
1292 | ACPI_FUNCTION_TRACE("acpi_bus_add"); | ||
1293 | |||
1294 | result = acpi_add_single_object(child, parent, handle, type); | ||
1295 | if (!result) { | ||
1296 | memset(&ops, 0, sizeof(ops)); | ||
1297 | ops.acpi_op_add = 1; | ||
1298 | result = acpi_bus_scan(*child, &ops); | ||
1299 | } | ||
1300 | return_VALUE(result); | ||
1301 | } | ||
1302 | EXPORT_SYMBOL(acpi_bus_add); | ||
1303 | |||
1304 | int | ||
1305 | acpi_bus_start ( | ||
1306 | struct acpi_device *device) | ||
1307 | { | ||
1308 | int result; | ||
1309 | struct acpi_bus_ops ops; | ||
1310 | |||
1311 | ACPI_FUNCTION_TRACE("acpi_bus_start"); | ||
1312 | |||
1313 | if (!device) | ||
1314 | return_VALUE(-EINVAL); | ||
1315 | |||
1316 | result = acpi_start_single_object(device); | ||
1317 | if (!result) { | ||
1318 | memset(&ops, 0, sizeof(ops)); | ||
1319 | ops.acpi_op_start = 1; | ||
1320 | result = acpi_bus_scan(device, &ops); | ||
1321 | } | ||
1322 | return_VALUE(result); | ||
1323 | } | ||
1324 | EXPORT_SYMBOL(acpi_bus_start); | ||
1262 | 1325 | ||
1263 | static int | 1326 | static int |
1264 | acpi_bus_trim(struct acpi_device *start, | 1327 | acpi_bus_trim(struct acpi_device *start, |
@@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed ( | |||
1331 | /* | 1394 | /* |
1332 | * Enumerate all fixed-feature devices. | 1395 | * Enumerate all fixed-feature devices. |
1333 | */ | 1396 | */ |
1334 | if (acpi_fadt.pwr_button == 0) | 1397 | if (acpi_fadt.pwr_button == 0) { |
1335 | result = acpi_bus_add(&device, acpi_root, | 1398 | result = acpi_add_single_object(&device, acpi_root, |
1336 | NULL, ACPI_BUS_TYPE_POWER_BUTTON); | 1399 | NULL, ACPI_BUS_TYPE_POWER_BUTTON); |
1400 | if (!result) | ||
1401 | result = acpi_start_single_object(device); | ||
1402 | } | ||
1337 | 1403 | ||
1338 | if (acpi_fadt.sleep_button == 0) | 1404 | if (acpi_fadt.sleep_button == 0) { |
1339 | result = acpi_bus_add(&device, acpi_root, | 1405 | result = acpi_add_single_object(&device, acpi_root, |
1340 | NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); | 1406 | NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); |
1407 | if (!result) | ||
1408 | result = acpi_start_single_object(device); | ||
1409 | } | ||
1341 | 1410 | ||
1342 | return_VALUE(result); | 1411 | return_VALUE(result); |
1343 | } | 1412 | } |
@@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed ( | |||
1346 | static int __init acpi_scan_init(void) | 1415 | static int __init acpi_scan_init(void) |
1347 | { | 1416 | { |
1348 | int result; | 1417 | int result; |
1418 | struct acpi_bus_ops ops; | ||
1349 | 1419 | ||
1350 | ACPI_FUNCTION_TRACE("acpi_scan_init"); | 1420 | ACPI_FUNCTION_TRACE("acpi_scan_init"); |
1351 | 1421 | ||
@@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void) | |||
1357 | /* | 1427 | /* |
1358 | * Create the root device in the bus's device tree | 1428 | * Create the root device in the bus's device tree |
1359 | */ | 1429 | */ |
1360 | result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, | 1430 | result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, |
1361 | ACPI_BUS_TYPE_SYSTEM); | 1431 | ACPI_BUS_TYPE_SYSTEM); |
1362 | if (result) | 1432 | if (result) |
1363 | goto Done; | 1433 | goto Done; |
1364 | 1434 | ||
1435 | result = acpi_start_single_object(acpi_root); | ||
1436 | |||
1365 | /* | 1437 | /* |
1366 | * Enumerate devices in the ACPI namespace. | 1438 | * Enumerate devices in the ACPI namespace. |
1367 | */ | 1439 | */ |
1368 | result = acpi_bus_scan_fixed(acpi_root); | 1440 | result = acpi_bus_scan_fixed(acpi_root); |
1369 | if (!result) | 1441 | if (!result) { |
1370 | result = acpi_bus_scan(acpi_root); | 1442 | memset(&ops, 0, sizeof(ops)); |
1443 | ops.acpi_op_add = 1; | ||
1444 | ops.acpi_op_start = 1; | ||
1445 | result = acpi_bus_scan(acpi_root, &ops); | ||
1446 | } | ||
1371 | 1447 | ||
1372 | if (result) | 1448 | if (result) |
1373 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1449 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 97fe13f7f07c..652281402c92 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -74,6 +74,8 @@ static ssize_t | |||
74 | firmware_timeout_store(struct class *class, const char *buf, size_t count) | 74 | firmware_timeout_store(struct class *class, const char *buf, size_t count) |
75 | { | 75 | { |
76 | loading_timeout = simple_strtol(buf, NULL, 10); | 76 | loading_timeout = simple_strtol(buf, NULL, 10); |
77 | if (loading_timeout < 0) | ||
78 | loading_timeout = 0; | ||
77 | return count; | 79 | return count; |
78 | } | 80 | } |
79 | 81 | ||
@@ -138,6 +140,10 @@ firmware_loading_store(struct class_device *class_dev, | |||
138 | switch (loading) { | 140 | switch (loading) { |
139 | case 1: | 141 | case 1: |
140 | down(&fw_lock); | 142 | down(&fw_lock); |
143 | if (!fw_priv->fw) { | ||
144 | up(&fw_lock); | ||
145 | break; | ||
146 | } | ||
141 | vfree(fw_priv->fw->data); | 147 | vfree(fw_priv->fw->data); |
142 | fw_priv->fw->data = NULL; | 148 | fw_priv->fw->data = NULL; |
143 | fw_priv->fw->size = 0; | 149 | fw_priv->fw->size = 0; |
@@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj, | |||
178 | 184 | ||
179 | down(&fw_lock); | 185 | down(&fw_lock); |
180 | fw = fw_priv->fw; | 186 | fw = fw_priv->fw; |
181 | if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { | 187 | if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { |
182 | ret_count = -ENODEV; | 188 | ret_count = -ENODEV; |
183 | goto out; | 189 | goto out; |
184 | } | 190 | } |
@@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj, | |||
238 | 244 | ||
239 | if (!capable(CAP_SYS_RAWIO)) | 245 | if (!capable(CAP_SYS_RAWIO)) |
240 | return -EPERM; | 246 | return -EPERM; |
247 | |||
241 | down(&fw_lock); | 248 | down(&fw_lock); |
242 | fw = fw_priv->fw; | 249 | fw = fw_priv->fw; |
243 | if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { | 250 | if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { |
244 | retval = -ENODEV; | 251 | retval = -ENODEV; |
245 | goto out; | 252 | goto out; |
246 | } | 253 | } |
@@ -418,7 +425,7 @@ request_firmware(const struct firmware **firmware_p, const char *name, | |||
418 | 425 | ||
419 | fw_priv = class_get_devdata(class_dev); | 426 | fw_priv = class_get_devdata(class_dev); |
420 | 427 | ||
421 | if (loading_timeout) { | 428 | if (loading_timeout > 0) { |
422 | fw_priv->timeout.expires = jiffies + loading_timeout * HZ; | 429 | fw_priv->timeout.expires = jiffies + loading_timeout * HZ; |
423 | add_timer(&fw_priv->timeout); | 430 | add_timer(&fw_priv->timeout); |
424 | } | 431 | } |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 653512b77570..3e9fb6e4a52a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -786,7 +786,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
786 | 786 | ||
787 | case CCISS_GETLUNINFO: { | 787 | case CCISS_GETLUNINFO: { |
788 | LogvolInfo_struct luninfo; | 788 | LogvolInfo_struct luninfo; |
789 | int i; | ||
790 | 789 | ||
791 | luninfo.LunID = drv->LunID; | 790 | luninfo.LunID = drv->LunID; |
792 | luninfo.num_opens = drv->usage_count; | 791 | luninfo.num_opens = drv->usage_count; |
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 234fdcfbdf01..692a5fced76e 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c | |||
@@ -1867,19 +1867,20 @@ static void freed_request(request_queue_t *q, int rw) | |||
1867 | 1867 | ||
1868 | #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) | 1868 | #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) |
1869 | /* | 1869 | /* |
1870 | * Get a free request, queue_lock must not be held | 1870 | * Get a free request, queue_lock must be held. |
1871 | * Returns NULL on failure, with queue_lock held. | ||
1872 | * Returns !NULL on success, with queue_lock *not held*. | ||
1871 | */ | 1873 | */ |
1872 | static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, | 1874 | static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, |
1873 | int gfp_mask) | 1875 | int gfp_mask) |
1874 | { | 1876 | { |
1875 | struct request *rq = NULL; | 1877 | struct request *rq = NULL; |
1876 | struct request_list *rl = &q->rq; | 1878 | struct request_list *rl = &q->rq; |
1877 | struct io_context *ioc = get_io_context(gfp_mask); | 1879 | struct io_context *ioc = current_io_context(GFP_ATOMIC); |
1878 | 1880 | ||
1879 | if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) | 1881 | if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) |
1880 | goto out; | 1882 | goto out; |
1881 | 1883 | ||
1882 | spin_lock_irq(q->queue_lock); | ||
1883 | if (rl->count[rw]+1 >= q->nr_requests) { | 1884 | if (rl->count[rw]+1 >= q->nr_requests) { |
1884 | /* | 1885 | /* |
1885 | * The queue will fill after this allocation, so set it as | 1886 | * The queue will fill after this allocation, so set it as |
@@ -1907,11 +1908,18 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, | |||
1907 | * The queue is full and the allocating process is not a | 1908 | * The queue is full and the allocating process is not a |
1908 | * "batcher", and not exempted by the IO scheduler | 1909 | * "batcher", and not exempted by the IO scheduler |
1909 | */ | 1910 | */ |
1910 | spin_unlock_irq(q->queue_lock); | ||
1911 | goto out; | 1911 | goto out; |
1912 | } | 1912 | } |
1913 | 1913 | ||
1914 | get_rq: | 1914 | get_rq: |
1915 | /* | ||
1916 | * Only allow batching queuers to allocate up to 50% over the defined | ||
1917 | * limit of requests, otherwise we could have thousands of requests | ||
1918 | * allocated with any setting of ->nr_requests | ||
1919 | */ | ||
1920 | if (rl->count[rw] >= (3 * q->nr_requests / 2)) | ||
1921 | goto out; | ||
1922 | |||
1915 | rl->count[rw]++; | 1923 | rl->count[rw]++; |
1916 | rl->starved[rw] = 0; | 1924 | rl->starved[rw] = 0; |
1917 | if (rl->count[rw] >= queue_congestion_on_threshold(q)) | 1925 | if (rl->count[rw] >= queue_congestion_on_threshold(q)) |
@@ -1941,7 +1949,6 @@ rq_starved: | |||
1941 | if (unlikely(rl->count[rw] == 0)) | 1949 | if (unlikely(rl->count[rw] == 0)) |
1942 | rl->starved[rw] = 1; | 1950 | rl->starved[rw] = 1; |
1943 | 1951 | ||
1944 | spin_unlock_irq(q->queue_lock); | ||
1945 | goto out; | 1952 | goto out; |
1946 | } | 1953 | } |
1947 | 1954 | ||
@@ -1951,21 +1958,23 @@ rq_starved: | |||
1951 | rq_init(q, rq); | 1958 | rq_init(q, rq); |
1952 | rq->rl = rl; | 1959 | rq->rl = rl; |
1953 | out: | 1960 | out: |
1954 | put_io_context(ioc); | ||
1955 | return rq; | 1961 | return rq; |
1956 | } | 1962 | } |
1957 | 1963 | ||
1958 | /* | 1964 | /* |
1959 | * No available requests for this queue, unplug the device and wait for some | 1965 | * No available requests for this queue, unplug the device and wait for some |
1960 | * requests to become available. | 1966 | * requests to become available. |
1967 | * | ||
1968 | * Called with q->queue_lock held, and returns with it unlocked. | ||
1961 | */ | 1969 | */ |
1962 | static struct request *get_request_wait(request_queue_t *q, int rw, | 1970 | static struct request *get_request_wait(request_queue_t *q, int rw, |
1963 | struct bio *bio) | 1971 | struct bio *bio) |
1964 | { | 1972 | { |
1965 | DEFINE_WAIT(wait); | ||
1966 | struct request *rq; | 1973 | struct request *rq; |
1967 | 1974 | ||
1968 | do { | 1975 | rq = get_request(q, rw, bio, GFP_NOIO); |
1976 | while (!rq) { | ||
1977 | DEFINE_WAIT(wait); | ||
1969 | struct request_list *rl = &q->rq; | 1978 | struct request_list *rl = &q->rq; |
1970 | 1979 | ||
1971 | prepare_to_wait_exclusive(&rl->wait[rw], &wait, | 1980 | prepare_to_wait_exclusive(&rl->wait[rw], &wait, |
@@ -1976,7 +1985,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw, | |||
1976 | if (!rq) { | 1985 | if (!rq) { |
1977 | struct io_context *ioc; | 1986 | struct io_context *ioc; |
1978 | 1987 | ||
1979 | generic_unplug_device(q); | 1988 | __generic_unplug_device(q); |
1989 | spin_unlock_irq(q->queue_lock); | ||
1980 | io_schedule(); | 1990 | io_schedule(); |
1981 | 1991 | ||
1982 | /* | 1992 | /* |
@@ -1985,12 +1995,13 @@ static struct request *get_request_wait(request_queue_t *q, int rw, | |||
1985 | * up to a big batch of them for a small period time. | 1995 | * up to a big batch of them for a small period time. |
1986 | * See ioc_batching, ioc_set_batching | 1996 | * See ioc_batching, ioc_set_batching |
1987 | */ | 1997 | */ |
1988 | ioc = get_io_context(GFP_NOIO); | 1998 | ioc = current_io_context(GFP_NOIO); |
1989 | ioc_set_batching(q, ioc); | 1999 | ioc_set_batching(q, ioc); |
1990 | put_io_context(ioc); | 2000 | |
2001 | spin_lock_irq(q->queue_lock); | ||
1991 | } | 2002 | } |
1992 | finish_wait(&rl->wait[rw], &wait); | 2003 | finish_wait(&rl->wait[rw], &wait); |
1993 | } while (!rq); | 2004 | } |
1994 | 2005 | ||
1995 | return rq; | 2006 | return rq; |
1996 | } | 2007 | } |
@@ -2001,14 +2012,18 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask) | |||
2001 | 2012 | ||
2002 | BUG_ON(rw != READ && rw != WRITE); | 2013 | BUG_ON(rw != READ && rw != WRITE); |
2003 | 2014 | ||
2004 | if (gfp_mask & __GFP_WAIT) | 2015 | spin_lock_irq(q->queue_lock); |
2016 | if (gfp_mask & __GFP_WAIT) { | ||
2005 | rq = get_request_wait(q, rw, NULL); | 2017 | rq = get_request_wait(q, rw, NULL); |
2006 | else | 2018 | } else { |
2007 | rq = get_request(q, rw, NULL, gfp_mask); | 2019 | rq = get_request(q, rw, NULL, gfp_mask); |
2020 | if (!rq) | ||
2021 | spin_unlock_irq(q->queue_lock); | ||
2022 | } | ||
2023 | /* q->queue_lock is unlocked at this point */ | ||
2008 | 2024 | ||
2009 | return rq; | 2025 | return rq; |
2010 | } | 2026 | } |
2011 | |||
2012 | EXPORT_SYMBOL(blk_get_request); | 2027 | EXPORT_SYMBOL(blk_get_request); |
2013 | 2028 | ||
2014 | /** | 2029 | /** |
@@ -2512,7 +2527,7 @@ EXPORT_SYMBOL(blk_attempt_remerge); | |||
2512 | 2527 | ||
2513 | static int __make_request(request_queue_t *q, struct bio *bio) | 2528 | static int __make_request(request_queue_t *q, struct bio *bio) |
2514 | { | 2529 | { |
2515 | struct request *req, *freereq = NULL; | 2530 | struct request *req; |
2516 | int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; | 2531 | int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; |
2517 | unsigned short prio; | 2532 | unsigned short prio; |
2518 | sector_t sector; | 2533 | sector_t sector; |
@@ -2540,14 +2555,9 @@ static int __make_request(request_queue_t *q, struct bio *bio) | |||
2540 | goto end_io; | 2555 | goto end_io; |
2541 | } | 2556 | } |
2542 | 2557 | ||
2543 | again: | ||
2544 | spin_lock_irq(q->queue_lock); | 2558 | spin_lock_irq(q->queue_lock); |
2545 | 2559 | ||
2546 | if (elv_queue_empty(q)) { | 2560 | if (unlikely(barrier) || elv_queue_empty(q)) |
2547 | blk_plug_device(q); | ||
2548 | goto get_rq; | ||
2549 | } | ||
2550 | if (barrier) | ||
2551 | goto get_rq; | 2561 | goto get_rq; |
2552 | 2562 | ||
2553 | el_ret = elv_merge(q, &req, bio); | 2563 | el_ret = elv_merge(q, &req, bio); |
@@ -2592,40 +2602,24 @@ again: | |||
2592 | elv_merged_request(q, req); | 2602 | elv_merged_request(q, req); |
2593 | goto out; | 2603 | goto out; |
2594 | 2604 | ||
2595 | /* | 2605 | /* ELV_NO_MERGE: elevator says don't/can't merge. */ |
2596 | * elevator says don't/can't merge. get new request | ||
2597 | */ | ||
2598 | case ELEVATOR_NO_MERGE: | ||
2599 | break; | ||
2600 | |||
2601 | default: | 2606 | default: |
2602 | printk("elevator returned crap (%d)\n", el_ret); | 2607 | ; |
2603 | BUG(); | ||
2604 | } | 2608 | } |
2605 | 2609 | ||
2610 | get_rq: | ||
2606 | /* | 2611 | /* |
2607 | * Grab a free request from the freelist - if that is empty, check | 2612 | * Grab a free request. This is might sleep but can not fail. |
2608 | * if we are doing read ahead and abort instead of blocking for | 2613 | * Returns with the queue unlocked. |
2609 | * a free slot. | 2614 | */ |
2615 | req = get_request_wait(q, rw, bio); | ||
2616 | |||
2617 | /* | ||
2618 | * After dropping the lock and possibly sleeping here, our request | ||
2619 | * may now be mergeable after it had proven unmergeable (above). | ||
2620 | * We don't worry about that case for efficiency. It won't happen | ||
2621 | * often, and the elevators are able to handle it. | ||
2610 | */ | 2622 | */ |
2611 | get_rq: | ||
2612 | if (freereq) { | ||
2613 | req = freereq; | ||
2614 | freereq = NULL; | ||
2615 | } else { | ||
2616 | spin_unlock_irq(q->queue_lock); | ||
2617 | if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) { | ||
2618 | /* | ||
2619 | * READA bit set | ||
2620 | */ | ||
2621 | err = -EWOULDBLOCK; | ||
2622 | if (bio_rw_ahead(bio)) | ||
2623 | goto end_io; | ||
2624 | |||
2625 | freereq = get_request_wait(q, rw, bio); | ||
2626 | } | ||
2627 | goto again; | ||
2628 | } | ||
2629 | 2623 | ||
2630 | req->flags |= REQ_CMD; | 2624 | req->flags |= REQ_CMD; |
2631 | 2625 | ||
@@ -2654,10 +2648,11 @@ get_rq: | |||
2654 | req->rq_disk = bio->bi_bdev->bd_disk; | 2648 | req->rq_disk = bio->bi_bdev->bd_disk; |
2655 | req->start_time = jiffies; | 2649 | req->start_time = jiffies; |
2656 | 2650 | ||
2651 | spin_lock_irq(q->queue_lock); | ||
2652 | if (elv_queue_empty(q)) | ||
2653 | blk_plug_device(q); | ||
2657 | add_request(q, req); | 2654 | add_request(q, req); |
2658 | out: | 2655 | out: |
2659 | if (freereq) | ||
2660 | __blk_put_request(q, freereq); | ||
2661 | if (sync) | 2656 | if (sync) |
2662 | __generic_unplug_device(q); | 2657 | __generic_unplug_device(q); |
2663 | 2658 | ||
@@ -3284,24 +3279,20 @@ void exit_io_context(void) | |||
3284 | 3279 | ||
3285 | /* | 3280 | /* |
3286 | * If the current task has no IO context then create one and initialise it. | 3281 | * If the current task has no IO context then create one and initialise it. |
3287 | * If it does have a context, take a ref on it. | 3282 | * Otherwise, return its existing IO context. |
3288 | * | 3283 | * |
3289 | * This is always called in the context of the task which submitted the I/O. | 3284 | * This returned IO context doesn't have a specifically elevated refcount, |
3290 | * But weird things happen, so we disable local interrupts to ensure exclusive | 3285 | * but since the current task itself holds a reference, the context can be |
3291 | * access to *current. | 3286 | * used in general code, so long as it stays within `current` context. |
3292 | */ | 3287 | */ |
3293 | struct io_context *get_io_context(int gfp_flags) | 3288 | struct io_context *current_io_context(int gfp_flags) |
3294 | { | 3289 | { |
3295 | struct task_struct *tsk = current; | 3290 | struct task_struct *tsk = current; |
3296 | unsigned long flags; | ||
3297 | struct io_context *ret; | 3291 | struct io_context *ret; |
3298 | 3292 | ||
3299 | local_irq_save(flags); | ||
3300 | ret = tsk->io_context; | 3293 | ret = tsk->io_context; |
3301 | if (ret) | 3294 | if (likely(ret)) |
3302 | goto out; | 3295 | return ret; |
3303 | |||
3304 | local_irq_restore(flags); | ||
3305 | 3296 | ||
3306 | ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); | 3297 | ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); |
3307 | if (ret) { | 3298 | if (ret) { |
@@ -3312,25 +3303,25 @@ struct io_context *get_io_context(int gfp_flags) | |||
3312 | ret->nr_batch_requests = 0; /* because this is 0 */ | 3303 | ret->nr_batch_requests = 0; /* because this is 0 */ |
3313 | ret->aic = NULL; | 3304 | ret->aic = NULL; |
3314 | ret->cic = NULL; | 3305 | ret->cic = NULL; |
3306 | tsk->io_context = ret; | ||
3307 | } | ||
3315 | 3308 | ||
3316 | local_irq_save(flags); | 3309 | return ret; |
3317 | 3310 | } | |
3318 | /* | 3311 | EXPORT_SYMBOL(current_io_context); |
3319 | * very unlikely, someone raced with us in setting up the task | ||
3320 | * io context. free new context and just grab a reference. | ||
3321 | */ | ||
3322 | if (!tsk->io_context) | ||
3323 | tsk->io_context = ret; | ||
3324 | else { | ||
3325 | kmem_cache_free(iocontext_cachep, ret); | ||
3326 | ret = tsk->io_context; | ||
3327 | } | ||
3328 | 3312 | ||
3329 | out: | 3313 | /* |
3314 | * If the current task has no IO context then create one and initialise it. | ||
3315 | * If it does have a context, take a ref on it. | ||
3316 | * | ||
3317 | * This is always called in the context of the task which submitted the I/O. | ||
3318 | */ | ||
3319 | struct io_context *get_io_context(int gfp_flags) | ||
3320 | { | ||
3321 | struct io_context *ret; | ||
3322 | ret = current_io_context(gfp_flags); | ||
3323 | if (likely(ret)) | ||
3330 | atomic_inc(&ret->refcount); | 3324 | atomic_inc(&ret->refcount); |
3331 | local_irq_restore(flags); | ||
3332 | } | ||
3333 | |||
3334 | return ret; | 3325 | return ret; |
3335 | } | 3326 | } |
3336 | EXPORT_SYMBOL(get_io_context); | 3327 | EXPORT_SYMBOL(get_io_context); |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 1407945a5892..59f589d733f9 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -686,6 +686,15 @@ static struct pci_device_id agp_amd64_pci_table[] = { | |||
686 | .subvendor = PCI_ANY_ID, | 686 | .subvendor = PCI_ANY_ID, |
687 | .subdevice = PCI_ANY_ID, | 687 | .subdevice = PCI_ANY_ID, |
688 | }, | 688 | }, |
689 | /* SIS 760 */ | ||
690 | { | ||
691 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | ||
692 | .class_mask = ~0, | ||
693 | .vendor = PCI_VENDOR_ID_SI, | ||
694 | .device = PCI_DEVICE_ID_SI_760, | ||
695 | .subvendor = PCI_ANY_ID, | ||
696 | .subdevice = PCI_ANY_ID, | ||
697 | }, | ||
689 | { } | 698 | { } |
690 | }; | 699 | }; |
691 | 700 | ||
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 1813d0d198f1..e16c13fe698d 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -1088,8 +1088,8 @@ static inline int i_ipmi_request(ipmi_user_t user, | |||
1088 | long seqid; | 1088 | long seqid; |
1089 | int broadcast = 0; | 1089 | int broadcast = 0; |
1090 | 1090 | ||
1091 | if (addr->channel > IPMI_NUM_CHANNELS) { | 1091 | if (addr->channel >= IPMI_MAX_CHANNELS) { |
1092 | spin_lock_irqsave(&intf->counter_lock, flags); | 1092 | spin_lock_irqsave(&intf->counter_lock, flags); |
1093 | intf->sent_invalid_commands++; | 1093 | intf->sent_invalid_commands++; |
1094 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 1094 | spin_unlock_irqrestore(&intf->counter_lock, flags); |
1095 | rv = -EINVAL; | 1095 | rv = -EINVAL; |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 7c24fbe831f8..95f7046ff059 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -451,7 +451,7 @@ static int __init moxa_init(void) | |||
451 | int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1; | 451 | int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1; |
452 | i = 0; | 452 | i = 0; |
453 | while (i < n) { | 453 | while (i < n) { |
454 | while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) | 454 | while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) |
455 | { | 455 | { |
456 | if (pci_enable_device(p)) | 456 | if (pci_enable_device(p)) |
457 | continue; | 457 | continue; |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 7db3370f4972..d7d484024e2b 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -1095,7 +1095,7 @@ static int __init rio_init(void) | |||
1095 | 1095 | ||
1096 | #ifdef CONFIG_PCI | 1096 | #ifdef CONFIG_PCI |
1097 | /* First look for the JET devices: */ | 1097 | /* First look for the JET devices: */ |
1098 | while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, | 1098 | while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, |
1099 | PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | 1099 | PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, |
1100 | pdev))) { | 1100 | pdev))) { |
1101 | if (pci_enable_device(pdev)) continue; | 1101 | if (pci_enable_device(pdev)) continue; |
@@ -1169,7 +1169,7 @@ static int __init rio_init(void) | |||
1169 | */ | 1169 | */ |
1170 | 1170 | ||
1171 | /* Then look for the older RIO/PCI devices: */ | 1171 | /* Then look for the older RIO/PCI devices: */ |
1172 | while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, | 1172 | while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, |
1173 | PCI_DEVICE_ID_SPECIALIX_RIO, | 1173 | PCI_DEVICE_ID_SPECIALIX_RIO, |
1174 | pdev))) { | 1174 | pdev))) { |
1175 | if (pci_enable_device(pdev)) continue; | 1175 | if (pci_enable_device(pdev)) continue; |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index ff4f09804865..d8f9e94ae475 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -78,6 +78,7 @@ | |||
78 | #include <linux/sysctl.h> | 78 | #include <linux/sysctl.h> |
79 | #include <linux/wait.h> | 79 | #include <linux/wait.h> |
80 | #include <linux/bcd.h> | 80 | #include <linux/bcd.h> |
81 | #include <linux/delay.h> | ||
81 | 82 | ||
82 | #include <asm/current.h> | 83 | #include <asm/current.h> |
83 | #include <asm/uaccess.h> | 84 | #include <asm/uaccess.h> |
@@ -894,7 +895,6 @@ static int __init rtc_init(void) | |||
894 | struct proc_dir_entry *ent; | 895 | struct proc_dir_entry *ent; |
895 | #if defined(__alpha__) || defined(__mips__) | 896 | #if defined(__alpha__) || defined(__mips__) |
896 | unsigned int year, ctrl; | 897 | unsigned int year, ctrl; |
897 | unsigned long uip_watchdog; | ||
898 | char *guess = NULL; | 898 | char *guess = NULL; |
899 | #endif | 899 | #endif |
900 | #ifdef __sparc__ | 900 | #ifdef __sparc__ |
@@ -1000,12 +1000,8 @@ no_irq: | |||
1000 | /* Each operating system on an Alpha uses its own epoch. | 1000 | /* Each operating system on an Alpha uses its own epoch. |
1001 | Let's try to guess which one we are using now. */ | 1001 | Let's try to guess which one we are using now. */ |
1002 | 1002 | ||
1003 | uip_watchdog = jiffies; | ||
1004 | if (rtc_is_updating() != 0) | 1003 | if (rtc_is_updating() != 0) |
1005 | while (jiffies - uip_watchdog < 2*HZ/100) { | 1004 | msleep(20); |
1006 | barrier(); | ||
1007 | cpu_relax(); | ||
1008 | } | ||
1009 | 1005 | ||
1010 | spin_lock_irq(&rtc_lock); | 1006 | spin_lock_irq(&rtc_lock); |
1011 | year = CMOS_READ(RTC_YEAR); | 1007 | year = CMOS_READ(RTC_YEAR); |
@@ -1213,7 +1209,6 @@ static int rtc_proc_open(struct inode *inode, struct file *file) | |||
1213 | 1209 | ||
1214 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) | 1210 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) |
1215 | { | 1211 | { |
1216 | unsigned long uip_watchdog = jiffies; | ||
1217 | unsigned char ctrl; | 1212 | unsigned char ctrl; |
1218 | #ifdef CONFIG_MACH_DECSTATION | 1213 | #ifdef CONFIG_MACH_DECSTATION |
1219 | unsigned int real_year; | 1214 | unsigned int real_year; |
@@ -1221,7 +1216,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1221 | 1216 | ||
1222 | /* | 1217 | /* |
1223 | * read RTC once any update in progress is done. The update | 1218 | * read RTC once any update in progress is done. The update |
1224 | * can take just over 2ms. We wait 10 to 20ms. There is no need to | 1219 | * can take just over 2ms. We wait 20ms. There is no need to |
1225 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. | 1220 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. |
1226 | * If you need to know *exactly* when a second has started, enable | 1221 | * If you need to know *exactly* when a second has started, enable |
1227 | * periodic update complete interrupts, (via ioctl) and then | 1222 | * periodic update complete interrupts, (via ioctl) and then |
@@ -1230,10 +1225,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1230 | */ | 1225 | */ |
1231 | 1226 | ||
1232 | if (rtc_is_updating() != 0) | 1227 | if (rtc_is_updating() != 0) |
1233 | while (jiffies - uip_watchdog < 2*HZ/100) { | 1228 | msleep(20); |
1234 | barrier(); | ||
1235 | cpu_relax(); | ||
1236 | } | ||
1237 | 1229 | ||
1238 | /* | 1230 | /* |
1239 | * Only the values that we read from the RTC are set. We leave | 1231 | * Only the values that we read from the RTC are set. We leave |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 659335d80ee7..ec78d2f161f7 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -396,7 +396,7 @@ static struct file_operations tipar_fops = { | |||
396 | static int __init | 396 | static int __init |
397 | tipar_setup(char *str) | 397 | tipar_setup(char *str) |
398 | { | 398 | { |
399 | int ints[2]; | 399 | int ints[3]; |
400 | 400 | ||
401 | str = get_options(str, ARRAY_SIZE(ints), ints); | 401 | str = get_options(str, ARRAY_SIZE(ints), ints); |
402 | 402 | ||
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 58597993954f..f19cf9d7792d 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, | |||
476 | ld = tty_ldisc_ref(tty); | 476 | ld = tty_ldisc_ref(tty); |
477 | switch (arg) { | 477 | switch (arg) { |
478 | case TCIFLUSH: | 478 | case TCIFLUSH: |
479 | if (ld->flush_buffer) | 479 | if (ld && ld->flush_buffer) |
480 | ld->flush_buffer(tty); | 480 | ld->flush_buffer(tty); |
481 | break; | 481 | break; |
482 | case TCIOFLUSH: | 482 | case TCIOFLUSH: |
483 | if (ld->flush_buffer) | 483 | if (ld && ld->flush_buffer) |
484 | ld->flush_buffer(tty); | 484 | ld->flush_buffer(tty); |
485 | /* fall through */ | 485 | /* fall through */ |
486 | case TCOFLUSH: | 486 | case TCOFLUSH: |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 8971484b956b..1d44f69e1fda 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/signal.h> | 27 | #include <linux/signal.h> |
28 | #include <linux/timex.h> | ||
28 | 29 | ||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -386,7 +387,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
386 | if (!perm) | 387 | if (!perm) |
387 | return -EPERM; | 388 | return -EPERM; |
388 | if (arg) | 389 | if (arg) |
389 | arg = 1193182 / arg; | 390 | arg = CLOCK_TICK_RATE / arg; |
390 | kd_mksound(arg, 0); | 391 | kd_mksound(arg, 0); |
391 | return 0; | 392 | return 0; |
392 | 393 | ||
@@ -403,7 +404,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
403 | ticks = HZ * ((arg >> 16) & 0xffff) / 1000; | 404 | ticks = HZ * ((arg >> 16) & 0xffff) / 1000; |
404 | count = ticks ? (arg & 0xffff) : 0; | 405 | count = ticks ? (arg & 0xffff) : 0; |
405 | if (count) | 406 | if (count) |
406 | count = 1193182 / count; | 407 | count = CLOCK_TICK_RATE / count; |
407 | kd_mksound(count, ticks); | 408 | kd_mksound(count, ticks); |
408 | return 0; | 409 | return 0; |
409 | } | 410 | } |
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c index 4e98c215e5b1..4b039516cc86 100644 --- a/drivers/char/watchdog/ixp2000_wdt.c +++ b/drivers/char/watchdog/ixp2000_wdt.c | |||
@@ -162,7 +162,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) | |||
162 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { | 162 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { |
163 | wdt_disable(); | 163 | wdt_disable(); |
164 | } else { | 164 | } else { |
165 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " | 165 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
166 | "timer will not stop\n"); | 166 | "timer will not stop\n"); |
167 | } | 167 | } |
168 | 168 | ||
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c index 82396e06c8a8..83df369113a4 100644 --- a/drivers/char/watchdog/ixp4xx_wdt.c +++ b/drivers/char/watchdog/ixp4xx_wdt.c | |||
@@ -156,7 +156,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file) | |||
156 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { | 156 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { |
157 | wdt_disable(); | 157 | wdt_disable(); |
158 | } else { | 158 | } else { |
159 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " | 159 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
160 | "timer will not stop\n"); | 160 | "timer will not stop\n"); |
161 | } | 161 | } |
162 | 162 | ||
diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c index 6e548a222ef1..89497890158d 100644 --- a/drivers/isdn/hardware/eicon/dadapter.c +++ b/drivers/isdn/hardware/eicon/dadapter.c | |||
@@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\ | |||
44 | Array to held adapter information | 44 | Array to held adapter information |
45 | -------------------------------------------------------------------------- */ | 45 | -------------------------------------------------------------------------- */ |
46 | static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS]; | 46 | static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS]; |
47 | dword Adapters = 0; /* Number of adapters */ | 47 | static dword Adapters = 0; /* Number of adapters */ |
48 | /* -------------------------------------------------------------------------- | 48 | /* -------------------------------------------------------------------------- |
49 | Shadow IDI_DIMAINT | 49 | Shadow IDI_DIMAINT |
50 | and 'shadow' debug stuff | 50 | and 'shadow' debug stuff |
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index 6e7e060716b7..7333377ab31d 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c | |||
@@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a) | |||
312 | /* function to read critical counter registers that */ | 312 | /* function to read critical counter registers that */ |
313 | /* may be udpated by the chip during read */ | 313 | /* may be udpated by the chip during read */ |
314 | /******************************************************/ | 314 | /******************************************************/ |
315 | static volatile u_char | 315 | static u_char |
316 | Read_hfc8_stable(hfc4s8s_hw * hw, int reg) | 316 | Read_hfc8_stable(hfc4s8s_hw * hw, int reg) |
317 | { | 317 | { |
318 | u_char ref8; | 318 | u_char ref8; |
@@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg) | |||
324 | return in8; | 324 | return in8; |
325 | } | 325 | } |
326 | 326 | ||
327 | static volatile int | 327 | static int |
328 | Read_hfc16_stable(hfc4s8s_hw * hw, int reg) | 328 | Read_hfc16_stable(hfc4s8s_hw * hw, int reg) |
329 | { | 329 | { |
330 | int ref16; | 330 | int ref16; |
@@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode) | |||
1465 | /******************************************/ | 1465 | /******************************************/ |
1466 | /* disable memory mapped ports / io ports */ | 1466 | /* disable memory mapped ports / io ports */ |
1467 | /******************************************/ | 1467 | /******************************************/ |
1468 | void | 1468 | static void |
1469 | release_pci_ports(hfc4s8s_hw * hw) | 1469 | release_pci_ports(hfc4s8s_hw * hw) |
1470 | { | 1470 | { |
1471 | pci_write_config_word(hw->pdev, PCI_COMMAND, 0); | 1471 | pci_write_config_word(hw->pdev, PCI_COMMAND, 0); |
@@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw) | |||
1481 | /*****************************************/ | 1481 | /*****************************************/ |
1482 | /* enable memory mapped ports / io ports */ | 1482 | /* enable memory mapped ports / io ports */ |
1483 | /*****************************************/ | 1483 | /*****************************************/ |
1484 | void | 1484 | static void |
1485 | enable_pci_ports(hfc4s8s_hw * hw) | 1485 | enable_pci_ports(hfc4s8s_hw * hw) |
1486 | { | 1486 | { |
1487 | #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM | 1487 | #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM |
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 8ee25b2ccce1..1fd3d4e5f284 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c | |||
@@ -42,6 +42,8 @@ typedef struct _hycapi_appl { | |||
42 | 42 | ||
43 | static hycapi_appl hycapi_applications[CAPI_MAXAPPL]; | 43 | static hycapi_appl hycapi_applications[CAPI_MAXAPPL]; |
44 | 44 | ||
45 | static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); | ||
46 | |||
45 | static inline int _hycapi_appCheck(int app_id, int ctrl_no) | 47 | static inline int _hycapi_appCheck(int app_id, int ctrl_no) |
46 | { | 48 | { |
47 | if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) || | 49 | if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) || |
@@ -57,7 +59,7 @@ static inline int _hycapi_appCheck(int app_id, int ctrl_no) | |||
57 | Kernel-Capi callback reset_ctr | 59 | Kernel-Capi callback reset_ctr |
58 | ******************************/ | 60 | ******************************/ |
59 | 61 | ||
60 | void | 62 | static void |
61 | hycapi_reset_ctr(struct capi_ctr *ctrl) | 63 | hycapi_reset_ctr(struct capi_ctr *ctrl) |
62 | { | 64 | { |
63 | hycapictrl_info *cinfo = ctrl->driverdata; | 65 | hycapictrl_info *cinfo = ctrl->driverdata; |
@@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) | |||
73 | Kernel-Capi callback remove_ctr | 75 | Kernel-Capi callback remove_ctr |
74 | ******************************/ | 76 | ******************************/ |
75 | 77 | ||
76 | void | 78 | static void |
77 | hycapi_remove_ctr(struct capi_ctr *ctrl) | 79 | hycapi_remove_ctr(struct capi_ctr *ctrl) |
78 | { | 80 | { |
79 | int i; | 81 | int i; |
@@ -215,7 +217,7 @@ Error-checking is done for CAPI-compliance. | |||
215 | The application is recorded in the internal list. | 217 | The application is recorded in the internal list. |
216 | *************************************************************/ | 218 | *************************************************************/ |
217 | 219 | ||
218 | void | 220 | static void |
219 | hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, | 221 | hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, |
220 | capi_register_params *rp) | 222 | capi_register_params *rp) |
221 | { | 223 | { |
@@ -291,7 +293,7 @@ Release the application from the internal list an remove it's | |||
291 | registration at controller-level | 293 | registration at controller-level |
292 | ******************************************************************/ | 294 | ******************************************************************/ |
293 | 295 | ||
294 | void | 296 | static void |
295 | hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl) | 297 | hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl) |
296 | { | 298 | { |
297 | int chk; | 299 | int chk; |
@@ -364,7 +366,7 @@ firmware-releases that do not check the MsgLen-Indication! | |||
364 | 366 | ||
365 | ***************************************************************/ | 367 | ***************************************************************/ |
366 | 368 | ||
367 | u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) | 369 | static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) |
368 | { | 370 | { |
369 | __u16 appl_id; | 371 | __u16 appl_id; |
370 | int _len, _len2; | 372 | int _len, _len2; |
@@ -437,8 +439,8 @@ Informations provided in the /proc/capi-entries. | |||
437 | 439 | ||
438 | *********************************************************************/ | 440 | *********************************************************************/ |
439 | 441 | ||
440 | int hycapi_read_proc(char *page, char **start, off_t off, | 442 | static int hycapi_read_proc(char *page, char **start, off_t off, |
441 | int count, int *eof, struct capi_ctr *ctrl) | 443 | int count, int *eof, struct capi_ctr *ctrl) |
442 | { | 444 | { |
443 | hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); | 445 | hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); |
444 | hysdn_card *card = cinfo->card; | 446 | hysdn_card *card = cinfo->card; |
@@ -485,7 +487,7 @@ on capi-interface registration. | |||
485 | 487 | ||
486 | **************************************************************/ | 488 | **************************************************************/ |
487 | 489 | ||
488 | int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) | 490 | static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) |
489 | { | 491 | { |
490 | #ifdef HYCAPI_PRINTFNAMES | 492 | #ifdef HYCAPI_PRINTFNAMES |
491 | printk(KERN_NOTICE "hycapi_load_firmware\n"); | 493 | printk(KERN_NOTICE "hycapi_load_firmware\n"); |
@@ -494,7 +496,7 @@ int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) | |||
494 | } | 496 | } |
495 | 497 | ||
496 | 498 | ||
497 | char *hycapi_procinfo(struct capi_ctr *ctrl) | 499 | static char *hycapi_procinfo(struct capi_ctr *ctrl) |
498 | { | 500 | { |
499 | hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); | 501 | hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); |
500 | #ifdef HYCAPI_PRINTFNAMES | 502 | #ifdef HYCAPI_PRINTFNAMES |
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c index 6c04281e57b8..7bfba196f315 100644 --- a/drivers/isdn/hysdn/hysdn_boot.c +++ b/drivers/isdn/hysdn/hysdn_boot.c | |||
@@ -53,7 +53,7 @@ struct boot_data { | |||
53 | /* to be called at start of POF file reading, */ | 53 | /* to be called at start of POF file reading, */ |
54 | /* before starting any decryption on any POF record. */ | 54 | /* before starting any decryption on any POF record. */ |
55 | /*****************************************************/ | 55 | /*****************************************************/ |
56 | void | 56 | static void |
57 | StartDecryption(struct boot_data *boot) | 57 | StartDecryption(struct boot_data *boot) |
58 | { | 58 | { |
59 | boot->Cryptor = CRYPT_STARTTERM; | 59 | boot->Cryptor = CRYPT_STARTTERM; |
@@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot) | |||
66 | /* to HI and LO boot loader and (all) seq tags, because */ | 66 | /* to HI and LO boot loader and (all) seq tags, because */ |
67 | /* global Cryptor is started for whole POF. */ | 67 | /* global Cryptor is started for whole POF. */ |
68 | /***************************************************************/ | 68 | /***************************************************************/ |
69 | void | 69 | static void |
70 | DecryptBuf(struct boot_data *boot, int cnt) | 70 | DecryptBuf(struct boot_data *boot, int cnt) |
71 | { | 71 | { |
72 | uchar *bufp = boot->buf.BootBuf; | 72 | uchar *bufp = boot->buf.BootBuf; |
diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 4cee26e558ee..432f6f99089e 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h | |||
@@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictrl_info; | |||
227 | /*****************/ | 227 | /*****************/ |
228 | /* exported vars */ | 228 | /* exported vars */ |
229 | /*****************/ | 229 | /*****************/ |
230 | extern int cardmax; /* number of found cards */ | ||
231 | extern hysdn_card *card_root; /* pointer to first card */ | 230 | extern hysdn_card *card_root; /* pointer to first card */ |
232 | 231 | ||
233 | 232 | ||
@@ -244,7 +243,6 @@ extern void hysdn_procconf_release(void); /* deinit proc config filesys */ | |||
244 | /* hysdn_proclog.c */ | 243 | /* hysdn_proclog.c */ |
245 | extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */ | 244 | extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */ |
246 | extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */ | 245 | extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */ |
247 | extern void put_log_buffer(hysdn_card *, char *); /* output log data */ | ||
248 | extern void hysdn_addlog(hysdn_card *, char *,...); /* output data to log */ | 246 | extern void hysdn_addlog(hysdn_card *, char *,...); /* output data to log */ |
249 | extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */ | 247 | extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */ |
250 | 248 | ||
@@ -278,16 +276,6 @@ extern unsigned int hycapi_enable; | |||
278 | extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */ | 276 | extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */ |
279 | extern int hycapi_capi_release(hysdn_card *); /* delete the device */ | 277 | extern int hycapi_capi_release(hysdn_card *); /* delete the device */ |
280 | extern int hycapi_capi_stop(hysdn_card *card); /* suspend */ | 278 | extern int hycapi_capi_stop(hysdn_card *card); /* suspend */ |
281 | extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *); | ||
282 | extern void hycapi_reset_ctr(struct capi_ctr *); | ||
283 | extern void hycapi_remove_ctr(struct capi_ctr *); | ||
284 | extern void hycapi_register_appl(struct capi_ctr *, __u16 appl, | ||
285 | capi_register_params *); | ||
286 | extern void hycapi_release_appl(struct capi_ctr *, __u16 appl); | ||
287 | extern u16 hycapi_send_message(struct capi_ctr *, struct sk_buff *skb); | ||
288 | extern char *hycapi_procinfo(struct capi_ctr *); | ||
289 | extern int hycapi_read_proc(char *page, char **start, off_t off, | ||
290 | int count, int *eof, struct capi_ctr *card); | ||
291 | extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len); | 279 | extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len); |
292 | extern void hycapi_tx_capiack(hysdn_card * card); | 280 | extern void hycapi_tx_capiack(hysdn_card * card); |
293 | extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card); | 281 | extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card); |
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index 5cac2bf5f4b0..12c8137b5161 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c | |||
@@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius"); | |||
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | 35 | ||
36 | static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; | 36 | static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; |
37 | int cardmax; /* number of found cards */ | 37 | static int cardmax; /* number of found cards */ |
38 | hysdn_card *card_root = NULL; /* pointer to first card */ | 38 | hysdn_card *card_root = NULL; /* pointer to first card */ |
39 | 39 | ||
40 | /**********************************************/ | 40 | /**********************************************/ |
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 8ef2b7c952a6..4d57011c5737 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c | |||
@@ -22,6 +22,8 @@ | |||
22 | /* the proc subdir for the interface is defined in the procconf module */ | 22 | /* the proc subdir for the interface is defined in the procconf module */ |
23 | extern struct proc_dir_entry *hysdn_proc_entry; | 23 | extern struct proc_dir_entry *hysdn_proc_entry; |
24 | 24 | ||
25 | static void put_log_buffer(hysdn_card * card, char *cp); | ||
26 | |||
25 | /*************************************************/ | 27 | /*************************************************/ |
26 | /* structure keeping ascii log for device output */ | 28 | /* structure keeping ascii log for device output */ |
27 | /*************************************************/ | 29 | /*************************************************/ |
@@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...) | |||
93 | /* opened for read got the contents. */ | 95 | /* opened for read got the contents. */ |
94 | /* Flushes buffers not longer in use. */ | 96 | /* Flushes buffers not longer in use. */ |
95 | /********************************************/ | 97 | /********************************************/ |
96 | void | 98 | static void |
97 | put_log_buffer(hysdn_card * card, char *cp) | 99 | put_log_buffer(hysdn_card * card, char *cp) |
98 | { | 100 | { |
99 | struct log_data *ib; | 101 | struct log_data *ib; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 3802f7a17f16..4a0c57db2b67 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -338,6 +338,7 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error) | |||
338 | 338 | ||
339 | if (atomic_dec_and_test(&rdev->mddev->pending_writes)) | 339 | if (atomic_dec_and_test(&rdev->mddev->pending_writes)) |
340 | wake_up(&rdev->mddev->sb_wait); | 340 | wake_up(&rdev->mddev->sb_wait); |
341 | bio_put(bio); | ||
341 | return 0; | 342 | return 0; |
342 | } | 343 | } |
343 | 344 | ||
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 2dc906fdfa55..810e7aac0a53 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -7,8 +7,7 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ | |||
7 | zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o | 7 | zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o |
8 | zr36067-objs := zoran_procfs.o zoran_device.o \ | 8 | zr36067-objs := zoran_procfs.o zoran_device.o \ |
9 | zoran_driver.o zoran_card.o | 9 | zoran_driver.o zoran_card.o |
10 | tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o | 10 | tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o |
11 | |||
12 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o | 11 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o |
13 | 12 | ||
14 | obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ | 13 | obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 290289a99757..7d62b394c509 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $ | 2 | $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $ |
3 | 3 | ||
4 | bttv - Bt848 frame grabber driver | 4 | bttv - Bt848 frame grabber driver |
5 | 5 | ||
@@ -76,6 +76,9 @@ static unsigned int whitecrush_upper = 0xCF; | |||
76 | static unsigned int whitecrush_lower = 0x7F; | 76 | static unsigned int whitecrush_lower = 0x7F; |
77 | static unsigned int vcr_hack = 0; | 77 | static unsigned int vcr_hack = 0; |
78 | static unsigned int irq_iswitch = 0; | 78 | static unsigned int irq_iswitch = 0; |
79 | static unsigned int uv_ratio = 50; | ||
80 | static unsigned int full_luma_range = 0; | ||
81 | static unsigned int coring = 0; | ||
79 | 82 | ||
80 | /* API features (turn on/off stuff for testing) */ | 83 | /* API features (turn on/off stuff for testing) */ |
81 | static unsigned int v4l2 = 1; | 84 | static unsigned int v4l2 = 1; |
@@ -106,6 +109,9 @@ module_param(adc_crush, int, 0444); | |||
106 | module_param(whitecrush_upper, int, 0444); | 109 | module_param(whitecrush_upper, int, 0444); |
107 | module_param(whitecrush_lower, int, 0444); | 110 | module_param(whitecrush_lower, int, 0444); |
108 | module_param(vcr_hack, int, 0444); | 111 | module_param(vcr_hack, int, 0444); |
112 | module_param(uv_ratio, int, 0444); | ||
113 | module_param(full_luma_range, int, 0444); | ||
114 | module_param(coring, int, 0444); | ||
109 | 115 | ||
110 | module_param_array(radio, int, NULL, 0444); | 116 | module_param_array(radio, int, NULL, 0444); |
111 | 117 | ||
@@ -124,6 +130,9 @@ MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is | |||
124 | MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); | 130 | MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); |
125 | MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); | 131 | MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); |
126 | MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); | 132 | MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); |
133 | MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); | ||
134 | MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); | ||
135 | MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); | ||
127 | 136 | ||
128 | MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); | 137 | MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); |
129 | MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); | 138 | MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); |
@@ -484,7 +493,10 @@ static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats); | |||
484 | #define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) | 493 | #define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) |
485 | #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) | 494 | #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) |
486 | #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) | 495 | #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) |
487 | #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8) | 496 | #define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8) |
497 | #define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9) | ||
498 | #define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10) | ||
499 | #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11) | ||
488 | 500 | ||
489 | static const struct v4l2_queryctrl no_ctl = { | 501 | static const struct v4l2_queryctrl no_ctl = { |
490 | .name = "42", | 502 | .name = "42", |
@@ -618,8 +630,32 @@ static const struct v4l2_queryctrl bttv_ctls[] = { | |||
618 | .step = 1, | 630 | .step = 1, |
619 | .default_value = 0x7F, | 631 | .default_value = 0x7F, |
620 | .type = V4L2_CTRL_TYPE_INTEGER, | 632 | .type = V4L2_CTRL_TYPE_INTEGER, |
633 | },{ | ||
634 | .id = V4L2_CID_PRIVATE_UV_RATIO, | ||
635 | .name = "uv ratio", | ||
636 | .minimum = 0, | ||
637 | .maximum = 100, | ||
638 | .step = 1, | ||
639 | .default_value = 50, | ||
640 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
641 | },{ | ||
642 | .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, | ||
643 | .name = "full luma range", | ||
644 | .minimum = 0, | ||
645 | .maximum = 1, | ||
646 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
647 | },{ | ||
648 | .id = V4L2_CID_PRIVATE_CORING, | ||
649 | .name = "coring", | ||
650 | .minimum = 0, | ||
651 | .maximum = 3, | ||
652 | .step = 1, | ||
653 | .default_value = 0, | ||
654 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
621 | } | 655 | } |
622 | 656 | ||
657 | |||
658 | |||
623 | }; | 659 | }; |
624 | static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); | 660 | static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); |
625 | 661 | ||
@@ -833,8 +869,8 @@ static void bt848_sat(struct bttv *btv, int color) | |||
833 | btv->saturation = color; | 869 | btv->saturation = color; |
834 | 870 | ||
835 | /* 0-511 for the color */ | 871 | /* 0-511 for the color */ |
836 | val_u = color >> 7; | 872 | val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; |
837 | val_v = ((color>>7)*180L)/254; | 873 | val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; |
838 | hibits = (val_u >> 7) & 2; | 874 | hibits = (val_u >> 7) & 2; |
839 | hibits |= (val_v >> 8) & 1; | 875 | hibits |= (val_v >> 8) & 1; |
840 | btwrite(val_u & 0xff, BT848_SAT_U_LO); | 876 | btwrite(val_u & 0xff, BT848_SAT_U_LO); |
@@ -1151,6 +1187,15 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) | |||
1151 | case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: | 1187 | case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: |
1152 | c->value = btv->opt_whitecrush_lower; | 1188 | c->value = btv->opt_whitecrush_lower; |
1153 | break; | 1189 | break; |
1190 | case V4L2_CID_PRIVATE_UV_RATIO: | ||
1191 | c->value = btv->opt_uv_ratio; | ||
1192 | break; | ||
1193 | case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: | ||
1194 | c->value = btv->opt_full_luma_range; | ||
1195 | break; | ||
1196 | case V4L2_CID_PRIVATE_CORING: | ||
1197 | c->value = btv->opt_coring; | ||
1198 | break; | ||
1154 | default: | 1199 | default: |
1155 | return -EINVAL; | 1200 | return -EINVAL; |
1156 | } | 1201 | } |
@@ -1247,6 +1292,18 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) | |||
1247 | btv->opt_whitecrush_lower = c->value; | 1292 | btv->opt_whitecrush_lower = c->value; |
1248 | btwrite(c->value, BT848_WC_DOWN); | 1293 | btwrite(c->value, BT848_WC_DOWN); |
1249 | break; | 1294 | break; |
1295 | case V4L2_CID_PRIVATE_UV_RATIO: | ||
1296 | btv->opt_uv_ratio = c->value; | ||
1297 | bt848_sat(btv, btv->saturation); | ||
1298 | break; | ||
1299 | case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: | ||
1300 | btv->opt_full_luma_range = c->value; | ||
1301 | btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); | ||
1302 | break; | ||
1303 | case V4L2_CID_PRIVATE_CORING: | ||
1304 | btv->opt_coring = c->value; | ||
1305 | btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); | ||
1306 | break; | ||
1250 | default: | 1307 | default: |
1251 | return -EINVAL; | 1308 | return -EINVAL; |
1252 | } | 1309 | } |
@@ -3117,11 +3174,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
3117 | return -EINVAL; | 3174 | return -EINVAL; |
3118 | memset(v,0,sizeof(*v)); | 3175 | memset(v,0,sizeof(*v)); |
3119 | strcpy(v->name, "Radio"); | 3176 | strcpy(v->name, "Radio"); |
3120 | /* japan: 76.0 MHz - 89.9 MHz | ||
3121 | western europe: 87.5 MHz - 108.0 MHz | ||
3122 | russia: 65.0 MHz - 108.0 MHz */ | ||
3123 | v->rangelow=(int)(65*16); | ||
3124 | v->rangehigh=(int)(108*16); | ||
3125 | bttv_call_i2c_clients(btv,cmd,v); | 3177 | bttv_call_i2c_clients(btv,cmd,v); |
3126 | return 0; | 3178 | return 0; |
3127 | } | 3179 | } |
@@ -3876,6 +3928,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3876 | btv->opt_vcr_hack = vcr_hack; | 3928 | btv->opt_vcr_hack = vcr_hack; |
3877 | btv->opt_whitecrush_upper = whitecrush_upper; | 3929 | btv->opt_whitecrush_upper = whitecrush_upper; |
3878 | btv->opt_whitecrush_lower = whitecrush_lower; | 3930 | btv->opt_whitecrush_lower = whitecrush_lower; |
3931 | btv->opt_uv_ratio = uv_ratio; | ||
3932 | btv->opt_full_luma_range = full_luma_range; | ||
3933 | btv->opt_coring = coring; | ||
3879 | 3934 | ||
3880 | /* fill struct bttv with some useful defaults */ | 3935 | /* fill struct bttv with some useful defaults */ |
3881 | btv->init.btv = btv; | 3936 | btv->init.btv = btv; |
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 7b6f1e856028..f3293e4a15ad 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $ | 2 | $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $ |
3 | 3 | ||
4 | bttv - Bt848 frame grabber driver | 4 | bttv - Bt848 frame grabber driver |
5 | 5 | ||
@@ -326,6 +326,9 @@ struct bttv { | |||
326 | int opt_vcr_hack; | 326 | int opt_vcr_hack; |
327 | int opt_whitecrush_upper; | 327 | int opt_whitecrush_upper; |
328 | int opt_whitecrush_lower; | 328 | int opt_whitecrush_lower; |
329 | int opt_uv_ratio; | ||
330 | int opt_full_luma_range; | ||
331 | int opt_coring; | ||
329 | 332 | ||
330 | /* radio data/state */ | 333 | /* radio data/state */ |
331 | int has_radio; | 334 | int has_radio; |
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 95ad17b7f38e..9c005cb128d7 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $ | 2 | * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * controls microtune tuners, mt2032 + mt2050 at the moment. | 5 | * controls microtune tuners, mt2032 + mt2050 at the moment. |
@@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
295 | int if2 = t->radio_if2; | 295 | int if2 = t->radio_if2; |
296 | 296 | ||
297 | // per Manual for FM tuning: first if center freq. 1085 MHz | 297 | // per Manual for FM tuning: first if center freq. 1085 MHz |
298 | mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, | 298 | mt2032_set_if_freq(c, freq * 1000 / 16, |
299 | 1085*1000*1000,if2,if2,if2); | 299 | 1085*1000*1000,if2,if2,if2); |
300 | } | 300 | } |
301 | 301 | ||
302 | // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 | 302 | // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index b27cc348d95c..f59d4601cc63 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $ | 2 | * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * controls the philips tda8290+75 tuner chip combo. | 5 | * controls the philips tda8290+75 tuner chip combo. |
@@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) | |||
69 | static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; | 69 | static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; |
70 | static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; | 70 | static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; |
71 | static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, | 71 | static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, |
72 | 0x7C, 0x04, 0xA3, 0x3F, | 72 | 0xfC, 0x04, 0xA3, 0x3F, |
73 | 0x2A, 0x04, 0xFF, 0x00, | 73 | 0x2A, 0x04, 0xFF, 0x00, |
74 | 0x00, 0x40 }; | 74 | 0x00, 0x40 }; |
75 | static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; | 75 | static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; |
@@ -138,16 +138,24 @@ static int tda8290_tune(struct i2c_client *c) | |||
138 | 138 | ||
139 | static void set_frequency(struct tuner *t, u16 ifc) | 139 | static void set_frequency(struct tuner *t, u16 ifc) |
140 | { | 140 | { |
141 | u32 N = (((t->freq<<3)+ifc)&0x3fffc); | 141 | u32 freq; |
142 | u32 N; | ||
142 | 143 | ||
143 | N = N >> get_freq_entry(div_table, t->freq); | 144 | if (t->mode == V4L2_TUNER_RADIO) |
145 | freq = t->freq / 1000; | ||
146 | else | ||
147 | freq = t->freq; | ||
148 | |||
149 | N = (((freq<<3)+ifc)&0x3fffc); | ||
150 | |||
151 | N = N >> get_freq_entry(div_table, freq); | ||
144 | t->i2c_set_freq[0] = 0; | 152 | t->i2c_set_freq[0] = 0; |
145 | t->i2c_set_freq[1] = (unsigned char)(N>>8); | 153 | t->i2c_set_freq[1] = (unsigned char)(N>>8); |
146 | t->i2c_set_freq[2] = (unsigned char) N; | 154 | t->i2c_set_freq[2] = (unsigned char) N; |
147 | t->i2c_set_freq[3] = 0x40; | 155 | t->i2c_set_freq[3] = 0x40; |
148 | t->i2c_set_freq[4] = 0x52; | 156 | t->i2c_set_freq[4] = 0x52; |
149 | t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq); | 157 | t->i2c_set_freq[5] = get_freq_entry(band_table, freq); |
150 | t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq); | 158 | t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); |
151 | t->i2c_set_freq[7] = 0x8f; | 159 | t->i2c_set_freq[7] = 0x8f; |
152 | } | 160 | } |
153 | 161 | ||
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 39773633cc3c..ee35562f4d1a 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -368,7 +368,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) | |||
368 | if (t->radio_mode == V4L2_TUNER_MODE_MONO) | 368 | if (t->radio_mode == V4L2_TUNER_MODE_MONO) |
369 | norm = &radio_mono; | 369 | norm = &radio_mono; |
370 | else | 370 | else |
371 | norm = &radio_stereo; | 371 | norm = &radio_stereo; |
372 | } else { | 372 | } else { |
373 | for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { | 373 | for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { |
374 | if (tvnorms[i].std & t->std) { | 374 | if (tvnorms[i].std & t->std) { |
@@ -566,7 +566,6 @@ static int tda9887_configure(struct tda9887 *t) | |||
566 | if (UNSET != t->pinnacle_id) { | 566 | if (UNSET != t->pinnacle_id) { |
567 | tda9887_set_pinnacle(t,buf); | 567 | tda9887_set_pinnacle(t,buf); |
568 | } | 568 | } |
569 | |||
570 | tda9887_set_config(t,buf); | 569 | tda9887_set_config(t,buf); |
571 | tda9887_set_insmod(t,buf); | 570 | tda9887_set_insmod(t,buf); |
572 | 571 | ||
@@ -615,8 +614,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | |||
615 | t->pinnacle_id = UNSET; | 614 | t->pinnacle_id = UNSET; |
616 | t->radio_mode = V4L2_TUNER_MODE_STEREO; | 615 | t->radio_mode = V4L2_TUNER_MODE_STEREO; |
617 | 616 | ||
618 | i2c_set_clientdata(&t->client, t); | 617 | i2c_set_clientdata(&t->client, t); |
619 | i2c_attach_client(&t->client); | 618 | i2c_attach_client(&t->client); |
620 | 619 | ||
621 | return 0; | 620 | return 0; |
622 | } | 621 | } |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c new file mode 100644 index 000000000000..a29f08f81f63 --- /dev/null +++ b/drivers/media/video/tea5767.c | |||
@@ -0,0 +1,334 @@ | |||
1 | /* | ||
2 | * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview | ||
3 | * I2C address is allways 0xC0. | ||
4 | * | ||
5 | * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $ | ||
6 | * | ||
7 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) | ||
8 | * This code is placed under the terms of the GNU General Public License | ||
9 | * | ||
10 | * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa | ||
11 | * from their contributions on DScaler. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/timer.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/videodev.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/i2c-algo-bit.h> | ||
26 | |||
27 | #include <media/tuner.h> | ||
28 | |||
29 | /* Declared at tuner-core.c */ | ||
30 | extern unsigned int tuner_debug; | ||
31 | |||
32 | #define PREFIX "TEA5767 " | ||
33 | |||
34 | /*****************************************************************************/ | ||
35 | |||
36 | /****************************** | ||
37 | * Write mode register values * | ||
38 | ******************************/ | ||
39 | |||
40 | /* First register */ | ||
41 | #define TEA5767_MUTE 0x80 /* Mutes output */ | ||
42 | #define TEA5767_SEARCH 0x40 /* Activates station search */ | ||
43 | /* Bits 0-5 for divider MSB */ | ||
44 | |||
45 | /* Second register */ | ||
46 | /* Bits 0-7 for divider LSB */ | ||
47 | |||
48 | /* Third register */ | ||
49 | |||
50 | /* Station search from botton to up */ | ||
51 | #define TEA5767_SEARCH_UP 0x80 | ||
52 | |||
53 | /* Searches with ADC output = 10 */ | ||
54 | #define TEA5767_SRCH_HIGH_LVL 0x60 | ||
55 | |||
56 | /* Searches with ADC output = 10 */ | ||
57 | #define TEA5767_SRCH_MID_LVL 0x40 | ||
58 | |||
59 | /* Searches with ADC output = 5 */ | ||
60 | #define TEA5767_SRCH_LOW_LVL 0x20 | ||
61 | |||
62 | /* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */ | ||
63 | #define TEA5767_HIGH_LO_INJECT 0x10 | ||
64 | |||
65 | /* Disable stereo */ | ||
66 | #define TEA5767_MONO 0x08 | ||
67 | |||
68 | /* Disable right channel and turns to mono */ | ||
69 | #define TEA5767_MUTE_RIGHT 0x04 | ||
70 | |||
71 | /* Disable left channel and turns to mono */ | ||
72 | #define TEA5767_MUTE_LEFT 0x02 | ||
73 | |||
74 | #define TEA5767_PORT1_HIGH 0x01 | ||
75 | |||
76 | /* Forth register */ | ||
77 | #define TEA5767_PORT2_HIGH 0x80 | ||
78 | /* Chips stops working. Only I2C bus remains on */ | ||
79 | #define TEA5767_STDBY 0x40 | ||
80 | |||
81 | /* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */ | ||
82 | #define TEA5767_JAPAN_BAND 0x20 | ||
83 | |||
84 | /* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */ | ||
85 | #define TEA5767_XTAL_32768 0x10 | ||
86 | |||
87 | /* Cuts weak signals */ | ||
88 | #define TEA5767_SOFT_MUTE 0x08 | ||
89 | |||
90 | /* Activates high cut control */ | ||
91 | #define TEA5767_HIGH_CUT_CTRL 0x04 | ||
92 | |||
93 | /* Activates stereo noise control */ | ||
94 | #define TEA5767_ST_NOISE_CTL 0x02 | ||
95 | |||
96 | /* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ | ||
97 | #define TEA5767_SRCH_IND 0x01 | ||
98 | |||
99 | /* Fiveth register */ | ||
100 | |||
101 | /* By activating, it will use Xtal at 13 MHz as reference for divider */ | ||
102 | #define TEA5767_PLLREF_ENABLE 0x80 | ||
103 | |||
104 | /* By activating, deemphasis=50, or else, deemphasis of 50us */ | ||
105 | #define TEA5767_DEEMPH_75 0X40 | ||
106 | |||
107 | /***************************** | ||
108 | * Read mode register values * | ||
109 | *****************************/ | ||
110 | |||
111 | /* First register */ | ||
112 | #define TEA5767_READY_FLAG_MASK 0x80 | ||
113 | #define TEA5767_BAND_LIMIT_MASK 0X40 | ||
114 | /* Bits 0-5 for divider MSB after search or preset */ | ||
115 | |||
116 | /* Second register */ | ||
117 | /* Bits 0-7 for divider LSB after search or preset */ | ||
118 | |||
119 | /* Third register */ | ||
120 | #define TEA5767_STEREO_MASK 0x80 | ||
121 | #define TEA5767_IF_CNTR_MASK 0x7f | ||
122 | |||
123 | /* Four register */ | ||
124 | #define TEA5767_ADC_LEVEL_MASK 0xf0 | ||
125 | |||
126 | /* should be 0 */ | ||
127 | #define TEA5767_CHIP_ID_MASK 0x0f | ||
128 | |||
129 | /* Fiveth register */ | ||
130 | /* Reserved for future extensions */ | ||
131 | #define TEA5767_RESERVED_MASK 0xff | ||
132 | |||
133 | /*****************************************************************************/ | ||
134 | |||
135 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) | ||
136 | { | ||
137 | struct tuner *t = i2c_get_clientdata(c); | ||
138 | |||
139 | tuner_warn("This tuner doesn't support TV freq.\n"); | ||
140 | } | ||
141 | |||
142 | static void tea5767_status_dump(unsigned char *buffer) | ||
143 | { | ||
144 | unsigned int div, frq; | ||
145 | |||
146 | if (TEA5767_READY_FLAG_MASK & buffer[0]) | ||
147 | printk(PREFIX "Ready Flag ON\n"); | ||
148 | else | ||
149 | printk(PREFIX "Ready Flag OFF\n"); | ||
150 | |||
151 | if (TEA5767_BAND_LIMIT_MASK & buffer[0]) | ||
152 | printk(PREFIX "Tuner at band limit\n"); | ||
153 | else | ||
154 | printk(PREFIX "Tuner not at band limit\n"); | ||
155 | |||
156 | div=((buffer[0]&0x3f)<<8) | buffer[1]; | ||
157 | |||
158 | switch (TEA5767_HIGH_LO_32768) { | ||
159 | case TEA5767_HIGH_LO_13MHz: | ||
160 | frq = 1000*(div*50-700-225)/4; /* Freq in KHz */ | ||
161 | break; | ||
162 | case TEA5767_LOW_LO_13MHz: | ||
163 | frq = 1000*(div*50+700+225)/4; /* Freq in KHz */ | ||
164 | break; | ||
165 | case TEA5767_LOW_LO_32768: | ||
166 | frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */ | ||
167 | break; | ||
168 | case TEA5767_HIGH_LO_32768: | ||
169 | default: | ||
170 | frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */ | ||
171 | break; | ||
172 | } | ||
173 | buffer[0] = (div>>8) & 0x3f; | ||
174 | buffer[1] = div & 0xff; | ||
175 | |||
176 | printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", | ||
177 | frq/1000,frq%1000,div); | ||
178 | |||
179 | if (TEA5767_STEREO_MASK & buffer[2]) | ||
180 | printk(PREFIX "Stereo\n"); | ||
181 | else | ||
182 | printk(PREFIX "Mono\n"); | ||
183 | |||
184 | printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK); | ||
185 | |||
186 | printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4); | ||
187 | |||
188 | printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK)); | ||
189 | |||
190 | printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK)); | ||
191 | } | ||
192 | |||
193 | /* Freq should be specifyed at 62.5 Hz */ | ||
194 | static void set_radio_freq(struct i2c_client *c, unsigned int frq) | ||
195 | { | ||
196 | struct tuner *t = i2c_get_clientdata(c); | ||
197 | unsigned char buffer[5]; | ||
198 | unsigned div; | ||
199 | int rc; | ||
200 | |||
201 | if ( tuner_debug ) | ||
202 | printk(PREFIX "radio freq counter %d\n",frq); | ||
203 | |||
204 | /* Rounds freq to next decimal value - for 62.5 KHz step */ | ||
205 | /* frq = 20*(frq/16)+radio_frq[frq%16]; */ | ||
206 | |||
207 | buffer[2] = TEA5767_PORT1_HIGH; | ||
208 | buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND; | ||
209 | buffer[4]=0; | ||
210 | |||
211 | if (t->audmode == V4L2_TUNER_MODE_MONO) { | ||
212 | tuner_dbg("TEA5767 set to mono\n"); | ||
213 | buffer[2] |= TEA5767_MONO; | ||
214 | } else | ||
215 | tuner_dbg("TEA5767 set to stereo\n"); | ||
216 | |||
217 | switch (t->type) { | ||
218 | case TEA5767_HIGH_LO_13MHz: | ||
219 | tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); | ||
220 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | ||
221 | buffer[4] |= TEA5767_PLLREF_ENABLE; | ||
222 | div = (frq*4/16+700+225+25)/50; | ||
223 | break; | ||
224 | case TEA5767_LOW_LO_13MHz: | ||
225 | tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); | ||
226 | |||
227 | buffer[4] |= TEA5767_PLLREF_ENABLE; | ||
228 | div = (frq*4/16-700-225+25)/50; | ||
229 | break; | ||
230 | case TEA5767_LOW_LO_32768: | ||
231 | tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); | ||
232 | buffer[3] |= TEA5767_XTAL_32768; | ||
233 | /* const 700=4000*175 Khz - to adjust freq to right value */ | ||
234 | div = (1000*(frq*4/16-700-225)+16384)>>15; | ||
235 | break; | ||
236 | case TEA5767_HIGH_LO_32768: | ||
237 | default: | ||
238 | tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n"); | ||
239 | |||
240 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | ||
241 | buffer[3] |= TEA5767_XTAL_32768; | ||
242 | div = (1000*(frq*4/16+700+225)+16384)>>15; | ||
243 | break; | ||
244 | } | ||
245 | buffer[0] = (div>>8) & 0x3f; | ||
246 | buffer[1] = div & 0xff; | ||
247 | |||
248 | if ( tuner_debug ) | ||
249 | tea5767_status_dump(buffer); | ||
250 | |||
251 | if (5 != (rc = i2c_master_send(c,buffer,5))) | ||
252 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc); | ||
253 | } | ||
254 | |||
255 | static int tea5767_signal(struct i2c_client *c) | ||
256 | { | ||
257 | unsigned char buffer[5]; | ||
258 | int rc; | ||
259 | struct tuner *t = i2c_get_clientdata(c); | ||
260 | |||
261 | memset(buffer,0,sizeof(buffer)); | ||
262 | if (5 != (rc = i2c_master_recv(c,buffer,5))) | ||
263 | tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); | ||
264 | |||
265 | return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4)); | ||
266 | } | ||
267 | |||
268 | static int tea5767_stereo(struct i2c_client *c) | ||
269 | { | ||
270 | unsigned char buffer[5]; | ||
271 | int rc; | ||
272 | struct tuner *t = i2c_get_clientdata(c); | ||
273 | |||
274 | memset(buffer,0,sizeof(buffer)); | ||
275 | if (5 != (rc = i2c_master_recv(c,buffer,5))) | ||
276 | tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); | ||
277 | |||
278 | rc = buffer[2] & TEA5767_STEREO_MASK; | ||
279 | |||
280 | if ( tuner_debug ) | ||
281 | tuner_dbg("TEA5767 radio ST GET = %02x\n", rc); | ||
282 | |||
283 | return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0); | ||
284 | } | ||
285 | |||
286 | int tea_detection(struct i2c_client *c) | ||
287 | { | ||
288 | unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
289 | int rc; | ||
290 | struct tuner *t = i2c_get_clientdata(c); | ||
291 | |||
292 | if (5 != (rc = i2c_master_recv(c,buffer,5))) { | ||
293 | tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc ); | ||
294 | return EINVAL; | ||
295 | } | ||
296 | |||
297 | /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */ | ||
298 | if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && | ||
299 | buffer[0] == buffer[3] && buffer[0] == buffer[4]) { | ||
300 | tuner_warn ( "All bytes are equal. It is not a TEA5767\n" ); | ||
301 | return EINVAL; | ||
302 | } | ||
303 | |||
304 | /* Status bytes: | ||
305 | * Byte 4: bit 3:1 : CI (Chip Identification) == 0 | ||
306 | * bit 0 : internally set to 0 | ||
307 | * Byte 5: bit 7:0 : == 0 | ||
308 | */ | ||
309 | |||
310 | if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { | ||
311 | tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" ); | ||
312 | return EINVAL; | ||
313 | } | ||
314 | tuner_warn ( "TEA5767 detected.\n" ); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | int tea5767_tuner_init(struct i2c_client *c) | ||
319 | { | ||
320 | struct tuner *t = i2c_get_clientdata(c); | ||
321 | |||
322 | if (tea_detection(c)==EINVAL) return EINVAL; | ||
323 | |||
324 | tuner_info("type set to %d (%s)\n", | ||
325 | t->type, TEA5767_TUNER_NAME); | ||
326 | strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name)); | ||
327 | |||
328 | t->tv_freq = set_tv_freq; | ||
329 | t->radio_freq = set_radio_freq; | ||
330 | t->has_signal = tea5767_signal; | ||
331 | t->is_stereo = tea5767_stereo; | ||
332 | |||
333 | return (0); | ||
334 | } | ||
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index eaabfc858703..6f6bf4a633fc 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $ | 2 | * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * core core, i.e. kernel interfaces, registering and so on | 5 | * core core, i.e. kernel interfaces, registering and so on |
@@ -26,7 +26,6 @@ | |||
26 | /* | 26 | /* |
27 | * comment line bellow to return to old behavor, where only one I2C device is supported | 27 | * comment line bellow to return to old behavor, where only one I2C device is supported |
28 | */ | 28 | */ |
29 | #define CONFIG_TUNER_MULTI_I2C /**/ | ||
30 | 29 | ||
31 | #define UNSET (-1U) | 30 | #define UNSET (-1U) |
32 | 31 | ||
@@ -58,9 +57,7 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | |||
58 | MODULE_LICENSE("GPL"); | 57 | MODULE_LICENSE("GPL"); |
59 | 58 | ||
60 | static int this_adap; | 59 | static int this_adap; |
61 | #ifdef CONFIG_TUNER_MULTI_I2C | ||
62 | static unsigned short first_tuner, tv_tuner, radio_tuner; | 60 | static unsigned short first_tuner, tv_tuner, radio_tuner; |
63 | #endif | ||
64 | 61 | ||
65 | static struct i2c_driver driver; | 62 | static struct i2c_driver driver; |
66 | static struct i2c_client client_template; | 63 | static struct i2c_client client_template; |
@@ -81,26 +78,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
81 | return; | 78 | return; |
82 | } | 79 | } |
83 | if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { | 80 | if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { |
84 | |||
85 | if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { | ||
86 | /* V4L2_TUNER_CAP_LOW frequency */ | ||
87 | |||
88 | tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n"); | ||
89 | |||
90 | t->tv_freq(c,freq>>10); | ||
91 | |||
92 | return; | ||
93 | } else { | ||
94 | /* FIXME: better do that chip-specific, but | ||
95 | right now we don't have that in the config | ||
96 | struct and this way is still better than no | ||
97 | check at all */ | ||
98 | tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", | 81 | tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", |
99 | freq/16,freq%16*100/16,tv_range[0],tv_range[1]); | 82 | freq/16,freq%16*100/16,tv_range[0],tv_range[1]); |
100 | return; | ||
101 | } | ||
102 | } | 83 | } |
103 | tuner_dbg("62.5 Khz freq step selected for TV.\n"); | ||
104 | t->tv_freq(c,freq); | 84 | t->tv_freq(c,freq); |
105 | } | 85 | } |
106 | 86 | ||
@@ -116,31 +96,18 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
116 | tuner_info("no radio tuning for this one, sorry.\n"); | 96 | tuner_info("no radio tuning for this one, sorry.\n"); |
117 | return; | 97 | return; |
118 | } | 98 | } |
119 | if (freq < radio_range[0]*16 || freq > radio_range[1]*16) { | 99 | if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) { |
120 | if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { | 100 | if (tuner_debug) |
121 | /* V4L2_TUNER_CAP_LOW frequency */ | 101 | tuner_info("radio freq step 62.5Hz (%d.%06d)\n", |
122 | if (t->type == TUNER_TEA5767) { | 102 | freq/16000,freq%16000*1000/16); |
123 | tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); | 103 | t->radio_freq(c,freq); |
124 | t->radio_freq(c,freq>>10); | 104 | } else { |
125 | return; | 105 | tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", |
126 | } | 106 | freq/16,freq%16*100/16, |
127 | 107 | radio_range[0],radio_range[1]); | |
128 | tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n"); | ||
129 | |||
130 | tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); | ||
131 | |||
132 | t->radio_freq(c,freq>>10); | ||
133 | return; | ||
134 | |||
135 | } else { | ||
136 | tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", | ||
137 | freq/16,freq%16*100/16, | ||
138 | radio_range[0],radio_range[1]); | ||
139 | return; | ||
140 | } | ||
141 | } | 108 | } |
142 | tuner_dbg("62.5 Khz freq step selected for Radio.\n"); | 109 | |
143 | t->radio_freq(c,freq); | 110 | return; |
144 | } | 111 | } |
145 | 112 | ||
146 | static void set_freq(struct i2c_client *c, unsigned long freq) | 113 | static void set_freq(struct i2c_client *c, unsigned long freq) |
@@ -166,8 +133,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq) | |||
166 | static void set_type(struct i2c_client *c, unsigned int type) | 133 | static void set_type(struct i2c_client *c, unsigned int type) |
167 | { | 134 | { |
168 | struct tuner *t = i2c_get_clientdata(c); | 135 | struct tuner *t = i2c_get_clientdata(c); |
136 | unsigned char buffer[4]; | ||
169 | 137 | ||
170 | tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); | ||
171 | /* sanity check */ | 138 | /* sanity check */ |
172 | if (type == UNSET || type == TUNER_ABSENT) | 139 | if (type == UNSET || type == TUNER_ABSENT) |
173 | return; | 140 | return; |
@@ -179,8 +146,8 @@ static void set_type(struct i2c_client *c, unsigned int type) | |||
179 | t->type = type; | 146 | t->type = type; |
180 | return; | 147 | return; |
181 | } | 148 | } |
182 | if (t->initialized) | 149 | if ((t->initialized) && (t->type == type)) |
183 | /* run only once */ | 150 | /* run only once except type change Hac 04/05*/ |
184 | return; | 151 | return; |
185 | 152 | ||
186 | t->initialized = 1; | 153 | t->initialized = 1; |
@@ -193,25 +160,42 @@ static void set_type(struct i2c_client *c, unsigned int type) | |||
193 | case TUNER_PHILIPS_TDA8290: | 160 | case TUNER_PHILIPS_TDA8290: |
194 | tda8290_init(c); | 161 | tda8290_init(c); |
195 | break; | 162 | break; |
163 | case TUNER_TEA5767: | ||
164 | if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT; | ||
165 | break; | ||
166 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
167 | buffer[0] = 0x0b; | ||
168 | buffer[1] = 0xdc; | ||
169 | buffer[2] = 0x9c; | ||
170 | buffer[3] = 0x60; | ||
171 | i2c_master_send(c,buffer,4); | ||
172 | mdelay(1); | ||
173 | buffer[2] = 0x86; | ||
174 | buffer[3] = 0x54; | ||
175 | i2c_master_send(c,buffer,4); | ||
176 | default_tuner_init(c); | ||
177 | break; | ||
196 | default: | 178 | default: |
179 | /* TEA5767 autodetection code */ | ||
180 | if (tea5767_tuner_init(c)!=EINVAL) { | ||
181 | t->type = TUNER_TEA5767; | ||
182 | if (first_tuner == 0x60) | ||
183 | first_tuner++; | ||
184 | break; | ||
185 | } | ||
186 | |||
197 | default_tuner_init(c); | 187 | default_tuner_init(c); |
198 | break; | 188 | break; |
199 | } | 189 | } |
190 | tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); | ||
200 | } | 191 | } |
201 | 192 | ||
202 | #ifdef CONFIG_TUNER_MULTI_I2C | ||
203 | #define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ | 193 | #define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ |
204 | return 0; } else \ | 194 | return 0; } else if (tuner_debug) \ |
205 | tuner_info ("Cmd %s accepted to "tun"\n",cmd); | 195 | tuner_info ("Cmd %s accepted to "tun"\n",cmd); |
206 | #define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ | 196 | #define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ |
207 | CHECK_ADDR(radio_tuner,cmd,"radio") } else \ | 197 | CHECK_ADDR(radio_tuner,cmd,"radio") } else \ |
208 | { CHECK_ADDR(tv_tuner,cmd,"TV"); } | 198 | { CHECK_ADDR(tv_tuner,cmd,"TV"); } |
209 | #else | ||
210 | #define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd); | ||
211 | #define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd); | ||
212 | #endif | ||
213 | |||
214 | #ifdef CONFIG_TUNER_MULTI_I2C | ||
215 | 199 | ||
216 | static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) | 200 | static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) |
217 | { | 201 | { |
@@ -242,9 +226,6 @@ static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) | |||
242 | } | 226 | } |
243 | set_type(c,tun_addr->type); | 227 | set_type(c,tun_addr->type); |
244 | } | 228 | } |
245 | #else | ||
246 | #define set_addr(c,tun_addr) set_type(c,(tun_addr)->type) | ||
247 | #endif | ||
248 | 229 | ||
249 | static char pal[] = "-"; | 230 | static char pal[] = "-"; |
250 | module_param_string(pal, pal, sizeof(pal), 0644); | 231 | module_param_string(pal, pal, sizeof(pal), 0644); |
@@ -284,17 +265,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
284 | { | 265 | { |
285 | struct tuner *t; | 266 | struct tuner *t; |
286 | 267 | ||
287 | #ifndef CONFIG_TUNER_MULTI_I2C | ||
288 | if (this_adap > 0) | ||
289 | return -1; | ||
290 | #else | ||
291 | /* by default, first I2C card is both tv and radio tuner */ | 268 | /* by default, first I2C card is both tv and radio tuner */ |
292 | if (this_adap == 0) { | 269 | if (this_adap == 0) { |
293 | first_tuner = addr; | 270 | first_tuner = addr; |
294 | tv_tuner = addr; | 271 | tv_tuner = addr; |
295 | radio_tuner = addr; | 272 | radio_tuner = addr; |
296 | } | 273 | } |
297 | #endif | ||
298 | this_adap++; | 274 | this_adap++; |
299 | 275 | ||
300 | client_template.adapter = adap; | 276 | client_template.adapter = adap; |
@@ -308,6 +284,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
308 | i2c_set_clientdata(&t->i2c, t); | 284 | i2c_set_clientdata(&t->i2c, t); |
309 | t->type = UNSET; | 285 | t->type = UNSET; |
310 | t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */ | 286 | t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */ |
287 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
311 | 288 | ||
312 | i2c_attach_client(&t->i2c); | 289 | i2c_attach_client(&t->i2c); |
313 | tuner_info("chip found @ 0x%x (%s)\n", | 290 | tuner_info("chip found @ 0x%x (%s)\n", |
@@ -325,11 +302,9 @@ static int tuner_probe(struct i2c_adapter *adap) | |||
325 | } | 302 | } |
326 | this_adap = 0; | 303 | this_adap = 0; |
327 | 304 | ||
328 | #ifdef CONFIG_TUNER_MULTI_I2C | ||
329 | first_tuner = 0; | 305 | first_tuner = 0; |
330 | tv_tuner = 0; | 306 | tv_tuner = 0; |
331 | radio_tuner = 0; | 307 | radio_tuner = 0; |
332 | #endif | ||
333 | 308 | ||
334 | if (adap->class & I2C_CLASS_TV_ANALOG) | 309 | if (adap->class & I2C_CLASS_TV_ANALOG) |
335 | return i2c_probe(adap, &addr_data, tuner_attach); | 310 | return i2c_probe(adap, &addr_data, tuner_attach); |
@@ -392,8 +367,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
392 | t->radio_if2 = 41300 * 1000; | 367 | t->radio_if2 = 41300 * 1000; |
393 | break; | 368 | break; |
394 | } | 369 | } |
395 | break; | 370 | break; |
396 | |||
397 | /* --- v4l ioctls --- */ | 371 | /* --- v4l ioctls --- */ |
398 | /* take care: bttv does userspace copying, we'll get a | 372 | /* take care: bttv does userspace copying, we'll get a |
399 | kernel pointer here... */ | 373 | kernel pointer here... */ |
@@ -440,11 +414,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
440 | vt->signal = t->has_signal(client); | 414 | vt->signal = t->has_signal(client); |
441 | if (t->is_stereo) { | 415 | if (t->is_stereo) { |
442 | if (t->is_stereo(client)) | 416 | if (t->is_stereo(client)) |
443 | vt-> flags |= VIDEO_TUNER_STEREO_ON; | 417 | vt->flags |= VIDEO_TUNER_STEREO_ON; |
444 | else | 418 | else |
445 | vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON; | 419 | vt->flags &= ~VIDEO_TUNER_STEREO_ON; |
446 | } | 420 | } |
447 | vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */ | 421 | vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */ |
422 | |||
423 | vt->rangelow = radio_range[0] * 16000; | ||
424 | vt->rangehigh = radio_range[1] * 16000; | ||
425 | |||
426 | } else { | ||
427 | vt->rangelow = tv_range[0] * 16; | ||
428 | vt->rangehigh = tv_range[1] * 16; | ||
448 | } | 429 | } |
449 | 430 | ||
450 | return 0; | 431 | return 0; |
@@ -510,20 +491,46 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
510 | tuner -> signal = t->has_signal(client); | 491 | tuner -> signal = t->has_signal(client); |
511 | if (t->is_stereo) { | 492 | if (t->is_stereo) { |
512 | if (t->is_stereo(client)) { | 493 | if (t->is_stereo(client)) { |
513 | tuner -> capability |= V4L2_TUNER_CAP_STEREO; | 494 | tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; |
514 | tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO; | ||
515 | } else { | 495 | } else { |
516 | tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO; | 496 | tuner -> rxsubchans = V4L2_TUNER_SUB_MONO; |
517 | } | 497 | } |
518 | } | 498 | } |
499 | tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
500 | tuner->audmode = t->audmode; | ||
501 | |||
502 | tuner->rangelow = radio_range[0] * 16000; | ||
503 | tuner->rangehigh = radio_range[1] * 16000; | ||
504 | } else { | ||
505 | tuner->rangelow = tv_range[0] * 16; | ||
506 | tuner->rangehigh = tv_range[1] * 16; | ||
519 | } | 507 | } |
520 | /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */ | ||
521 | tuner->rangelow = tv_range[0] * 16; | ||
522 | // tuner->rangehigh = tv_range[1] * 16; | ||
523 | // tuner->rangelow = tv_range[0] * 16384; | ||
524 | tuner->rangehigh = tv_range[1] * 16384; | ||
525 | break; | 508 | break; |
526 | } | 509 | } |
510 | case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */ | ||
511 | { | ||
512 | struct v4l2_tuner *tuner = arg; | ||
513 | |||
514 | CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio"); | ||
515 | SWITCH_V4L2; | ||
516 | |||
517 | /* To switch the audio mode, applications initialize the | ||
518 | index and audmode fields and the reserved array and | ||
519 | call the VIDIOC_S_TUNER ioctl. */ | ||
520 | /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO, | ||
521 | V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2, | ||
522 | V4L2_TUNER_MODE_SAP */ | ||
523 | |||
524 | if (tuner->audmode == V4L2_TUNER_MODE_MONO) | ||
525 | t->audmode = V4L2_TUNER_MODE_MONO; | ||
526 | else | ||
527 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
528 | |||
529 | set_radio_freq(client, t->freq); | ||
530 | break; | ||
531 | } | ||
532 | case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */ | ||
533 | break; | ||
527 | default: | 534 | default: |
528 | tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); | 535 | tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); |
529 | /* nothing */ | 536 | /* nothing */ |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 539f30557317..c39ed6226ee0 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $ | 2 | * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * controls all those simple 4-control-bytes style tuners. | 5 | * controls all those simple 4-control-bytes style tuners. |
@@ -207,28 +207,27 @@ static struct tunertype tuners[] = { | |||
207 | { "LG PAL (TAPE series)", LGINNOTEK, PAL, | 207 | { "LG PAL (TAPE series)", LGINNOTEK, PAL, |
208 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, | 208 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, |
209 | 209 | ||
210 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, | 210 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, |
211 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, | 211 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, |
212 | { "Philips FQ1236A MK4", Philips, NTSC, | 212 | { "Philips FQ1236A MK4", Philips, NTSC, |
213 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | 213 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, |
214 | 214 | ||
215 | /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */ | 215 | /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */ |
216 | { "Ymec TVision TVF-8531MF", Philips, NTSC, | 216 | { "Ymec TVision TVF-8531MF", Philips, NTSC, |
217 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, | 217 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, |
218 | { "Ymec TVision TVF-5533MF", Philips, NTSC, | 218 | { "Ymec TVision TVF-5533MF", Philips, NTSC, |
219 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, | 219 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, |
220 | |||
221 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, | 220 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, |
222 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | 221 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, |
223 | { "Tena TNF9533-D/IF", LGINNOTEK, PAL, | 222 | /* Should work for TNF9533-D/IF, TNF9533-B/DF */ |
224 | 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623}, | 223 | { "Tena TNF9533-D/IF", Philips, PAL, |
224 | 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, | ||
225 | 225 | ||
226 | /* | 226 | /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */ |
227 | * This entry is for TEA5767 FM radio only chip used on several boards | ||
228 | * w/TV tuner | ||
229 | */ | ||
230 | { TEA5767_TUNER_NAME, Philips, RADIO, | 227 | { TEA5767_TUNER_NAME, Philips, RADIO, |
231 | -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, | 228 | -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, |
229 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, | ||
230 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, | ||
232 | }; | 231 | }; |
233 | 232 | ||
234 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 233 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
@@ -455,24 +454,24 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
455 | int rc; | 454 | int rc; |
456 | 455 | ||
457 | tun=&tuners[t->type]; | 456 | tun=&tuners[t->type]; |
458 | div = freq + (int)(16*10.7); | 457 | div = (freq / 1000) + (int)(16*10.7); |
459 | buffer[2] = tun->config; | 458 | buffer[2] = tun->config; |
460 | 459 | ||
461 | switch (t->type) { | 460 | switch (t->type) { |
462 | case TUNER_TENA_9533_DI: | 461 | case TUNER_TENA_9533_DI: |
463 | case TUNER_YMEC_TVF_5533MF: | 462 | case TUNER_YMEC_TVF_5533MF: |
464 | |||
465 | /*These values are empirically determinated */ | 463 | /*These values are empirically determinated */ |
466 | div = (freq*122)/16 - 20; | 464 | div = (freq * 122) / 16000 - 20; |
467 | buffer[2] = 0x88; /* could be also 0x80 */ | 465 | buffer[2] = 0x88; /* could be also 0x80 */ |
468 | buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */ | 466 | buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */ |
469 | break; | 467 | break; |
470 | case TUNER_PHILIPS_FM1216ME_MK3: | 468 | case TUNER_PHILIPS_FM1216ME_MK3: |
471 | case TUNER_PHILIPS_FM1236_MK3: | 469 | case TUNER_PHILIPS_FM1236_MK3: |
470 | case TUNER_PHILIPS_FMD1216ME_MK3: | ||
472 | buffer[3] = 0x19; | 471 | buffer[3] = 0x19; |
473 | break; | 472 | break; |
474 | case TUNER_PHILIPS_FM1256_IH3: | 473 | case TUNER_PHILIPS_FM1256_IH3: |
475 | div = (20 * freq)/16 + 333 * 2; | 474 | div = (20 * freq) / 16000 + 333 * 2; |
476 | buffer[2] = 0x80; | 475 | buffer[2] = 0x80; |
477 | buffer[3] = 0x19; | 476 | buffer[3] = 0x19; |
478 | break; | 477 | break; |
@@ -505,6 +504,7 @@ int default_tuner_init(struct i2c_client *c) | |||
505 | t->radio_freq = default_set_radio_freq; | 504 | t->radio_freq = default_set_radio_freq; |
506 | t->has_signal = tuner_signal; | 505 | t->has_signal = tuner_signal; |
507 | t->is_stereo = tuner_stereo; | 506 | t->is_stereo = tuner_stereo; |
507 | |||
508 | return 0; | 508 | return 0; |
509 | } | 509 | } |
510 | 510 | ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index d8d65397e06e..353deb25e397 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = { | |||
364 | .id_table = mptfc_pci_table, | 364 | .id_table = mptfc_pci_table, |
365 | .probe = mptfc_probe, | 365 | .probe = mptfc_probe, |
366 | .remove = __devexit_p(mptscsih_remove), | 366 | .remove = __devexit_p(mptscsih_remove), |
367 | .driver = { | 367 | .shutdown = mptscsih_shutdown, |
368 | .shutdown = mptscsih_shutdown, | ||
369 | }, | ||
370 | #ifdef CONFIG_PM | 368 | #ifdef CONFIG_PM |
371 | .suspend = mptscsih_suspend, | 369 | .suspend = mptscsih_suspend, |
372 | .resume = mptscsih_resume, | 370 | .resume = mptscsih_resume, |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index a0078ae5b9b8..4f973a49be4c 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width); | |||
170 | #endif | 170 | #endif |
171 | 171 | ||
172 | void mptscsih_remove(struct pci_dev *); | 172 | void mptscsih_remove(struct pci_dev *); |
173 | void mptscsih_shutdown(struct device *); | 173 | void mptscsih_shutdown(struct pci_dev *); |
174 | #ifdef CONFIG_PM | 174 | #ifdef CONFIG_PM |
175 | int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); | 175 | int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); |
176 | int mptscsih_resume(struct pci_dev *pdev); | 176 | int mptscsih_resume(struct pci_dev *pdev); |
@@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev) | |||
988 | #endif | 988 | #endif |
989 | #endif | 989 | #endif |
990 | 990 | ||
991 | mptscsih_shutdown(&pdev->dev); | 991 | mptscsih_shutdown(pdev); |
992 | 992 | ||
993 | sz1=0; | 993 | sz1=0; |
994 | 994 | ||
@@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev) | |||
1026 | * | 1026 | * |
1027 | */ | 1027 | */ |
1028 | void | 1028 | void |
1029 | mptscsih_shutdown(struct device * dev) | 1029 | mptscsih_shutdown(struct pci_dev *pdev) |
1030 | { | 1030 | { |
1031 | MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev)); | 1031 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
1032 | struct Scsi_Host *host = ioc->sh; | 1032 | struct Scsi_Host *host = ioc->sh; |
1033 | MPT_SCSI_HOST *hd; | 1033 | MPT_SCSI_HOST *hd; |
1034 | 1034 | ||
@@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev) | |||
1054 | int | 1054 | int |
1055 | mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) | 1055 | mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) |
1056 | { | 1056 | { |
1057 | mptscsih_shutdown(&pdev->dev); | 1057 | mptscsih_shutdown(pdev); |
1058 | return mpt_suspend(pdev,state); | 1058 | return mpt_suspend(pdev,state); |
1059 | } | 1059 | } |
1060 | 1060 | ||
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index d73aec33e16a..5ea89bf0df19 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
@@ -82,7 +82,7 @@ | |||
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | extern void mptscsih_remove(struct pci_dev *); | 84 | extern void mptscsih_remove(struct pci_dev *); |
85 | extern void mptscsih_shutdown(struct device *); | 85 | extern void mptscsih_shutdown(struct pci_dev *); |
86 | #ifdef CONFIG_PM | 86 | #ifdef CONFIG_PM |
87 | extern int mptscsih_suspend(struct pci_dev *pdev, u32 state); | 87 | extern int mptscsih_suspend(struct pci_dev *pdev, u32 state); |
88 | extern int mptscsih_resume(struct pci_dev *pdev); | 88 | extern int mptscsih_resume(struct pci_dev *pdev); |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 5f9a61b85b3b..e0c0ee5bc966 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = { | |||
419 | .id_table = mptspi_pci_table, | 419 | .id_table = mptspi_pci_table, |
420 | .probe = mptspi_probe, | 420 | .probe = mptspi_probe, |
421 | .remove = __devexit_p(mptscsih_remove), | 421 | .remove = __devexit_p(mptscsih_remove), |
422 | .driver = { | 422 | .shutdown = mptscsih_shutdown, |
423 | .shutdown = mptscsih_shutdown, | ||
424 | }, | ||
425 | #ifdef CONFIG_PM | 423 | #ifdef CONFIG_PM |
426 | .suspend = mptscsih_suspend, | 424 | .suspend = mptscsih_suspend, |
427 | .resume = mptscsih_resume, | 425 | .resume = mptscsih_resume, |
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index d272ea36a578..91d1c4c24d9b 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c | |||
@@ -822,7 +822,7 @@ static int corkscrew_open(struct net_device *dev) | |||
822 | break; /* Bad news! */ | 822 | break; /* Bad news! */ |
823 | skb->dev = dev; /* Mark as being used by this device. */ | 823 | skb->dev = dev; /* Mark as being used by this device. */ |
824 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 824 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
825 | vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail); | 825 | vp->rx_ring[i].addr = isa_virt_to_bus(skb->data); |
826 | } | 826 | } |
827 | vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */ | 827 | vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */ |
828 | outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr); | 828 | outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr); |
@@ -1406,7 +1406,7 @@ static int boomerang_rx(struct net_device *dev) | |||
1406 | break; /* Bad news! */ | 1406 | break; /* Bad news! */ |
1407 | skb->dev = dev; /* Mark as being used by this device. */ | 1407 | skb->dev = dev; /* Mark as being used by this device. */ |
1408 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1408 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
1409 | vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail); | 1409 | vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data); |
1410 | vp->rx_skbuff[entry] = skb; | 1410 | vp->rx_skbuff[entry] = skb; |
1411 | } | 1411 | } |
1412 | vp->rx_ring[entry].status = 0; /* Clear complete bit. */ | 1412 | vp->rx_ring[entry].status = 0; /* Clear complete bit. */ |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 80ec9aa575bb..07746b95fd83 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev) | |||
1802 | break; /* Bad news! */ | 1802 | break; /* Bad news! */ |
1803 | skb->dev = dev; /* Mark as being used by this device. */ | 1803 | skb->dev = dev; /* Mark as being used by this device. */ |
1804 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1804 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
1805 | vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); | 1805 | vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); |
1806 | } | 1806 | } |
1807 | if (i != RX_RING_SIZE) { | 1807 | if (i != RX_RING_SIZE) { |
1808 | int j; | 1808 | int j; |
@@ -2632,7 +2632,7 @@ boomerang_rx(struct net_device *dev) | |||
2632 | pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | 2632 | pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); |
2633 | /* 'skb_put()' points to the start of sk_buff data area. */ | 2633 | /* 'skb_put()' points to the start of sk_buff data area. */ |
2634 | memcpy(skb_put(skb, pkt_len), | 2634 | memcpy(skb_put(skb, pkt_len), |
2635 | vp->rx_skbuff[entry]->tail, | 2635 | vp->rx_skbuff[entry]->data, |
2636 | pkt_len); | 2636 | pkt_len); |
2637 | pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | 2637 | pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); |
2638 | vp->rx_copy++; | 2638 | vp->rx_copy++; |
@@ -2678,7 +2678,7 @@ boomerang_rx(struct net_device *dev) | |||
2678 | } | 2678 | } |
2679 | skb->dev = dev; /* Mark as being used by this device. */ | 2679 | skb->dev = dev; /* Mark as being used by this device. */ |
2680 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 2680 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
2681 | vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); | 2681 | vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); |
2682 | vp->rx_skbuff[entry] = skb; | 2682 | vp->rx_skbuff[entry] = skb; |
2683 | } | 2683 | } |
2684 | vp->rx_ring[entry].status = 0; /* Clear complete bit. */ | 2684 | vp->rx_ring[entry].status = 0; /* Clear complete bit. */ |
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index e4b3c5c88542..7b293f01c9ed 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -596,7 +596,7 @@ rx_status_loop: | |||
596 | 596 | ||
597 | mapping = | 597 | mapping = |
598 | cp->rx_skb[rx_tail].mapping = | 598 | cp->rx_skb[rx_tail].mapping = |
599 | pci_map_single(cp->pdev, new_skb->tail, | 599 | pci_map_single(cp->pdev, new_skb->data, |
600 | buflen, PCI_DMA_FROMDEVICE); | 600 | buflen, PCI_DMA_FROMDEVICE); |
601 | cp->rx_skb[rx_tail].skb = new_skb; | 601 | cp->rx_skb[rx_tail].skb = new_skb; |
602 | 602 | ||
@@ -1101,7 +1101,7 @@ static int cp_refill_rx (struct cp_private *cp) | |||
1101 | skb_reserve(skb, RX_OFFSET); | 1101 | skb_reserve(skb, RX_OFFSET); |
1102 | 1102 | ||
1103 | cp->rx_skb[i].mapping = pci_map_single(cp->pdev, | 1103 | cp->rx_skb[i].mapping = pci_map_single(cp->pdev, |
1104 | skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1104 | skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1105 | cp->rx_skb[i].skb = skb; | 1105 | cp->rx_skb[i].skb = skb; |
1106 | 1106 | ||
1107 | cp->rx_ring[i].opts2 = 0; | 1107 | cp->rx_ring[i].opts2 = 0; |
diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 65f97b1dc581..13b745b39667 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c | |||
@@ -546,11 +546,11 @@ static inline void init_rx_bufs(struct net_device *dev) | |||
546 | rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); | 546 | rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); |
547 | rbd->b_addr = WSWAPrbd(virt_to_bus(rbd)); | 547 | rbd->b_addr = WSWAPrbd(virt_to_bus(rbd)); |
548 | rbd->skb = skb; | 548 | rbd->skb = skb; |
549 | rbd->v_data = skb->tail; | 549 | rbd->v_data = skb->data; |
550 | rbd->b_data = WSWAPchar(virt_to_bus(skb->tail)); | 550 | rbd->b_data = WSWAPchar(virt_to_bus(skb->data)); |
551 | rbd->size = PKT_BUF_SZ; | 551 | rbd->size = PKT_BUF_SZ; |
552 | #ifdef __mc68000__ | 552 | #ifdef __mc68000__ |
553 | cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ); | 553 | cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ); |
554 | #endif | 554 | #endif |
555 | } | 555 | } |
556 | lp->rbd_head = lp->rbds; | 556 | lp->rbd_head = lp->rbds; |
@@ -816,10 +816,10 @@ static inline int i596_rx(struct net_device *dev) | |||
816 | rx_in_place = 1; | 816 | rx_in_place = 1; |
817 | rbd->skb = newskb; | 817 | rbd->skb = newskb; |
818 | newskb->dev = dev; | 818 | newskb->dev = dev; |
819 | rbd->v_data = newskb->tail; | 819 | rbd->v_data = newskb->data; |
820 | rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail)); | 820 | rbd->b_data = WSWAPchar(virt_to_bus(newskb->data)); |
821 | #ifdef __mc68000__ | 821 | #ifdef __mc68000__ |
822 | cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ); | 822 | cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ); |
823 | #endif | 823 | #endif |
824 | } | 824 | } |
825 | else | 825 | else |
@@ -840,7 +840,7 @@ memory_squeeze: | |||
840 | skb->protocol=eth_type_trans(skb,dev); | 840 | skb->protocol=eth_type_trans(skb,dev); |
841 | skb->len = pkt_len; | 841 | skb->len = pkt_len; |
842 | #ifdef __mc68000__ | 842 | #ifdef __mc68000__ |
843 | cache_clear(virt_to_phys(rbd->skb->tail), | 843 | cache_clear(virt_to_phys(rbd->skb->data), |
844 | pkt_len); | 844 | pkt_len); |
845 | #endif | 845 | #endif |
846 | netif_rx(skb); | 846 | netif_rx(skb); |
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index b7dd7260cafb..8618012df06a 100755 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c | |||
@@ -87,6 +87,7 @@ Revision History: | |||
87 | #include <linux/if_vlan.h> | 87 | #include <linux/if_vlan.h> |
88 | #include <linux/ctype.h> | 88 | #include <linux/ctype.h> |
89 | #include <linux/crc32.h> | 89 | #include <linux/crc32.h> |
90 | #include <linux/dma-mapping.h> | ||
90 | 91 | ||
91 | #include <asm/system.h> | 92 | #include <asm/system.h> |
92 | #include <asm/io.h> | 93 | #include <asm/io.h> |
@@ -2006,12 +2007,11 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, | |||
2006 | } | 2007 | } |
2007 | 2008 | ||
2008 | /* Initialize DMA */ | 2009 | /* Initialize DMA */ |
2009 | if(!pci_dma_supported(pdev, 0xffffffff)){ | 2010 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) { |
2010 | printk(KERN_ERR "amd8111e: DMA not supported," | 2011 | printk(KERN_ERR "amd8111e: DMA not supported," |
2011 | "exiting.\n"); | 2012 | "exiting.\n"); |
2012 | goto err_free_reg; | 2013 | goto err_free_reg; |
2013 | } else | 2014 | } |
2014 | pdev->dma_mask = 0xffffffff; | ||
2015 | 2015 | ||
2016 | reg_addr = pci_resource_start(pdev, 0); | 2016 | reg_addr = pci_resource_start(pdev, 0); |
2017 | reg_len = pci_resource_len(pdev, 0); | 2017 | reg_len = pci_resource_len(pdev, 0); |
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index b8ab2b6355eb..e613cc289749 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c | |||
@@ -34,10 +34,6 @@ | |||
34 | only is it difficult to detect, it also moves around in I/O space in | 34 | only is it difficult to detect, it also moves around in I/O space in |
35 | response to inb()s from other device probes! | 35 | response to inb()s from other device probes! |
36 | */ | 36 | */ |
37 | /* | ||
38 | 99/03/03 Allied Telesis RE1000 Plus support by T.Hagawa | ||
39 | 99/12/30 port to 2.3.35 by K.Takai | ||
40 | */ | ||
41 | 37 | ||
42 | #include <linux/config.h> | 38 | #include <linux/config.h> |
43 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index aa42b7a27735..430c628279b3 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c | |||
@@ -547,7 +547,7 @@ rio_timer (unsigned long data) | |||
547 | skb_reserve (skb, 2); | 547 | skb_reserve (skb, 2); |
548 | np->rx_ring[entry].fraginfo = | 548 | np->rx_ring[entry].fraginfo = |
549 | cpu_to_le64 (pci_map_single | 549 | cpu_to_le64 (pci_map_single |
550 | (np->pdev, skb->tail, np->rx_buf_sz, | 550 | (np->pdev, skb->data, np->rx_buf_sz, |
551 | PCI_DMA_FROMDEVICE)); | 551 | PCI_DMA_FROMDEVICE)); |
552 | } | 552 | } |
553 | np->rx_ring[entry].fraginfo |= | 553 | np->rx_ring[entry].fraginfo |= |
@@ -618,7 +618,7 @@ alloc_list (struct net_device *dev) | |||
618 | /* Rubicon now supports 40 bits of addressing space. */ | 618 | /* Rubicon now supports 40 bits of addressing space. */ |
619 | np->rx_ring[i].fraginfo = | 619 | np->rx_ring[i].fraginfo = |
620 | cpu_to_le64 ( pci_map_single ( | 620 | cpu_to_le64 ( pci_map_single ( |
621 | np->pdev, skb->tail, np->rx_buf_sz, | 621 | np->pdev, skb->data, np->rx_buf_sz, |
622 | PCI_DMA_FROMDEVICE)); | 622 | PCI_DMA_FROMDEVICE)); |
623 | np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; | 623 | np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; |
624 | } | 624 | } |
@@ -906,7 +906,7 @@ receive_packet (struct net_device *dev) | |||
906 | /* 16 byte align the IP header */ | 906 | /* 16 byte align the IP header */ |
907 | skb_reserve (skb, 2); | 907 | skb_reserve (skb, 2); |
908 | eth_copy_and_sum (skb, | 908 | eth_copy_and_sum (skb, |
909 | np->rx_skbuff[entry]->tail, | 909 | np->rx_skbuff[entry]->data, |
910 | pkt_len, 0); | 910 | pkt_len, 0); |
911 | skb_put (skb, pkt_len); | 911 | skb_put (skb, pkt_len); |
912 | pci_dma_sync_single_for_device(np->pdev, | 912 | pci_dma_sync_single_for_device(np->pdev, |
@@ -950,7 +950,7 @@ receive_packet (struct net_device *dev) | |||
950 | skb_reserve (skb, 2); | 950 | skb_reserve (skb, 2); |
951 | np->rx_ring[entry].fraginfo = | 951 | np->rx_ring[entry].fraginfo = |
952 | cpu_to_le64 (pci_map_single | 952 | cpu_to_le64 (pci_map_single |
953 | (np->pdev, skb->tail, np->rx_buf_sz, | 953 | (np->pdev, skb->data, np->rx_buf_sz, |
954 | PCI_DMA_FROMDEVICE)); | 954 | PCI_DMA_FROMDEVICE)); |
955 | } | 955 | } |
956 | np->rx_ring[entry].fraginfo |= | 956 | np->rx_ring[entry].fraginfo |= |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 1e56c8eea35f..d0fa2448761d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2447,9 +2447,8 @@ static int e100_resume(struct pci_dev *pdev) | |||
2447 | #endif | 2447 | #endif |
2448 | 2448 | ||
2449 | 2449 | ||
2450 | static void e100_shutdown(struct device *dev) | 2450 | static void e100_shutdown(struct pci_dev *pdev) |
2451 | { | 2451 | { |
2452 | struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); | ||
2453 | struct net_device *netdev = pci_get_drvdata(pdev); | 2452 | struct net_device *netdev = pci_get_drvdata(pdev); |
2454 | struct nic *nic = netdev_priv(netdev); | 2453 | struct nic *nic = netdev_priv(netdev); |
2455 | 2454 | ||
@@ -2470,11 +2469,7 @@ static struct pci_driver e100_driver = { | |||
2470 | .suspend = e100_suspend, | 2469 | .suspend = e100_suspend, |
2471 | .resume = e100_resume, | 2470 | .resume = e100_resume, |
2472 | #endif | 2471 | #endif |
2473 | 2472 | .shutdown = e100_shutdown, | |
2474 | .driver = { | ||
2475 | .shutdown = e100_shutdown, | ||
2476 | } | ||
2477 | |||
2478 | }; | 2473 | }; |
2479 | 2474 | ||
2480 | static int __init e100_init_module(void) | 2475 | static int __init e100_init_module(void) |
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 98b3a2fdce90..1795425f512e 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c | |||
@@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev) | |||
1269 | if (skb == NULL) | 1269 | if (skb == NULL) |
1270 | break; /* OK. Just initially short of Rx bufs. */ | 1270 | break; /* OK. Just initially short of Rx bufs. */ |
1271 | skb->dev = dev; /* Mark as being used by this device. */ | 1271 | skb->dev = dev; /* Mark as being used by this device. */ |
1272 | rxf = (struct RxFD *)skb->tail; | 1272 | rxf = (struct RxFD *)skb->data; |
1273 | sp->rx_ringp[i] = rxf; | 1273 | sp->rx_ringp[i] = rxf; |
1274 | sp->rx_ring_dma[i] = | 1274 | sp->rx_ring_dma[i] = |
1275 | pci_map_single(sp->pdev, rxf, | 1275 | pci_map_single(sp->pdev, rxf, |
@@ -1661,7 +1661,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) | |||
1661 | sp->rx_ringp[entry] = NULL; | 1661 | sp->rx_ringp[entry] = NULL; |
1662 | return NULL; | 1662 | return NULL; |
1663 | } | 1663 | } |
1664 | rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail; | 1664 | rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data; |
1665 | sp->rx_ring_dma[entry] = | 1665 | sp->rx_ring_dma[entry] = |
1666 | pci_map_single(sp->pdev, rxf, | 1666 | pci_map_single(sp->pdev, rxf, |
1667 | PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); | 1667 | PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); |
@@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev) | |||
1808 | 1808 | ||
1809 | #if 1 || USE_IP_CSUM | 1809 | #if 1 || USE_IP_CSUM |
1810 | /* Packet is in one chunk -- we can copy + cksum. */ | 1810 | /* Packet is in one chunk -- we can copy + cksum. */ |
1811 | eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0); | 1811 | eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0); |
1812 | skb_put(skb, pkt_len); | 1812 | skb_put(skb, pkt_len); |
1813 | #else | 1813 | #else |
1814 | memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail, | 1814 | memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data, |
1815 | pkt_len); | 1815 | pkt_len); |
1816 | #endif | 1816 | #endif |
1817 | pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry], | 1817 | pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry], |
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 81ebaedaa240..87f522738bfc 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c | |||
@@ -1003,7 +1003,7 @@ static void epic_init_ring(struct net_device *dev) | |||
1003 | skb->dev = dev; /* Mark as being used by this device. */ | 1003 | skb->dev = dev; /* Mark as being used by this device. */ |
1004 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ | 1004 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ |
1005 | ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, | 1005 | ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, |
1006 | skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1006 | skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1007 | ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn); | 1007 | ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn); |
1008 | } | 1008 | } |
1009 | ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE); | 1009 | ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE); |
@@ -1274,7 +1274,7 @@ static int epic_rx(struct net_device *dev, int budget) | |||
1274 | ep->rx_ring[entry].bufaddr, | 1274 | ep->rx_ring[entry].bufaddr, |
1275 | ep->rx_buf_sz, | 1275 | ep->rx_buf_sz, |
1276 | PCI_DMA_FROMDEVICE); | 1276 | PCI_DMA_FROMDEVICE); |
1277 | eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0); | 1277 | eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0); |
1278 | skb_put(skb, pkt_len); | 1278 | skb_put(skb, pkt_len); |
1279 | pci_dma_sync_single_for_device(ep->pci_dev, | 1279 | pci_dma_sync_single_for_device(ep->pci_dev, |
1280 | ep->rx_ring[entry].bufaddr, | 1280 | ep->rx_ring[entry].bufaddr, |
@@ -1308,7 +1308,7 @@ static int epic_rx(struct net_device *dev, int budget) | |||
1308 | skb->dev = dev; /* Mark as being used by this device. */ | 1308 | skb->dev = dev; /* Mark as being used by this device. */ |
1309 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1309 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
1310 | ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, | 1310 | ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, |
1311 | skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1311 | skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1312 | work_done++; | 1312 | work_done++; |
1313 | } | 1313 | } |
1314 | ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn); | 1314 | ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn); |
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 9e0303f6d73c..55dbe9a3fd56 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c | |||
@@ -1107,7 +1107,7 @@ static void allocate_rx_buffers(struct net_device *dev) | |||
1107 | 1107 | ||
1108 | skb->dev = dev; /* Mark as being used by this device. */ | 1108 | skb->dev = dev; /* Mark as being used by this device. */ |
1109 | np->lack_rxbuf->skbuff = skb; | 1109 | np->lack_rxbuf->skbuff = skb; |
1110 | np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail, | 1110 | np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data, |
1111 | np->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1111 | np->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1112 | np->lack_rxbuf->status = RXOWN; | 1112 | np->lack_rxbuf->status = RXOWN; |
1113 | ++np->really_rx_count; | 1113 | ++np->really_rx_count; |
@@ -1300,7 +1300,7 @@ static void init_ring(struct net_device *dev) | |||
1300 | ++np->really_rx_count; | 1300 | ++np->really_rx_count; |
1301 | np->rx_ring[i].skbuff = skb; | 1301 | np->rx_ring[i].skbuff = skb; |
1302 | skb->dev = dev; /* Mark as being used by this device. */ | 1302 | skb->dev = dev; /* Mark as being used by this device. */ |
1303 | np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail, | 1303 | np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data, |
1304 | np->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1304 | np->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1305 | np->rx_ring[i].status = RXOWN; | 1305 | np->rx_ring[i].status = RXOWN; |
1306 | np->rx_ring[i].control |= RXIC; | 1306 | np->rx_ring[i].control |= RXIC; |
@@ -1737,11 +1737,11 @@ static int netdev_rx(struct net_device *dev) | |||
1737 | 1737 | ||
1738 | #if ! defined(__alpha__) | 1738 | #if ! defined(__alpha__) |
1739 | eth_copy_and_sum(skb, | 1739 | eth_copy_and_sum(skb, |
1740 | np->cur_rx->skbuff->tail, pkt_len, 0); | 1740 | np->cur_rx->skbuff->data, pkt_len, 0); |
1741 | skb_put(skb, pkt_len); | 1741 | skb_put(skb, pkt_len); |
1742 | #else | 1742 | #else |
1743 | memcpy(skb_put(skb, pkt_len), | 1743 | memcpy(skb_put(skb, pkt_len), |
1744 | np->cur_rx->skbuff->tail, pkt_len); | 1744 | np->cur_rx->skbuff->data, pkt_len); |
1745 | #endif | 1745 | #endif |
1746 | pci_dma_sync_single_for_device(np->pci_dev, | 1746 | pci_dma_sync_single_for_device(np->pci_dev, |
1747 | np->cur_rx->buffer, | 1747 | np->cur_rx->buffer, |
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 3d96714ed3cf..d9df1d9a5739 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c | |||
@@ -1149,7 +1149,7 @@ static void hamachi_tx_timeout(struct net_device *dev) | |||
1149 | skb->dev = dev; /* Mark as being used by this device. */ | 1149 | skb->dev = dev; /* Mark as being used by this device. */ |
1150 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ | 1150 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ |
1151 | hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, | 1151 | hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, |
1152 | skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 1152 | skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
1153 | hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | | 1153 | hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | |
1154 | DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2)); | 1154 | DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2)); |
1155 | } | 1155 | } |
@@ -1210,7 +1210,7 @@ static void hamachi_init_ring(struct net_device *dev) | |||
1210 | skb->dev = dev; /* Mark as being used by this device. */ | 1210 | skb->dev = dev; /* Mark as being used by this device. */ |
1211 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ | 1211 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ |
1212 | hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, | 1212 | hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, |
1213 | skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 1213 | skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
1214 | /* -2 because it doesn't REALLY have that first 2 bytes -KDU */ | 1214 | /* -2 because it doesn't REALLY have that first 2 bytes -KDU */ |
1215 | hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | | 1215 | hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | |
1216 | DescEndPacket | DescIntr | (hmp->rx_buf_sz -2)); | 1216 | DescEndPacket | DescIntr | (hmp->rx_buf_sz -2)); |
@@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device *dev) | |||
1509 | desc->addr, | 1509 | desc->addr, |
1510 | hmp->rx_buf_sz, | 1510 | hmp->rx_buf_sz, |
1511 | PCI_DMA_FROMDEVICE); | 1511 | PCI_DMA_FROMDEVICE); |
1512 | buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail; | 1512 | buf_addr = (u8 *) hmp->rx_skbuff[entry]->data; |
1513 | frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); | 1513 | frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); |
1514 | if (hamachi_debug > 4) | 1514 | if (hamachi_debug > 4) |
1515 | printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n", | 1515 | printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n", |
@@ -1678,7 +1678,7 @@ static int hamachi_rx(struct net_device *dev) | |||
1678 | skb->dev = dev; /* Mark as being used by this device. */ | 1678 | skb->dev = dev; /* Mark as being used by this device. */ |
1679 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1679 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
1680 | desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, | 1680 | desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, |
1681 | skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 1681 | skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
1682 | } | 1682 | } |
1683 | desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz); | 1683 | desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz); |
1684 | if (entry >= RX_RING_SIZE-1) | 1684 | if (entry >= RX_RING_SIZE-1) |
@@ -1772,9 +1772,9 @@ static int hamachi_close(struct net_device *dev) | |||
1772 | readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ', | 1772 | readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ', |
1773 | i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr); | 1773 | i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr); |
1774 | if (hamachi_debug > 6) { | 1774 | if (hamachi_debug > 6) { |
1775 | if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) { | 1775 | if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) { |
1776 | u16 *addr = (u16 *) | 1776 | u16 *addr = (u16 *) |
1777 | hmp->rx_skbuff[i]->tail; | 1777 | hmp->rx_skbuff[i]->data; |
1778 | int j; | 1778 | int j; |
1779 | 1779 | ||
1780 | for (j = 0; j < 0x50; j++) | 1780 | for (j = 0; j < 0x50; j++) |
diff --git a/drivers/net/lance.c b/drivers/net/lance.c index ca90f0d1e4b0..b4929beb33b2 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c | |||
@@ -862,7 +862,7 @@ lance_init_ring(struct net_device *dev, int gfp) | |||
862 | lp->rx_skbuff[i] = skb; | 862 | lp->rx_skbuff[i] = skb; |
863 | if (skb) { | 863 | if (skb) { |
864 | skb->dev = dev; | 864 | skb->dev = dev; |
865 | rx_buff = skb->tail; | 865 | rx_buff = skb->data; |
866 | } else | 866 | } else |
867 | rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp); | 867 | rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp); |
868 | if (rx_buff == NULL) | 868 | if (rx_buff == NULL) |
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 5e263fcba669..41bad07ac1ac 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c | |||
@@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct net_device *dev) | |||
553 | if (skb == NULL) | 553 | if (skb == NULL) |
554 | panic("%s: alloc_skb() failed", __FILE__); | 554 | panic("%s: alloc_skb() failed", __FILE__); |
555 | skb_reserve(skb, 2); | 555 | skb_reserve(skb, 2); |
556 | dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ, | 556 | dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ, |
557 | DMA_FROM_DEVICE); | 557 | DMA_FROM_DEVICE); |
558 | skb->dev = dev; | 558 | skb->dev = dev; |
559 | rbd->v_next = rbd+1; | 559 | rbd->v_next = rbd+1; |
560 | rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); | 560 | rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); |
561 | rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd)); | 561 | rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd)); |
562 | rbd->skb = skb; | 562 | rbd->skb = skb; |
563 | rbd->v_data = skb->tail; | 563 | rbd->v_data = skb->data; |
564 | rbd->b_data = WSWAPchar(dma_addr); | 564 | rbd->b_data = WSWAPchar(dma_addr); |
565 | rbd->size = PKT_BUF_SZ; | 565 | rbd->size = PKT_BUF_SZ; |
566 | } | 566 | } |
@@ -783,8 +783,8 @@ static inline int i596_rx(struct net_device *dev) | |||
783 | rx_in_place = 1; | 783 | rx_in_place = 1; |
784 | rbd->skb = newskb; | 784 | rbd->skb = newskb; |
785 | newskb->dev = dev; | 785 | newskb->dev = dev; |
786 | dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE); | 786 | dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE); |
787 | rbd->v_data = newskb->tail; | 787 | rbd->v_data = newskb->data; |
788 | rbd->b_data = WSWAPchar(dma_addr); | 788 | rbd->b_data = WSWAPchar(dma_addr); |
789 | CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); | 789 | CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); |
790 | } | 790 | } |
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index babb59e146ea..9d6d2548c2d3 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c | |||
@@ -1926,7 +1926,7 @@ static void refill_rx(struct net_device *dev) | |||
1926 | break; /* Better luck next round. */ | 1926 | break; /* Better luck next round. */ |
1927 | skb->dev = dev; /* Mark as being used by this device. */ | 1927 | skb->dev = dev; /* Mark as being used by this device. */ |
1928 | np->rx_dma[entry] = pci_map_single(np->pci_dev, | 1928 | np->rx_dma[entry] = pci_map_single(np->pci_dev, |
1929 | skb->tail, buflen, PCI_DMA_FROMDEVICE); | 1929 | skb->data, buflen, PCI_DMA_FROMDEVICE); |
1930 | np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); | 1930 | np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); |
1931 | } | 1931 | } |
1932 | np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); | 1932 | np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); |
@@ -2280,7 +2280,7 @@ static void netdev_rx(struct net_device *dev) | |||
2280 | buflen, | 2280 | buflen, |
2281 | PCI_DMA_FROMDEVICE); | 2281 | PCI_DMA_FROMDEVICE); |
2282 | eth_copy_and_sum(skb, | 2282 | eth_copy_and_sum(skb, |
2283 | np->rx_skbuff[entry]->tail, pkt_len, 0); | 2283 | np->rx_skbuff[entry]->data, pkt_len, 0); |
2284 | skb_put(skb, pkt_len); | 2284 | skb_put(skb, pkt_len); |
2285 | pci_dma_sync_single_for_device(np->pci_dev, | 2285 | pci_dma_sync_single_for_device(np->pci_dev, |
2286 | np->rx_dma[entry], | 2286 | np->rx_dma[entry], |
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index cc7965271778..e64df4d0800b 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -574,7 +574,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) | |||
574 | 574 | ||
575 | dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; | 575 | dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; |
576 | cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR; | 576 | cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR; |
577 | buf = pci_map_single(dev->pci_dev, skb->tail, | 577 | buf = pci_map_single(dev->pci_dev, skb->data, |
578 | REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 578 | REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
579 | build_rx_desc(dev, sg, 0, buf, cmdsts, 0); | 579 | build_rx_desc(dev, sg, 0, buf, cmdsts, 0); |
580 | /* update link of previous rx */ | 580 | /* update link of previous rx */ |
@@ -604,7 +604,7 @@ static inline int rx_refill(struct net_device *ndev, int gfp) | |||
604 | if (unlikely(!skb)) | 604 | if (unlikely(!skb)) |
605 | break; | 605 | break; |
606 | 606 | ||
607 | res = (long)skb->tail & 0xf; | 607 | res = (long)skb->data & 0xf; |
608 | res = 0x10 - res; | 608 | res = 0x10 - res; |
609 | res &= 0xf; | 609 | res &= 0xf; |
610 | skb_reserve(skb, res); | 610 | skb_reserve(skb, res); |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 3213f3e50487..113b68099216 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev) | |||
1602 | 1602 | ||
1603 | rmb(); | 1603 | rmb(); |
1604 | if (lp->rx_dma_addr[i] == 0) | 1604 | if (lp->rx_dma_addr[i] == 0) |
1605 | lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, | 1605 | lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data, |
1606 | PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); | 1606 | PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); |
1607 | lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); | 1607 | lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); |
1608 | lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ); | 1608 | lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ); |
@@ -1983,7 +1983,7 @@ pcnet32_rx(struct net_device *dev) | |||
1983 | lp->rx_skbuff[entry] = newskb; | 1983 | lp->rx_skbuff[entry] = newskb; |
1984 | newskb->dev = dev; | 1984 | newskb->dev = dev; |
1985 | lp->rx_dma_addr[entry] = | 1985 | lp->rx_dma_addr[entry] = |
1986 | pci_map_single(lp->pci_dev, newskb->tail, | 1986 | pci_map_single(lp->pci_dev, newskb->data, |
1987 | PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); | 1987 | PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); |
1988 | lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); | 1988 | lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); |
1989 | rx_in_place = 1; | 1989 | rx_in_place = 1; |
@@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev) | |||
2020 | PKT_BUF_SZ-2, | 2020 | PKT_BUF_SZ-2, |
2021 | PCI_DMA_FROMDEVICE); | 2021 | PCI_DMA_FROMDEVICE); |
2022 | eth_copy_and_sum(skb, | 2022 | eth_copy_and_sum(skb, |
2023 | (unsigned char *)(lp->rx_skbuff[entry]->tail), | 2023 | (unsigned char *)(lp->rx_skbuff[entry]->data), |
2024 | pkt_len,0); | 2024 | pkt_len,0); |
2025 | pci_dma_sync_single_for_device(lp->pci_dev, | 2025 | pci_dma_sync_single_for_device(lp->pci_dev, |
2026 | lp->rx_dma_addr[entry], | 2026 | lp->rx_dma_addr[entry], |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ce449fe90e6d..d5afe05cd826 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -1876,7 +1876,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, | |||
1876 | skb_reserve(skb, NET_IP_ALIGN); | 1876 | skb_reserve(skb, NET_IP_ALIGN); |
1877 | *sk_buff = skb; | 1877 | *sk_buff = skb; |
1878 | 1878 | ||
1879 | mapping = pci_map_single(pdev, skb->tail, rx_buf_sz, | 1879 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, |
1880 | PCI_DMA_FROMDEVICE); | 1880 | PCI_DMA_FROMDEVICE); |
1881 | 1881 | ||
1882 | rtl8169_map_to_asic(desc, mapping, rx_buf_sz); | 1882 | rtl8169_map_to_asic(desc, mapping, rx_buf_sz); |
@@ -2336,7 +2336,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, | |||
2336 | skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); | 2336 | skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); |
2337 | if (skb) { | 2337 | if (skb) { |
2338 | skb_reserve(skb, NET_IP_ALIGN); | 2338 | skb_reserve(skb, NET_IP_ALIGN); |
2339 | eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0); | 2339 | eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); |
2340 | *sk_buff = skb; | 2340 | *sk_buff = skb; |
2341 | rtl8169_mark_to_asic(desc, rx_buf_sz); | 2341 | rtl8169_mark_to_asic(desc, rx_buf_sz); |
2342 | ret = 0; | 2342 | ret = 0; |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index bb639a8794d4..ea638b162d3f 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -1699,11 +1699,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1699 | #else | 1699 | #else |
1700 | ba = &nic->ba[ring_no][block_no][off]; | 1700 | ba = &nic->ba[ring_no][block_no][off]; |
1701 | skb_reserve(skb, BUF0_LEN); | 1701 | skb_reserve(skb, BUF0_LEN); |
1702 | tmp = (unsigned long) skb->data; | 1702 | tmp = ((unsigned long) skb->data & ALIGN_SIZE); |
1703 | tmp += ALIGN_SIZE; | 1703 | if (tmp) |
1704 | tmp &= ~ALIGN_SIZE; | 1704 | skb_reserve(skb, (ALIGN_SIZE + 1) - tmp); |
1705 | skb->data = (void *) tmp; | ||
1706 | skb->tail = (void *) tmp; | ||
1707 | 1705 | ||
1708 | memset(rxdp, 0, sizeof(RxD_t)); | 1706 | memset(rxdp, 0, sizeof(RxD_t)); |
1709 | rxdp->Buffer2_ptr = pci_map_single | 1707 | rxdp->Buffer2_ptr = pci_map_single |
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index fd2e7c374906..7abd55a4fb21 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -963,11 +963,11 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb) | |||
963 | /* | 963 | /* |
964 | * Do not interrupt per DMA transfer. | 964 | * Do not interrupt per DMA transfer. |
965 | */ | 965 | */ |
966 | dsc->dscr_a = virt_to_phys(sb_new->tail) | | 966 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
967 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | | 967 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | |
968 | 0; | 968 | 0; |
969 | #else | 969 | #else |
970 | dsc->dscr_a = virt_to_phys(sb_new->tail) | | 970 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
971 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | | 971 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | |
972 | M_DMA_DSCRA_INTERRUPT; | 972 | M_DMA_DSCRA_INTERRUPT; |
973 | #endif | 973 | #endif |
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 127324f014de..23b713c700b3 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
@@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev) | |||
1154 | sis_priv->rx_skbuff[i] = skb; | 1154 | sis_priv->rx_skbuff[i] = skb; |
1155 | sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE; | 1155 | sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE; |
1156 | sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev, | 1156 | sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev, |
1157 | skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 1157 | skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
1158 | } | 1158 | } |
1159 | sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC); | 1159 | sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC); |
1160 | 1160 | ||
@@ -1776,7 +1776,7 @@ static int sis900_rx(struct net_device *net_dev) | |||
1776 | sis_priv->rx_skbuff[entry] = skb; | 1776 | sis_priv->rx_skbuff[entry] = skb; |
1777 | sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; | 1777 | sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; |
1778 | sis_priv->rx_ring[entry].bufptr = | 1778 | sis_priv->rx_ring[entry].bufptr = |
1779 | pci_map_single(sis_priv->pci_dev, skb->tail, | 1779 | pci_map_single(sis_priv->pci_dev, skb->data, |
1780 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 1780 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
1781 | sis_priv->dirty_rx++; | 1781 | sis_priv->dirty_rx++; |
1782 | } | 1782 | } |
@@ -1809,7 +1809,7 @@ static int sis900_rx(struct net_device *net_dev) | |||
1809 | sis_priv->rx_skbuff[entry] = skb; | 1809 | sis_priv->rx_skbuff[entry] = skb; |
1810 | sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; | 1810 | sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; |
1811 | sis_priv->rx_ring[entry].bufptr = | 1811 | sis_priv->rx_ring[entry].bufptr = |
1812 | pci_map_single(sis_priv->pci_dev, skb->tail, | 1812 | pci_map_single(sis_priv->pci_dev, skb->data, |
1813 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 1813 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
1814 | } | 1814 | } |
1815 | } | 1815 | } |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 30e8d589d167..3dbb1cb09ed8 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * of the original driver such as link fail-over and link management because | 7 | * of the original driver such as link fail-over and link management because |
8 | * those should be done at higher levels. | 8 | * those should be done at higher levels. |
9 | * | 9 | * |
10 | * Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org> | 10 | * Copyright (C) 2004, 2005 Stephen Hemminger <shemminger@osdl.org> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
@@ -42,19 +42,20 @@ | |||
42 | #include "skge.h" | 42 | #include "skge.h" |
43 | 43 | ||
44 | #define DRV_NAME "skge" | 44 | #define DRV_NAME "skge" |
45 | #define DRV_VERSION "0.6" | 45 | #define DRV_VERSION "0.7" |
46 | #define PFX DRV_NAME " " | 46 | #define PFX DRV_NAME " " |
47 | 47 | ||
48 | #define DEFAULT_TX_RING_SIZE 128 | 48 | #define DEFAULT_TX_RING_SIZE 128 |
49 | #define DEFAULT_RX_RING_SIZE 512 | 49 | #define DEFAULT_RX_RING_SIZE 512 |
50 | #define MAX_TX_RING_SIZE 1024 | 50 | #define MAX_TX_RING_SIZE 1024 |
51 | #define MAX_RX_RING_SIZE 4096 | 51 | #define MAX_RX_RING_SIZE 4096 |
52 | #define RX_COPY_THRESHOLD 128 | ||
53 | #define RX_BUF_SIZE 1536 | ||
52 | #define PHY_RETRIES 1000 | 54 | #define PHY_RETRIES 1000 |
53 | #define ETH_JUMBO_MTU 9000 | 55 | #define ETH_JUMBO_MTU 9000 |
54 | #define TX_WATCHDOG (5 * HZ) | 56 | #define TX_WATCHDOG (5 * HZ) |
55 | #define NAPI_WEIGHT 64 | 57 | #define NAPI_WEIGHT 64 |
56 | #define BLINK_HZ (HZ/4) | 58 | #define BLINK_HZ (HZ/4) |
57 | #define LINK_POLL_HZ (HZ/10) | ||
58 | 59 | ||
59 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); | 60 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); |
60 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); | 61 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); |
@@ -70,28 +71,17 @@ module_param(debug, int, 0); | |||
70 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | 71 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); |
71 | 72 | ||
72 | static const struct pci_device_id skge_id_table[] = { | 73 | static const struct pci_device_id skge_id_table[] = { |
73 | { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940, | 74 | { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) }, |
74 | PCI_ANY_ID, PCI_ANY_ID }, | 75 | { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, |
75 | { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B, | 76 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, |
76 | PCI_ANY_ID, PCI_ANY_ID }, | 77 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, |
77 | { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE, | 78 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ |
78 | PCI_ANY_ID, PCI_ANY_ID }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, |
79 | { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU, | 80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, |
80 | PCI_ANY_ID, PCI_ANY_ID }, | 81 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ |
81 | { PCI_VENDOR_ID_SYSKONNECT, 0x9E00, /* SK-9Exx */ | 82 | { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, |
82 | PCI_ANY_ID, PCI_ANY_ID }, | 83 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) }, |
83 | { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T, | 84 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, |
84 | PCI_ANY_ID, PCI_ANY_ID }, | ||
85 | { PCI_VENDOR_ID_MARVELL, 0x4320, /* Gigabit Ethernet Controller */ | ||
86 | PCI_ANY_ID, PCI_ANY_ID }, | ||
87 | { PCI_VENDOR_ID_MARVELL, 0x5005, /* Marvell (11ab), Belkin */ | ||
88 | PCI_ANY_ID, PCI_ANY_ID }, | ||
89 | { PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD, | ||
90 | PCI_ANY_ID, PCI_ANY_ID }, | ||
91 | { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032, | ||
92 | PCI_ANY_ID, PCI_ANY_ID }, | ||
93 | { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064, | ||
94 | PCI_ANY_ID, PCI_ANY_ID }, | ||
95 | { 0 } | 85 | { 0 } |
96 | }; | 86 | }; |
97 | MODULE_DEVICE_TABLE(pci, skge_id_table); | 87 | MODULE_DEVICE_TABLE(pci, skge_id_table); |
@@ -99,19 +89,22 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); | |||
99 | static int skge_up(struct net_device *dev); | 89 | static int skge_up(struct net_device *dev); |
100 | static int skge_down(struct net_device *dev); | 90 | static int skge_down(struct net_device *dev); |
101 | static void skge_tx_clean(struct skge_port *skge); | 91 | static void skge_tx_clean(struct skge_port *skge); |
102 | static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 92 | static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
103 | static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 93 | static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
104 | static void genesis_get_stats(struct skge_port *skge, u64 *data); | 94 | static void genesis_get_stats(struct skge_port *skge, u64 *data); |
105 | static void yukon_get_stats(struct skge_port *skge, u64 *data); | 95 | static void yukon_get_stats(struct skge_port *skge, u64 *data); |
106 | static void yukon_init(struct skge_hw *hw, int port); | 96 | static void yukon_init(struct skge_hw *hw, int port); |
107 | static void yukon_reset(struct skge_hw *hw, int port); | 97 | static void yukon_reset(struct skge_hw *hw, int port); |
108 | static void genesis_mac_init(struct skge_hw *hw, int port); | 98 | static void genesis_mac_init(struct skge_hw *hw, int port); |
109 | static void genesis_reset(struct skge_hw *hw, int port); | 99 | static void genesis_reset(struct skge_hw *hw, int port); |
100 | static void genesis_link_up(struct skge_port *skge); | ||
110 | 101 | ||
102 | /* Avoid conditionals by using array */ | ||
111 | static const int txqaddr[] = { Q_XA1, Q_XA2 }; | 103 | static const int txqaddr[] = { Q_XA1, Q_XA2 }; |
112 | static const int rxqaddr[] = { Q_R1, Q_R2 }; | 104 | static const int rxqaddr[] = { Q_R1, Q_R2 }; |
113 | static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; | 105 | static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; |
114 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; | 106 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; |
107 | static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; | ||
115 | 108 | ||
116 | /* Don't need to look at whole 16K. | 109 | /* Don't need to look at whole 16K. |
117 | * last interesting register is descriptor poll timer. | 110 | * last interesting register is descriptor poll timer. |
@@ -154,7 +147,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
154 | static int wol_supported(const struct skge_hw *hw) | 147 | static int wol_supported(const struct skge_hw *hw) |
155 | { | 148 | { |
156 | return !((hw->chip_id == CHIP_ID_GENESIS || | 149 | return !((hw->chip_id == CHIP_ID_GENESIS || |
157 | (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0))); | 150 | (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0))); |
158 | } | 151 | } |
159 | 152 | ||
160 | static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 153 | static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
@@ -170,7 +163,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
170 | struct skge_port *skge = netdev_priv(dev); | 163 | struct skge_port *skge = netdev_priv(dev); |
171 | struct skge_hw *hw = skge->hw; | 164 | struct skge_hw *hw = skge->hw; |
172 | 165 | ||
173 | if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) | 166 | if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) |
174 | return -EOPNOTSUPP; | 167 | return -EOPNOTSUPP; |
175 | 168 | ||
176 | if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw)) | 169 | if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw)) |
@@ -190,6 +183,36 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
190 | return 0; | 183 | return 0; |
191 | } | 184 | } |
192 | 185 | ||
186 | /* Determine supported/adverised modes based on hardware. | ||
187 | * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx | ||
188 | */ | ||
189 | static u32 skge_supported_modes(const struct skge_hw *hw) | ||
190 | { | ||
191 | u32 supported; | ||
192 | |||
193 | if (iscopper(hw)) { | ||
194 | supported = SUPPORTED_10baseT_Half | ||
195 | | SUPPORTED_10baseT_Full | ||
196 | | SUPPORTED_100baseT_Half | ||
197 | | SUPPORTED_100baseT_Full | ||
198 | | SUPPORTED_1000baseT_Half | ||
199 | | SUPPORTED_1000baseT_Full | ||
200 | | SUPPORTED_Autoneg| SUPPORTED_TP; | ||
201 | |||
202 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
203 | supported &= ~(SUPPORTED_10baseT_Half | ||
204 | | SUPPORTED_10baseT_Full | ||
205 | | SUPPORTED_100baseT_Half | ||
206 | | SUPPORTED_100baseT_Full); | ||
207 | |||
208 | else if (hw->chip_id == CHIP_ID_YUKON) | ||
209 | supported &= ~SUPPORTED_1000baseT_Half; | ||
210 | } else | ||
211 | supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE | ||
212 | | SUPPORTED_Autoneg; | ||
213 | |||
214 | return supported; | ||
215 | } | ||
193 | 216 | ||
194 | static int skge_get_settings(struct net_device *dev, | 217 | static int skge_get_settings(struct net_device *dev, |
195 | struct ethtool_cmd *ecmd) | 218 | struct ethtool_cmd *ecmd) |
@@ -198,38 +221,13 @@ static int skge_get_settings(struct net_device *dev, | |||
198 | struct skge_hw *hw = skge->hw; | 221 | struct skge_hw *hw = skge->hw; |
199 | 222 | ||
200 | ecmd->transceiver = XCVR_INTERNAL; | 223 | ecmd->transceiver = XCVR_INTERNAL; |
224 | ecmd->supported = skge_supported_modes(hw); | ||
201 | 225 | ||
202 | if (iscopper(hw)) { | 226 | if (iscopper(hw)) { |
203 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
204 | ecmd->supported = SUPPORTED_1000baseT_Full | ||
205 | | SUPPORTED_1000baseT_Half | ||
206 | | SUPPORTED_Autoneg | SUPPORTED_TP; | ||
207 | else { | ||
208 | ecmd->supported = SUPPORTED_10baseT_Half | ||
209 | | SUPPORTED_10baseT_Full | ||
210 | | SUPPORTED_100baseT_Half | ||
211 | | SUPPORTED_100baseT_Full | ||
212 | | SUPPORTED_1000baseT_Half | ||
213 | | SUPPORTED_1000baseT_Full | ||
214 | | SUPPORTED_Autoneg| SUPPORTED_TP; | ||
215 | |||
216 | if (hw->chip_id == CHIP_ID_YUKON) | ||
217 | ecmd->supported &= ~SUPPORTED_1000baseT_Half; | ||
218 | |||
219 | else if (hw->chip_id == CHIP_ID_YUKON_FE) | ||
220 | ecmd->supported &= ~(SUPPORTED_1000baseT_Half | ||
221 | | SUPPORTED_1000baseT_Full); | ||
222 | } | ||
223 | |||
224 | ecmd->port = PORT_TP; | 227 | ecmd->port = PORT_TP; |
225 | ecmd->phy_address = hw->phy_addr; | 228 | ecmd->phy_address = hw->phy_addr; |
226 | } else { | 229 | } else |
227 | ecmd->supported = SUPPORTED_1000baseT_Full | ||
228 | | SUPPORTED_FIBRE | ||
229 | | SUPPORTED_Autoneg; | ||
230 | |||
231 | ecmd->port = PORT_FIBRE; | 230 | ecmd->port = PORT_FIBRE; |
232 | } | ||
233 | 231 | ||
234 | ecmd->advertising = skge->advertising; | 232 | ecmd->advertising = skge->advertising; |
235 | ecmd->autoneg = skge->autoneg; | 233 | ecmd->autoneg = skge->autoneg; |
@@ -238,65 +236,57 @@ static int skge_get_settings(struct net_device *dev, | |||
238 | return 0; | 236 | return 0; |
239 | } | 237 | } |
240 | 238 | ||
241 | static u32 skge_modes(const struct skge_hw *hw) | ||
242 | { | ||
243 | u32 modes = ADVERTISED_Autoneg | ||
244 | | ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half | ||
245 | | ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half | ||
246 | | ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half; | ||
247 | |||
248 | if (iscopper(hw)) { | ||
249 | modes |= ADVERTISED_TP; | ||
250 | switch(hw->chip_id) { | ||
251 | case CHIP_ID_GENESIS: | ||
252 | modes &= ~(ADVERTISED_100baseT_Full | ||
253 | | ADVERTISED_100baseT_Half | ||
254 | | ADVERTISED_10baseT_Full | ||
255 | | ADVERTISED_10baseT_Half); | ||
256 | break; | ||
257 | |||
258 | case CHIP_ID_YUKON: | ||
259 | modes &= ~ADVERTISED_1000baseT_Half; | ||
260 | break; | ||
261 | |||
262 | case CHIP_ID_YUKON_FE: | ||
263 | modes &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); | ||
264 | break; | ||
265 | } | ||
266 | } else { | ||
267 | modes |= ADVERTISED_FIBRE; | ||
268 | modes &= ~ADVERTISED_1000baseT_Half; | ||
269 | } | ||
270 | return modes; | ||
271 | } | ||
272 | |||
273 | static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | 239 | static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) |
274 | { | 240 | { |
275 | struct skge_port *skge = netdev_priv(dev); | 241 | struct skge_port *skge = netdev_priv(dev); |
276 | const struct skge_hw *hw = skge->hw; | 242 | const struct skge_hw *hw = skge->hw; |
243 | u32 supported = skge_supported_modes(hw); | ||
277 | 244 | ||
278 | if (ecmd->autoneg == AUTONEG_ENABLE) { | 245 | if (ecmd->autoneg == AUTONEG_ENABLE) { |
279 | if (ecmd->advertising & skge_modes(hw)) | 246 | ecmd->advertising = supported; |
280 | return -EINVAL; | 247 | skge->duplex = -1; |
248 | skge->speed = -1; | ||
281 | } else { | 249 | } else { |
250 | u32 setting; | ||
251 | |||
282 | switch(ecmd->speed) { | 252 | switch(ecmd->speed) { |
283 | case SPEED_1000: | 253 | case SPEED_1000: |
284 | if (hw->chip_id == CHIP_ID_YUKON_FE) | 254 | if (ecmd->duplex == DUPLEX_FULL) |
255 | setting = SUPPORTED_1000baseT_Full; | ||
256 | else if (ecmd->duplex == DUPLEX_HALF) | ||
257 | setting = SUPPORTED_1000baseT_Half; | ||
258 | else | ||
285 | return -EINVAL; | 259 | return -EINVAL; |
286 | break; | 260 | break; |
287 | case SPEED_100: | 261 | case SPEED_100: |
262 | if (ecmd->duplex == DUPLEX_FULL) | ||
263 | setting = SUPPORTED_100baseT_Full; | ||
264 | else if (ecmd->duplex == DUPLEX_HALF) | ||
265 | setting = SUPPORTED_100baseT_Half; | ||
266 | else | ||
267 | return -EINVAL; | ||
268 | break; | ||
269 | |||
288 | case SPEED_10: | 270 | case SPEED_10: |
289 | if (iscopper(hw) || hw->chip_id == CHIP_ID_GENESIS) | 271 | if (ecmd->duplex == DUPLEX_FULL) |
272 | setting = SUPPORTED_10baseT_Full; | ||
273 | else if (ecmd->duplex == DUPLEX_HALF) | ||
274 | setting = SUPPORTED_10baseT_Half; | ||
275 | else | ||
290 | return -EINVAL; | 276 | return -EINVAL; |
291 | break; | 277 | break; |
292 | default: | 278 | default: |
293 | return -EINVAL; | 279 | return -EINVAL; |
294 | } | 280 | } |
281 | |||
282 | if ((setting & supported) == 0) | ||
283 | return -EINVAL; | ||
284 | |||
285 | skge->speed = ecmd->speed; | ||
286 | skge->duplex = ecmd->duplex; | ||
295 | } | 287 | } |
296 | 288 | ||
297 | skge->autoneg = ecmd->autoneg; | 289 | skge->autoneg = ecmd->autoneg; |
298 | skge->speed = ecmd->speed; | ||
299 | skge->duplex = ecmd->duplex; | ||
300 | skge->advertising = ecmd->advertising; | 290 | skge->advertising = ecmd->advertising; |
301 | 291 | ||
302 | if (netif_running(dev)) { | 292 | if (netif_running(dev)) { |
@@ -393,7 +383,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data) | |||
393 | { | 383 | { |
394 | int i; | 384 | int i; |
395 | 385 | ||
396 | switch(stringset) { | 386 | switch (stringset) { |
397 | case ETH_SS_STATS: | 387 | case ETH_SS_STATS: |
398 | for (i = 0; i < ARRAY_SIZE(skge_stats); i++) | 388 | for (i = 0; i < ARRAY_SIZE(skge_stats); i++) |
399 | memcpy(data + i * ETH_GSTRING_LEN, | 389 | memcpy(data + i * ETH_GSTRING_LEN, |
@@ -511,14 +501,6 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data) | |||
511 | return 0; | 501 | return 0; |
512 | } | 502 | } |
513 | 503 | ||
514 | /* Only Yukon II supports TSO (not implemented yet) */ | ||
515 | static int skge_set_tso(struct net_device *dev, u32 data) | ||
516 | { | ||
517 | if (data) | ||
518 | return -EOPNOTSUPP; | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static void skge_get_pauseparam(struct net_device *dev, | 504 | static void skge_get_pauseparam(struct net_device *dev, |
523 | struct ethtool_pauseparam *ecmd) | 505 | struct ethtool_pauseparam *ecmd) |
524 | { | 506 | { |
@@ -540,9 +522,9 @@ static int skge_set_pauseparam(struct net_device *dev, | |||
540 | skge->autoneg = ecmd->autoneg; | 522 | skge->autoneg = ecmd->autoneg; |
541 | if (ecmd->rx_pause && ecmd->tx_pause) | 523 | if (ecmd->rx_pause && ecmd->tx_pause) |
542 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 524 | skge->flow_control = FLOW_MODE_SYMMETRIC; |
543 | else if(ecmd->rx_pause && !ecmd->tx_pause) | 525 | else if (ecmd->rx_pause && !ecmd->tx_pause) |
544 | skge->flow_control = FLOW_MODE_REM_SEND; | 526 | skge->flow_control = FLOW_MODE_REM_SEND; |
545 | else if(!ecmd->rx_pause && ecmd->tx_pause) | 527 | else if (!ecmd->rx_pause && ecmd->tx_pause) |
546 | skge->flow_control = FLOW_MODE_LOC_SEND; | 528 | skge->flow_control = FLOW_MODE_LOC_SEND; |
547 | else | 529 | else |
548 | skge->flow_control = FLOW_MODE_NONE; | 530 | skge->flow_control = FLOW_MODE_NONE; |
@@ -559,8 +541,6 @@ static inline u32 hwkhz(const struct skge_hw *hw) | |||
559 | { | 541 | { |
560 | if (hw->chip_id == CHIP_ID_GENESIS) | 542 | if (hw->chip_id == CHIP_ID_GENESIS) |
561 | return 53215; /* or: 53.125 MHz */ | 543 | return 53215; /* or: 53.125 MHz */ |
562 | else if (hw->chip_id == CHIP_ID_YUKON_EC) | ||
563 | return 125000; /* or: 125.000 MHz */ | ||
564 | else | 544 | else |
565 | return 78215; /* or: 78.125 MHz */ | 545 | return 78215; /* or: 78.125 MHz */ |
566 | } | 546 | } |
@@ -643,30 +623,18 @@ static int skge_set_coalesce(struct net_device *dev, | |||
643 | static void skge_led_on(struct skge_hw *hw, int port) | 623 | static void skge_led_on(struct skge_hw *hw, int port) |
644 | { | 624 | { |
645 | if (hw->chip_id == CHIP_ID_GENESIS) { | 625 | if (hw->chip_id == CHIP_ID_GENESIS) { |
646 | skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON); | 626 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); |
647 | skge_write8(hw, B0_LED, LED_STAT_ON); | 627 | skge_write8(hw, B0_LED, LED_STAT_ON); |
648 | 628 | ||
649 | skge_write8(hw, SKGEMAC_REG(port, RX_LED_TST), LED_T_ON); | 629 | skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); |
650 | skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 100); | 630 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); |
651 | skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START); | 631 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
652 | 632 | ||
653 | switch (hw->phy_type) { | 633 | /* For Broadcom Phy only */ |
654 | case SK_PHY_BCOM: | 634 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); |
655 | skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, | ||
656 | PHY_B_PEC_LED_ON); | ||
657 | break; | ||
658 | case SK_PHY_LONE: | ||
659 | skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG, | ||
660 | 0x0800); | ||
661 | break; | ||
662 | default: | ||
663 | skge_write8(hw, SKGEMAC_REG(port, TX_LED_TST), LED_T_ON); | ||
664 | skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 100); | ||
665 | skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START); | ||
666 | } | ||
667 | } else { | 635 | } else { |
668 | skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 636 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
669 | skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 637 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
670 | PHY_M_LED_MO_DUP(MO_LED_ON) | | 638 | PHY_M_LED_MO_DUP(MO_LED_ON) | |
671 | PHY_M_LED_MO_10(MO_LED_ON) | | 639 | PHY_M_LED_MO_10(MO_LED_ON) | |
672 | PHY_M_LED_MO_100(MO_LED_ON) | | 640 | PHY_M_LED_MO_100(MO_LED_ON) | |
@@ -678,28 +646,17 @@ static void skge_led_on(struct skge_hw *hw, int port) | |||
678 | static void skge_led_off(struct skge_hw *hw, int port) | 646 | static void skge_led_off(struct skge_hw *hw, int port) |
679 | { | 647 | { |
680 | if (hw->chip_id == CHIP_ID_GENESIS) { | 648 | if (hw->chip_id == CHIP_ID_GENESIS) { |
681 | skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_OFF); | 649 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); |
682 | skge_write8(hw, B0_LED, LED_STAT_OFF); | 650 | skge_write8(hw, B0_LED, LED_STAT_OFF); |
683 | 651 | ||
684 | skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 0); | 652 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); |
685 | skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_T_OFF); | 653 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); |
686 | 654 | ||
687 | switch (hw->phy_type) { | 655 | /* Broadcom only */ |
688 | case SK_PHY_BCOM: | 656 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); |
689 | skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, | ||
690 | PHY_B_PEC_LED_OFF); | ||
691 | break; | ||
692 | case SK_PHY_LONE: | ||
693 | skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG, | ||
694 | PHY_L_LC_LEDT); | ||
695 | break; | ||
696 | default: | ||
697 | skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 0); | ||
698 | skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_T_OFF); | ||
699 | } | ||
700 | } else { | 657 | } else { |
701 | skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 658 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
702 | skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
703 | PHY_M_LED_MO_DUP(MO_LED_OFF) | | 660 | PHY_M_LED_MO_DUP(MO_LED_OFF) | |
704 | PHY_M_LED_MO_10(MO_LED_OFF) | | 661 | PHY_M_LED_MO_10(MO_LED_OFF) | |
705 | PHY_M_LED_MO_100(MO_LED_OFF) | | 662 | PHY_M_LED_MO_100(MO_LED_OFF) | |
@@ -730,7 +687,7 @@ static int skge_phys_id(struct net_device *dev, u32 data) | |||
730 | { | 687 | { |
731 | struct skge_port *skge = netdev_priv(dev); | 688 | struct skge_port *skge = netdev_priv(dev); |
732 | 689 | ||
733 | if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) | 690 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) |
734 | data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); | 691 | data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); |
735 | 692 | ||
736 | /* start blinking */ | 693 | /* start blinking */ |
@@ -763,8 +720,6 @@ static struct ethtool_ops skge_ethtool_ops = { | |||
763 | .set_pauseparam = skge_set_pauseparam, | 720 | .set_pauseparam = skge_set_pauseparam, |
764 | .get_coalesce = skge_get_coalesce, | 721 | .get_coalesce = skge_get_coalesce, |
765 | .set_coalesce = skge_set_coalesce, | 722 | .set_coalesce = skge_set_coalesce, |
766 | .get_tso = ethtool_op_get_tso, | ||
767 | .set_tso = skge_set_tso, | ||
768 | .get_sg = ethtool_op_get_sg, | 723 | .get_sg = ethtool_op_get_sg, |
769 | .set_sg = skge_set_sg, | 724 | .set_sg = skge_set_sg, |
770 | .get_tx_csum = ethtool_op_get_tx_csum, | 725 | .get_tx_csum = ethtool_op_get_tx_csum, |
@@ -793,6 +748,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) | |||
793 | 748 | ||
794 | for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) { | 749 | for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) { |
795 | e->desc = d; | 750 | e->desc = d; |
751 | e->skb = NULL; | ||
796 | if (i == ring->count - 1) { | 752 | if (i == ring->count - 1) { |
797 | e->next = ring->start; | 753 | e->next = ring->start; |
798 | d->next_offset = base; | 754 | d->next_offset = base; |
@@ -806,24 +762,23 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) | |||
806 | return 0; | 762 | return 0; |
807 | } | 763 | } |
808 | 764 | ||
809 | /* Setup buffer for receiving */ | 765 | static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size) |
810 | static inline int skge_rx_alloc(struct skge_port *skge, | ||
811 | struct skge_element *e) | ||
812 | { | 766 | { |
813 | unsigned long bufsize = skge->netdev->mtu + ETH_HLEN; /* VLAN? */ | 767 | struct sk_buff *skb = dev_alloc_skb(size); |
814 | struct skge_rx_desc *rd = e->desc; | ||
815 | struct sk_buff *skb; | ||
816 | u64 map; | ||
817 | 768 | ||
818 | skb = dev_alloc_skb(bufsize + NET_IP_ALIGN); | 769 | if (likely(skb)) { |
819 | if (unlikely(!skb)) { | 770 | skb->dev = dev; |
820 | printk(KERN_DEBUG PFX "%s: out of memory for receive\n", | 771 | skb_reserve(skb, NET_IP_ALIGN); |
821 | skge->netdev->name); | ||
822 | return -ENOMEM; | ||
823 | } | 772 | } |
773 | return skb; | ||
774 | } | ||
824 | 775 | ||
825 | skb->dev = skge->netdev; | 776 | /* Allocate and setup a new buffer for receiving */ |
826 | skb_reserve(skb, NET_IP_ALIGN); | 777 | static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, |
778 | struct sk_buff *skb, unsigned int bufsize) | ||
779 | { | ||
780 | struct skge_rx_desc *rd = e->desc; | ||
781 | u64 map; | ||
827 | 782 | ||
828 | map = pci_map_single(skge->hw->pdev, skb->data, bufsize, | 783 | map = pci_map_single(skge->hw->pdev, skb->data, bufsize, |
829 | PCI_DMA_FROMDEVICE); | 784 | PCI_DMA_FROMDEVICE); |
@@ -841,55 +796,69 @@ static inline int skge_rx_alloc(struct skge_port *skge, | |||
841 | rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize; | 796 | rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize; |
842 | pci_unmap_addr_set(e, mapaddr, map); | 797 | pci_unmap_addr_set(e, mapaddr, map); |
843 | pci_unmap_len_set(e, maplen, bufsize); | 798 | pci_unmap_len_set(e, maplen, bufsize); |
844 | return 0; | ||
845 | } | 799 | } |
846 | 800 | ||
847 | /* Free all unused buffers in receive ring, assumes receiver stopped */ | 801 | /* Resume receiving using existing skb, |
802 | * Note: DMA address is not changed by chip. | ||
803 | * MTU not changed while receiver active. | ||
804 | */ | ||
805 | static void skge_rx_reuse(struct skge_element *e, unsigned int size) | ||
806 | { | ||
807 | struct skge_rx_desc *rd = e->desc; | ||
808 | |||
809 | rd->csum2 = 0; | ||
810 | rd->csum2_start = ETH_HLEN; | ||
811 | |||
812 | wmb(); | ||
813 | |||
814 | rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size; | ||
815 | } | ||
816 | |||
817 | |||
818 | /* Free all buffers in receive ring, assumes receiver stopped */ | ||
848 | static void skge_rx_clean(struct skge_port *skge) | 819 | static void skge_rx_clean(struct skge_port *skge) |
849 | { | 820 | { |
850 | struct skge_hw *hw = skge->hw; | 821 | struct skge_hw *hw = skge->hw; |
851 | struct skge_ring *ring = &skge->rx_ring; | 822 | struct skge_ring *ring = &skge->rx_ring; |
852 | struct skge_element *e; | 823 | struct skge_element *e; |
853 | 824 | ||
854 | for (e = ring->to_clean; e != ring->to_use; e = e->next) { | 825 | e = ring->start; |
826 | do { | ||
855 | struct skge_rx_desc *rd = e->desc; | 827 | struct skge_rx_desc *rd = e->desc; |
856 | rd->control = 0; | 828 | rd->control = 0; |
857 | 829 | if (e->skb) { | |
858 | pci_unmap_single(hw->pdev, | 830 | pci_unmap_single(hw->pdev, |
859 | pci_unmap_addr(e, mapaddr), | 831 | pci_unmap_addr(e, mapaddr), |
860 | pci_unmap_len(e, maplen), | 832 | pci_unmap_len(e, maplen), |
861 | PCI_DMA_FROMDEVICE); | 833 | PCI_DMA_FROMDEVICE); |
862 | dev_kfree_skb(e->skb); | 834 | dev_kfree_skb(e->skb); |
863 | e->skb = NULL; | 835 | e->skb = NULL; |
864 | } | 836 | } |
865 | ring->to_clean = e; | 837 | } while ((e = e->next) != ring->start); |
866 | } | 838 | } |
867 | 839 | ||
840 | |||
868 | /* Allocate buffers for receive ring | 841 | /* Allocate buffers for receive ring |
869 | * For receive: to_use is refill location | 842 | * For receive: to_clean is next received frame. |
870 | * to_clean is next received frame. | ||
871 | * | ||
872 | * if (to_use == to_clean) | ||
873 | * then ring all frames in ring need buffers | ||
874 | * if (to_use->next == to_clean) | ||
875 | * then ring all frames in ring have buffers | ||
876 | */ | 843 | */ |
877 | static int skge_rx_fill(struct skge_port *skge) | 844 | static int skge_rx_fill(struct skge_port *skge) |
878 | { | 845 | { |
879 | struct skge_ring *ring = &skge->rx_ring; | 846 | struct skge_ring *ring = &skge->rx_ring; |
880 | struct skge_element *e; | 847 | struct skge_element *e; |
881 | int ret = 0; | 848 | unsigned int bufsize = skge->rx_buf_size; |
882 | 849 | ||
883 | for (e = ring->to_use; e->next != ring->to_clean; e = e->next) { | 850 | e = ring->start; |
884 | if (skge_rx_alloc(skge, e)) { | 851 | do { |
885 | ret = 1; | 852 | struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize); |
886 | break; | ||
887 | } | ||
888 | 853 | ||
889 | } | 854 | if (!skb) |
890 | ring->to_use = e; | 855 | return -ENOMEM; |
856 | |||
857 | skge_rx_setup(skge, e, skb, bufsize); | ||
858 | } while ( (e = e->next) != ring->start); | ||
891 | 859 | ||
892 | return ret; | 860 | ring->to_clean = ring->start; |
861 | return 0; | ||
893 | } | 862 | } |
894 | 863 | ||
895 | static void skge_link_up(struct skge_port *skge) | 864 | static void skge_link_up(struct skge_port *skge) |
@@ -919,50 +888,50 @@ static void skge_link_down(struct skge_port *skge) | |||
919 | printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); | 888 | printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); |
920 | } | 889 | } |
921 | 890 | ||
922 | static u16 skge_xm_phy_read(struct skge_hw *hw, int port, u16 reg) | 891 | static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) |
923 | { | 892 | { |
924 | int i; | 893 | int i; |
925 | u16 v; | 894 | u16 v; |
926 | 895 | ||
927 | skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); | 896 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); |
928 | v = skge_xm_read16(hw, port, XM_PHY_DATA); | 897 | v = xm_read16(hw, port, XM_PHY_DATA); |
929 | if (hw->phy_type != SK_PHY_XMAC) { | ||
930 | for (i = 0; i < PHY_RETRIES; i++) { | ||
931 | udelay(1); | ||
932 | if (skge_xm_read16(hw, port, XM_MMU_CMD) | ||
933 | & XM_MMU_PHY_RDY) | ||
934 | goto ready; | ||
935 | } | ||
936 | 898 | ||
937 | printk(KERN_WARNING PFX "%s: phy read timed out\n", | 899 | /* Need to wait for external PHY */ |
938 | hw->dev[port]->name); | 900 | for (i = 0; i < PHY_RETRIES; i++) { |
939 | return 0; | 901 | udelay(1); |
940 | ready: | 902 | if (xm_read16(hw, port, XM_MMU_CMD) |
941 | v = skge_xm_read16(hw, port, XM_PHY_DATA); | 903 | & XM_MMU_PHY_RDY) |
904 | goto ready; | ||
942 | } | 905 | } |
943 | 906 | ||
907 | printk(KERN_WARNING PFX "%s: phy read timed out\n", | ||
908 | hw->dev[port]->name); | ||
909 | return 0; | ||
910 | ready: | ||
911 | v = xm_read16(hw, port, XM_PHY_DATA); | ||
912 | |||
944 | return v; | 913 | return v; |
945 | } | 914 | } |
946 | 915 | ||
947 | static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | 916 | static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) |
948 | { | 917 | { |
949 | int i; | 918 | int i; |
950 | 919 | ||
951 | skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); | 920 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); |
952 | for (i = 0; i < PHY_RETRIES; i++) { | 921 | for (i = 0; i < PHY_RETRIES; i++) { |
953 | if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) | 922 | if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) |
954 | goto ready; | 923 | goto ready; |
955 | cpu_relax(); | 924 | udelay(1); |
956 | } | 925 | } |
957 | printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", | 926 | printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", |
958 | hw->dev[port]->name); | 927 | hw->dev[port]->name); |
959 | 928 | ||
960 | 929 | ||
961 | ready: | 930 | ready: |
962 | skge_xm_write16(hw, port, XM_PHY_DATA, val); | 931 | xm_write16(hw, port, XM_PHY_DATA, val); |
963 | for (i = 0; i < PHY_RETRIES; i++) { | 932 | for (i = 0; i < PHY_RETRIES; i++) { |
964 | udelay(1); | 933 | udelay(1); |
965 | if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) | 934 | if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) |
966 | return; | 935 | return; |
967 | } | 936 | } |
968 | printk(KERN_WARNING PFX "%s: phy write timed out\n", | 937 | printk(KERN_WARNING PFX "%s: phy write timed out\n", |
@@ -999,34 +968,112 @@ static void genesis_init(struct skge_hw *hw) | |||
999 | 968 | ||
1000 | static void genesis_reset(struct skge_hw *hw, int port) | 969 | static void genesis_reset(struct skge_hw *hw, int port) |
1001 | { | 970 | { |
1002 | int i; | 971 | const u8 zero[8] = { 0 }; |
1003 | u64 zero = 0; | ||
1004 | 972 | ||
1005 | /* reset the statistics module */ | 973 | /* reset the statistics module */ |
1006 | skge_xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); | 974 | xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); |
1007 | skge_xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ | 975 | xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ |
1008 | skge_xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ | 976 | xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ |
1009 | skge_xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ | 977 | xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ |
1010 | skge_xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ | 978 | xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ |
1011 | 979 | ||
1012 | /* disable all PHY IRQs */ | 980 | /* disable Broadcom PHY IRQ */ |
1013 | if (hw->phy_type == SK_PHY_BCOM) | 981 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); |
1014 | skge_xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); | ||
1015 | 982 | ||
1016 | skge_xm_outhash(hw, port, XM_HSM, (u8 *) &zero); | 983 | xm_outhash(hw, port, XM_HSM, zero); |
1017 | for (i = 0; i < 15; i++) | ||
1018 | skge_xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero); | ||
1019 | skge_xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero); | ||
1020 | } | 984 | } |
1021 | 985 | ||
1022 | 986 | ||
1023 | static void genesis_mac_init(struct skge_hw *hw, int port) | 987 | /* Convert mode to MII values */ |
988 | static const u16 phy_pause_map[] = { | ||
989 | [FLOW_MODE_NONE] = 0, | ||
990 | [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM, | ||
991 | [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP, | ||
992 | [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, | ||
993 | }; | ||
994 | |||
995 | |||
996 | /* Check status of Broadcom phy link */ | ||
997 | static void bcom_check_link(struct skge_hw *hw, int port) | ||
1024 | { | 998 | { |
1025 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 999 | struct net_device *dev = hw->dev[port]; |
1000 | struct skge_port *skge = netdev_priv(dev); | ||
1001 | u16 status; | ||
1002 | |||
1003 | /* read twice because of latch */ | ||
1004 | (void) xm_phy_read(hw, port, PHY_BCOM_STAT); | ||
1005 | status = xm_phy_read(hw, port, PHY_BCOM_STAT); | ||
1006 | |||
1007 | pr_debug("bcom_check_link status=0x%x\n", status); | ||
1008 | |||
1009 | if ((status & PHY_ST_LSYNC) == 0) { | ||
1010 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); | ||
1011 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
1012 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
1013 | /* dummy read to ensure writing */ | ||
1014 | (void) xm_read16(hw, port, XM_MMU_CMD); | ||
1015 | |||
1016 | if (netif_carrier_ok(dev)) | ||
1017 | skge_link_down(skge); | ||
1018 | } else { | ||
1019 | if (skge->autoneg == AUTONEG_ENABLE && | ||
1020 | (status & PHY_ST_AN_OVER)) { | ||
1021 | u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP); | ||
1022 | u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); | ||
1023 | |||
1024 | if (lpa & PHY_B_AN_RF) { | ||
1025 | printk(KERN_NOTICE PFX "%s: remote fault\n", | ||
1026 | dev->name); | ||
1027 | return; | ||
1028 | } | ||
1029 | |||
1030 | /* Check Duplex mismatch */ | ||
1031 | switch(aux & PHY_B_AS_AN_RES_MSK) { | ||
1032 | case PHY_B_RES_1000FD: | ||
1033 | skge->duplex = DUPLEX_FULL; | ||
1034 | break; | ||
1035 | case PHY_B_RES_1000HD: | ||
1036 | skge->duplex = DUPLEX_HALF; | ||
1037 | break; | ||
1038 | default: | ||
1039 | printk(KERN_NOTICE PFX "%s: duplex mismatch\n", | ||
1040 | dev->name); | ||
1041 | return; | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | ||
1046 | switch (aux & PHY_B_AS_PAUSE_MSK) { | ||
1047 | case PHY_B_AS_PAUSE_MSK: | ||
1048 | skge->flow_control = FLOW_MODE_SYMMETRIC; | ||
1049 | break; | ||
1050 | case PHY_B_AS_PRR: | ||
1051 | skge->flow_control = FLOW_MODE_REM_SEND; | ||
1052 | break; | ||
1053 | case PHY_B_AS_PRT: | ||
1054 | skge->flow_control = FLOW_MODE_LOC_SEND; | ||
1055 | break; | ||
1056 | default: | ||
1057 | skge->flow_control = FLOW_MODE_NONE; | ||
1058 | } | ||
1059 | |||
1060 | skge->speed = SPEED_1000; | ||
1061 | } | ||
1062 | |||
1063 | if (!netif_carrier_ok(dev)) | ||
1064 | genesis_link_up(skge); | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | /* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional | ||
1069 | * Phy on for 100 or 10Mbit operation | ||
1070 | */ | ||
1071 | static void bcom_phy_init(struct skge_port *skge, int jumbo) | ||
1072 | { | ||
1073 | struct skge_hw *hw = skge->hw; | ||
1074 | int port = skge->port; | ||
1026 | int i; | 1075 | int i; |
1027 | u32 r; | 1076 | u16 id1, r, ext, ctl; |
1028 | u16 id1; | ||
1029 | u16 ctrl1, ctrl2, ctrl3, ctrl4, ctrl5; | ||
1030 | 1077 | ||
1031 | /* magic workaround patterns for Broadcom */ | 1078 | /* magic workaround patterns for Broadcom */ |
1032 | static const struct { | 1079 | static const struct { |
@@ -1042,16 +1089,120 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1042 | { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, | 1089 | { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, |
1043 | }; | 1090 | }; |
1044 | 1091 | ||
1092 | pr_debug("bcom_phy_init\n"); | ||
1093 | |||
1094 | /* read Id from external PHY (all have the same address) */ | ||
1095 | id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); | ||
1096 | |||
1097 | /* Optimize MDIO transfer by suppressing preamble. */ | ||
1098 | r = xm_read16(hw, port, XM_MMU_CMD); | ||
1099 | r |= XM_MMU_NO_PRE; | ||
1100 | xm_write16(hw, port, XM_MMU_CMD,r); | ||
1101 | |||
1102 | switch(id1) { | ||
1103 | case PHY_BCOM_ID1_C0: | ||
1104 | /* | ||
1105 | * Workaround BCOM Errata for the C0 type. | ||
1106 | * Write magic patterns to reserved registers. | ||
1107 | */ | ||
1108 | for (i = 0; i < ARRAY_SIZE(C0hack); i++) | ||
1109 | xm_phy_write(hw, port, | ||
1110 | C0hack[i].reg, C0hack[i].val); | ||
1111 | |||
1112 | break; | ||
1113 | case PHY_BCOM_ID1_A1: | ||
1114 | /* | ||
1115 | * Workaround BCOM Errata for the A1 type. | ||
1116 | * Write magic patterns to reserved registers. | ||
1117 | */ | ||
1118 | for (i = 0; i < ARRAY_SIZE(A1hack); i++) | ||
1119 | xm_phy_write(hw, port, | ||
1120 | A1hack[i].reg, A1hack[i].val); | ||
1121 | break; | ||
1122 | } | ||
1123 | |||
1124 | /* | ||
1125 | * Workaround BCOM Errata (#10523) for all BCom PHYs. | ||
1126 | * Disable Power Management after reset. | ||
1127 | */ | ||
1128 | r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); | ||
1129 | r |= PHY_B_AC_DIS_PM; | ||
1130 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r); | ||
1131 | |||
1132 | /* Dummy read */ | ||
1133 | xm_read16(hw, port, XM_ISRC); | ||
1134 | |||
1135 | ext = PHY_B_PEC_EN_LTR; /* enable tx led */ | ||
1136 | ctl = PHY_CT_SP1000; /* always 1000mbit */ | ||
1137 | |||
1138 | if (skge->autoneg == AUTONEG_ENABLE) { | ||
1139 | /* | ||
1140 | * Workaround BCOM Errata #1 for the C5 type. | ||
1141 | * 1000Base-T Link Acquisition Failure in Slave Mode | ||
1142 | * Set Repeater/DTE bit 10 of the 1000Base-T Control Register | ||
1143 | */ | ||
1144 | u16 adv = PHY_B_1000C_RD; | ||
1145 | if (skge->advertising & ADVERTISED_1000baseT_Half) | ||
1146 | adv |= PHY_B_1000C_AHD; | ||
1147 | if (skge->advertising & ADVERTISED_1000baseT_Full) | ||
1148 | adv |= PHY_B_1000C_AFD; | ||
1149 | xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv); | ||
1150 | |||
1151 | ctl |= PHY_CT_ANE | PHY_CT_RE_CFG; | ||
1152 | } else { | ||
1153 | if (skge->duplex == DUPLEX_FULL) | ||
1154 | ctl |= PHY_CT_DUP_MD; | ||
1155 | /* Force to slave */ | ||
1156 | xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE); | ||
1157 | } | ||
1158 | |||
1159 | /* Set autonegotiation pause parameters */ | ||
1160 | xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, | ||
1161 | phy_pause_map[skge->flow_control] | PHY_AN_CSMA); | ||
1162 | |||
1163 | /* Handle Jumbo frames */ | ||
1164 | if (jumbo) { | ||
1165 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, | ||
1166 | PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); | ||
1167 | |||
1168 | ext |= PHY_B_PEC_HIGH_LA; | ||
1169 | |||
1170 | } | ||
1171 | |||
1172 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); | ||
1173 | xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); | ||
1174 | |||
1175 | /* Use link status change interrrupt */ | ||
1176 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); | ||
1177 | |||
1178 | bcom_check_link(hw, port); | ||
1179 | } | ||
1180 | |||
1181 | static void genesis_mac_init(struct skge_hw *hw, int port) | ||
1182 | { | ||
1183 | struct net_device *dev = hw->dev[port]; | ||
1184 | struct skge_port *skge = netdev_priv(dev); | ||
1185 | int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN; | ||
1186 | int i; | ||
1187 | u32 r; | ||
1188 | const u8 zero[6] = { 0 }; | ||
1189 | |||
1190 | /* Clear MIB counters */ | ||
1191 | xm_write16(hw, port, XM_STAT_CMD, | ||
1192 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
1193 | /* Clear two times according to Errata #3 */ | ||
1194 | xm_write16(hw, port, XM_STAT_CMD, | ||
1195 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
1045 | 1196 | ||
1046 | /* initialize Rx, Tx and Link LED */ | 1197 | /* initialize Rx, Tx and Link LED */ |
1047 | skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON); | 1198 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); |
1048 | skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); | 1199 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); |
1049 | 1200 | ||
1050 | skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START); | 1201 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
1051 | skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START); | 1202 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); |
1052 | 1203 | ||
1053 | /* Unreset the XMAC. */ | 1204 | /* Unreset the XMAC. */ |
1054 | skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); | 1205 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); |
1055 | 1206 | ||
1056 | /* | 1207 | /* |
1057 | * Perform additional initialization for external PHYs, | 1208 | * Perform additional initialization for external PHYs, |
@@ -1059,67 +1210,56 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1059 | * GMII mode. | 1210 | * GMII mode. |
1060 | */ | 1211 | */ |
1061 | spin_lock_bh(&hw->phy_lock); | 1212 | spin_lock_bh(&hw->phy_lock); |
1062 | if (hw->phy_type != SK_PHY_XMAC) { | 1213 | /* Take external Phy out of reset */ |
1063 | /* Take PHY out of reset. */ | 1214 | r = skge_read32(hw, B2_GP_IO); |
1064 | r = skge_read32(hw, B2_GP_IO); | 1215 | if (port == 0) |
1065 | if (port == 0) | 1216 | r |= GP_DIR_0|GP_IO_0; |
1066 | r |= GP_DIR_0|GP_IO_0; | 1217 | else |
1067 | else | 1218 | r |= GP_DIR_2|GP_IO_2; |
1068 | r |= GP_DIR_2|GP_IO_2; | ||
1069 | |||
1070 | skge_write32(hw, B2_GP_IO, r); | ||
1071 | skge_read32(hw, B2_GP_IO); | ||
1072 | |||
1073 | /* Enable GMII mode on the XMAC. */ | ||
1074 | skge_xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | ||
1075 | |||
1076 | id1 = skge_xm_phy_read(hw, port, PHY_XMAC_ID1); | ||
1077 | |||
1078 | /* Optimize MDIO transfer by suppressing preamble. */ | ||
1079 | skge_xm_write16(hw, port, XM_MMU_CMD, | ||
1080 | skge_xm_read16(hw, port, XM_MMU_CMD) | ||
1081 | | XM_MMU_NO_PRE); | ||
1082 | |||
1083 | if (id1 == PHY_BCOM_ID1_C0) { | ||
1084 | /* | ||
1085 | * Workaround BCOM Errata for the C0 type. | ||
1086 | * Write magic patterns to reserved registers. | ||
1087 | */ | ||
1088 | for (i = 0; i < ARRAY_SIZE(C0hack); i++) | ||
1089 | skge_xm_phy_write(hw, port, | ||
1090 | C0hack[i].reg, C0hack[i].val); | ||
1091 | |||
1092 | } else if (id1 == PHY_BCOM_ID1_A1) { | ||
1093 | /* | ||
1094 | * Workaround BCOM Errata for the A1 type. | ||
1095 | * Write magic patterns to reserved registers. | ||
1096 | */ | ||
1097 | for (i = 0; i < ARRAY_SIZE(A1hack); i++) | ||
1098 | skge_xm_phy_write(hw, port, | ||
1099 | A1hack[i].reg, A1hack[i].val); | ||
1100 | } | ||
1101 | 1219 | ||
1102 | /* | 1220 | skge_write32(hw, B2_GP_IO, r); |
1103 | * Workaround BCOM Errata (#10523) for all BCom PHYs. | 1221 | skge_read32(hw, B2_GP_IO); |
1104 | * Disable Power Management after reset. | 1222 | spin_unlock_bh(&hw->phy_lock); |
1105 | */ | ||
1106 | r = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); | ||
1107 | skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); | ||
1108 | } | ||
1109 | 1223 | ||
1110 | /* Dummy read */ | 1224 | /* Enable GMII interfac */ |
1111 | skge_xm_read16(hw, port, XM_ISRC); | 1225 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); |
1226 | |||
1227 | bcom_phy_init(skge, jumbo); | ||
1228 | |||
1229 | /* Set Station Address */ | ||
1230 | xm_outaddr(hw, port, XM_SA, dev->dev_addr); | ||
1231 | |||
1232 | /* We don't use match addresses so clear */ | ||
1233 | for (i = 1; i < 16; i++) | ||
1234 | xm_outaddr(hw, port, XM_EXM(i), zero); | ||
1112 | 1235 | ||
1113 | r = skge_xm_read32(hw, port, XM_MODE); | 1236 | /* configure Rx High Water Mark (XM_RX_HI_WM) */ |
1114 | skge_xm_write32(hw, port, XM_MODE, r|XM_MD_CSA); | 1237 | xm_write16(hw, port, XM_RX_HI_WM, 1450); |
1115 | 1238 | ||
1116 | /* We don't need the FCS appended to the packet. */ | 1239 | /* We don't need the FCS appended to the packet. */ |
1117 | r = skge_xm_read16(hw, port, XM_RX_CMD); | 1240 | r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS; |
1118 | skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS); | 1241 | if (jumbo) |
1242 | r |= XM_RX_BIG_PK_OK; | ||
1243 | |||
1244 | if (skge->duplex == DUPLEX_HALF) { | ||
1245 | /* | ||
1246 | * If in manual half duplex mode the other side might be in | ||
1247 | * full duplex mode, so ignore if a carrier extension is not seen | ||
1248 | * on frames received | ||
1249 | */ | ||
1250 | r |= XM_RX_DIS_CEXT; | ||
1251 | } | ||
1252 | xm_write16(hw, port, XM_RX_CMD, r); | ||
1253 | |||
1119 | 1254 | ||
1120 | /* We want short frames padded to 60 bytes. */ | 1255 | /* We want short frames padded to 60 bytes. */ |
1121 | r = skge_xm_read16(hw, port, XM_TX_CMD); | 1256 | xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD); |
1122 | skge_xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD); | 1257 | |
1258 | /* | ||
1259 | * Bump up the transmit threshold. This helps hold off transmit | ||
1260 | * underruns when we're blasting traffic from both ports at once. | ||
1261 | */ | ||
1262 | xm_write16(hw, port, XM_TX_THR, 512); | ||
1123 | 1263 | ||
1124 | /* | 1264 | /* |
1125 | * Enable the reception of all error frames. This is is | 1265 | * Enable the reception of all error frames. This is is |
@@ -1135,19 +1275,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1135 | * case the XMAC will start transfering frames out of the | 1275 | * case the XMAC will start transfering frames out of the |
1136 | * RX FIFO as soon as the FIFO threshold is reached. | 1276 | * RX FIFO as soon as the FIFO threshold is reached. |
1137 | */ | 1277 | */ |
1138 | r = skge_xm_read32(hw, port, XM_MODE); | 1278 | xm_write32(hw, port, XM_MODE, XM_DEF_MODE); |
1139 | skge_xm_write32(hw, port, XM_MODE, | ||
1140 | XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| | ||
1141 | XM_MD_RX_ERR|XM_MD_RX_IRLE); | ||
1142 | 1279 | ||
1143 | skge_xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); | ||
1144 | skge_xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); | ||
1145 | 1280 | ||
1146 | /* | 1281 | /* |
1147 | * Bump up the transmit threshold. This helps hold off transmit | 1282 | * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK) |
1148 | * underruns when we're blasting traffic from both ports at once. | 1283 | * - Enable all bits excepting 'Octets Rx OK Low CntOv' |
1284 | * and 'Octets Rx OK Hi Cnt Ov'. | ||
1149 | */ | 1285 | */ |
1150 | skge_xm_write16(hw, port, XM_TX_THR, 512); | 1286 | xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK); |
1287 | |||
1288 | /* | ||
1289 | * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK) | ||
1290 | * - Enable all bits excepting 'Octets Tx OK Low CntOv' | ||
1291 | * and 'Octets Tx OK Hi Cnt Ov'. | ||
1292 | */ | ||
1293 | xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK); | ||
1151 | 1294 | ||
1152 | /* Configure MAC arbiter */ | 1295 | /* Configure MAC arbiter */ |
1153 | skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR); | 1296 | skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR); |
@@ -1164,137 +1307,30 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1164 | skge_write8(hw, B3_MA_RCINI_TX2, 0); | 1307 | skge_write8(hw, B3_MA_RCINI_TX2, 0); |
1165 | 1308 | ||
1166 | /* Configure Rx MAC FIFO */ | 1309 | /* Configure Rx MAC FIFO */ |
1167 | skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_CLR); | 1310 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR); |
1168 | skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT); | 1311 | skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT); |
1169 | skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD); | 1312 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD); |
1170 | 1313 | ||
1171 | /* Configure Tx MAC FIFO */ | 1314 | /* Configure Tx MAC FIFO */ |
1172 | skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_CLR); | 1315 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR); |
1173 | skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); | 1316 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); |
1174 | skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); | 1317 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); |
1175 | 1318 | ||
1176 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { | 1319 | if (jumbo) { |
1177 | /* Enable frame flushing if jumbo frames used */ | 1320 | /* Enable frame flushing if jumbo frames used */ |
1178 | skge_write16(hw, SKGEMAC_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); | 1321 | skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); |
1179 | } else { | 1322 | } else { |
1180 | /* enable timeout timers if normal frames */ | 1323 | /* enable timeout timers if normal frames */ |
1181 | skge_write16(hw, B3_PA_CTRL, | 1324 | skge_write16(hw, B3_PA_CTRL, |
1182 | port == 0 ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); | 1325 | (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); |
1183 | } | 1326 | } |
1184 | |||
1185 | |||
1186 | r = skge_xm_read16(hw, port, XM_RX_CMD); | ||
1187 | if (hw->dev[port]->mtu > ETH_DATA_LEN) | ||
1188 | skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK); | ||
1189 | else | ||
1190 | skge_xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); | ||
1191 | |||
1192 | switch (hw->phy_type) { | ||
1193 | case SK_PHY_XMAC: | ||
1194 | if (skge->autoneg == AUTONEG_ENABLE) { | ||
1195 | ctrl1 = PHY_X_AN_FD | PHY_X_AN_HD; | ||
1196 | |||
1197 | switch (skge->flow_control) { | ||
1198 | case FLOW_MODE_NONE: | ||
1199 | ctrl1 |= PHY_X_P_NO_PAUSE; | ||
1200 | break; | ||
1201 | case FLOW_MODE_LOC_SEND: | ||
1202 | ctrl1 |= PHY_X_P_ASYM_MD; | ||
1203 | break; | ||
1204 | case FLOW_MODE_SYMMETRIC: | ||
1205 | ctrl1 |= PHY_X_P_SYM_MD; | ||
1206 | break; | ||
1207 | case FLOW_MODE_REM_SEND: | ||
1208 | ctrl1 |= PHY_X_P_BOTH_MD; | ||
1209 | break; | ||
1210 | } | ||
1211 | |||
1212 | skge_xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1); | ||
1213 | ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG; | ||
1214 | } else { | ||
1215 | ctrl2 = 0; | ||
1216 | if (skge->duplex == DUPLEX_FULL) | ||
1217 | ctrl2 |= PHY_CT_DUP_MD; | ||
1218 | } | ||
1219 | |||
1220 | skge_xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2); | ||
1221 | break; | ||
1222 | |||
1223 | case SK_PHY_BCOM: | ||
1224 | ctrl1 = PHY_CT_SP1000; | ||
1225 | ctrl2 = 0; | ||
1226 | ctrl3 = PHY_SEL_TYPE; | ||
1227 | ctrl4 = PHY_B_PEC_EN_LTR; | ||
1228 | ctrl5 = PHY_B_AC_TX_TST; | ||
1229 | |||
1230 | if (skge->autoneg == AUTONEG_ENABLE) { | ||
1231 | /* | ||
1232 | * Workaround BCOM Errata #1 for the C5 type. | ||
1233 | * 1000Base-T Link Acquisition Failure in Slave Mode | ||
1234 | * Set Repeater/DTE bit 10 of the 1000Base-T Control Register | ||
1235 | */ | ||
1236 | ctrl2 |= PHY_B_1000C_RD; | ||
1237 | if (skge->advertising & ADVERTISED_1000baseT_Half) | ||
1238 | ctrl2 |= PHY_B_1000C_AHD; | ||
1239 | if (skge->advertising & ADVERTISED_1000baseT_Full) | ||
1240 | ctrl2 |= PHY_B_1000C_AFD; | ||
1241 | |||
1242 | /* Set Flow-control capabilities */ | ||
1243 | switch (skge->flow_control) { | ||
1244 | case FLOW_MODE_NONE: | ||
1245 | ctrl3 |= PHY_B_P_NO_PAUSE; | ||
1246 | break; | ||
1247 | case FLOW_MODE_LOC_SEND: | ||
1248 | ctrl3 |= PHY_B_P_ASYM_MD; | ||
1249 | break; | ||
1250 | case FLOW_MODE_SYMMETRIC: | ||
1251 | ctrl3 |= PHY_B_P_SYM_MD; | ||
1252 | break; | ||
1253 | case FLOW_MODE_REM_SEND: | ||
1254 | ctrl3 |= PHY_B_P_BOTH_MD; | ||
1255 | break; | ||
1256 | } | ||
1257 | |||
1258 | /* Restart Auto-negotiation */ | ||
1259 | ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; | ||
1260 | } else { | ||
1261 | if (skge->duplex == DUPLEX_FULL) | ||
1262 | ctrl1 |= PHY_CT_DUP_MD; | ||
1263 | |||
1264 | ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ | ||
1265 | } | ||
1266 | |||
1267 | skge_xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); | ||
1268 | skge_xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); | ||
1269 | |||
1270 | if (skge->netdev->mtu > ETH_DATA_LEN) { | ||
1271 | ctrl4 |= PHY_B_PEC_HIGH_LA; | ||
1272 | ctrl5 |= PHY_B_AC_LONG_PACK; | ||
1273 | |||
1274 | skge_xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); | ||
1275 | } | ||
1276 | |||
1277 | skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); | ||
1278 | skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); | ||
1279 | break; | ||
1280 | } | ||
1281 | spin_unlock_bh(&hw->phy_lock); | ||
1282 | |||
1283 | /* Clear MIB counters */ | ||
1284 | skge_xm_write16(hw, port, XM_STAT_CMD, | ||
1285 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
1286 | /* Clear two times according to Errata #3 */ | ||
1287 | skge_xm_write16(hw, port, XM_STAT_CMD, | ||
1288 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
1289 | |||
1290 | /* Start polling for link status */ | ||
1291 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1292 | } | 1327 | } |
1293 | 1328 | ||
1294 | static void genesis_stop(struct skge_port *skge) | 1329 | static void genesis_stop(struct skge_port *skge) |
1295 | { | 1330 | { |
1296 | struct skge_hw *hw = skge->hw; | 1331 | struct skge_hw *hw = skge->hw; |
1297 | int port = skge->port; | 1332 | int port = skge->port; |
1333 | u32 reg; | ||
1298 | 1334 | ||
1299 | /* Clear Tx packet arbiter timeout IRQ */ | 1335 | /* Clear Tx packet arbiter timeout IRQ */ |
1300 | skge_write16(hw, B3_PA_CTRL, | 1336 | skge_write16(hw, B3_PA_CTRL, |
@@ -1304,33 +1340,30 @@ static void genesis_stop(struct skge_port *skge) | |||
1304 | * If the transfer stucks at the MAC the STOP command will not | 1340 | * If the transfer stucks at the MAC the STOP command will not |
1305 | * terminate if we don't flush the XMAC's transmit FIFO ! | 1341 | * terminate if we don't flush the XMAC's transmit FIFO ! |
1306 | */ | 1342 | */ |
1307 | skge_xm_write32(hw, port, XM_MODE, | 1343 | xm_write32(hw, port, XM_MODE, |
1308 | skge_xm_read32(hw, port, XM_MODE)|XM_MD_FTF); | 1344 | xm_read32(hw, port, XM_MODE)|XM_MD_FTF); |
1309 | 1345 | ||
1310 | 1346 | ||
1311 | /* Reset the MAC */ | 1347 | /* Reset the MAC */ |
1312 | skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); | 1348 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); |
1313 | 1349 | ||
1314 | /* For external PHYs there must be special handling */ | 1350 | /* For external PHYs there must be special handling */ |
1315 | if (hw->phy_type != SK_PHY_XMAC) { | 1351 | reg = skge_read32(hw, B2_GP_IO); |
1316 | u32 reg = skge_read32(hw, B2_GP_IO); | 1352 | if (port == 0) { |
1317 | 1353 | reg |= GP_DIR_0; | |
1318 | if (port == 0) { | 1354 | reg &= ~GP_IO_0; |
1319 | reg |= GP_DIR_0; | 1355 | } else { |
1320 | reg &= ~GP_IO_0; | 1356 | reg |= GP_DIR_2; |
1321 | } else { | 1357 | reg &= ~GP_IO_2; |
1322 | reg |= GP_DIR_2; | ||
1323 | reg &= ~GP_IO_2; | ||
1324 | } | ||
1325 | skge_write32(hw, B2_GP_IO, reg); | ||
1326 | skge_read32(hw, B2_GP_IO); | ||
1327 | } | 1358 | } |
1359 | skge_write32(hw, B2_GP_IO, reg); | ||
1360 | skge_read32(hw, B2_GP_IO); | ||
1328 | 1361 | ||
1329 | skge_xm_write16(hw, port, XM_MMU_CMD, | 1362 | xm_write16(hw, port, XM_MMU_CMD, |
1330 | skge_xm_read16(hw, port, XM_MMU_CMD) | 1363 | xm_read16(hw, port, XM_MMU_CMD) |
1331 | & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); | 1364 | & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); |
1332 | 1365 | ||
1333 | skge_xm_read16(hw, port, XM_MMU_CMD); | 1366 | xm_read16(hw, port, XM_MMU_CMD); |
1334 | } | 1367 | } |
1335 | 1368 | ||
1336 | 1369 | ||
@@ -1341,11 +1374,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data) | |||
1341 | int i; | 1374 | int i; |
1342 | unsigned long timeout = jiffies + HZ; | 1375 | unsigned long timeout = jiffies + HZ; |
1343 | 1376 | ||
1344 | skge_xm_write16(hw, port, | 1377 | xm_write16(hw, port, |
1345 | XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); | 1378 | XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); |
1346 | 1379 | ||
1347 | /* wait for update to complete */ | 1380 | /* wait for update to complete */ |
1348 | while (skge_xm_read16(hw, port, XM_STAT_CMD) | 1381 | while (xm_read16(hw, port, XM_STAT_CMD) |
1349 | & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) { | 1382 | & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) { |
1350 | if (time_after(jiffies, timeout)) | 1383 | if (time_after(jiffies, timeout)) |
1351 | break; | 1384 | break; |
@@ -1353,68 +1386,60 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data) | |||
1353 | } | 1386 | } |
1354 | 1387 | ||
1355 | /* special case for 64 bit octet counter */ | 1388 | /* special case for 64 bit octet counter */ |
1356 | data[0] = (u64) skge_xm_read32(hw, port, XM_TXO_OK_HI) << 32 | 1389 | data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32 |
1357 | | skge_xm_read32(hw, port, XM_TXO_OK_LO); | 1390 | | xm_read32(hw, port, XM_TXO_OK_LO); |
1358 | data[1] = (u64) skge_xm_read32(hw, port, XM_RXO_OK_HI) << 32 | 1391 | data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32 |
1359 | | skge_xm_read32(hw, port, XM_RXO_OK_LO); | 1392 | | xm_read32(hw, port, XM_RXO_OK_LO); |
1360 | 1393 | ||
1361 | for (i = 2; i < ARRAY_SIZE(skge_stats); i++) | 1394 | for (i = 2; i < ARRAY_SIZE(skge_stats); i++) |
1362 | data[i] = skge_xm_read32(hw, port, skge_stats[i].xmac_offset); | 1395 | data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset); |
1363 | } | 1396 | } |
1364 | 1397 | ||
1365 | static void genesis_mac_intr(struct skge_hw *hw, int port) | 1398 | static void genesis_mac_intr(struct skge_hw *hw, int port) |
1366 | { | 1399 | { |
1367 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1400 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
1368 | u16 status = skge_xm_read16(hw, port, XM_ISRC); | 1401 | u16 status = xm_read16(hw, port, XM_ISRC); |
1369 | 1402 | ||
1370 | pr_debug("genesis_intr status %x\n", status); | 1403 | if (netif_msg_intr(skge)) |
1371 | if (hw->phy_type == SK_PHY_XMAC) { | 1404 | printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", |
1372 | /* LInk down, start polling for state change */ | 1405 | skge->netdev->name, status); |
1373 | if (status & XM_IS_INP_ASS) { | ||
1374 | skge_xm_write16(hw, port, XM_IMSK, | ||
1375 | skge_xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS); | ||
1376 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1377 | } | ||
1378 | else if (status & XM_IS_AND) | ||
1379 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1380 | } | ||
1381 | 1406 | ||
1382 | if (status & XM_IS_TXF_UR) { | 1407 | if (status & XM_IS_TXF_UR) { |
1383 | skge_xm_write32(hw, port, XM_MODE, XM_MD_FTF); | 1408 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); |
1384 | ++skge->net_stats.tx_fifo_errors; | 1409 | ++skge->net_stats.tx_fifo_errors; |
1385 | } | 1410 | } |
1386 | if (status & XM_IS_RXF_OV) { | 1411 | if (status & XM_IS_RXF_OV) { |
1387 | skge_xm_write32(hw, port, XM_MODE, XM_MD_FRF); | 1412 | xm_write32(hw, port, XM_MODE, XM_MD_FRF); |
1388 | ++skge->net_stats.rx_fifo_errors; | 1413 | ++skge->net_stats.rx_fifo_errors; |
1389 | } | 1414 | } |
1390 | } | 1415 | } |
1391 | 1416 | ||
1392 | static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | 1417 | static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) |
1393 | { | 1418 | { |
1394 | int i; | 1419 | int i; |
1395 | 1420 | ||
1396 | skge_gma_write16(hw, port, GM_SMI_DATA, val); | 1421 | gma_write16(hw, port, GM_SMI_DATA, val); |
1397 | skge_gma_write16(hw, port, GM_SMI_CTRL, | 1422 | gma_write16(hw, port, GM_SMI_CTRL, |
1398 | GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg)); | 1423 | GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg)); |
1399 | for (i = 0; i < PHY_RETRIES; i++) { | 1424 | for (i = 0; i < PHY_RETRIES; i++) { |
1400 | udelay(1); | 1425 | udelay(1); |
1401 | 1426 | ||
1402 | if (!(skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) | 1427 | if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) |
1403 | break; | 1428 | break; |
1404 | } | 1429 | } |
1405 | } | 1430 | } |
1406 | 1431 | ||
1407 | static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg) | 1432 | static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg) |
1408 | { | 1433 | { |
1409 | int i; | 1434 | int i; |
1410 | 1435 | ||
1411 | skge_gma_write16(hw, port, GM_SMI_CTRL, | 1436 | gma_write16(hw, port, GM_SMI_CTRL, |
1412 | GM_SMI_CT_PHY_AD(hw->phy_addr) | 1437 | GM_SMI_CT_PHY_AD(hw->phy_addr) |
1413 | | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); | 1438 | | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); |
1414 | 1439 | ||
1415 | for (i = 0; i < PHY_RETRIES; i++) { | 1440 | for (i = 0; i < PHY_RETRIES; i++) { |
1416 | udelay(1); | 1441 | udelay(1); |
1417 | if (skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) | 1442 | if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) |
1418 | goto ready; | 1443 | goto ready; |
1419 | } | 1444 | } |
1420 | 1445 | ||
@@ -1422,24 +1447,7 @@ static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg) | |||
1422 | hw->dev[port]->name); | 1447 | hw->dev[port]->name); |
1423 | return 0; | 1448 | return 0; |
1424 | ready: | 1449 | ready: |
1425 | return skge_gma_read16(hw, port, GM_SMI_DATA); | 1450 | return gma_read16(hw, port, GM_SMI_DATA); |
1426 | } | ||
1427 | |||
1428 | static void genesis_link_down(struct skge_port *skge) | ||
1429 | { | ||
1430 | struct skge_hw *hw = skge->hw; | ||
1431 | int port = skge->port; | ||
1432 | |||
1433 | pr_debug("genesis_link_down\n"); | ||
1434 | |||
1435 | skge_xm_write16(hw, port, XM_MMU_CMD, | ||
1436 | skge_xm_read16(hw, port, XM_MMU_CMD) | ||
1437 | & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); | ||
1438 | |||
1439 | /* dummy read to ensure writing */ | ||
1440 | (void) skge_xm_read16(hw, port, XM_MMU_CMD); | ||
1441 | |||
1442 | skge_link_down(skge); | ||
1443 | } | 1451 | } |
1444 | 1452 | ||
1445 | static void genesis_link_up(struct skge_port *skge) | 1453 | static void genesis_link_up(struct skge_port *skge) |
@@ -1450,7 +1458,7 @@ static void genesis_link_up(struct skge_port *skge) | |||
1450 | u32 mode, msk; | 1458 | u32 mode, msk; |
1451 | 1459 | ||
1452 | pr_debug("genesis_link_up\n"); | 1460 | pr_debug("genesis_link_up\n"); |
1453 | cmd = skge_xm_read16(hw, port, XM_MMU_CMD); | 1461 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
1454 | 1462 | ||
1455 | /* | 1463 | /* |
1456 | * enabling pause frame reception is required for 1000BT | 1464 | * enabling pause frame reception is required for 1000BT |
@@ -1458,14 +1466,15 @@ static void genesis_link_up(struct skge_port *skge) | |||
1458 | */ | 1466 | */ |
1459 | if (skge->flow_control == FLOW_MODE_NONE || | 1467 | if (skge->flow_control == FLOW_MODE_NONE || |
1460 | skge->flow_control == FLOW_MODE_LOC_SEND) | 1468 | skge->flow_control == FLOW_MODE_LOC_SEND) |
1469 | /* Disable Pause Frame Reception */ | ||
1461 | cmd |= XM_MMU_IGN_PF; | 1470 | cmd |= XM_MMU_IGN_PF; |
1462 | else | 1471 | else |
1463 | /* Enable Pause Frame Reception */ | 1472 | /* Enable Pause Frame Reception */ |
1464 | cmd &= ~XM_MMU_IGN_PF; | 1473 | cmd &= ~XM_MMU_IGN_PF; |
1465 | 1474 | ||
1466 | skge_xm_write16(hw, port, XM_MMU_CMD, cmd); | 1475 | xm_write16(hw, port, XM_MMU_CMD, cmd); |
1467 | 1476 | ||
1468 | mode = skge_xm_read32(hw, port, XM_MODE); | 1477 | mode = xm_read32(hw, port, XM_MODE); |
1469 | if (skge->flow_control == FLOW_MODE_SYMMETRIC || | 1478 | if (skge->flow_control == FLOW_MODE_SYMMETRIC || |
1470 | skge->flow_control == FLOW_MODE_LOC_SEND) { | 1479 | skge->flow_control == FLOW_MODE_LOC_SEND) { |
1471 | /* | 1480 | /* |
@@ -1479,10 +1488,10 @@ static void genesis_link_up(struct skge_port *skge) | |||
1479 | /* XM_PAUSE_DA = '010000C28001' (default) */ | 1488 | /* XM_PAUSE_DA = '010000C28001' (default) */ |
1480 | /* XM_MAC_PTIME = 0xffff (maximum) */ | 1489 | /* XM_MAC_PTIME = 0xffff (maximum) */ |
1481 | /* remember this value is defined in big endian (!) */ | 1490 | /* remember this value is defined in big endian (!) */ |
1482 | skge_xm_write16(hw, port, XM_MAC_PTIME, 0xffff); | 1491 | xm_write16(hw, port, XM_MAC_PTIME, 0xffff); |
1483 | 1492 | ||
1484 | mode |= XM_PAUSE_MODE; | 1493 | mode |= XM_PAUSE_MODE; |
1485 | skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE); | 1494 | skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE); |
1486 | } else { | 1495 | } else { |
1487 | /* | 1496 | /* |
1488 | * disable pause frame generation is required for 1000BT | 1497 | * disable pause frame generation is required for 1000BT |
@@ -1491,125 +1500,68 @@ static void genesis_link_up(struct skge_port *skge) | |||
1491 | /* Disable Pause Mode in Mode Register */ | 1500 | /* Disable Pause Mode in Mode Register */ |
1492 | mode &= ~XM_PAUSE_MODE; | 1501 | mode &= ~XM_PAUSE_MODE; |
1493 | 1502 | ||
1494 | skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE); | 1503 | skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE); |
1495 | } | 1504 | } |
1496 | 1505 | ||
1497 | skge_xm_write32(hw, port, XM_MODE, mode); | 1506 | xm_write32(hw, port, XM_MODE, mode); |
1498 | 1507 | ||
1499 | msk = XM_DEF_MSK; | 1508 | msk = XM_DEF_MSK; |
1500 | if (hw->phy_type != SK_PHY_XMAC) | 1509 | /* disable GP0 interrupt bit for external Phy */ |
1501 | msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ | 1510 | msk |= XM_IS_INP_ASS; |
1502 | 1511 | ||
1503 | skge_xm_write16(hw, port, XM_IMSK, msk); | 1512 | xm_write16(hw, port, XM_IMSK, msk); |
1504 | skge_xm_read16(hw, port, XM_ISRC); | 1513 | xm_read16(hw, port, XM_ISRC); |
1505 | 1514 | ||
1506 | /* get MMU Command Reg. */ | 1515 | /* get MMU Command Reg. */ |
1507 | cmd = skge_xm_read16(hw, port, XM_MMU_CMD); | 1516 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
1508 | if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL) | 1517 | if (skge->duplex == DUPLEX_FULL) |
1509 | cmd |= XM_MMU_GMII_FD; | 1518 | cmd |= XM_MMU_GMII_FD; |
1510 | 1519 | ||
1511 | if (hw->phy_type == SK_PHY_BCOM) { | 1520 | /* |
1512 | /* | 1521 | * Workaround BCOM Errata (#10523) for all BCom Phys |
1513 | * Workaround BCOM Errata (#10523) for all BCom Phys | 1522 | * Enable Power Management after link up |
1514 | * Enable Power Management after link up | 1523 | */ |
1515 | */ | 1524 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, |
1516 | skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, | 1525 | xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) |
1517 | skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) | 1526 | & ~PHY_B_AC_DIS_PM); |
1518 | & ~PHY_B_AC_DIS_PM); | 1527 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); |
1519 | skge_xm_phy_write(hw, port, PHY_BCOM_INT_MASK, | ||
1520 | PHY_B_DEF_MSK); | ||
1521 | } | ||
1522 | 1528 | ||
1523 | /* enable Rx/Tx */ | 1529 | /* enable Rx/Tx */ |
1524 | skge_xm_write16(hw, port, XM_MMU_CMD, | 1530 | xm_write16(hw, port, XM_MMU_CMD, |
1525 | cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX); | 1531 | cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX); |
1526 | skge_link_up(skge); | 1532 | skge_link_up(skge); |
1527 | } | 1533 | } |
1528 | 1534 | ||
1529 | 1535 | ||
1530 | static void genesis_bcom_intr(struct skge_port *skge) | 1536 | static inline void bcom_phy_intr(struct skge_port *skge) |
1531 | { | 1537 | { |
1532 | struct skge_hw *hw = skge->hw; | 1538 | struct skge_hw *hw = skge->hw; |
1533 | int port = skge->port; | 1539 | int port = skge->port; |
1534 | u16 stat = skge_xm_phy_read(hw, port, PHY_BCOM_INT_STAT); | 1540 | u16 isrc; |
1541 | |||
1542 | isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); | ||
1543 | if (netif_msg_intr(skge)) | ||
1544 | printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n", | ||
1545 | skge->netdev->name, isrc); | ||
1535 | 1546 | ||
1536 | pr_debug("genesis_bcom intr stat=%x\n", stat); | 1547 | if (isrc & PHY_B_IS_PSE) |
1548 | printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n", | ||
1549 | hw->dev[port]->name); | ||
1537 | 1550 | ||
1538 | /* Workaround BCom Errata: | 1551 | /* Workaround BCom Errata: |
1539 | * enable and disable loopback mode if "NO HCD" occurs. | 1552 | * enable and disable loopback mode if "NO HCD" occurs. |
1540 | */ | 1553 | */ |
1541 | if (stat & PHY_B_IS_NO_HDCL) { | 1554 | if (isrc & PHY_B_IS_NO_HDCL) { |
1542 | u16 ctrl = skge_xm_phy_read(hw, port, PHY_BCOM_CTRL); | 1555 | u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL); |
1543 | skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, | 1556 | xm_phy_write(hw, port, PHY_BCOM_CTRL, |
1544 | ctrl | PHY_CT_LOOP); | 1557 | ctrl | PHY_CT_LOOP); |
1545 | skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, | 1558 | xm_phy_write(hw, port, PHY_BCOM_CTRL, |
1546 | ctrl & ~PHY_CT_LOOP); | 1559 | ctrl & ~PHY_CT_LOOP); |
1547 | } | 1560 | } |
1548 | 1561 | ||
1549 | stat = skge_xm_phy_read(hw, port, PHY_BCOM_STAT); | 1562 | if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) |
1550 | if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) { | 1563 | bcom_check_link(hw, port); |
1551 | u16 aux = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); | ||
1552 | if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev)) | ||
1553 | genesis_link_down(skge); | ||
1554 | |||
1555 | else if (stat & PHY_B_IS_LST_CHANGE) { | ||
1556 | if (aux & PHY_B_AS_AN_C) { | ||
1557 | switch (aux & PHY_B_AS_AN_RES_MSK) { | ||
1558 | case PHY_B_RES_1000FD: | ||
1559 | skge->duplex = DUPLEX_FULL; | ||
1560 | break; | ||
1561 | case PHY_B_RES_1000HD: | ||
1562 | skge->duplex = DUPLEX_HALF; | ||
1563 | break; | ||
1564 | } | ||
1565 | |||
1566 | switch (aux & PHY_B_AS_PAUSE_MSK) { | ||
1567 | case PHY_B_AS_PAUSE_MSK: | ||
1568 | skge->flow_control = FLOW_MODE_SYMMETRIC; | ||
1569 | break; | ||
1570 | case PHY_B_AS_PRR: | ||
1571 | skge->flow_control = FLOW_MODE_REM_SEND; | ||
1572 | break; | ||
1573 | case PHY_B_AS_PRT: | ||
1574 | skge->flow_control = FLOW_MODE_LOC_SEND; | ||
1575 | break; | ||
1576 | default: | ||
1577 | skge->flow_control = FLOW_MODE_NONE; | ||
1578 | } | ||
1579 | skge->speed = SPEED_1000; | ||
1580 | } | ||
1581 | genesis_link_up(skge); | ||
1582 | } | ||
1583 | else | ||
1584 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1585 | } | ||
1586 | } | ||
1587 | 1564 | ||
1588 | /* Perodic poll of phy status to check for link transistion */ | ||
1589 | static void skge_link_timer(unsigned long __arg) | ||
1590 | { | ||
1591 | struct skge_port *skge = (struct skge_port *) __arg; | ||
1592 | struct skge_hw *hw = skge->hw; | ||
1593 | int port = skge->port; | ||
1594 | |||
1595 | if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev)) | ||
1596 | return; | ||
1597 | |||
1598 | spin_lock_bh(&hw->phy_lock); | ||
1599 | if (hw->phy_type == SK_PHY_BCOM) | ||
1600 | genesis_bcom_intr(skge); | ||
1601 | else { | ||
1602 | int i; | ||
1603 | for (i = 0; i < 3; i++) | ||
1604 | if (skge_xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) | ||
1605 | break; | ||
1606 | |||
1607 | if (i == 3) | ||
1608 | mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); | ||
1609 | else | ||
1610 | genesis_link_up(skge); | ||
1611 | } | ||
1612 | spin_unlock_bh(&hw->phy_lock); | ||
1613 | } | 1565 | } |
1614 | 1566 | ||
1615 | /* Marvell Phy Initailization */ | 1567 | /* Marvell Phy Initailization */ |
@@ -1621,31 +1573,27 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1621 | 1573 | ||
1622 | pr_debug("yukon_init\n"); | 1574 | pr_debug("yukon_init\n"); |
1623 | if (skge->autoneg == AUTONEG_ENABLE) { | 1575 | if (skge->autoneg == AUTONEG_ENABLE) { |
1624 | u16 ectrl = skge_gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); | 1576 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
1625 | 1577 | ||
1626 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | | 1578 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | |
1627 | PHY_M_EC_MAC_S_MSK); | 1579 | PHY_M_EC_MAC_S_MSK); |
1628 | ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); | 1580 | ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); |
1629 | 1581 | ||
1630 | /* on PHY 88E1111 there is a change for downshift control */ | 1582 | ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); |
1631 | if (hw->chip_id == CHIP_ID_YUKON_EC) | ||
1632 | ectrl |= PHY_M_EC_M_DSC_2(0) | PHY_M_EC_DOWN_S_ENA; | ||
1633 | else | ||
1634 | ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); | ||
1635 | 1583 | ||
1636 | skge_gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); | 1584 | gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); |
1637 | } | 1585 | } |
1638 | 1586 | ||
1639 | ctrl = skge_gm_phy_read(hw, port, PHY_MARV_CTRL); | 1587 | ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); |
1640 | if (skge->autoneg == AUTONEG_DISABLE) | 1588 | if (skge->autoneg == AUTONEG_DISABLE) |
1641 | ctrl &= ~PHY_CT_ANE; | 1589 | ctrl &= ~PHY_CT_ANE; |
1642 | 1590 | ||
1643 | ctrl |= PHY_CT_RESET; | 1591 | ctrl |= PHY_CT_RESET; |
1644 | skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | 1592 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); |
1645 | 1593 | ||
1646 | ctrl = 0; | 1594 | ctrl = 0; |
1647 | ct1000 = 0; | 1595 | ct1000 = 0; |
1648 | adv = PHY_SEL_TYPE; | 1596 | adv = PHY_AN_CSMA; |
1649 | 1597 | ||
1650 | if (skge->autoneg == AUTONEG_ENABLE) { | 1598 | if (skge->autoneg == AUTONEG_ENABLE) { |
1651 | if (iscopper(hw)) { | 1599 | if (iscopper(hw)) { |
@@ -1661,41 +1609,12 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1661 | adv |= PHY_M_AN_10_FD; | 1609 | adv |= PHY_M_AN_10_FD; |
1662 | if (skge->advertising & ADVERTISED_10baseT_Half) | 1610 | if (skge->advertising & ADVERTISED_10baseT_Half) |
1663 | adv |= PHY_M_AN_10_HD; | 1611 | adv |= PHY_M_AN_10_HD; |
1664 | 1612 | } else /* special defines for FIBER (88E1011S only) */ | |
1665 | /* Set Flow-control capabilities */ | ||
1666 | switch (skge->flow_control) { | ||
1667 | case FLOW_MODE_NONE: | ||
1668 | adv |= PHY_B_P_NO_PAUSE; | ||
1669 | break; | ||
1670 | case FLOW_MODE_LOC_SEND: | ||
1671 | adv |= PHY_B_P_ASYM_MD; | ||
1672 | break; | ||
1673 | case FLOW_MODE_SYMMETRIC: | ||
1674 | adv |= PHY_B_P_SYM_MD; | ||
1675 | break; | ||
1676 | case FLOW_MODE_REM_SEND: | ||
1677 | adv |= PHY_B_P_BOTH_MD; | ||
1678 | break; | ||
1679 | } | ||
1680 | } else { /* special defines for FIBER (88E1011S only) */ | ||
1681 | adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; | 1613 | adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; |
1682 | 1614 | ||
1683 | /* Set Flow-control capabilities */ | 1615 | /* Set Flow-control capabilities */ |
1684 | switch (skge->flow_control) { | 1616 | adv |= phy_pause_map[skge->flow_control]; |
1685 | case FLOW_MODE_NONE: | 1617 | |
1686 | adv |= PHY_M_P_NO_PAUSE_X; | ||
1687 | break; | ||
1688 | case FLOW_MODE_LOC_SEND: | ||
1689 | adv |= PHY_M_P_ASYM_MD_X; | ||
1690 | break; | ||
1691 | case FLOW_MODE_SYMMETRIC: | ||
1692 | adv |= PHY_M_P_SYM_MD_X; | ||
1693 | break; | ||
1694 | case FLOW_MODE_REM_SEND: | ||
1695 | adv |= PHY_M_P_BOTH_MD_X; | ||
1696 | break; | ||
1697 | } | ||
1698 | } | ||
1699 | /* Restart Auto-negotiation */ | 1618 | /* Restart Auto-negotiation */ |
1700 | ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; | 1619 | ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; |
1701 | } else { | 1620 | } else { |
@@ -1717,36 +1636,23 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1717 | ctrl |= PHY_CT_RESET; | 1636 | ctrl |= PHY_CT_RESET; |
1718 | } | 1637 | } |
1719 | 1638 | ||
1720 | if (hw->chip_id != CHIP_ID_YUKON_FE) | 1639 | gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); |
1721 | skge_gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); | ||
1722 | 1640 | ||
1723 | skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); | 1641 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); |
1724 | skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | 1642 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); |
1725 | 1643 | ||
1726 | /* Setup Phy LED's */ | 1644 | /* Setup Phy LED's */ |
1727 | ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); | 1645 | ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); |
1728 | ledover = 0; | 1646 | ledover = 0; |
1729 | 1647 | ||
1730 | if (hw->chip_id == CHIP_ID_YUKON_FE) { | 1648 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; |
1731 | /* on 88E3082 these bits are at 11..9 (shifted left) */ | ||
1732 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1; | ||
1733 | |||
1734 | skge_gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, | ||
1735 | ((skge_gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR) | ||
1736 | |||
1737 | & ~PHY_M_FELP_LED1_MSK) | ||
1738 | | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL))); | ||
1739 | } else { | ||
1740 | /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ | ||
1741 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; | ||
1742 | 1649 | ||
1743 | /* turn off the Rx LED (LED_RX) */ | 1650 | /* turn off the Rx LED (LED_RX) */ |
1744 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | 1651 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
1745 | } | ||
1746 | 1652 | ||
1747 | /* disable blink mode (LED_DUPLEX) on collisions */ | 1653 | /* disable blink mode (LED_DUPLEX) on collisions */ |
1748 | ctrl |= PHY_M_LEDC_DP_CTRL; | 1654 | ctrl |= PHY_M_LEDC_DP_CTRL; |
1749 | skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 1655 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
1750 | 1656 | ||
1751 | if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { | 1657 | if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { |
1752 | /* turn on 100 Mbps LED (LED_LINK100) */ | 1658 | /* turn on 100 Mbps LED (LED_LINK100) */ |
@@ -1754,25 +1660,25 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1754 | } | 1660 | } |
1755 | 1661 | ||
1756 | if (ledover) | 1662 | if (ledover) |
1757 | skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | 1663 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
1758 | 1664 | ||
1759 | /* Enable phy interrupt on autonegotiation complete (or link up) */ | 1665 | /* Enable phy interrupt on autonegotiation complete (or link up) */ |
1760 | if (skge->autoneg == AUTONEG_ENABLE) | 1666 | if (skge->autoneg == AUTONEG_ENABLE) |
1761 | skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); | 1667 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
1762 | else | 1668 | else |
1763 | skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 1669 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
1764 | } | 1670 | } |
1765 | 1671 | ||
1766 | static void yukon_reset(struct skge_hw *hw, int port) | 1672 | static void yukon_reset(struct skge_hw *hw, int port) |
1767 | { | 1673 | { |
1768 | skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */ | 1674 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */ |
1769 | skge_gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ | 1675 | gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ |
1770 | skge_gma_write16(hw, port, GM_MC_ADDR_H2, 0); | 1676 | gma_write16(hw, port, GM_MC_ADDR_H2, 0); |
1771 | skge_gma_write16(hw, port, GM_MC_ADDR_H3, 0); | 1677 | gma_write16(hw, port, GM_MC_ADDR_H3, 0); |
1772 | skge_gma_write16(hw, port, GM_MC_ADDR_H4, 0); | 1678 | gma_write16(hw, port, GM_MC_ADDR_H4, 0); |
1773 | 1679 | ||
1774 | skge_gma_write16(hw, port, GM_RX_CTRL, | 1680 | gma_write16(hw, port, GM_RX_CTRL, |
1775 | skge_gma_read16(hw, port, GM_RX_CTRL) | 1681 | gma_read16(hw, port, GM_RX_CTRL) |
1776 | | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); | 1682 | | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); |
1777 | } | 1683 | } |
1778 | 1684 | ||
@@ -1785,17 +1691,17 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1785 | 1691 | ||
1786 | /* WA code for COMA mode -- set PHY reset */ | 1692 | /* WA code for COMA mode -- set PHY reset */ |
1787 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1693 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1788 | chip_rev(hw) == CHIP_REV_YU_LITE_A3) | 1694 | hw->chip_rev == CHIP_REV_YU_LITE_A3) |
1789 | skge_write32(hw, B2_GP_IO, | 1695 | skge_write32(hw, B2_GP_IO, |
1790 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); | 1696 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); |
1791 | 1697 | ||
1792 | /* hard reset */ | 1698 | /* hard reset */ |
1793 | skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), GPC_RST_SET); | 1699 | skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
1794 | skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_RST_SET); | 1700 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); |
1795 | 1701 | ||
1796 | /* WA code for COMA mode -- clear PHY reset */ | 1702 | /* WA code for COMA mode -- clear PHY reset */ |
1797 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1703 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1798 | chip_rev(hw) == CHIP_REV_YU_LITE_A3) | 1704 | hw->chip_rev == CHIP_REV_YU_LITE_A3) |
1799 | skge_write32(hw, B2_GP_IO, | 1705 | skge_write32(hw, B2_GP_IO, |
1800 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) | 1706 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) |
1801 | & ~GP_IO_9); | 1707 | & ~GP_IO_9); |
@@ -1806,13 +1712,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1806 | reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; | 1712 | reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; |
1807 | 1713 | ||
1808 | /* Clear GMC reset */ | 1714 | /* Clear GMC reset */ |
1809 | skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_SET); | 1715 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); |
1810 | skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); | 1716 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); |
1811 | skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); | 1717 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); |
1812 | if (skge->autoneg == AUTONEG_DISABLE) { | 1718 | if (skge->autoneg == AUTONEG_DISABLE) { |
1813 | reg = GM_GPCR_AU_ALL_DIS; | 1719 | reg = GM_GPCR_AU_ALL_DIS; |
1814 | skge_gma_write16(hw, port, GM_GP_CTRL, | 1720 | gma_write16(hw, port, GM_GP_CTRL, |
1815 | skge_gma_read16(hw, port, GM_GP_CTRL) | reg); | 1721 | gma_read16(hw, port, GM_GP_CTRL) | reg); |
1816 | 1722 | ||
1817 | switch (skge->speed) { | 1723 | switch (skge->speed) { |
1818 | case SPEED_1000: | 1724 | case SPEED_1000: |
@@ -1828,7 +1734,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1828 | reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; | 1734 | reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; |
1829 | switch (skge->flow_control) { | 1735 | switch (skge->flow_control) { |
1830 | case FLOW_MODE_NONE: | 1736 | case FLOW_MODE_NONE: |
1831 | skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1737 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
1832 | reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; | 1738 | reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; |
1833 | break; | 1739 | break; |
1834 | case FLOW_MODE_LOC_SEND: | 1740 | case FLOW_MODE_LOC_SEND: |
@@ -1836,7 +1742,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1836 | reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; | 1742 | reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; |
1837 | } | 1743 | } |
1838 | 1744 | ||
1839 | skge_gma_write16(hw, port, GM_GP_CTRL, reg); | 1745 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1840 | skge_read16(hw, GMAC_IRQ_SRC); | 1746 | skge_read16(hw, GMAC_IRQ_SRC); |
1841 | 1747 | ||
1842 | spin_lock_bh(&hw->phy_lock); | 1748 | spin_lock_bh(&hw->phy_lock); |
@@ -1844,25 +1750,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1844 | spin_unlock_bh(&hw->phy_lock); | 1750 | spin_unlock_bh(&hw->phy_lock); |
1845 | 1751 | ||
1846 | /* MIB clear */ | 1752 | /* MIB clear */ |
1847 | reg = skge_gma_read16(hw, port, GM_PHY_ADDR); | 1753 | reg = gma_read16(hw, port, GM_PHY_ADDR); |
1848 | skge_gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); | 1754 | gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); |
1849 | 1755 | ||
1850 | for (i = 0; i < GM_MIB_CNT_SIZE; i++) | 1756 | for (i = 0; i < GM_MIB_CNT_SIZE; i++) |
1851 | skge_gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i); | 1757 | gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i); |
1852 | skge_gma_write16(hw, port, GM_PHY_ADDR, reg); | 1758 | gma_write16(hw, port, GM_PHY_ADDR, reg); |
1853 | 1759 | ||
1854 | /* transmit control */ | 1760 | /* transmit control */ |
1855 | skge_gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF)); | 1761 | gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF)); |
1856 | 1762 | ||
1857 | /* receive control reg: unicast + multicast + no FCS */ | 1763 | /* receive control reg: unicast + multicast + no FCS */ |
1858 | skge_gma_write16(hw, port, GM_RX_CTRL, | 1764 | gma_write16(hw, port, GM_RX_CTRL, |
1859 | GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA); | 1765 | GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA); |
1860 | 1766 | ||
1861 | /* transmit flow control */ | 1767 | /* transmit flow control */ |
1862 | skge_gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff); | 1768 | gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff); |
1863 | 1769 | ||
1864 | /* transmit parameter */ | 1770 | /* transmit parameter */ |
1865 | skge_gma_write16(hw, port, GM_TX_PARAM, | 1771 | gma_write16(hw, port, GM_TX_PARAM, |
1866 | TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) | | 1772 | TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) | |
1867 | TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) | | 1773 | TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) | |
1868 | TX_IPG_JAM_DATA(TX_IPG_JAM_DEF)); | 1774 | TX_IPG_JAM_DATA(TX_IPG_JAM_DEF)); |
@@ -1872,33 +1778,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1872 | if (hw->dev[port]->mtu > 1500) | 1778 | if (hw->dev[port]->mtu > 1500) |
1873 | reg |= GM_SMOD_JUMBO_ENA; | 1779 | reg |= GM_SMOD_JUMBO_ENA; |
1874 | 1780 | ||
1875 | skge_gma_write16(hw, port, GM_SERIAL_MODE, reg); | 1781 | gma_write16(hw, port, GM_SERIAL_MODE, reg); |
1876 | 1782 | ||
1877 | /* physical address: used for pause frames */ | 1783 | /* physical address: used for pause frames */ |
1878 | skge_gm_set_addr(hw, port, GM_SRC_ADDR_1L, addr); | 1784 | gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr); |
1879 | /* virtual address for data */ | 1785 | /* virtual address for data */ |
1880 | skge_gm_set_addr(hw, port, GM_SRC_ADDR_2L, addr); | 1786 | gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr); |
1881 | 1787 | ||
1882 | /* enable interrupt mask for counter overflows */ | 1788 | /* enable interrupt mask for counter overflows */ |
1883 | skge_gma_write16(hw, port, GM_TX_IRQ_MSK, 0); | 1789 | gma_write16(hw, port, GM_TX_IRQ_MSK, 0); |
1884 | skge_gma_write16(hw, port, GM_RX_IRQ_MSK, 0); | 1790 | gma_write16(hw, port, GM_RX_IRQ_MSK, 0); |
1885 | skge_gma_write16(hw, port, GM_TR_IRQ_MSK, 0); | 1791 | gma_write16(hw, port, GM_TR_IRQ_MSK, 0); |
1886 | 1792 | ||
1887 | /* Initialize Mac Fifo */ | 1793 | /* Initialize Mac Fifo */ |
1888 | 1794 | ||
1889 | /* Configure Rx MAC FIFO */ | 1795 | /* Configure Rx MAC FIFO */ |
1890 | skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); | 1796 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); |
1891 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 1797 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
1892 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1798 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1893 | chip_rev(hw) == CHIP_REV_YU_LITE_A3) | 1799 | hw->chip_rev == CHIP_REV_YU_LITE_A3) |
1894 | reg &= ~GMF_RX_F_FL_ON; | 1800 | reg &= ~GMF_RX_F_FL_ON; |
1895 | skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 1801 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
1896 | skge_write16(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), reg); | 1802 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); |
1897 | skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); | 1803 | skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); |
1898 | 1804 | ||
1899 | /* Configure Tx MAC FIFO */ | 1805 | /* Configure Tx MAC FIFO */ |
1900 | skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); | 1806 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); |
1901 | skge_write16(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); | 1807 | skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); |
1902 | } | 1808 | } |
1903 | 1809 | ||
1904 | static void yukon_stop(struct skge_port *skge) | 1810 | static void yukon_stop(struct skge_port *skge) |
@@ -1907,19 +1813,19 @@ static void yukon_stop(struct skge_port *skge) | |||
1907 | int port = skge->port; | 1813 | int port = skge->port; |
1908 | 1814 | ||
1909 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1815 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1910 | chip_rev(hw) == CHIP_REV_YU_LITE_A3) { | 1816 | hw->chip_rev == CHIP_REV_YU_LITE_A3) { |
1911 | skge_write32(hw, B2_GP_IO, | 1817 | skge_write32(hw, B2_GP_IO, |
1912 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); | 1818 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); |
1913 | } | 1819 | } |
1914 | 1820 | ||
1915 | skge_gma_write16(hw, port, GM_GP_CTRL, | 1821 | gma_write16(hw, port, GM_GP_CTRL, |
1916 | skge_gma_read16(hw, port, GM_GP_CTRL) | 1822 | gma_read16(hw, port, GM_GP_CTRL) |
1917 | & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA)); | 1823 | & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA)); |
1918 | skge_gma_read16(hw, port, GM_GP_CTRL); | 1824 | gma_read16(hw, port, GM_GP_CTRL); |
1919 | 1825 | ||
1920 | /* set GPHY Control reset */ | 1826 | /* set GPHY Control reset */ |
1921 | skge_gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); | 1827 | gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); |
1922 | skge_gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); | 1828 | gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); |
1923 | } | 1829 | } |
1924 | 1830 | ||
1925 | static void yukon_get_stats(struct skge_port *skge, u64 *data) | 1831 | static void yukon_get_stats(struct skge_port *skge, u64 *data) |
@@ -1928,39 +1834,40 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data) | |||
1928 | int port = skge->port; | 1834 | int port = skge->port; |
1929 | int i; | 1835 | int i; |
1930 | 1836 | ||
1931 | data[0] = (u64) skge_gma_read32(hw, port, GM_TXO_OK_HI) << 32 | 1837 | data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32 |
1932 | | skge_gma_read32(hw, port, GM_TXO_OK_LO); | 1838 | | gma_read32(hw, port, GM_TXO_OK_LO); |
1933 | data[1] = (u64) skge_gma_read32(hw, port, GM_RXO_OK_HI) << 32 | 1839 | data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32 |
1934 | | skge_gma_read32(hw, port, GM_RXO_OK_LO); | 1840 | | gma_read32(hw, port, GM_RXO_OK_LO); |
1935 | 1841 | ||
1936 | for (i = 2; i < ARRAY_SIZE(skge_stats); i++) | 1842 | for (i = 2; i < ARRAY_SIZE(skge_stats); i++) |
1937 | data[i] = skge_gma_read32(hw, port, | 1843 | data[i] = gma_read32(hw, port, |
1938 | skge_stats[i].gma_offset); | 1844 | skge_stats[i].gma_offset); |
1939 | } | 1845 | } |
1940 | 1846 | ||
1941 | static void yukon_mac_intr(struct skge_hw *hw, int port) | 1847 | static void yukon_mac_intr(struct skge_hw *hw, int port) |
1942 | { | 1848 | { |
1943 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1849 | struct net_device *dev = hw->dev[port]; |
1944 | u8 status = skge_read8(hw, SKGEMAC_REG(port, GMAC_IRQ_SRC)); | 1850 | struct skge_port *skge = netdev_priv(dev); |
1851 | u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); | ||
1852 | |||
1853 | if (netif_msg_intr(skge)) | ||
1854 | printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", | ||
1855 | dev->name, status); | ||
1945 | 1856 | ||
1946 | pr_debug("yukon_intr status %x\n", status); | ||
1947 | if (status & GM_IS_RX_FF_OR) { | 1857 | if (status & GM_IS_RX_FF_OR) { |
1948 | ++skge->net_stats.rx_fifo_errors; | 1858 | ++skge->net_stats.rx_fifo_errors; |
1949 | skge_gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); | 1859 | gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); |
1950 | } | 1860 | } |
1951 | if (status & GM_IS_TX_FF_UR) { | 1861 | if (status & GM_IS_TX_FF_UR) { |
1952 | ++skge->net_stats.tx_fifo_errors; | 1862 | ++skge->net_stats.tx_fifo_errors; |
1953 | skge_gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); | 1863 | gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); |
1954 | } | 1864 | } |
1955 | 1865 | ||
1956 | } | 1866 | } |
1957 | 1867 | ||
1958 | static u16 yukon_speed(const struct skge_hw *hw, u16 aux) | 1868 | static u16 yukon_speed(const struct skge_hw *hw, u16 aux) |
1959 | { | 1869 | { |
1960 | if (hw->chip_id == CHIP_ID_YUKON_FE) | 1870 | switch (aux & PHY_M_PS_SPEED_MSK) { |
1961 | return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; | ||
1962 | |||
1963 | switch(aux & PHY_M_PS_SPEED_MSK) { | ||
1964 | case PHY_M_PS_SPEED_1000: | 1871 | case PHY_M_PS_SPEED_1000: |
1965 | return SPEED_1000; | 1872 | return SPEED_1000; |
1966 | case PHY_M_PS_SPEED_100: | 1873 | case PHY_M_PS_SPEED_100: |
@@ -1981,15 +1888,15 @@ static void yukon_link_up(struct skge_port *skge) | |||
1981 | /* Enable Transmit FIFO Underrun */ | 1888 | /* Enable Transmit FIFO Underrun */ |
1982 | skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK); | 1889 | skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK); |
1983 | 1890 | ||
1984 | reg = skge_gma_read16(hw, port, GM_GP_CTRL); | 1891 | reg = gma_read16(hw, port, GM_GP_CTRL); |
1985 | if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) | 1892 | if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) |
1986 | reg |= GM_GPCR_DUP_FULL; | 1893 | reg |= GM_GPCR_DUP_FULL; |
1987 | 1894 | ||
1988 | /* enable Rx/Tx */ | 1895 | /* enable Rx/Tx */ |
1989 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; | 1896 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; |
1990 | skge_gma_write16(hw, port, GM_GP_CTRL, reg); | 1897 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1991 | 1898 | ||
1992 | skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 1899 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
1993 | skge_link_up(skge); | 1900 | skge_link_up(skge); |
1994 | } | 1901 | } |
1995 | 1902 | ||
@@ -1999,16 +1906,15 @@ static void yukon_link_down(struct skge_port *skge) | |||
1999 | int port = skge->port; | 1906 | int port = skge->port; |
2000 | 1907 | ||
2001 | pr_debug("yukon_link_down\n"); | 1908 | pr_debug("yukon_link_down\n"); |
2002 | skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); | 1909 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); |
2003 | skge_gm_phy_write(hw, port, GM_GP_CTRL, | 1910 | gm_phy_write(hw, port, GM_GP_CTRL, |
2004 | skge_gm_phy_read(hw, port, GM_GP_CTRL) | 1911 | gm_phy_read(hw, port, GM_GP_CTRL) |
2005 | & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); | 1912 | & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); |
2006 | 1913 | ||
2007 | if (hw->chip_id != CHIP_ID_YUKON_FE && | 1914 | if (skge->flow_control == FLOW_MODE_REM_SEND) { |
2008 | skge->flow_control == FLOW_MODE_REM_SEND) { | ||
2009 | /* restore Asymmetric Pause bit */ | 1915 | /* restore Asymmetric Pause bit */ |
2010 | skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, | 1916 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, |
2011 | skge_gm_phy_read(hw, port, | 1917 | gm_phy_read(hw, port, |
2012 | PHY_MARV_AUNE_ADV) | 1918 | PHY_MARV_AUNE_ADV) |
2013 | | PHY_M_AN_ASP); | 1919 | | PHY_M_AN_ASP); |
2014 | 1920 | ||
@@ -2027,20 +1933,21 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
2027 | const char *reason = NULL; | 1933 | const char *reason = NULL; |
2028 | u16 istatus, phystat; | 1934 | u16 istatus, phystat; |
2029 | 1935 | ||
2030 | istatus = skge_gm_phy_read(hw, port, PHY_MARV_INT_STAT); | 1936 | istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); |
2031 | phystat = skge_gm_phy_read(hw, port, PHY_MARV_PHY_STAT); | 1937 | phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); |
2032 | pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat); | 1938 | |
1939 | if (netif_msg_intr(skge)) | ||
1940 | printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n", | ||
1941 | skge->netdev->name, istatus, phystat); | ||
2033 | 1942 | ||
2034 | if (istatus & PHY_M_IS_AN_COMPL) { | 1943 | if (istatus & PHY_M_IS_AN_COMPL) { |
2035 | if (skge_gm_phy_read(hw, port, PHY_MARV_AUNE_LP) | 1944 | if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP) |
2036 | & PHY_M_AN_RF) { | 1945 | & PHY_M_AN_RF) { |
2037 | reason = "remote fault"; | 1946 | reason = "remote fault"; |
2038 | goto failed; | 1947 | goto failed; |
2039 | } | 1948 | } |
2040 | 1949 | ||
2041 | if (!(hw->chip_id == CHIP_ID_YUKON_FE || hw->chip_id == CHIP_ID_YUKON_EC) | 1950 | if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) { |
2042 | && (skge_gm_phy_read(hw, port, PHY_MARV_1000T_STAT) | ||
2043 | & PHY_B_1000S_MSF)) { | ||
2044 | reason = "master/slave fault"; | 1951 | reason = "master/slave fault"; |
2045 | goto failed; | 1952 | goto failed; |
2046 | } | 1953 | } |
@@ -2054,10 +1961,6 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
2054 | ? DUPLEX_FULL : DUPLEX_HALF; | 1961 | ? DUPLEX_FULL : DUPLEX_HALF; |
2055 | skge->speed = yukon_speed(hw, phystat); | 1962 | skge->speed = yukon_speed(hw, phystat); |
2056 | 1963 | ||
2057 | /* Tx & Rx Pause Enabled bits are at 9..8 */ | ||
2058 | if (hw->chip_id == CHIP_ID_YUKON_XL) | ||
2059 | phystat >>= 6; | ||
2060 | |||
2061 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | 1964 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ |
2062 | switch (phystat & PHY_M_PS_PAUSE_MSK) { | 1965 | switch (phystat & PHY_M_PS_PAUSE_MSK) { |
2063 | case PHY_M_PS_PAUSE_MSK: | 1966 | case PHY_M_PS_PAUSE_MSK: |
@@ -2075,9 +1978,9 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
2075 | 1978 | ||
2076 | if (skge->flow_control == FLOW_MODE_NONE || | 1979 | if (skge->flow_control == FLOW_MODE_NONE || |
2077 | (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) | 1980 | (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) |
2078 | skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1981 | skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
2079 | else | 1982 | else |
2080 | skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON); | 1983 | skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
2081 | yukon_link_up(skge); | 1984 | yukon_link_up(skge); |
2082 | return; | 1985 | return; |
2083 | } | 1986 | } |
@@ -2161,6 +2064,12 @@ static int skge_up(struct net_device *dev) | |||
2161 | if (netif_msg_ifup(skge)) | 2064 | if (netif_msg_ifup(skge)) |
2162 | printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); | 2065 | printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); |
2163 | 2066 | ||
2067 | if (dev->mtu > RX_BUF_SIZE) | ||
2068 | skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN; | ||
2069 | else | ||
2070 | skge->rx_buf_size = RX_BUF_SIZE; | ||
2071 | |||
2072 | |||
2164 | rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc); | 2073 | rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc); |
2165 | tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc); | 2074 | tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc); |
2166 | skge->mem_size = tx_size + rx_size; | 2075 | skge->mem_size = tx_size + rx_size; |
@@ -2173,7 +2082,8 @@ static int skge_up(struct net_device *dev) | |||
2173 | if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma))) | 2082 | if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma))) |
2174 | goto free_pci_mem; | 2083 | goto free_pci_mem; |
2175 | 2084 | ||
2176 | if (skge_rx_fill(skge)) | 2085 | err = skge_rx_fill(skge); |
2086 | if (err) | ||
2177 | goto free_rx_ring; | 2087 | goto free_rx_ring; |
2178 | 2088 | ||
2179 | if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size, | 2089 | if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size, |
@@ -2182,6 +2092,10 @@ static int skge_up(struct net_device *dev) | |||
2182 | 2092 | ||
2183 | skge->tx_avail = skge->tx_ring.count - 1; | 2093 | skge->tx_avail = skge->tx_ring.count - 1; |
2184 | 2094 | ||
2095 | /* Enable IRQ from port */ | ||
2096 | hw->intr_mask |= portirqmask[port]; | ||
2097 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2098 | |||
2185 | /* Initialze MAC */ | 2099 | /* Initialze MAC */ |
2186 | if (hw->chip_id == CHIP_ID_GENESIS) | 2100 | if (hw->chip_id == CHIP_ID_GENESIS) |
2187 | genesis_mac_init(hw, port); | 2101 | genesis_mac_init(hw, port); |
@@ -2189,7 +2103,7 @@ static int skge_up(struct net_device *dev) | |||
2189 | yukon_mac_init(hw, port); | 2103 | yukon_mac_init(hw, port); |
2190 | 2104 | ||
2191 | /* Configure RAMbuffers */ | 2105 | /* Configure RAMbuffers */ |
2192 | chunk = hw->ram_size / (isdualport(hw) ? 4 : 2); | 2106 | chunk = hw->ram_size / ((hw->ports + 1)*2); |
2193 | ram_addr = hw->ram_offset + 2 * chunk * port; | 2107 | ram_addr = hw->ram_offset + 2 * chunk * port; |
2194 | 2108 | ||
2195 | skge_ramset(hw, rxqaddr[port], ram_addr, chunk); | 2109 | skge_ramset(hw, rxqaddr[port], ram_addr, chunk); |
@@ -2227,7 +2141,6 @@ static int skge_down(struct net_device *dev) | |||
2227 | netif_stop_queue(dev); | 2141 | netif_stop_queue(dev); |
2228 | 2142 | ||
2229 | del_timer_sync(&skge->led_blink); | 2143 | del_timer_sync(&skge->led_blink); |
2230 | del_timer_sync(&skge->link_check); | ||
2231 | 2144 | ||
2232 | /* Stop transmitter */ | 2145 | /* Stop transmitter */ |
2233 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2146 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
@@ -2240,12 +2153,12 @@ static int skge_down(struct net_device *dev) | |||
2240 | yukon_stop(skge); | 2153 | yukon_stop(skge); |
2241 | 2154 | ||
2242 | /* Disable Force Sync bit and Enable Alloc bit */ | 2155 | /* Disable Force Sync bit and Enable Alloc bit */ |
2243 | skge_write8(hw, SKGEMAC_REG(port, TXA_CTRL), | 2156 | skge_write8(hw, SK_REG(port, TXA_CTRL), |
2244 | TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); | 2157 | TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); |
2245 | 2158 | ||
2246 | /* Stop Interval Timer and Limit Counter of Tx Arbiter */ | 2159 | /* Stop Interval Timer and Limit Counter of Tx Arbiter */ |
2247 | skge_write32(hw, SKGEMAC_REG(port, TXA_ITI_INI), 0L); | 2160 | skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L); |
2248 | skge_write32(hw, SKGEMAC_REG(port, TXA_LIM_INI), 0L); | 2161 | skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L); |
2249 | 2162 | ||
2250 | /* Reset PCI FIFO */ | 2163 | /* Reset PCI FIFO */ |
2251 | skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET); | 2164 | skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET); |
@@ -2260,13 +2173,13 @@ static int skge_down(struct net_device *dev) | |||
2260 | skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET); | 2173 | skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET); |
2261 | 2174 | ||
2262 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2175 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2263 | skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_SET); | 2176 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); |
2264 | skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_SET); | 2177 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); |
2265 | skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_STOP); | 2178 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP); |
2266 | skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_STOP); | 2179 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP); |
2267 | } else { | 2180 | } else { |
2268 | skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 2181 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
2269 | skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 2182 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
2270 | } | 2183 | } |
2271 | 2184 | ||
2272 | /* turn off led's */ | 2185 | /* turn off led's */ |
@@ -2299,10 +2212,10 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
2299 | 2212 | ||
2300 | local_irq_save(flags); | 2213 | local_irq_save(flags); |
2301 | if (!spin_trylock(&skge->tx_lock)) { | 2214 | if (!spin_trylock(&skge->tx_lock)) { |
2302 | /* Collision - tell upper layer to requeue */ | 2215 | /* Collision - tell upper layer to requeue */ |
2303 | local_irq_restore(flags); | 2216 | local_irq_restore(flags); |
2304 | return NETDEV_TX_LOCKED; | 2217 | return NETDEV_TX_LOCKED; |
2305 | } | 2218 | } |
2306 | 2219 | ||
2307 | if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { | 2220 | if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { |
2308 | netif_stop_queue(dev); | 2221 | netif_stop_queue(dev); |
@@ -2333,7 +2246,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
2333 | * does. Looks like hardware is wrong? | 2246 | * does. Looks like hardware is wrong? |
2334 | */ | 2247 | */ |
2335 | if (ip->protocol == IPPROTO_UDP | 2248 | if (ip->protocol == IPPROTO_UDP |
2336 | && chip_rev(hw) == 0 && hw->chip_id == CHIP_ID_YUKON) | 2249 | && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON) |
2337 | control = BMU_TCP_CHECK; | 2250 | control = BMU_TCP_CHECK; |
2338 | else | 2251 | else |
2339 | control = BMU_UDP_CHECK; | 2252 | control = BMU_UDP_CHECK; |
@@ -2394,6 +2307,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
2394 | 2307 | ||
2395 | static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e) | 2308 | static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e) |
2396 | { | 2309 | { |
2310 | /* This ring element can be skb or fragment */ | ||
2397 | if (e->skb) { | 2311 | if (e->skb) { |
2398 | pci_unmap_single(hw->pdev, | 2312 | pci_unmap_single(hw->pdev, |
2399 | pci_unmap_addr(e, mapaddr), | 2313 | pci_unmap_addr(e, mapaddr), |
@@ -2438,16 +2352,17 @@ static void skge_tx_timeout(struct net_device *dev) | |||
2438 | static int skge_change_mtu(struct net_device *dev, int new_mtu) | 2352 | static int skge_change_mtu(struct net_device *dev, int new_mtu) |
2439 | { | 2353 | { |
2440 | int err = 0; | 2354 | int err = 0; |
2355 | int running = netif_running(dev); | ||
2441 | 2356 | ||
2442 | if(new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 2357 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
2443 | return -EINVAL; | 2358 | return -EINVAL; |
2444 | 2359 | ||
2445 | dev->mtu = new_mtu; | ||
2446 | 2360 | ||
2447 | if (netif_running(dev)) { | 2361 | if (running) |
2448 | skge_down(dev); | 2362 | skge_down(dev); |
2363 | dev->mtu = new_mtu; | ||
2364 | if (running) | ||
2449 | skge_up(dev); | 2365 | skge_up(dev); |
2450 | } | ||
2451 | 2366 | ||
2452 | return err; | 2367 | return err; |
2453 | } | 2368 | } |
@@ -2462,7 +2377,9 @@ static void genesis_set_multicast(struct net_device *dev) | |||
2462 | u32 mode; | 2377 | u32 mode; |
2463 | u8 filter[8]; | 2378 | u8 filter[8]; |
2464 | 2379 | ||
2465 | mode = skge_xm_read32(hw, port, XM_MODE); | 2380 | pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count); |
2381 | |||
2382 | mode = xm_read32(hw, port, XM_MODE); | ||
2466 | mode |= XM_MD_ENA_HASH; | 2383 | mode |= XM_MD_ENA_HASH; |
2467 | if (dev->flags & IFF_PROMISC) | 2384 | if (dev->flags & IFF_PROMISC) |
2468 | mode |= XM_MD_ENA_PROM; | 2385 | mode |= XM_MD_ENA_PROM; |
@@ -2473,17 +2390,16 @@ static void genesis_set_multicast(struct net_device *dev) | |||
2473 | memset(filter, 0xff, sizeof(filter)); | 2390 | memset(filter, 0xff, sizeof(filter)); |
2474 | else { | 2391 | else { |
2475 | memset(filter, 0, sizeof(filter)); | 2392 | memset(filter, 0, sizeof(filter)); |
2476 | for(i = 0; list && i < count; i++, list = list->next) { | 2393 | for (i = 0; list && i < count; i++, list = list->next) { |
2477 | u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN); | 2394 | u32 crc, bit; |
2478 | u8 bit = 63 - (crc & 63); | 2395 | crc = ether_crc_le(ETH_ALEN, list->dmi_addr); |
2479 | 2396 | bit = ~crc & 0x3f; | |
2480 | filter[bit/8] |= 1 << (bit%8); | 2397 | filter[bit/8] |= 1 << (bit%8); |
2481 | } | 2398 | } |
2482 | } | 2399 | } |
2483 | 2400 | ||
2484 | skge_xm_outhash(hw, port, XM_HSM, filter); | 2401 | xm_write32(hw, port, XM_MODE, mode); |
2485 | 2402 | xm_outhash(hw, port, XM_HSM, filter); | |
2486 | skge_xm_write32(hw, port, XM_MODE, mode); | ||
2487 | } | 2403 | } |
2488 | 2404 | ||
2489 | static void yukon_set_multicast(struct net_device *dev) | 2405 | static void yukon_set_multicast(struct net_device *dev) |
@@ -2497,7 +2413,7 @@ static void yukon_set_multicast(struct net_device *dev) | |||
2497 | 2413 | ||
2498 | memset(filter, 0, sizeof(filter)); | 2414 | memset(filter, 0, sizeof(filter)); |
2499 | 2415 | ||
2500 | reg = skge_gma_read16(hw, port, GM_RX_CTRL); | 2416 | reg = gma_read16(hw, port, GM_RX_CTRL); |
2501 | reg |= GM_RXCR_UCF_ENA; | 2417 | reg |= GM_RXCR_UCF_ENA; |
2502 | 2418 | ||
2503 | if (dev->flags & IFF_PROMISC) /* promiscious */ | 2419 | if (dev->flags & IFF_PROMISC) /* promiscious */ |
@@ -2510,23 +2426,23 @@ static void yukon_set_multicast(struct net_device *dev) | |||
2510 | int i; | 2426 | int i; |
2511 | reg |= GM_RXCR_MCF_ENA; | 2427 | reg |= GM_RXCR_MCF_ENA; |
2512 | 2428 | ||
2513 | for(i = 0; list && i < dev->mc_count; i++, list = list->next) { | 2429 | for (i = 0; list && i < dev->mc_count; i++, list = list->next) { |
2514 | u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f; | 2430 | u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f; |
2515 | filter[bit/8] |= 1 << (bit%8); | 2431 | filter[bit/8] |= 1 << (bit%8); |
2516 | } | 2432 | } |
2517 | } | 2433 | } |
2518 | 2434 | ||
2519 | 2435 | ||
2520 | skge_gma_write16(hw, port, GM_MC_ADDR_H1, | 2436 | gma_write16(hw, port, GM_MC_ADDR_H1, |
2521 | (u16)filter[0] | ((u16)filter[1] << 8)); | 2437 | (u16)filter[0] | ((u16)filter[1] << 8)); |
2522 | skge_gma_write16(hw, port, GM_MC_ADDR_H2, | 2438 | gma_write16(hw, port, GM_MC_ADDR_H2, |
2523 | (u16)filter[2] | ((u16)filter[3] << 8)); | 2439 | (u16)filter[2] | ((u16)filter[3] << 8)); |
2524 | skge_gma_write16(hw, port, GM_MC_ADDR_H3, | 2440 | gma_write16(hw, port, GM_MC_ADDR_H3, |
2525 | (u16)filter[4] | ((u16)filter[5] << 8)); | 2441 | (u16)filter[4] | ((u16)filter[5] << 8)); |
2526 | skge_gma_write16(hw, port, GM_MC_ADDR_H4, | 2442 | gma_write16(hw, port, GM_MC_ADDR_H4, |
2527 | (u16)filter[6] | ((u16)filter[7] << 8)); | 2443 | (u16)filter[6] | ((u16)filter[7] << 8)); |
2528 | 2444 | ||
2529 | skge_gma_write16(hw, port, GM_RX_CTRL, reg); | 2445 | gma_write16(hw, port, GM_RX_CTRL, reg); |
2530 | } | 2446 | } |
2531 | 2447 | ||
2532 | static inline int bad_phy_status(const struct skge_hw *hw, u32 status) | 2448 | static inline int bad_phy_status(const struct skge_hw *hw, u32 status) |
@@ -2545,28 +2461,76 @@ static void skge_rx_error(struct skge_port *skge, int slot, | |||
2545 | printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n", | 2461 | printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n", |
2546 | skge->netdev->name, slot, control, status); | 2462 | skge->netdev->name, slot, control, status); |
2547 | 2463 | ||
2548 | if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) | 2464 | if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)) |
2549 | || (control & BMU_BBC) > skge->netdev->mtu + VLAN_ETH_HLEN) | ||
2550 | skge->net_stats.rx_length_errors++; | 2465 | skge->net_stats.rx_length_errors++; |
2551 | else { | 2466 | else if (skge->hw->chip_id == CHIP_ID_GENESIS) { |
2552 | if (skge->hw->chip_id == CHIP_ID_GENESIS) { | 2467 | if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) |
2553 | if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) | 2468 | skge->net_stats.rx_length_errors++; |
2554 | skge->net_stats.rx_length_errors++; | 2469 | if (status & XMR_FS_FRA_ERR) |
2555 | if (status & XMR_FS_FRA_ERR) | 2470 | skge->net_stats.rx_frame_errors++; |
2556 | skge->net_stats.rx_frame_errors++; | 2471 | if (status & XMR_FS_FCS_ERR) |
2557 | if (status & XMR_FS_FCS_ERR) | 2472 | skge->net_stats.rx_crc_errors++; |
2558 | skge->net_stats.rx_crc_errors++; | 2473 | } else { |
2559 | } else { | 2474 | if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) |
2560 | if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) | 2475 | skge->net_stats.rx_length_errors++; |
2561 | skge->net_stats.rx_length_errors++; | 2476 | if (status & GMR_FS_FRAGMENT) |
2562 | if (status & GMR_FS_FRAGMENT) | 2477 | skge->net_stats.rx_frame_errors++; |
2563 | skge->net_stats.rx_frame_errors++; | 2478 | if (status & GMR_FS_CRC_ERR) |
2564 | if (status & GMR_FS_CRC_ERR) | 2479 | skge->net_stats.rx_crc_errors++; |
2565 | skge->net_stats.rx_crc_errors++; | 2480 | } |
2481 | } | ||
2482 | |||
2483 | /* Get receive buffer from descriptor. | ||
2484 | * Handles copy of small buffers and reallocation failures | ||
2485 | */ | ||
2486 | static inline struct sk_buff *skge_rx_get(struct skge_port *skge, | ||
2487 | struct skge_element *e, | ||
2488 | unsigned int len) | ||
2489 | { | ||
2490 | struct sk_buff *nskb, *skb; | ||
2491 | |||
2492 | if (len < RX_COPY_THRESHOLD) { | ||
2493 | nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN); | ||
2494 | if (unlikely(!nskb)) | ||
2495 | return NULL; | ||
2496 | |||
2497 | pci_dma_sync_single_for_cpu(skge->hw->pdev, | ||
2498 | pci_unmap_addr(e, mapaddr), | ||
2499 | len, PCI_DMA_FROMDEVICE); | ||
2500 | memcpy(nskb->data, e->skb->data, len); | ||
2501 | pci_dma_sync_single_for_device(skge->hw->pdev, | ||
2502 | pci_unmap_addr(e, mapaddr), | ||
2503 | len, PCI_DMA_FROMDEVICE); | ||
2504 | |||
2505 | if (skge->rx_csum) { | ||
2506 | struct skge_rx_desc *rd = e->desc; | ||
2507 | nskb->csum = le16_to_cpu(rd->csum2); | ||
2508 | nskb->ip_summed = CHECKSUM_HW; | ||
2566 | } | 2509 | } |
2510 | skge_rx_reuse(e, skge->rx_buf_size); | ||
2511 | return nskb; | ||
2512 | } else { | ||
2513 | nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size); | ||
2514 | if (unlikely(!nskb)) | ||
2515 | return NULL; | ||
2516 | |||
2517 | pci_unmap_single(skge->hw->pdev, | ||
2518 | pci_unmap_addr(e, mapaddr), | ||
2519 | pci_unmap_len(e, maplen), | ||
2520 | PCI_DMA_FROMDEVICE); | ||
2521 | skb = e->skb; | ||
2522 | if (skge->rx_csum) { | ||
2523 | struct skge_rx_desc *rd = e->desc; | ||
2524 | skb->csum = le16_to_cpu(rd->csum2); | ||
2525 | skb->ip_summed = CHECKSUM_HW; | ||
2526 | } | ||
2527 | |||
2528 | skge_rx_setup(skge, e, nskb, skge->rx_buf_size); | ||
2529 | return skb; | ||
2567 | } | 2530 | } |
2568 | } | 2531 | } |
2569 | 2532 | ||
2533 | |||
2570 | static int skge_poll(struct net_device *dev, int *budget) | 2534 | static int skge_poll(struct net_device *dev, int *budget) |
2571 | { | 2535 | { |
2572 | struct skge_port *skge = netdev_priv(dev); | 2536 | struct skge_port *skge = netdev_priv(dev); |
@@ -2575,13 +2539,12 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2575 | struct skge_element *e; | 2539 | struct skge_element *e; |
2576 | unsigned int to_do = min(dev->quota, *budget); | 2540 | unsigned int to_do = min(dev->quota, *budget); |
2577 | unsigned int work_done = 0; | 2541 | unsigned int work_done = 0; |
2578 | int done; | ||
2579 | static const u32 irqmask[] = { IS_PORT_1, IS_PORT_2 }; | ||
2580 | 2542 | ||
2581 | for (e = ring->to_clean; e != ring->to_use && work_done < to_do; | 2543 | pr_debug("skge_poll\n"); |
2582 | e = e->next) { | 2544 | |
2545 | for (e = ring->to_clean; work_done < to_do; e = e->next) { | ||
2583 | struct skge_rx_desc *rd = e->desc; | 2546 | struct skge_rx_desc *rd = e->desc; |
2584 | struct sk_buff *skb = e->skb; | 2547 | struct sk_buff *skb; |
2585 | u32 control, len, status; | 2548 | u32 control, len, status; |
2586 | 2549 | ||
2587 | rmb(); | 2550 | rmb(); |
@@ -2590,19 +2553,12 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2590 | break; | 2553 | break; |
2591 | 2554 | ||
2592 | len = control & BMU_BBC; | 2555 | len = control & BMU_BBC; |
2593 | e->skb = NULL; | ||
2594 | |||
2595 | pci_unmap_single(hw->pdev, | ||
2596 | pci_unmap_addr(e, mapaddr), | ||
2597 | pci_unmap_len(e, maplen), | ||
2598 | PCI_DMA_FROMDEVICE); | ||
2599 | |||
2600 | status = rd->status; | 2556 | status = rd->status; |
2601 | if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) | 2557 | |
2602 | || len > dev->mtu + VLAN_ETH_HLEN | 2558 | if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) |
2603 | || bad_phy_status(hw, status)) { | 2559 | || bad_phy_status(hw, status))) { |
2604 | skge_rx_error(skge, e - ring->start, control, status); | 2560 | skge_rx_error(skge, e - ring->start, control, status); |
2605 | dev_kfree_skb(skb); | 2561 | skge_rx_reuse(e, skge->rx_buf_size); |
2606 | continue; | 2562 | continue; |
2607 | } | 2563 | } |
2608 | 2564 | ||
@@ -2610,43 +2566,37 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2610 | printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n", | 2566 | printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n", |
2611 | dev->name, e - ring->start, rd->status, len); | 2567 | dev->name, e - ring->start, rd->status, len); |
2612 | 2568 | ||
2613 | skb_put(skb, len); | 2569 | skb = skge_rx_get(skge, e, len); |
2614 | skb->protocol = eth_type_trans(skb, dev); | 2570 | if (likely(skb)) { |
2615 | 2571 | skb_put(skb, len); | |
2616 | if (skge->rx_csum) { | 2572 | skb->protocol = eth_type_trans(skb, dev); |
2617 | skb->csum = le16_to_cpu(rd->csum2); | ||
2618 | skb->ip_summed = CHECKSUM_HW; | ||
2619 | } | ||
2620 | 2573 | ||
2621 | dev->last_rx = jiffies; | 2574 | dev->last_rx = jiffies; |
2622 | netif_receive_skb(skb); | 2575 | netif_receive_skb(skb); |
2623 | 2576 | ||
2624 | ++work_done; | 2577 | ++work_done; |
2578 | } else | ||
2579 | skge_rx_reuse(e, skge->rx_buf_size); | ||
2625 | } | 2580 | } |
2626 | ring->to_clean = e; | 2581 | ring->to_clean = e; |
2627 | 2582 | ||
2628 | *budget -= work_done; | ||
2629 | dev->quota -= work_done; | ||
2630 | done = work_done < to_do; | ||
2631 | |||
2632 | if (skge_rx_fill(skge)) | ||
2633 | done = 0; | ||
2634 | |||
2635 | /* restart receiver */ | 2583 | /* restart receiver */ |
2636 | wmb(); | 2584 | wmb(); |
2637 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), | 2585 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), |
2638 | CSR_START | CSR_IRQ_CL_F); | 2586 | CSR_START | CSR_IRQ_CL_F); |
2639 | 2587 | ||
2640 | if (done) { | 2588 | *budget -= work_done; |
2641 | local_irq_disable(); | 2589 | dev->quota -= work_done; |
2642 | hw->intr_mask |= irqmask[skge->port]; | ||
2643 | /* Order is important since data can get interrupted */ | ||
2644 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2645 | __netif_rx_complete(dev); | ||
2646 | local_irq_enable(); | ||
2647 | } | ||
2648 | 2590 | ||
2649 | return !done; | 2591 | if (work_done >= to_do) |
2592 | return 1; /* not done */ | ||
2593 | |||
2594 | local_irq_disable(); | ||
2595 | __netif_rx_complete(dev); | ||
2596 | hw->intr_mask |= portirqmask[skge->port]; | ||
2597 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2598 | local_irq_enable(); | ||
2599 | return 0; | ||
2650 | } | 2600 | } |
2651 | 2601 | ||
2652 | static inline void skge_tx_intr(struct net_device *dev) | 2602 | static inline void skge_tx_intr(struct net_device *dev) |
@@ -2657,7 +2607,7 @@ static inline void skge_tx_intr(struct net_device *dev) | |||
2657 | struct skge_element *e; | 2607 | struct skge_element *e; |
2658 | 2608 | ||
2659 | spin_lock(&skge->tx_lock); | 2609 | spin_lock(&skge->tx_lock); |
2660 | for(e = ring->to_clean; e != ring->to_use; e = e->next) { | 2610 | for (e = ring->to_clean; e != ring->to_use; e = e->next) { |
2661 | struct skge_tx_desc *td = e->desc; | 2611 | struct skge_tx_desc *td = e->desc; |
2662 | u32 control; | 2612 | u32 control; |
2663 | 2613 | ||
@@ -2690,12 +2640,12 @@ static void skge_mac_parity(struct skge_hw *hw, int port) | |||
2690 | : (port == 0 ? "(port A)": "(port B")); | 2640 | : (port == 0 ? "(port A)": "(port B")); |
2691 | 2641 | ||
2692 | if (hw->chip_id == CHIP_ID_GENESIS) | 2642 | if (hw->chip_id == CHIP_ID_GENESIS) |
2693 | skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), | 2643 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), |
2694 | MFF_CLR_PERR); | 2644 | MFF_CLR_PERR); |
2695 | else | 2645 | else |
2696 | /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ | 2646 | /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ |
2697 | skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), | 2647 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), |
2698 | (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0) | 2648 | (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) |
2699 | ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); | 2649 | ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); |
2700 | } | 2650 | } |
2701 | 2651 | ||
@@ -2703,16 +2653,16 @@ static void skge_pci_clear(struct skge_hw *hw) | |||
2703 | { | 2653 | { |
2704 | u16 status; | 2654 | u16 status; |
2705 | 2655 | ||
2706 | status = skge_read16(hw, SKGEPCI_REG(PCI_STATUS)); | 2656 | pci_read_config_word(hw->pdev, PCI_STATUS, &status); |
2707 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2657 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2708 | skge_write16(hw, SKGEPCI_REG(PCI_STATUS), | 2658 | pci_write_config_word(hw->pdev, PCI_STATUS, |
2709 | status | PCI_STATUS_ERROR_BITS); | 2659 | status | PCI_STATUS_ERROR_BITS); |
2710 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2660 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2711 | } | 2661 | } |
2712 | 2662 | ||
2713 | static void skge_mac_intr(struct skge_hw *hw, int port) | 2663 | static void skge_mac_intr(struct skge_hw *hw, int port) |
2714 | { | 2664 | { |
2715 | if (hw->chip_id == CHIP_ID_GENESIS) | 2665 | if (hw->chip_id == CHIP_ID_GENESIS) |
2716 | genesis_mac_intr(hw, port); | 2666 | genesis_mac_intr(hw, port); |
2717 | else | 2667 | else |
2718 | yukon_mac_intr(hw, port); | 2668 | yukon_mac_intr(hw, port); |
@@ -2726,9 +2676,9 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2726 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2676 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2727 | /* clear xmac errors */ | 2677 | /* clear xmac errors */ |
2728 | if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) | 2678 | if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) |
2729 | skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); | 2679 | skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); |
2730 | if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) | 2680 | if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) |
2731 | skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); | 2681 | skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); |
2732 | } else { | 2682 | } else { |
2733 | /* Timestamp (unused) overflow */ | 2683 | /* Timestamp (unused) overflow */ |
2734 | if (hwstatus & IS_IRQ_TIST_OV) | 2684 | if (hwstatus & IS_IRQ_TIST_OV) |
@@ -2803,8 +2753,8 @@ static void skge_extirq(unsigned long data) | |||
2803 | 2753 | ||
2804 | if (hw->chip_id != CHIP_ID_GENESIS) | 2754 | if (hw->chip_id != CHIP_ID_GENESIS) |
2805 | yukon_phy_intr(skge); | 2755 | yukon_phy_intr(skge); |
2806 | else if (hw->phy_type == SK_PHY_BCOM) | 2756 | else |
2807 | genesis_bcom_intr(skge); | 2757 | bcom_phy_intr(skge); |
2808 | } | 2758 | } |
2809 | } | 2759 | } |
2810 | spin_unlock(&hw->phy_lock); | 2760 | spin_unlock(&hw->phy_lock); |
@@ -2824,19 +2774,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2824 | return IRQ_NONE; | 2774 | return IRQ_NONE; |
2825 | 2775 | ||
2826 | status &= hw->intr_mask; | 2776 | status &= hw->intr_mask; |
2827 | 2777 | if (status & IS_R1_F) { | |
2828 | if ((status & IS_R1_F) && netif_rx_schedule_prep(hw->dev[0])) { | ||
2829 | status &= ~IS_R1_F; | ||
2830 | hw->intr_mask &= ~IS_R1_F; | 2778 | hw->intr_mask &= ~IS_R1_F; |
2831 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2779 | netif_rx_schedule(hw->dev[0]); |
2832 | __netif_rx_schedule(hw->dev[0]); | ||
2833 | } | 2780 | } |
2834 | 2781 | ||
2835 | if ((status & IS_R2_F) && netif_rx_schedule_prep(hw->dev[1])) { | 2782 | if (status & IS_R2_F) { |
2836 | status &= ~IS_R2_F; | ||
2837 | hw->intr_mask &= ~IS_R2_F; | 2783 | hw->intr_mask &= ~IS_R2_F; |
2838 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2784 | netif_rx_schedule(hw->dev[1]); |
2839 | __netif_rx_schedule(hw->dev[1]); | ||
2840 | } | 2785 | } |
2841 | 2786 | ||
2842 | if (status & IS_XA1_F) | 2787 | if (status & IS_XA1_F) |
@@ -2845,9 +2790,27 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2845 | if (status & IS_XA2_F) | 2790 | if (status & IS_XA2_F) |
2846 | skge_tx_intr(hw->dev[1]); | 2791 | skge_tx_intr(hw->dev[1]); |
2847 | 2792 | ||
2793 | if (status & IS_PA_TO_RX1) { | ||
2794 | struct skge_port *skge = netdev_priv(hw->dev[0]); | ||
2795 | ++skge->net_stats.rx_over_errors; | ||
2796 | skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1); | ||
2797 | } | ||
2798 | |||
2799 | if (status & IS_PA_TO_RX2) { | ||
2800 | struct skge_port *skge = netdev_priv(hw->dev[1]); | ||
2801 | ++skge->net_stats.rx_over_errors; | ||
2802 | skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2); | ||
2803 | } | ||
2804 | |||
2805 | if (status & IS_PA_TO_TX1) | ||
2806 | skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1); | ||
2807 | |||
2808 | if (status & IS_PA_TO_TX2) | ||
2809 | skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2); | ||
2810 | |||
2848 | if (status & IS_MAC1) | 2811 | if (status & IS_MAC1) |
2849 | skge_mac_intr(hw, 0); | 2812 | skge_mac_intr(hw, 0); |
2850 | 2813 | ||
2851 | if (status & IS_MAC2) | 2814 | if (status & IS_MAC2) |
2852 | skge_mac_intr(hw, 1); | 2815 | skge_mac_intr(hw, 1); |
2853 | 2816 | ||
@@ -2859,8 +2822,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2859 | tasklet_schedule(&hw->ext_tasklet); | 2822 | tasklet_schedule(&hw->ext_tasklet); |
2860 | } | 2823 | } |
2861 | 2824 | ||
2862 | if (status) | 2825 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2863 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2864 | 2826 | ||
2865 | return IRQ_HANDLED; | 2827 | return IRQ_HANDLED; |
2866 | } | 2828 | } |
@@ -2904,9 +2866,6 @@ static const struct { | |||
2904 | { CHIP_ID_YUKON, "Yukon" }, | 2866 | { CHIP_ID_YUKON, "Yukon" }, |
2905 | { CHIP_ID_YUKON_LITE, "Yukon-Lite"}, | 2867 | { CHIP_ID_YUKON_LITE, "Yukon-Lite"}, |
2906 | { CHIP_ID_YUKON_LP, "Yukon-LP"}, | 2868 | { CHIP_ID_YUKON_LP, "Yukon-LP"}, |
2907 | { CHIP_ID_YUKON_XL, "Yukon-2 XL"}, | ||
2908 | { CHIP_ID_YUKON_EC, "YUKON-2 EC"}, | ||
2909 | { CHIP_ID_YUKON_FE, "YUKON-2 FE"}, | ||
2910 | }; | 2869 | }; |
2911 | 2870 | ||
2912 | static const char *skge_board_name(const struct skge_hw *hw) | 2871 | static const char *skge_board_name(const struct skge_hw *hw) |
@@ -2930,8 +2889,8 @@ static const char *skge_board_name(const struct skge_hw *hw) | |||
2930 | static int skge_reset(struct skge_hw *hw) | 2889 | static int skge_reset(struct skge_hw *hw) |
2931 | { | 2890 | { |
2932 | u16 ctst; | 2891 | u16 ctst; |
2933 | u8 t8; | 2892 | u8 t8, mac_cfg; |
2934 | int i, ports; | 2893 | int i; |
2935 | 2894 | ||
2936 | ctst = skge_read16(hw, B0_CTST); | 2895 | ctst = skge_read16(hw, B0_CTST); |
2937 | 2896 | ||
@@ -2952,12 +2911,9 @@ static int skge_reset(struct skge_hw *hw) | |||
2952 | hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; | 2911 | hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; |
2953 | hw->pmd_type = skge_read8(hw, B2_PMD_TYP); | 2912 | hw->pmd_type = skge_read8(hw, B2_PMD_TYP); |
2954 | 2913 | ||
2955 | switch(hw->chip_id) { | 2914 | switch (hw->chip_id) { |
2956 | case CHIP_ID_GENESIS: | 2915 | case CHIP_ID_GENESIS: |
2957 | switch (hw->phy_type) { | 2916 | switch (hw->phy_type) { |
2958 | case SK_PHY_XMAC: | ||
2959 | hw->phy_addr = PHY_ADDR_XMAC; | ||
2960 | break; | ||
2961 | case SK_PHY_BCOM: | 2917 | case SK_PHY_BCOM: |
2962 | hw->phy_addr = PHY_ADDR_BCOM; | 2918 | hw->phy_addr = PHY_ADDR_BCOM; |
2963 | break; | 2919 | break; |
@@ -2986,8 +2942,9 @@ static int skge_reset(struct skge_hw *hw) | |||
2986 | return -EOPNOTSUPP; | 2942 | return -EOPNOTSUPP; |
2987 | } | 2943 | } |
2988 | 2944 | ||
2989 | hw->mac_cfg = skge_read8(hw, B2_MAC_CFG); | 2945 | mac_cfg = skge_read8(hw, B2_MAC_CFG); |
2990 | ports = isdualport(hw) ? 2 : 1; | 2946 | hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2; |
2947 | hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4; | ||
2991 | 2948 | ||
2992 | /* read the adapters RAM size */ | 2949 | /* read the adapters RAM size */ |
2993 | t8 = skge_read8(hw, B2_E_0); | 2950 | t8 = skge_read8(hw, B2_E_0); |
@@ -3010,9 +2967,9 @@ static int skge_reset(struct skge_hw *hw) | |||
3010 | /* switch power to VCC (WA for VAUX problem) */ | 2967 | /* switch power to VCC (WA for VAUX problem) */ |
3011 | skge_write8(hw, B0_POWER_CTRL, | 2968 | skge_write8(hw, B0_POWER_CTRL, |
3012 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); | 2969 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); |
3013 | for (i = 0; i < ports; i++) { | 2970 | for (i = 0; i < hw->ports; i++) { |
3014 | skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); | 2971 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); |
3015 | skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); | 2972 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); |
3016 | } | 2973 | } |
3017 | } | 2974 | } |
3018 | 2975 | ||
@@ -3022,8 +2979,8 @@ static int skge_reset(struct skge_hw *hw) | |||
3022 | skge_write8(hw, B0_LED, LED_STAT_ON); | 2979 | skge_write8(hw, B0_LED, LED_STAT_ON); |
3023 | 2980 | ||
3024 | /* enable the Tx Arbiters */ | 2981 | /* enable the Tx Arbiters */ |
3025 | for (i = 0; i < ports; i++) | 2982 | for (i = 0; i < hw->ports; i++) |
3026 | skge_write8(hw, SKGEMAC_REG(i, TXA_CTRL), TXA_ENA_ARB); | 2983 | skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB); |
3027 | 2984 | ||
3028 | /* Initialize ram interface */ | 2985 | /* Initialize ram interface */ |
3029 | skge_write16(hw, B3_RI_CTRL, RI_RST_CLR); | 2986 | skge_write16(hw, B3_RI_CTRL, RI_RST_CLR); |
@@ -3050,16 +3007,14 @@ static int skge_reset(struct skge_hw *hw) | |||
3050 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); | 3007 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); |
3051 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); | 3008 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); |
3052 | 3009 | ||
3053 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; | 3010 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG; |
3054 | if (isdualport(hw)) | ||
3055 | hw->intr_mask |= IS_PORT_2; | ||
3056 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 3011 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
3057 | 3012 | ||
3058 | if (hw->chip_id != CHIP_ID_GENESIS) | 3013 | if (hw->chip_id != CHIP_ID_GENESIS) |
3059 | skge_write8(hw, GMAC_IRQ_MSK, 0); | 3014 | skge_write8(hw, GMAC_IRQ_MSK, 0); |
3060 | 3015 | ||
3061 | spin_lock_bh(&hw->phy_lock); | 3016 | spin_lock_bh(&hw->phy_lock); |
3062 | for (i = 0; i < ports; i++) { | 3017 | for (i = 0; i < hw->ports; i++) { |
3063 | if (hw->chip_id == CHIP_ID_GENESIS) | 3018 | if (hw->chip_id == CHIP_ID_GENESIS) |
3064 | genesis_reset(hw, i); | 3019 | genesis_reset(hw, i); |
3065 | else | 3020 | else |
@@ -3071,7 +3026,8 @@ static int skge_reset(struct skge_hw *hw) | |||
3071 | } | 3026 | } |
3072 | 3027 | ||
3073 | /* Initialize network device */ | 3028 | /* Initialize network device */ |
3074 | static struct net_device *skge_devinit(struct skge_hw *hw, int port) | 3029 | static struct net_device *skge_devinit(struct skge_hw *hw, int port, |
3030 | int highmem) | ||
3075 | { | 3031 | { |
3076 | struct skge_port *skge; | 3032 | struct skge_port *skge; |
3077 | struct net_device *dev = alloc_etherdev(sizeof(*skge)); | 3033 | struct net_device *dev = alloc_etherdev(sizeof(*skge)); |
@@ -3104,6 +3060,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) | |||
3104 | #endif | 3060 | #endif |
3105 | dev->irq = hw->pdev->irq; | 3061 | dev->irq = hw->pdev->irq; |
3106 | dev->features = NETIF_F_LLTX; | 3062 | dev->features = NETIF_F_LLTX; |
3063 | if (highmem) | ||
3064 | dev->features |= NETIF_F_HIGHDMA; | ||
3107 | 3065 | ||
3108 | skge = netdev_priv(dev); | 3066 | skge = netdev_priv(dev); |
3109 | skge->netdev = dev; | 3067 | skge->netdev = dev; |
@@ -3117,7 +3075,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) | |||
3117 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 3075 | skge->flow_control = FLOW_MODE_SYMMETRIC; |
3118 | skge->duplex = -1; | 3076 | skge->duplex = -1; |
3119 | skge->speed = -1; | 3077 | skge->speed = -1; |
3120 | skge->advertising = skge_modes(hw); | 3078 | skge->advertising = skge_supported_modes(hw); |
3121 | 3079 | ||
3122 | hw->dev[port] = dev; | 3080 | hw->dev[port] = dev; |
3123 | 3081 | ||
@@ -3125,10 +3083,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) | |||
3125 | 3083 | ||
3126 | spin_lock_init(&skge->tx_lock); | 3084 | spin_lock_init(&skge->tx_lock); |
3127 | 3085 | ||
3128 | init_timer(&skge->link_check); | ||
3129 | skge->link_check.function = skge_link_timer; | ||
3130 | skge->link_check.data = (unsigned long) skge; | ||
3131 | |||
3132 | init_timer(&skge->led_blink); | 3086 | init_timer(&skge->led_blink); |
3133 | skge->led_blink.function = skge_blink_timer; | 3087 | skge->led_blink.function = skge_blink_timer; |
3134 | skge->led_blink.data = (unsigned long) skge; | 3088 | skge->led_blink.data = (unsigned long) skge; |
@@ -3232,14 +3186,11 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3232 | 3186 | ||
3233 | printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", | 3187 | printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", |
3234 | pci_resource_start(pdev, 0), pdev->irq, | 3188 | pci_resource_start(pdev, 0), pdev->irq, |
3235 | skge_board_name(hw), chip_rev(hw)); | 3189 | skge_board_name(hw), hw->chip_rev); |
3236 | 3190 | ||
3237 | if ((dev = skge_devinit(hw, 0)) == NULL) | 3191 | if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) |
3238 | goto err_out_led_off; | 3192 | goto err_out_led_off; |
3239 | 3193 | ||
3240 | if (using_dac) | ||
3241 | dev->features |= NETIF_F_HIGHDMA; | ||
3242 | |||
3243 | if ((err = register_netdev(dev))) { | 3194 | if ((err = register_netdev(dev))) { |
3244 | printk(KERN_ERR PFX "%s: cannot register net device\n", | 3195 | printk(KERN_ERR PFX "%s: cannot register net device\n", |
3245 | pci_name(pdev)); | 3196 | pci_name(pdev)); |
@@ -3248,10 +3199,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3248 | 3199 | ||
3249 | skge_show_addr(dev); | 3200 | skge_show_addr(dev); |
3250 | 3201 | ||
3251 | if (isdualport(hw) && (dev1 = skge_devinit(hw, 1))) { | 3202 | if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) { |
3252 | if (using_dac) | ||
3253 | dev1->features |= NETIF_F_HIGHDMA; | ||
3254 | |||
3255 | if (register_netdev(dev1) == 0) | 3203 | if (register_netdev(dev1) == 0) |
3256 | skge_show_addr(dev1); | 3204 | skge_show_addr(dev1); |
3257 | else { | 3205 | else { |
@@ -3288,7 +3236,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) | |||
3288 | struct skge_hw *hw = pci_get_drvdata(pdev); | 3236 | struct skge_hw *hw = pci_get_drvdata(pdev); |
3289 | struct net_device *dev0, *dev1; | 3237 | struct net_device *dev0, *dev1; |
3290 | 3238 | ||
3291 | if(!hw) | 3239 | if (!hw) |
3292 | return; | 3240 | return; |
3293 | 3241 | ||
3294 | if ((dev1 = hw->dev[1])) | 3242 | if ((dev1 = hw->dev[1])) |
@@ -3316,7 +3264,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state) | |||
3316 | struct skge_hw *hw = pci_get_drvdata(pdev); | 3264 | struct skge_hw *hw = pci_get_drvdata(pdev); |
3317 | int i, wol = 0; | 3265 | int i, wol = 0; |
3318 | 3266 | ||
3319 | for(i = 0; i < 2; i++) { | 3267 | for (i = 0; i < 2; i++) { |
3320 | struct net_device *dev = hw->dev[i]; | 3268 | struct net_device *dev = hw->dev[i]; |
3321 | 3269 | ||
3322 | if (dev) { | 3270 | if (dev) { |
@@ -3349,11 +3297,11 @@ static int skge_resume(struct pci_dev *pdev) | |||
3349 | 3297 | ||
3350 | skge_reset(hw); | 3298 | skge_reset(hw); |
3351 | 3299 | ||
3352 | for(i = 0; i < 2; i++) { | 3300 | for (i = 0; i < 2; i++) { |
3353 | struct net_device *dev = hw->dev[i]; | 3301 | struct net_device *dev = hw->dev[i]; |
3354 | if (dev) { | 3302 | if (dev) { |
3355 | netif_device_attach(dev); | 3303 | netif_device_attach(dev); |
3356 | if(netif_running(dev)) | 3304 | if (netif_running(dev)) |
3357 | skge_up(dev); | 3305 | skge_up(dev); |
3358 | } | 3306 | } |
3359 | } | 3307 | } |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 36c62b68fab4..14d0cc01fb9a 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -7,31 +7,6 @@ | |||
7 | /* PCI config registers */ | 7 | /* PCI config registers */ |
8 | #define PCI_DEV_REG1 0x40 | 8 | #define PCI_DEV_REG1 0x40 |
9 | #define PCI_DEV_REG2 0x44 | 9 | #define PCI_DEV_REG2 0x44 |
10 | #ifndef PCI_VPD | ||
11 | #define PCI_VPD 0x50 | ||
12 | #endif | ||
13 | |||
14 | /* PCI_OUR_REG_2 32 bit Our Register 2 */ | ||
15 | enum { | ||
16 | PCI_VPD_WR_THR = 0xff<<24, /* Bit 31..24: VPD Write Threshold */ | ||
17 | PCI_DEV_SEL = 0x7f<<17, /* Bit 23..17: EEPROM Device Select */ | ||
18 | PCI_VPD_ROM_SZ = 7 <<14, /* Bit 16..14: VPD ROM Size */ | ||
19 | /* Bit 13..12: reserved */ | ||
20 | PCI_EN_DUMMY_RD = 1<<3, /* Enable Dummy Read */ | ||
21 | PCI_REV_DESC = 1<<2, /* Reverse Desc. Bytes */ | ||
22 | PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */ | ||
23 | }; | ||
24 | |||
25 | /* PCI_VPD_ADR_REG 16 bit VPD Address Register */ | ||
26 | enum { | ||
27 | PCI_VPD_FLAG = 1<<15, /* starts VPD rd/wr cycle */ | ||
28 | PCI_VPD_ADR_MSK =0x7fffL, /* Bit 14.. 0: VPD Address Mask */ | ||
29 | VPD_RES_ID = 0x82, | ||
30 | VPD_RES_READ = 0x90, | ||
31 | VPD_RES_WRITE = 0x81, | ||
32 | VPD_RES_END = 0x78, | ||
33 | }; | ||
34 | |||
35 | 10 | ||
36 | #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ | 11 | #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ |
37 | PCI_STATUS_SIG_SYSTEM_ERROR | \ | 12 | PCI_STATUS_SIG_SYSTEM_ERROR | \ |
@@ -39,7 +14,6 @@ enum { | |||
39 | PCI_STATUS_REC_TARGET_ABORT | \ | 14 | PCI_STATUS_REC_TARGET_ABORT | \ |
40 | PCI_STATUS_PARITY) | 15 | PCI_STATUS_PARITY) |
41 | 16 | ||
42 | |||
43 | enum csr_regs { | 17 | enum csr_regs { |
44 | B0_RAP = 0x0000, | 18 | B0_RAP = 0x0000, |
45 | B0_CTST = 0x0004, | 19 | B0_CTST = 0x0004, |
@@ -229,8 +203,11 @@ enum { | |||
229 | IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */ | 203 | IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */ |
230 | IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */ | 204 | IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */ |
231 | 205 | ||
232 | IS_PORT_1 = IS_XA1_F| IS_R1_F| IS_MAC1, | 206 | IS_TO_PORT1 = IS_PA_TO_RX1 | IS_PA_TO_TX1, |
233 | IS_PORT_2 = IS_XA2_F| IS_R2_F| IS_MAC2, | 207 | IS_TO_PORT2 = IS_PA_TO_RX2 | IS_PA_TO_TX2, |
208 | |||
209 | IS_PORT_1 = IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1, | ||
210 | IS_PORT_2 = IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2, | ||
234 | }; | 211 | }; |
235 | 212 | ||
236 | 213 | ||
@@ -288,14 +265,6 @@ enum { | |||
288 | CHIP_REV_YU_LITE_A3 = 7, /* Chip Rev. for YUKON-Lite A3 */ | 265 | CHIP_REV_YU_LITE_A3 = 7, /* Chip Rev. for YUKON-Lite A3 */ |
289 | }; | 266 | }; |
290 | 267 | ||
291 | /* B2_LD_TEST 8 bit EPROM loader test register */ | ||
292 | enum { | ||
293 | LD_T_ON = 1<<3, /* Loader Test mode on */ | ||
294 | LD_T_OFF = 1<<2, /* Loader Test mode off */ | ||
295 | LD_T_STEP = 1<<1, /* Decrement FPROM addr. Counter */ | ||
296 | LD_START = 1<<0, /* Start loading FPROM */ | ||
297 | }; | ||
298 | |||
299 | /* B2_TI_CTRL 8 bit Timer control */ | 268 | /* B2_TI_CTRL 8 bit Timer control */ |
300 | /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ | 269 | /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ |
301 | enum { | 270 | enum { |
@@ -313,16 +282,6 @@ enum { | |||
313 | TIM_T_STEP = 1<<0, /* Test step */ | 282 | TIM_T_STEP = 1<<0, /* Test step */ |
314 | }; | 283 | }; |
315 | 284 | ||
316 | /* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */ | ||
317 | /* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */ | ||
318 | /* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */ | ||
319 | enum { | ||
320 | DPT_MSK = 0x00ffffffL, /* Bit 23.. 0: Desc Poll Timer Bits */ | ||
321 | |||
322 | DPT_START = 1<<1, /* Start Descriptor Poll Timer */ | ||
323 | DPT_STOP = 1<<0, /* Stop Descriptor Poll Timer */ | ||
324 | }; | ||
325 | |||
326 | /* B2_GP_IO 32 bit General Purpose I/O Register */ | 285 | /* B2_GP_IO 32 bit General Purpose I/O Register */ |
327 | enum { | 286 | enum { |
328 | GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */ | 287 | GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */ |
@@ -348,30 +307,6 @@ enum { | |||
348 | GP_IO_0 = 1<<0, /* IO_0 pin */ | 307 | GP_IO_0 = 1<<0, /* IO_0 pin */ |
349 | }; | 308 | }; |
350 | 309 | ||
351 | /* Rx/Tx Path related Arbiter Test Registers */ | ||
352 | /* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */ | ||
353 | /* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ | ||
354 | /* B3_PA_TEST 16 bit Packet Arbiter Test Register */ | ||
355 | /* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ | ||
356 | enum { | ||
357 | TX2_T_EV = 1<<15,/* TX2 Timeout/Recv Event occured */ | ||
358 | TX2_T_ON = 1<<14,/* TX2 Timeout/Recv Timer Test On */ | ||
359 | TX2_T_OFF = 1<<13,/* TX2 Timeout/Recv Timer Tst Off */ | ||
360 | TX2_T_STEP = 1<<12,/* TX2 Timeout/Recv Timer Step */ | ||
361 | TX1_T_EV = 1<<11,/* TX1 Timeout/Recv Event occured */ | ||
362 | TX1_T_ON = 1<<10,/* TX1 Timeout/Recv Timer Test On */ | ||
363 | TX1_T_OFF = 1<<9, /* TX1 Timeout/Recv Timer Tst Off */ | ||
364 | TX1_T_STEP = 1<<8, /* TX1 Timeout/Recv Timer Step */ | ||
365 | RX2_T_EV = 1<<7, /* RX2 Timeout/Recv Event occured */ | ||
366 | RX2_T_ON = 1<<6, /* RX2 Timeout/Recv Timer Test On */ | ||
367 | RX2_T_OFF = 1<<5, /* RX2 Timeout/Recv Timer Tst Off */ | ||
368 | RX2_T_STEP = 1<<4, /* RX2 Timeout/Recv Timer Step */ | ||
369 | RX1_T_EV = 1<<3, /* RX1 Timeout/Recv Event occured */ | ||
370 | RX1_T_ON = 1<<2, /* RX1 Timeout/Recv Timer Test On */ | ||
371 | RX1_T_OFF = 1<<1, /* RX1 Timeout/Recv Timer Tst Off */ | ||
372 | RX1_T_STEP = 1<<0, /* RX1 Timeout/Recv Timer Step */ | ||
373 | }; | ||
374 | |||
375 | /* Descriptor Bit Definition */ | 310 | /* Descriptor Bit Definition */ |
376 | /* TxCtrl Transmit Buffer Control Field */ | 311 | /* TxCtrl Transmit Buffer Control Field */ |
377 | /* RxCtrl Receive Buffer Control Field */ | 312 | /* RxCtrl Receive Buffer Control Field */ |
@@ -428,14 +363,6 @@ enum { | |||
428 | RI_RST_SET = 1<<0, /* Set RAM Interface Reset */ | 363 | RI_RST_SET = 1<<0, /* Set RAM Interface Reset */ |
429 | }; | 364 | }; |
430 | 365 | ||
431 | /* B3_RI_TEST 8 bit RAM Iface Test Register */ | ||
432 | enum { | ||
433 | RI_T_EV = 1<<3, /* Timeout Event occured */ | ||
434 | RI_T_ON = 1<<2, /* Timeout Timer Test On */ | ||
435 | RI_T_OFF = 1<<1, /* Timeout Timer Test Off */ | ||
436 | RI_T_STEP = 1<<0, /* Timeout Timer Step */ | ||
437 | }; | ||
438 | |||
439 | /* MAC Arbiter Registers */ | 366 | /* MAC Arbiter Registers */ |
440 | /* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */ | 367 | /* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */ |
441 | enum { | 368 | enum { |
@@ -452,19 +379,6 @@ enum { | |||
452 | #define SK_PKT_TO_MAX 0xffff /* Maximum value */ | 379 | #define SK_PKT_TO_MAX 0xffff /* Maximum value */ |
453 | #define SK_RI_TO_53 36 /* RAM interface timeout */ | 380 | #define SK_RI_TO_53 36 /* RAM interface timeout */ |
454 | 381 | ||
455 | |||
456 | /* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */ | ||
457 | enum { | ||
458 | MA_ENA_REC_TX2 = 1<<7, /* Enable Recovery Timer TX2 */ | ||
459 | MA_DIS_REC_TX2 = 1<<6, /* Disable Recovery Timer TX2 */ | ||
460 | MA_ENA_REC_TX1 = 1<<5, /* Enable Recovery Timer TX1 */ | ||
461 | MA_DIS_REC_TX1 = 1<<4, /* Disable Recovery Timer TX1 */ | ||
462 | MA_ENA_REC_RX2 = 1<<3, /* Enable Recovery Timer RX2 */ | ||
463 | MA_DIS_REC_RX2 = 1<<2, /* Disable Recovery Timer RX2 */ | ||
464 | MA_ENA_REC_RX1 = 1<<1, /* Enable Recovery Timer RX1 */ | ||
465 | MA_DIS_REC_RX1 = 1<<0, /* Disable Recovery Timer RX1 */ | ||
466 | }; | ||
467 | |||
468 | /* Packet Arbiter Registers */ | 382 | /* Packet Arbiter Registers */ |
469 | /* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ | 383 | /* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ |
470 | enum { | 384 | enum { |
@@ -488,7 +402,7 @@ enum { | |||
488 | PA_ENA_TO_TX1 | PA_ENA_TO_TX2) | 402 | PA_ENA_TO_TX1 | PA_ENA_TO_TX2) |
489 | 403 | ||
490 | 404 | ||
491 | /* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ | 405 | /* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */ |
492 | /* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ | 406 | /* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ |
493 | /* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ | 407 | /* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ |
494 | /* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ | 408 | /* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ |
@@ -511,7 +425,7 @@ enum { | |||
511 | /* | 425 | /* |
512 | * Bank 4 - 5 | 426 | * Bank 4 - 5 |
513 | */ | 427 | */ |
514 | /* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ | 428 | /* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */ |
515 | enum { | 429 | enum { |
516 | TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/ | 430 | TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/ |
517 | TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */ | 431 | TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */ |
@@ -537,7 +451,7 @@ enum { | |||
537 | 451 | ||
538 | /* Queue Register Offsets, use Q_ADDR() to access */ | 452 | /* Queue Register Offsets, use Q_ADDR() to access */ |
539 | enum { | 453 | enum { |
540 | B8_Q_REGS = 0x0400, /* base of Queue registers */ | 454 | B8_Q_REGS = 0x0400, /* base of Queue registers */ |
541 | Q_D = 0x00, /* 8*32 bit Current Descriptor */ | 455 | Q_D = 0x00, /* 8*32 bit Current Descriptor */ |
542 | Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ | 456 | Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ |
543 | Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ | 457 | Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ |
@@ -618,8 +532,7 @@ enum { | |||
618 | enum { | 532 | enum { |
619 | PHY_ADDR_XMAC = 0<<8, | 533 | PHY_ADDR_XMAC = 0<<8, |
620 | PHY_ADDR_BCOM = 1<<8, | 534 | PHY_ADDR_BCOM = 1<<8, |
621 | PHY_ADDR_LONE = 3<<8, | 535 | |
622 | PHY_ADDR_NAT = 0<<8, | ||
623 | /* GPHY address (bits 15..11 of SMI control reg) */ | 536 | /* GPHY address (bits 15..11 of SMI control reg) */ |
624 | PHY_ADDR_MARV = 0, | 537 | PHY_ADDR_MARV = 0, |
625 | }; | 538 | }; |
@@ -986,7 +899,7 @@ enum { | |||
986 | LINKLED_BLINK_OFF = 0x10, | 899 | LINKLED_BLINK_OFF = 0x10, |
987 | LINKLED_BLINK_ON = 0x20, | 900 | LINKLED_BLINK_ON = 0x20, |
988 | }; | 901 | }; |
989 | 902 | ||
990 | /* GMAC and GPHY Control Registers (YUKON only) */ | 903 | /* GMAC and GPHY Control Registers (YUKON only) */ |
991 | enum { | 904 | enum { |
992 | GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */ | 905 | GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */ |
@@ -1151,54 +1064,6 @@ enum { | |||
1151 | PHY_MARV_FE_SPEC_2 = 0x1c,/* 16 bit r/w Specific Control Reg. 2 */ | 1064 | PHY_MARV_FE_SPEC_2 = 0x1c,/* 16 bit r/w Specific Control Reg. 2 */ |
1152 | }; | 1065 | }; |
1153 | 1066 | ||
1154 | /* Level One-PHY Registers, indirect addressed over XMAC */ | ||
1155 | enum { | ||
1156 | PHY_LONE_CTRL = 0x00,/* 16 bit r/w PHY Control Register */ | ||
1157 | PHY_LONE_STAT = 0x01,/* 16 bit r/o PHY Status Register */ | ||
1158 | PHY_LONE_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */ | ||
1159 | PHY_LONE_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */ | ||
1160 | PHY_LONE_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ | ||
1161 | PHY_LONE_AUNE_LP = 0x05,/* 16 bit r/o Link Part Ability Reg */ | ||
1162 | PHY_LONE_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ | ||
1163 | PHY_LONE_NEPG = 0x07,/* 16 bit r/w Next Page Register */ | ||
1164 | PHY_LONE_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ | ||
1165 | /* Level One-specific registers */ | ||
1166 | PHY_LONE_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */ | ||
1167 | PHY_LONE_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */ | ||
1168 | PHY_LONE_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Reg */ | ||
1169 | PHY_LONE_PORT_CFG = 0x10,/* 16 bit r/w Port Configuration Reg*/ | ||
1170 | PHY_LONE_Q_STAT = 0x11,/* 16 bit r/o Quick Status Reg */ | ||
1171 | PHY_LONE_INT_ENAB = 0x12,/* 16 bit r/w Interrupt Enable Reg */ | ||
1172 | PHY_LONE_INT_STAT = 0x13,/* 16 bit r/o Interrupt Status Reg */ | ||
1173 | PHY_LONE_LED_CFG = 0x14,/* 16 bit r/w LED Configuration Reg */ | ||
1174 | PHY_LONE_PORT_CTRL = 0x15,/* 16 bit r/w Port Control Reg */ | ||
1175 | PHY_LONE_CIM = 0x16,/* 16 bit r/o CIM Reg */ | ||
1176 | }; | ||
1177 | |||
1178 | /* National-PHY Registers, indirect addressed over XMAC */ | ||
1179 | enum { | ||
1180 | PHY_NAT_CTRL = 0x00,/* 16 bit r/w PHY Control Register */ | ||
1181 | PHY_NAT_STAT = 0x01,/* 16 bit r/w PHY Status Register */ | ||
1182 | PHY_NAT_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */ | ||
1183 | PHY_NAT_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */ | ||
1184 | PHY_NAT_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ | ||
1185 | PHY_NAT_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Ability Reg */ | ||
1186 | PHY_NAT_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ | ||
1187 | PHY_NAT_NEPG = 0x07,/* 16 bit r/w Next Page Register */ | ||
1188 | PHY_NAT_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner Reg */ | ||
1189 | /* National-specific registers */ | ||
1190 | PHY_NAT_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */ | ||
1191 | PHY_NAT_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */ | ||
1192 | PHY_NAT_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Register */ | ||
1193 | PHY_NAT_EXT_CTRL1 = 0x10,/* 16 bit r/o Extended Control Reg1 */ | ||
1194 | PHY_NAT_Q_STAT1 = 0x11,/* 16 bit r/o Quick Status Reg1 */ | ||
1195 | PHY_NAT_10B_OP = 0x12,/* 16 bit r/o 10Base-T Operations Reg */ | ||
1196 | PHY_NAT_EXT_CTRL2 = 0x13,/* 16 bit r/o Extended Control Reg1 */ | ||
1197 | PHY_NAT_Q_STAT2 = 0x14,/* 16 bit r/o Quick Status Reg2 */ | ||
1198 | |||
1199 | PHY_NAT_PHY_ADDR = 0x19,/* 16 bit r/o PHY Address Register */ | ||
1200 | }; | ||
1201 | |||
1202 | enum { | 1067 | enum { |
1203 | PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */ | 1068 | PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */ |
1204 | PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */ | 1069 | PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */ |
@@ -1253,8 +1118,29 @@ enum { | |||
1253 | PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */ | 1118 | PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */ |
1254 | }; | 1119 | }; |
1255 | 1120 | ||
1121 | /* Advertisement register bits */ | ||
1256 | enum { | 1122 | enum { |
1257 | PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ | 1123 | PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ |
1124 | PHY_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ | ||
1125 | PHY_AN_RF = 1<<13, /* Bit 13: Remote Fault Bits */ | ||
1126 | |||
1127 | PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11: Try for asymmetric */ | ||
1128 | PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10: Try for pause */ | ||
1129 | PHY_AN_100BASE4 = 1<<9, /* Bit 9: Try for 100mbps 4k packets */ | ||
1130 | PHY_AN_100FULL = 1<<8, /* Bit 8: Try for 100mbps full-duplex */ | ||
1131 | PHY_AN_100HALF = 1<<7, /* Bit 7: Try for 100mbps half-duplex */ | ||
1132 | PHY_AN_10FULL = 1<<6, /* Bit 6: Try for 10mbps full-duplex */ | ||
1133 | PHY_AN_10HALF = 1<<5, /* Bit 5: Try for 10mbps half-duplex */ | ||
1134 | PHY_AN_CSMA = 1<<0, /* Bit 0: Only selector supported */ | ||
1135 | PHY_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ | ||
1136 | PHY_AN_FULL = PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA, | ||
1137 | PHY_AN_ALL = PHY_AN_10HALF | PHY_AN_10FULL | | ||
1138 | PHY_AN_100HALF | PHY_AN_100FULL, | ||
1139 | }; | ||
1140 | |||
1141 | /* Xmac Specific */ | ||
1142 | enum { | ||
1143 | PHY_X_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ | ||
1258 | PHY_X_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ | 1144 | PHY_X_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ |
1259 | PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */ | 1145 | PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */ |
1260 | 1146 | ||
@@ -1263,82 +1149,6 @@ enum { | |||
1263 | PHY_X_AN_FD = 1<<5, /* Bit 5: Full Duplex */ | 1149 | PHY_X_AN_FD = 1<<5, /* Bit 5: Full Duplex */ |
1264 | }; | 1150 | }; |
1265 | 1151 | ||
1266 | enum { | ||
1267 | PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */ | ||
1268 | |||
1269 | PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ | ||
1270 | PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */ | ||
1271 | PHY_B_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ | ||
1272 | }; | ||
1273 | |||
1274 | enum { | ||
1275 | PHY_L_AN_RF = 1<<13, /* Bit 13: Remote Fault */ | ||
1276 | /* Bit 12: reserved */ | ||
1277 | PHY_L_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ | ||
1278 | PHY_L_AN_PC = 1<<10, /* Bit 10: Pause Capable */ | ||
1279 | |||
1280 | PHY_L_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ | ||
1281 | }; | ||
1282 | |||
1283 | /* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */ | ||
1284 | /* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ | ||
1285 | /* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ | ||
1286 | enum { | ||
1287 | PHY_N_AN_RF = 1<<13, /* Bit 13: Remote Fault */ | ||
1288 | |||
1289 | PHY_N_AN_100F = 1<<11, /* Bit 11: 100Base-T2 FD Support */ | ||
1290 | PHY_N_AN_100H = 1<<10, /* Bit 10: 100Base-T2 HD Support */ | ||
1291 | |||
1292 | PHY_N_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ | ||
1293 | }; | ||
1294 | |||
1295 | /* field type definition for PHY_x_AN_SEL */ | ||
1296 | enum { | ||
1297 | PHY_SEL_TYPE = 1, /* 00001 = Ethernet */ | ||
1298 | }; | ||
1299 | |||
1300 | enum { | ||
1301 | PHY_ANE_LP_NP = 1<<3, /* Bit 3: Link Partner can Next Page */ | ||
1302 | PHY_ANE_LOC_NP = 1<<2, /* Bit 2: Local PHY can Next Page */ | ||
1303 | PHY_ANE_RX_PG = 1<<1, /* Bit 1: Page Received */ | ||
1304 | }; | ||
1305 | |||
1306 | enum { | ||
1307 | PHY_ANE_PAR_DF = 1<<4, /* Bit 4: Parallel Detection Fault */ | ||
1308 | |||
1309 | PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */ | ||
1310 | }; | ||
1311 | |||
1312 | enum { | ||
1313 | PHY_NP_MORE = 1<<15, /* Bit 15: More, Next Pages to follow */ | ||
1314 | PHY_NP_ACK1 = 1<<14, /* Bit 14: (ro) Ack1, for receiving a message */ | ||
1315 | PHY_NP_MSG_VAL = 1<<13, /* Bit 13: Message Page valid */ | ||
1316 | PHY_NP_ACK2 = 1<<12, /* Bit 12: Ack2, comply with msg content */ | ||
1317 | PHY_NP_TOG = 1<<11, /* Bit 11: Toggle Bit, ensure sync */ | ||
1318 | PHY_NP_MSG = 0x07ff, /* Bit 10..0: Message from/to Link Partner */ | ||
1319 | }; | ||
1320 | |||
1321 | enum { | ||
1322 | PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */ | ||
1323 | PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */ | ||
1324 | }; | ||
1325 | |||
1326 | enum { | ||
1327 | PHY_X_RS_PAUSE = 3<<7,/* Bit 8..7: selected Pause Mode */ | ||
1328 | PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */ | ||
1329 | PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */ | ||
1330 | PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */ | ||
1331 | PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */ | ||
1332 | }; | ||
1333 | |||
1334 | /** Remote Fault Bits (PHY_X_AN_RFB) encoding */ | ||
1335 | enum { | ||
1336 | X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */ | ||
1337 | X_RFB_LF = 1<<12, /* Bit 13..12 Link Failure */ | ||
1338 | X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */ | ||
1339 | X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */ | ||
1340 | }; | ||
1341 | |||
1342 | /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ | 1152 | /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ |
1343 | enum { | 1153 | enum { |
1344 | PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ | 1154 | PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ |
@@ -1418,6 +1228,16 @@ enum { | |||
1418 | PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */ | 1228 | PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */ |
1419 | }; | 1229 | }; |
1420 | 1230 | ||
1231 | /* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ | ||
1232 | /* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ | ||
1233 | enum { | ||
1234 | PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */ | ||
1235 | |||
1236 | PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ | ||
1237 | PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */ | ||
1238 | }; | ||
1239 | |||
1240 | |||
1421 | /***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ | 1241 | /***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ |
1422 | enum { | 1242 | enum { |
1423 | PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */ | 1243 | PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */ |
@@ -1478,7 +1298,9 @@ enum { | |||
1478 | PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */ | 1298 | PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */ |
1479 | PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */ | 1299 | PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */ |
1480 | }; | 1300 | }; |
1481 | #define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) | 1301 | #define PHY_B_DEF_MSK \ |
1302 | (~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \ | ||
1303 | PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE)) | ||
1482 | 1304 | ||
1483 | /* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ | 1305 | /* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ |
1484 | enum { | 1306 | enum { |
@@ -1495,166 +1317,6 @@ enum { | |||
1495 | PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */ | 1317 | PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */ |
1496 | }; | 1318 | }; |
1497 | 1319 | ||
1498 | /* | ||
1499 | * Level One-Specific | ||
1500 | */ | ||
1501 | /***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ | ||
1502 | enum { | ||
1503 | PHY_L_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */ | ||
1504 | PHY_L_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */ | ||
1505 | PHY_L_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */ | ||
1506 | PHY_L_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */ | ||
1507 | PHY_L_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */ | ||
1508 | PHY_L_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */ | ||
1509 | }; | ||
1510 | |||
1511 | /***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ | ||
1512 | enum { | ||
1513 | PHY_L_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */ | ||
1514 | PHY_L_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */ | ||
1515 | PHY_L_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */ | ||
1516 | PHY_L_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status */ | ||
1517 | PHY_L_1000S_LP_FD = 1<<11, /* Bit 11: Link Partner can FD */ | ||
1518 | PHY_L_1000S_LP_HD = 1<<10, /* Bit 10: Link Partner can HD */ | ||
1519 | |||
1520 | PHY_L_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */ | ||
1521 | |||
1522 | /***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/ | ||
1523 | PHY_L_ES_X_FD_CAP = 1<<15, /* Bit 15: 1000Base-X FD capable */ | ||
1524 | PHY_L_ES_X_HD_CAP = 1<<14, /* Bit 14: 1000Base-X HD capable */ | ||
1525 | PHY_L_ES_T_FD_CAP = 1<<13, /* Bit 13: 1000Base-T FD capable */ | ||
1526 | PHY_L_ES_T_HD_CAP = 1<<12, /* Bit 12: 1000Base-T HD capable */ | ||
1527 | }; | ||
1528 | |||
1529 | /***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/ | ||
1530 | enum { | ||
1531 | PHY_L_PC_REP_MODE = 1<<15, /* Bit 15: Repeater Mode */ | ||
1532 | |||
1533 | PHY_L_PC_TX_DIS = 1<<13, /* Bit 13: Tx output Disabled */ | ||
1534 | PHY_L_PC_BY_SCR = 1<<12, /* Bit 12: Bypass Scrambler */ | ||
1535 | PHY_L_PC_BY_45 = 1<<11, /* Bit 11: Bypass 4B5B-Decoder */ | ||
1536 | PHY_L_PC_JAB_DIS = 1<<10, /* Bit 10: Jabber Disabled */ | ||
1537 | PHY_L_PC_SQE = 1<<9, /* Bit 9: Enable Heartbeat */ | ||
1538 | PHY_L_PC_TP_LOOP = 1<<8, /* Bit 8: TP Loopback */ | ||
1539 | PHY_L_PC_SSS = 1<<7, /* Bit 7: Smart Speed Selection */ | ||
1540 | PHY_L_PC_FIFO_SIZE = 1<<6, /* Bit 6: FIFO Size */ | ||
1541 | PHY_L_PC_PRE_EN = 1<<5, /* Bit 5: Preamble Enable */ | ||
1542 | PHY_L_PC_CIM = 1<<4, /* Bit 4: Carrier Integrity Mon */ | ||
1543 | PHY_L_PC_10_SER = 1<<3, /* Bit 3: Use Serial Output */ | ||
1544 | PHY_L_PC_ANISOL = 1<<2, /* Bit 2: Unisolate Port */ | ||
1545 | PHY_L_PC_TEN_BIT = 1<<1, /* Bit 1: 10bit iface mode on */ | ||
1546 | PHY_L_PC_ALTCLOCK = 1<<0, /* Bit 0: (ro) ALTCLOCK Mode on */ | ||
1547 | }; | ||
1548 | |||
1549 | /***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/ | ||
1550 | enum { | ||
1551 | PHY_L_QS_D_RATE = 3<<14,/* Bit 15..14: Data Rate */ | ||
1552 | PHY_L_QS_TX_STAT = 1<<13, /* Bit 13: Transmitting */ | ||
1553 | PHY_L_QS_RX_STAT = 1<<12, /* Bit 12: Receiving */ | ||
1554 | PHY_L_QS_COL_STAT = 1<<11, /* Bit 11: Collision */ | ||
1555 | PHY_L_QS_L_STAT = 1<<10, /* Bit 10: Link is up */ | ||
1556 | PHY_L_QS_DUP_MOD = 1<<9, /* Bit 9: Full/Half Duplex */ | ||
1557 | PHY_L_QS_AN = 1<<8, /* Bit 8: AutoNeg is On */ | ||
1558 | PHY_L_QS_AN_C = 1<<7, /* Bit 7: AN is Complete */ | ||
1559 | PHY_L_QS_LLE = 7<<4,/* Bit 6..4: Line Length Estim. */ | ||
1560 | PHY_L_QS_PAUSE = 1<<3, /* Bit 3: LP advertised Pause */ | ||
1561 | PHY_L_QS_AS_PAUSE = 1<<2, /* Bit 2: LP adv. asym. Pause */ | ||
1562 | PHY_L_QS_ISOLATE = 1<<1, /* Bit 1: CIM Isolated */ | ||
1563 | PHY_L_QS_EVENT = 1<<0, /* Bit 0: Event has occurred */ | ||
1564 | }; | ||
1565 | |||
1566 | /***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/ | ||
1567 | /***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/ | ||
1568 | enum { | ||
1569 | PHY_L_IS_AN_F = 1<<13, /* Bit 13: Auto-Negotiation fault */ | ||
1570 | PHY_L_IS_CROSS = 1<<11, /* Bit 11: Crossover used */ | ||
1571 | PHY_L_IS_POL = 1<<10, /* Bit 10: Polarity correct. used */ | ||
1572 | PHY_L_IS_SS = 1<<9, /* Bit 9: Smart Speed Downgrade */ | ||
1573 | PHY_L_IS_CFULL = 1<<8, /* Bit 8: Counter Full */ | ||
1574 | PHY_L_IS_AN_C = 1<<7, /* Bit 7: AutoNeg Complete */ | ||
1575 | PHY_L_IS_SPEED = 1<<6, /* Bit 6: Speed Changed */ | ||
1576 | PHY_L_IS_DUP = 1<<5, /* Bit 5: Duplex Changed */ | ||
1577 | PHY_L_IS_LS = 1<<4, /* Bit 4: Link Status Changed */ | ||
1578 | PHY_L_IS_ISOL = 1<<3, /* Bit 3: Isolate Occured */ | ||
1579 | PHY_L_IS_MDINT = 1<<2, /* Bit 2: (ro) STAT: MII Int Pending */ | ||
1580 | PHY_L_IS_INTEN = 1<<1, /* Bit 1: ENAB: Enable IRQs */ | ||
1581 | PHY_L_IS_FORCE = 1<<0, /* Bit 0: ENAB: Force Interrupt */ | ||
1582 | }; | ||
1583 | |||
1584 | /* int. mask */ | ||
1585 | #define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN) | ||
1586 | |||
1587 | /***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/ | ||
1588 | enum { | ||
1589 | PHY_L_LC_LEDC = 3<<14,/* Bit 15..14: Col/Blink/On/Off */ | ||
1590 | PHY_L_LC_LEDR = 3<<12,/* Bit 13..12: Rx/Blink/On/Off */ | ||
1591 | PHY_L_LC_LEDT = 3<<10,/* Bit 11..10: Tx/Blink/On/Off */ | ||
1592 | PHY_L_LC_LEDG = 3<<8,/* Bit 9..8: Giga/Blink/On/Off */ | ||
1593 | PHY_L_LC_LEDS = 3<<6,/* Bit 7..6: 10-100/Blink/On/Off */ | ||
1594 | PHY_L_LC_LEDL = 3<<4,/* Bit 5..4: Link/Blink/On/Off */ | ||
1595 | PHY_L_LC_LEDF = 3<<2,/* Bit 3..2: Duplex/Blink/On/Off */ | ||
1596 | PHY_L_LC_PSTRECH= 1<<1, /* Bit 1: Strech LED Pulses */ | ||
1597 | PHY_L_LC_FREQ = 1<<0, /* Bit 0: 30/100 ms */ | ||
1598 | }; | ||
1599 | |||
1600 | /***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/ | ||
1601 | enum { | ||
1602 | PHY_L_PC_TX_TCLK = 1<<15, /* Bit 15: Enable TX_TCLK */ | ||
1603 | PHY_L_PC_ALT_NP = 1<<13, /* Bit 14: Alternate Next Page */ | ||
1604 | PHY_L_PC_GMII_ALT= 1<<12, /* Bit 13: Alternate GMII driver */ | ||
1605 | PHY_L_PC_TEN_CRS = 1<<10, /* Bit 10: Extend CRS*/ | ||
1606 | }; | ||
1607 | |||
1608 | /***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/ | ||
1609 | enum { | ||
1610 | PHY_L_CIM_ISOL = 0xff<<8,/* Bit 15..8: Isolate Count */ | ||
1611 | PHY_L_CIM_FALSE_CAR = 0xff, /* Bit 7..0: False Carrier Count */ | ||
1612 | }; | ||
1613 | |||
1614 | /* | ||
1615 | * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding | ||
1616 | */ | ||
1617 | enum { | ||
1618 | PHY_L_P_NO_PAUSE= 0<<10,/* Bit 11..10: no Pause Mode */ | ||
1619 | PHY_L_P_SYM_MD = 1<<10, /* Bit 11..10: symmetric Pause Mode */ | ||
1620 | PHY_L_P_ASYM_MD = 2<<10,/* Bit 11..10: asymmetric Pause Mode */ | ||
1621 | PHY_L_P_BOTH_MD = 3<<10,/* Bit 11..10: both Pause Mode */ | ||
1622 | }; | ||
1623 | |||
1624 | /* | ||
1625 | * National-Specific | ||
1626 | */ | ||
1627 | /***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ | ||
1628 | enum { | ||
1629 | PHY_N_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */ | ||
1630 | PHY_N_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */ | ||
1631 | PHY_N_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */ | ||
1632 | PHY_N_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */ | ||
1633 | PHY_N_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */ | ||
1634 | PHY_N_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */ | ||
1635 | PHY_N_1000C_APC = 1<<7, /* Bit 7: Asymmetric Pause Cap. */}; | ||
1636 | |||
1637 | |||
1638 | /***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ | ||
1639 | enum { | ||
1640 | PHY_N_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */ | ||
1641 | PHY_N_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */ | ||
1642 | PHY_N_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */ | ||
1643 | PHY_N_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status*/ | ||
1644 | PHY_N_1000S_LP_FD= 1<<11, /* Bit 11: Link Partner can FD */ | ||
1645 | PHY_N_1000S_LP_HD= 1<<10, /* Bit 10: Link Partner can HD */ | ||
1646 | PHY_N_1000C_LP_APC= 1<<9, /* Bit 9: LP Asym. Pause Cap. */ | ||
1647 | PHY_N_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */ | ||
1648 | }; | ||
1649 | |||
1650 | /***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/ | ||
1651 | enum { | ||
1652 | PHY_N_ES_X_FD_CAP= 1<<15, /* Bit 15: 1000Base-X FD capable */ | ||
1653 | PHY_N_ES_X_HD_CAP= 1<<14, /* Bit 14: 1000Base-X HD capable */ | ||
1654 | PHY_N_ES_T_FD_CAP= 1<<13, /* Bit 13: 1000Base-T FD capable */ | ||
1655 | PHY_N_ES_T_HD_CAP= 1<<12, /* Bit 12: 1000Base-T HD capable */ | ||
1656 | }; | ||
1657 | |||
1658 | /** Marvell-Specific */ | 1320 | /** Marvell-Specific */ |
1659 | enum { | 1321 | enum { |
1660 | PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */ | 1322 | PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */ |
@@ -1718,7 +1380,7 @@ enum { | |||
1718 | PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */ | 1380 | PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */ |
1719 | }; | 1381 | }; |
1720 | 1382 | ||
1721 | #define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) | 1383 | #define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) |
1722 | 1384 | ||
1723 | enum { | 1385 | enum { |
1724 | PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */ | 1386 | PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */ |
@@ -2105,7 +1767,7 @@ enum { | |||
2105 | GM_GPSR_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */ | 1767 | GM_GPSR_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */ |
2106 | GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */ | 1768 | GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */ |
2107 | }; | 1769 | }; |
2108 | 1770 | ||
2109 | /* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ | 1771 | /* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ |
2110 | enum { | 1772 | enum { |
2111 | GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */ | 1773 | GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */ |
@@ -2127,7 +1789,7 @@ enum { | |||
2127 | 1789 | ||
2128 | #define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) | 1790 | #define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) |
2129 | #define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS) | 1791 | #define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS) |
2130 | 1792 | ||
2131 | /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ | 1793 | /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ |
2132 | enum { | 1794 | enum { |
2133 | GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */ | 1795 | GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */ |
@@ -2138,7 +1800,7 @@ enum { | |||
2138 | 1800 | ||
2139 | #define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK) | 1801 | #define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK) |
2140 | #define TX_COL_DEF 0x04 | 1802 | #define TX_COL_DEF 0x04 |
2141 | 1803 | ||
2142 | /* GM_RX_CTRL 16 bit r/w Receive Control Register */ | 1804 | /* GM_RX_CTRL 16 bit r/w Receive Control Register */ |
2143 | enum { | 1805 | enum { |
2144 | GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */ | 1806 | GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */ |
@@ -2146,7 +1808,7 @@ enum { | |||
2146 | GM_RXCR_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */ | 1808 | GM_RXCR_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */ |
2147 | GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */ | 1809 | GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */ |
2148 | }; | 1810 | }; |
2149 | 1811 | ||
2150 | /* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ | 1812 | /* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ |
2151 | enum { | 1813 | enum { |
2152 | GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */ | 1814 | GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */ |
@@ -2171,7 +1833,7 @@ enum { | |||
2171 | GM_SMOD_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */ | 1833 | GM_SMOD_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */ |
2172 | GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ | 1834 | GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ |
2173 | }; | 1835 | }; |
2174 | 1836 | ||
2175 | #define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK) | 1837 | #define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK) |
2176 | #define DATA_BLIND_DEF 0x04 | 1838 | #define DATA_BLIND_DEF 0x04 |
2177 | 1839 | ||
@@ -2186,7 +1848,7 @@ enum { | |||
2186 | GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */ | 1848 | GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */ |
2187 | GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */ | 1849 | GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */ |
2188 | }; | 1850 | }; |
2189 | 1851 | ||
2190 | #define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK) | 1852 | #define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK) |
2191 | #define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK) | 1853 | #define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK) |
2192 | 1854 | ||
@@ -2195,7 +1857,7 @@ enum { | |||
2195 | GM_PAR_MIB_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */ | 1857 | GM_PAR_MIB_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */ |
2196 | GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */ | 1858 | GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */ |
2197 | }; | 1859 | }; |
2198 | 1860 | ||
2199 | /* Receive Frame Status Encoding */ | 1861 | /* Receive Frame Status Encoding */ |
2200 | enum { | 1862 | enum { |
2201 | GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ | 1863 | GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ |
@@ -2217,12 +1879,12 @@ enum { | |||
2217 | /* | 1879 | /* |
2218 | * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) | 1880 | * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) |
2219 | */ | 1881 | */ |
2220 | GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | | 1882 | GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | |
2221 | GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | | 1883 | GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | |
2222 | GMR_FS_JABBER, | 1884 | GMR_FS_JABBER, |
2223 | /* Rx GMAC FIFO Flush Mask (default) */ | 1885 | /* Rx GMAC FIFO Flush Mask (default) */ |
2224 | RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR | | 1886 | RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR | |
2225 | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | | 1887 | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | |
2226 | GMR_FS_JABBER, | 1888 | GMR_FS_JABBER, |
2227 | }; | 1889 | }; |
2228 | 1890 | ||
@@ -2540,10 +2202,6 @@ enum { | |||
2540 | }; | 2202 | }; |
2541 | 2203 | ||
2542 | 2204 | ||
2543 | /* XM_PHY_ADDR 16 bit r/w PHY Address Register */ | ||
2544 | #define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */ | ||
2545 | |||
2546 | |||
2547 | /* XM_GP_PORT 32 bit r/w General Purpose Port Register */ | 2205 | /* XM_GP_PORT 32 bit r/w General Purpose Port Register */ |
2548 | enum { | 2206 | enum { |
2549 | XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */ | 2207 | XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */ |
@@ -2662,8 +2320,8 @@ enum { | |||
2662 | }; | 2320 | }; |
2663 | 2321 | ||
2664 | #define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) | 2322 | #define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) |
2665 | #define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ | 2323 | #define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ |
2666 | XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) | 2324 | XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA) |
2667 | 2325 | ||
2668 | /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ | 2326 | /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ |
2669 | enum { | 2327 | enum { |
@@ -2793,28 +2451,20 @@ struct skge_hw { | |||
2793 | u32 intr_mask; | 2451 | u32 intr_mask; |
2794 | struct net_device *dev[2]; | 2452 | struct net_device *dev[2]; |
2795 | 2453 | ||
2796 | u8 mac_cfg; | ||
2797 | u8 chip_id; | 2454 | u8 chip_id; |
2455 | u8 chip_rev; | ||
2798 | u8 phy_type; | 2456 | u8 phy_type; |
2799 | u8 pmd_type; | 2457 | u8 pmd_type; |
2800 | u16 phy_addr; | 2458 | u16 phy_addr; |
2459 | u8 ports; | ||
2801 | 2460 | ||
2802 | u32 ram_size; | 2461 | u32 ram_size; |
2803 | u32 ram_offset; | 2462 | u32 ram_offset; |
2804 | 2463 | ||
2805 | struct tasklet_struct ext_tasklet; | 2464 | struct tasklet_struct ext_tasklet; |
2806 | spinlock_t phy_lock; | 2465 | spinlock_t phy_lock; |
2807 | }; | 2466 | }; |
2808 | 2467 | ||
2809 | static inline int isdualport(const struct skge_hw *hw) | ||
2810 | { | ||
2811 | return !(hw->mac_cfg & CFG_SNG_MAC); | ||
2812 | } | ||
2813 | |||
2814 | static inline u8 chip_rev(const struct skge_hw *hw) | ||
2815 | { | ||
2816 | return (hw->mac_cfg & CFG_CHIP_R_MSK) >> 4; | ||
2817 | } | ||
2818 | 2468 | ||
2819 | static inline int iscopper(const struct skge_hw *hw) | 2469 | static inline int iscopper(const struct skge_hw *hw) |
2820 | { | 2470 | { |
@@ -2827,7 +2477,7 @@ enum { | |||
2827 | FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */ | 2477 | FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */ |
2828 | FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ | 2478 | FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ |
2829 | }; | 2479 | }; |
2830 | 2480 | ||
2831 | struct skge_port { | 2481 | struct skge_port { |
2832 | u32 msg_enable; | 2482 | u32 msg_enable; |
2833 | struct skge_hw *hw; | 2483 | struct skge_hw *hw; |
@@ -2853,8 +2503,8 @@ struct skge_port { | |||
2853 | void *mem; /* PCI memory for rings */ | 2503 | void *mem; /* PCI memory for rings */ |
2854 | dma_addr_t dma; | 2504 | dma_addr_t dma; |
2855 | unsigned long mem_size; | 2505 | unsigned long mem_size; |
2506 | unsigned int rx_buf_size; | ||
2856 | 2507 | ||
2857 | struct timer_list link_check; | ||
2858 | struct timer_list led_blink; | 2508 | struct timer_list led_blink; |
2859 | }; | 2509 | }; |
2860 | 2510 | ||
@@ -2863,7 +2513,6 @@ struct skge_port { | |||
2863 | static inline u32 skge_read32(const struct skge_hw *hw, int reg) | 2513 | static inline u32 skge_read32(const struct skge_hw *hw, int reg) |
2864 | { | 2514 | { |
2865 | return readl(hw->regs + reg); | 2515 | return readl(hw->regs + reg); |
2866 | |||
2867 | } | 2516 | } |
2868 | 2517 | ||
2869 | static inline u16 skge_read16(const struct skge_hw *hw, int reg) | 2518 | static inline u16 skge_read16(const struct skge_hw *hw, int reg) |
@@ -2892,114 +2541,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val) | |||
2892 | } | 2541 | } |
2893 | 2542 | ||
2894 | /* MAC Related Registers inside the device. */ | 2543 | /* MAC Related Registers inside the device. */ |
2895 | #define SKGEMAC_REG(port,reg) (((port)<<7)+(reg)) | 2544 | #define SK_REG(port,reg) (((port)<<7)+(reg)) |
2896 | 2545 | #define SK_XMAC_REG(port, reg) \ | |
2897 | /* PCI config space can be accessed via memory mapped space */ | ||
2898 | #define SKGEPCI_REG(reg) ((reg)+ 0x380) | ||
2899 | |||
2900 | #define SKGEXM_REG(port, reg) \ | ||
2901 | ((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1) | 2546 | ((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1) |
2902 | 2547 | ||
2903 | static inline u32 skge_xm_read32(const struct skge_hw *hw, int port, int reg) | 2548 | static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg) |
2904 | { | ||
2905 | return skge_read32(hw, SKGEXM_REG(port,reg)); | ||
2906 | } | ||
2907 | |||
2908 | static inline u16 skge_xm_read16(const struct skge_hw *hw, int port, int reg) | ||
2909 | { | 2549 | { |
2910 | return skge_read16(hw, SKGEXM_REG(port,reg)); | 2550 | u32 v; |
2551 | v = skge_read16(hw, SK_XMAC_REG(port, reg)); | ||
2552 | v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16; | ||
2553 | return v; | ||
2911 | } | 2554 | } |
2912 | 2555 | ||
2913 | static inline u8 skge_xm_read8(const struct skge_hw *hw, int port, int reg) | 2556 | static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg) |
2914 | { | 2557 | { |
2915 | return skge_read8(hw, SKGEXM_REG(port,reg)); | 2558 | return skge_read16(hw, SK_XMAC_REG(port,reg)); |
2916 | } | 2559 | } |
2917 | 2560 | ||
2918 | static inline void skge_xm_write32(const struct skge_hw *hw, int port, int r, u32 v) | 2561 | static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v) |
2919 | { | 2562 | { |
2920 | skge_write32(hw, SKGEXM_REG(port,r), v); | 2563 | skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff); |
2564 | skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16); | ||
2921 | } | 2565 | } |
2922 | 2566 | ||
2923 | static inline void skge_xm_write16(const struct skge_hw *hw, int port, int r, u16 v) | 2567 | static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v) |
2924 | { | 2568 | { |
2925 | skge_write16(hw, SKGEXM_REG(port,r), v); | 2569 | skge_write16(hw, SK_XMAC_REG(port,r), v); |
2926 | } | 2570 | } |
2927 | 2571 | ||
2928 | static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 v) | 2572 | static inline void xm_outhash(const struct skge_hw *hw, int port, int reg, |
2929 | { | ||
2930 | skge_write8(hw, SKGEXM_REG(port,r), v); | ||
2931 | } | ||
2932 | |||
2933 | static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg, | ||
2934 | const u8 *hash) | 2573 | const u8 *hash) |
2935 | { | 2574 | { |
2936 | skge_xm_write16(hw, port, reg, | 2575 | xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8)); |
2937 | (u16)hash[0] | ((u16)hash[1] << 8)); | 2576 | xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8)); |
2938 | skge_xm_write16(hw, port, reg+2, | 2577 | xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8)); |
2939 | (u16)hash[2] | ((u16)hash[3] << 8)); | 2578 | xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8)); |
2940 | skge_xm_write16(hw, port, reg+4, | ||
2941 | (u16)hash[4] | ((u16)hash[5] << 8)); | ||
2942 | skge_xm_write16(hw, port, reg+6, | ||
2943 | (u16)hash[6] | ((u16)hash[7] << 8)); | ||
2944 | } | 2579 | } |
2945 | 2580 | ||
2946 | static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg, | 2581 | static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg, |
2947 | const u8 *addr) | 2582 | const u8 *addr) |
2948 | { | 2583 | { |
2949 | skge_xm_write16(hw, port, reg, | 2584 | xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8)); |
2950 | (u16)addr[0] | ((u16)addr[1] << 8)); | 2585 | xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8)); |
2951 | skge_xm_write16(hw, port, reg, | 2586 | xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8)); |
2952 | (u16)addr[2] | ((u16)addr[3] << 8)); | ||
2953 | skge_xm_write16(hw, port, reg, | ||
2954 | (u16)addr[4] | ((u16)addr[5] << 8)); | ||
2955 | } | 2587 | } |
2956 | 2588 | ||
2589 | #define SK_GMAC_REG(port,reg) \ | ||
2590 | (BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg)) | ||
2957 | 2591 | ||
2958 | #define SKGEGMA_REG(port,reg) \ | 2592 | static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg) |
2959 | ((reg) + BASE_GMAC_1 + \ | ||
2960 | (port) * (BASE_GMAC_2-BASE_GMAC_1)) | ||
2961 | |||
2962 | static inline u16 skge_gma_read16(const struct skge_hw *hw, int port, int reg) | ||
2963 | { | 2593 | { |
2964 | return skge_read16(hw, SKGEGMA_REG(port,reg)); | 2594 | return skge_read16(hw, SK_GMAC_REG(port,reg)); |
2965 | } | 2595 | } |
2966 | 2596 | ||
2967 | static inline u32 skge_gma_read32(const struct skge_hw *hw, int port, int reg) | 2597 | static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg) |
2968 | { | 2598 | { |
2969 | return (u32) skge_read16(hw, SKGEGMA_REG(port,reg)) | 2599 | return (u32) skge_read16(hw, SK_GMAC_REG(port,reg)) |
2970 | | ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16); | 2600 | | ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16); |
2971 | } | 2601 | } |
2972 | 2602 | ||
2973 | static inline u8 skge_gma_read8(const struct skge_hw *hw, int port, int reg) | 2603 | static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v) |
2974 | { | 2604 | { |
2975 | return skge_read8(hw, SKGEGMA_REG(port,reg)); | 2605 | skge_write16(hw, SK_GMAC_REG(port,r), v); |
2976 | } | 2606 | } |
2977 | 2607 | ||
2978 | static inline void skge_gma_write16(const struct skge_hw *hw, int port, int r, u16 v) | 2608 | static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v) |
2979 | { | 2609 | { |
2980 | skge_write16(hw, SKGEGMA_REG(port,r), v); | 2610 | skge_write16(hw, SK_GMAC_REG(port, r), (u16) v); |
2611 | skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16)); | ||
2981 | } | 2612 | } |
2982 | 2613 | ||
2983 | static inline void skge_gma_write32(const struct skge_hw *hw, int port, int r, u32 v) | 2614 | static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v) |
2984 | { | 2615 | { |
2985 | skge_write16(hw, SKGEGMA_REG(port, r), (u16) v); | 2616 | skge_write8(hw, SK_GMAC_REG(port,r), v); |
2986 | skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16)); | ||
2987 | } | 2617 | } |
2988 | 2618 | ||
2989 | static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v) | 2619 | static inline void gma_set_addr(struct skge_hw *hw, int port, int reg, |
2990 | { | ||
2991 | skge_write8(hw, SKGEGMA_REG(port,r), v); | ||
2992 | } | ||
2993 | |||
2994 | static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg, | ||
2995 | const u8 *addr) | 2620 | const u8 *addr) |
2996 | { | 2621 | { |
2997 | skge_gma_write16(hw, port, reg, | 2622 | gma_write16(hw, port, reg, (u16) addr[0] | ((u16) addr[1] << 8)); |
2998 | (u16) addr[0] | ((u16) addr[1] << 8)); | 2623 | gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8)); |
2999 | skge_gma_write16(hw, port, reg+4, | 2624 | gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8)); |
3000 | (u16) addr[2] | ((u16) addr[3] << 8)); | ||
3001 | skge_gma_write16(hw, port, reg+8, | ||
3002 | (u16) addr[4] | ((u16) addr[5] << 8)); | ||
3003 | } | 2625 | } |
3004 | 2626 | ||
3005 | #endif | 2627 | #endif |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 16363b5c6f56..404ea4297e32 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -74,6 +74,7 @@ | |||
74 | #include <linux/rtnetlink.h> | 74 | #include <linux/rtnetlink.h> |
75 | #include <linux/if_arp.h> | 75 | #include <linux/if_arp.h> |
76 | #include <linux/if_slip.h> | 76 | #include <linux/if_slip.h> |
77 | #include <linux/delay.h> | ||
77 | #include <linux/init.h> | 78 | #include <linux/init.h> |
78 | #include "slip.h" | 79 | #include "slip.h" |
79 | #ifdef CONFIG_INET | 80 | #ifdef CONFIG_INET |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index cfb9d3cdb04a..1438fdd20826 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1998,7 +1998,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) | |||
1998 | if (retval) | 1998 | if (retval) |
1999 | goto err_out; | 1999 | goto err_out; |
2000 | 2000 | ||
2001 | set_irq_type(dev->irq, IRQT_RISING); | 2001 | set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE); |
2002 | 2002 | ||
2003 | #ifdef SMC_USE_PXA_DMA | 2003 | #ifdef SMC_USE_PXA_DMA |
2004 | { | 2004 | { |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 946528e6b742..7089d86e857a 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -182,6 +182,16 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
182 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 182 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
183 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 183 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
184 | 184 | ||
185 | #include <asm/mach-types.h> | ||
186 | #include <asm/arch/cpu.h> | ||
187 | |||
188 | #define SMC_IRQ_TRIGGER_TYPE (( \ | ||
189 | machine_is_omap_h2() \ | ||
190 | || machine_is_omap_h3() \ | ||
191 | || (machine_is_omap_innovator() && !cpu_is_omap150()) \ | ||
192 | ) ? IRQT_FALLING : IRQT_RISING) | ||
193 | |||
194 | |||
185 | #elif defined(CONFIG_SH_SH4202_MICRODEV) | 195 | #elif defined(CONFIG_SH_SH4202_MICRODEV) |
186 | 196 | ||
187 | #define SMC_CAN_USE_8BIT 0 | 197 | #define SMC_CAN_USE_8BIT 0 |
@@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) | |||
300 | 310 | ||
301 | #endif | 311 | #endif |
302 | 312 | ||
313 | #ifndef SMC_IRQ_TRIGGER_TYPE | ||
314 | #define SMC_IRQ_TRIGGER_TYPE IRQT_RISING | ||
315 | #endif | ||
303 | 316 | ||
304 | #ifdef SMC_USE_PXA_DMA | 317 | #ifdef SMC_USE_PXA_DMA |
305 | /* | 318 | /* |
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 12e2b6826fa3..88b89dc95c77 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c | |||
@@ -1286,7 +1286,7 @@ static void init_ring(struct net_device *dev) | |||
1286 | np->rx_info[i].skb = skb; | 1286 | np->rx_info[i].skb = skb; |
1287 | if (skb == NULL) | 1287 | if (skb == NULL) |
1288 | break; | 1288 | break; |
1289 | np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1289 | np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1290 | skb->dev = dev; /* Mark as being used by this device. */ | 1290 | skb->dev = dev; /* Mark as being used by this device. */ |
1291 | /* Grrr, we cannot offset to correctly align the IP header. */ | 1291 | /* Grrr, we cannot offset to correctly align the IP header. */ |
1292 | np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); | 1292 | np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); |
@@ -1572,7 +1572,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) | |||
1572 | pci_dma_sync_single_for_cpu(np->pci_dev, | 1572 | pci_dma_sync_single_for_cpu(np->pci_dev, |
1573 | np->rx_info[entry].mapping, | 1573 | np->rx_info[entry].mapping, |
1574 | pkt_len, PCI_DMA_FROMDEVICE); | 1574 | pkt_len, PCI_DMA_FROMDEVICE); |
1575 | eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); | 1575 | eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0); |
1576 | pci_dma_sync_single_for_device(np->pci_dev, | 1576 | pci_dma_sync_single_for_device(np->pci_dev, |
1577 | np->rx_info[entry].mapping, | 1577 | np->rx_info[entry].mapping, |
1578 | pkt_len, PCI_DMA_FROMDEVICE); | 1578 | pkt_len, PCI_DMA_FROMDEVICE); |
@@ -1696,7 +1696,7 @@ static void refill_rx_ring(struct net_device *dev) | |||
1696 | if (skb == NULL) | 1696 | if (skb == NULL) |
1697 | break; /* Better luck next round. */ | 1697 | break; /* Better luck next round. */ |
1698 | np->rx_info[entry].mapping = | 1698 | np->rx_info[entry].mapping = |
1699 | pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1699 | pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1700 | skb->dev = dev; /* Mark as being used by this device. */ | 1700 | skb->dev = dev; /* Mark as being used by this device. */ |
1701 | np->rx_ring[entry].rxaddr = | 1701 | np->rx_ring[entry].rxaddr = |
1702 | cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); | 1702 | cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); |
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 08cb7177a175..d500a5771dbc 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c | |||
@@ -1028,7 +1028,7 @@ static void init_ring(struct net_device *dev) | |||
1028 | skb->dev = dev; /* Mark as being used by this device. */ | 1028 | skb->dev = dev; /* Mark as being used by this device. */ |
1029 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ | 1029 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ |
1030 | np->rx_ring[i].frag[0].addr = cpu_to_le32( | 1030 | np->rx_ring[i].frag[0].addr = cpu_to_le32( |
1031 | pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, | 1031 | pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, |
1032 | PCI_DMA_FROMDEVICE)); | 1032 | PCI_DMA_FROMDEVICE)); |
1033 | np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); | 1033 | np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); |
1034 | } | 1034 | } |
@@ -1341,7 +1341,7 @@ static void rx_poll(unsigned long data) | |||
1341 | np->rx_buf_sz, | 1341 | np->rx_buf_sz, |
1342 | PCI_DMA_FROMDEVICE); | 1342 | PCI_DMA_FROMDEVICE); |
1343 | 1343 | ||
1344 | eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); | 1344 | eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0); |
1345 | pci_dma_sync_single_for_device(np->pci_dev, | 1345 | pci_dma_sync_single_for_device(np->pci_dev, |
1346 | desc->frag[0].addr, | 1346 | desc->frag[0].addr, |
1347 | np->rx_buf_sz, | 1347 | np->rx_buf_sz, |
@@ -1400,7 +1400,7 @@ static void refill_rx (struct net_device *dev) | |||
1400 | skb->dev = dev; /* Mark as being used by this device. */ | 1400 | skb->dev = dev; /* Mark as being used by this device. */ |
1401 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1401 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
1402 | np->rx_ring[entry].frag[0].addr = cpu_to_le32( | 1402 | np->rx_ring[entry].frag[0].addr = cpu_to_le32( |
1403 | pci_map_single(np->pci_dev, skb->tail, | 1403 | pci_map_single(np->pci_dev, skb->data, |
1404 | np->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 1404 | np->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
1405 | } | 1405 | } |
1406 | /* Perhaps we need not reset this field. */ | 1406 | /* Perhaps we need not reset this field. */ |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index dd357dd8c370..fc353e348f9a 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -446,13 +446,13 @@ static void de_rx (struct de_private *de) | |||
446 | 446 | ||
447 | mapping = | 447 | mapping = |
448 | de->rx_skb[rx_tail].mapping = | 448 | de->rx_skb[rx_tail].mapping = |
449 | pci_map_single(de->pdev, copy_skb->tail, | 449 | pci_map_single(de->pdev, copy_skb->data, |
450 | buflen, PCI_DMA_FROMDEVICE); | 450 | buflen, PCI_DMA_FROMDEVICE); |
451 | de->rx_skb[rx_tail].skb = copy_skb; | 451 | de->rx_skb[rx_tail].skb = copy_skb; |
452 | } else { | 452 | } else { |
453 | pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); | 453 | pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); |
454 | skb_reserve(copy_skb, RX_OFFSET); | 454 | skb_reserve(copy_skb, RX_OFFSET); |
455 | memcpy(skb_put(copy_skb, len), skb->tail, len); | 455 | memcpy(skb_put(copy_skb, len), skb->data, len); |
456 | 456 | ||
457 | pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); | 457 | pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); |
458 | 458 | ||
@@ -1269,7 +1269,7 @@ static int de_refill_rx (struct de_private *de) | |||
1269 | skb->dev = de->dev; | 1269 | skb->dev = de->dev; |
1270 | 1270 | ||
1271 | de->rx_skb[i].mapping = pci_map_single(de->pdev, | 1271 | de->rx_skb[i].mapping = pci_map_single(de->pdev, |
1272 | skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1272 | skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1273 | de->rx_skb[i].skb = skb; | 1273 | de->rx_skb[i].skb = skb; |
1274 | 1274 | ||
1275 | de->rx_ring[i].opts1 = cpu_to_le32(DescOwn); | 1275 | de->rx_ring[i].opts1 = cpu_to_le32(DescOwn); |
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 7b899702ceb9..74e9075d9c48 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -945,8 +945,8 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) | |||
945 | 945 | ||
946 | /* Received Packet CRC check need or not */ | 946 | /* Received Packet CRC check need or not */ |
947 | if ( (db->dm910x_chk_mode & 1) && | 947 | if ( (db->dm910x_chk_mode & 1) && |
948 | (cal_CRC(skb->tail, rxlen, 1) != | 948 | (cal_CRC(skb->data, rxlen, 1) != |
949 | (*(u32 *) (skb->tail+rxlen) ))) { /* FIXME (?) */ | 949 | (*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */ |
950 | /* Found a error received packet */ | 950 | /* Found a error received packet */ |
951 | dmfe_reuse_skb(db, rxptr->rx_skb_ptr); | 951 | dmfe_reuse_skb(db, rxptr->rx_skb_ptr); |
952 | db->dm910x_chk_mode = 3; | 952 | db->dm910x_chk_mode = 3; |
@@ -959,7 +959,7 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) | |||
959 | /* size less than COPY_SIZE, allocate a rxlen SKB */ | 959 | /* size less than COPY_SIZE, allocate a rxlen SKB */ |
960 | skb->dev = dev; | 960 | skb->dev = dev; |
961 | skb_reserve(skb, 2); /* 16byte align */ | 961 | skb_reserve(skb, 2); /* 16byte align */ |
962 | memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen); | 962 | memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->data, rxlen); |
963 | dmfe_reuse_skb(db, rxptr->rx_skb_ptr); | 963 | dmfe_reuse_skb(db, rxptr->rx_skb_ptr); |
964 | } else { | 964 | } else { |
965 | skb->dev = dev; | 965 | skb->dev = dev; |
@@ -1252,7 +1252,7 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb) | |||
1252 | 1252 | ||
1253 | if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) { | 1253 | if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) { |
1254 | rxptr->rx_skb_ptr = skb; | 1254 | rxptr->rx_skb_ptr = skb; |
1255 | rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); | 1255 | rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); |
1256 | wmb(); | 1256 | wmb(); |
1257 | rxptr->rdes0 = cpu_to_le32(0x80000000); | 1257 | rxptr->rdes0 = cpu_to_le32(0x80000000); |
1258 | db->rx_avail_cnt++; | 1258 | db->rx_avail_cnt++; |
@@ -1463,7 +1463,7 @@ static void allocate_rx_buffer(struct dmfe_board_info *db) | |||
1463 | if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) | 1463 | if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) |
1464 | break; | 1464 | break; |
1465 | rxptr->rx_skb_ptr = skb; /* FIXME (?) */ | 1465 | rxptr->rx_skb_ptr = skb; /* FIXME (?) */ |
1466 | rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); | 1466 | rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); |
1467 | wmb(); | 1467 | wmb(); |
1468 | rxptr->rdes0 = cpu_to_le32(0x80000000); | 1468 | rxptr->rdes0 = cpu_to_le32(0x80000000); |
1469 | rxptr = rxptr->next_rx_desc; | 1469 | rxptr = rxptr->next_rx_desc; |
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index afb5cda9d8e1..bb3558164a5b 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c | |||
@@ -78,7 +78,7 @@ int tulip_refill_rx(struct net_device *dev) | |||
78 | if (skb == NULL) | 78 | if (skb == NULL) |
79 | break; | 79 | break; |
80 | 80 | ||
81 | mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ, | 81 | mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, |
82 | PCI_DMA_FROMDEVICE); | 82 | PCI_DMA_FROMDEVICE); |
83 | tp->rx_buffers[entry].mapping = mapping; | 83 | tp->rx_buffers[entry].mapping = mapping; |
84 | 84 | ||
@@ -199,12 +199,12 @@ int tulip_poll(struct net_device *dev, int *budget) | |||
199 | tp->rx_buffers[entry].mapping, | 199 | tp->rx_buffers[entry].mapping, |
200 | pkt_len, PCI_DMA_FROMDEVICE); | 200 | pkt_len, PCI_DMA_FROMDEVICE); |
201 | #if ! defined(__alpha__) | 201 | #if ! defined(__alpha__) |
202 | eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, | 202 | eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data, |
203 | pkt_len, 0); | 203 | pkt_len, 0); |
204 | skb_put(skb, pkt_len); | 204 | skb_put(skb, pkt_len); |
205 | #else | 205 | #else |
206 | memcpy(skb_put(skb, pkt_len), | 206 | memcpy(skb_put(skb, pkt_len), |
207 | tp->rx_buffers[entry].skb->tail, | 207 | tp->rx_buffers[entry].skb->data, |
208 | pkt_len); | 208 | pkt_len); |
209 | #endif | 209 | #endif |
210 | pci_dma_sync_single_for_device(tp->pdev, | 210 | pci_dma_sync_single_for_device(tp->pdev, |
@@ -423,12 +423,12 @@ static int tulip_rx(struct net_device *dev) | |||
423 | tp->rx_buffers[entry].mapping, | 423 | tp->rx_buffers[entry].mapping, |
424 | pkt_len, PCI_DMA_FROMDEVICE); | 424 | pkt_len, PCI_DMA_FROMDEVICE); |
425 | #if ! defined(__alpha__) | 425 | #if ! defined(__alpha__) |
426 | eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, | 426 | eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data, |
427 | pkt_len, 0); | 427 | pkt_len, 0); |
428 | skb_put(skb, pkt_len); | 428 | skb_put(skb, pkt_len); |
429 | #else | 429 | #else |
430 | memcpy(skb_put(skb, pkt_len), | 430 | memcpy(skb_put(skb, pkt_len), |
431 | tp->rx_buffers[entry].skb->tail, | 431 | tp->rx_buffers[entry].skb->data, |
432 | pkt_len); | 432 | pkt_len); |
433 | #endif | 433 | #endif |
434 | pci_dma_sync_single_for_device(tp->pdev, | 434 | pci_dma_sync_single_for_device(tp->pdev, |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 08e0f80f89d5..d45d8f56e5b4 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -625,7 +625,7 @@ static void tulip_init_ring(struct net_device *dev) | |||
625 | tp->rx_buffers[i].skb = skb; | 625 | tp->rx_buffers[i].skb = skb; |
626 | if (skb == NULL) | 626 | if (skb == NULL) |
627 | break; | 627 | break; |
628 | mapping = pci_map_single(tp->pdev, skb->tail, | 628 | mapping = pci_map_single(tp->pdev, skb->data, |
629 | PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | 629 | PKT_BUF_SZ, PCI_DMA_FROMDEVICE); |
630 | tp->rx_buffers[i].mapping = mapping; | 630 | tp->rx_buffers[i].mapping = mapping; |
631 | skb->dev = dev; /* Mark as being used by this device. */ | 631 | skb->dev = dev; /* Mark as being used by this device. */ |
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index db4b32c2369a..5b1af3986abf 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c | |||
@@ -849,7 +849,7 @@ static void init_rxtx_rings(struct net_device *dev) | |||
849 | if (skb == NULL) | 849 | if (skb == NULL) |
850 | break; | 850 | break; |
851 | skb->dev = dev; /* Mark as being used by this device. */ | 851 | skb->dev = dev; /* Mark as being used by this device. */ |
852 | np->rx_addr[i] = pci_map_single(np->pci_dev,skb->tail, | 852 | np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data, |
853 | skb->len,PCI_DMA_FROMDEVICE); | 853 | skb->len,PCI_DMA_FROMDEVICE); |
854 | 854 | ||
855 | np->rx_ring[i].buffer1 = np->rx_addr[i]; | 855 | np->rx_ring[i].buffer1 = np->rx_addr[i]; |
@@ -1269,7 +1269,7 @@ static int netdev_rx(struct net_device *dev) | |||
1269 | pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], | 1269 | pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], |
1270 | np->rx_skbuff[entry]->len, | 1270 | np->rx_skbuff[entry]->len, |
1271 | PCI_DMA_FROMDEVICE); | 1271 | PCI_DMA_FROMDEVICE); |
1272 | eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); | 1272 | eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0); |
1273 | skb_put(skb, pkt_len); | 1273 | skb_put(skb, pkt_len); |
1274 | pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry], | 1274 | pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry], |
1275 | np->rx_skbuff[entry]->len, | 1275 | np->rx_skbuff[entry]->len, |
@@ -1315,7 +1315,7 @@ static int netdev_rx(struct net_device *dev) | |||
1315 | break; /* Better luck next round. */ | 1315 | break; /* Better luck next round. */ |
1316 | skb->dev = dev; /* Mark as being used by this device. */ | 1316 | skb->dev = dev; /* Mark as being used by this device. */ |
1317 | np->rx_addr[entry] = pci_map_single(np->pci_dev, | 1317 | np->rx_addr[entry] = pci_map_single(np->pci_dev, |
1318 | skb->tail, | 1318 | skb->data, |
1319 | skb->len, PCI_DMA_FROMDEVICE); | 1319 | skb->len, PCI_DMA_FROMDEVICE); |
1320 | np->rx_ring[entry].buffer1 = np->rx_addr[entry]; | 1320 | np->rx_ring[entry].buffer1 = np->rx_addr[entry]; |
1321 | } | 1321 | } |
diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c index b8a9b395c5ea..887d7245fe7b 100644 --- a/drivers/net/tulip/xircom_tulip_cb.c +++ b/drivers/net/tulip/xircom_tulip_cb.c | |||
@@ -899,7 +899,7 @@ static void xircom_init_ring(struct net_device *dev) | |||
899 | break; | 899 | break; |
900 | skb->dev = dev; /* Mark as being used by this device. */ | 900 | skb->dev = dev; /* Mark as being used by this device. */ |
901 | tp->rx_ring[i].status = Rx0DescOwned; /* Owned by Xircom chip */ | 901 | tp->rx_ring[i].status = Rx0DescOwned; /* Owned by Xircom chip */ |
902 | tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail); | 902 | tp->rx_ring[i].buffer1 = virt_to_bus(skb->data); |
903 | } | 903 | } |
904 | tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); | 904 | tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); |
905 | 905 | ||
@@ -1291,7 +1291,7 @@ xircom_rx(struct net_device *dev) | |||
1291 | if (skb == NULL) | 1291 | if (skb == NULL) |
1292 | break; | 1292 | break; |
1293 | skb->dev = dev; /* Mark as being used by this device. */ | 1293 | skb->dev = dev; /* Mark as being used by this device. */ |
1294 | tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail); | 1294 | tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data); |
1295 | work_done++; | 1295 | work_done++; |
1296 | } | 1296 | } |
1297 | tp->rx_ring[entry].status = Rx0DescOwned; | 1297 | tp->rx_ring[entry].status = Rx0DescOwned; |
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 8f3392989a06..0b5ca2537963 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -1661,7 +1661,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) | |||
1661 | #endif | 1661 | #endif |
1662 | 1662 | ||
1663 | skb->dev = tp->dev; | 1663 | skb->dev = tp->dev; |
1664 | dma_addr = pci_map_single(tp->pdev, skb->tail, | 1664 | dma_addr = pci_map_single(tp->pdev, skb->data, |
1665 | PKT_BUF_SZ, PCI_DMA_FROMDEVICE); | 1665 | PKT_BUF_SZ, PCI_DMA_FROMDEVICE); |
1666 | 1666 | ||
1667 | /* Since no card does 64 bit DAC, the high bits will never | 1667 | /* Since no card does 64 bit DAC, the high bits will never |
@@ -1721,7 +1721,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready, | |||
1721 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, | 1721 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, |
1722 | PKT_BUF_SZ, | 1722 | PKT_BUF_SZ, |
1723 | PCI_DMA_FROMDEVICE); | 1723 | PCI_DMA_FROMDEVICE); |
1724 | eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0); | 1724 | eth_copy_and_sum(new_skb, skb->data, pkt_len, 0); |
1725 | pci_dma_sync_single_for_device(tp->pdev, dma_addr, | 1725 | pci_dma_sync_single_for_device(tp->pdev, dma_addr, |
1726 | PKT_BUF_SZ, | 1726 | PKT_BUF_SZ, |
1727 | PCI_DMA_FROMDEVICE); | 1727 | PCI_DMA_FROMDEVICE); |
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index be1c1047b9ba..fc7738ffbfff 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
@@ -507,7 +507,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev); | |||
507 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 507 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
508 | static struct ethtool_ops netdev_ethtool_ops; | 508 | static struct ethtool_ops netdev_ethtool_ops; |
509 | static int rhine_close(struct net_device *dev); | 509 | static int rhine_close(struct net_device *dev); |
510 | static void rhine_shutdown (struct device *gdev); | 510 | static void rhine_shutdown (struct pci_dev *pdev); |
511 | 511 | ||
512 | #define RHINE_WAIT_FOR(condition) do { \ | 512 | #define RHINE_WAIT_FOR(condition) do { \ |
513 | int i=1024; \ | 513 | int i=1024; \ |
@@ -990,7 +990,7 @@ static void alloc_rbufs(struct net_device *dev) | |||
990 | skb->dev = dev; /* Mark as being used by this device. */ | 990 | skb->dev = dev; /* Mark as being used by this device. */ |
991 | 991 | ||
992 | rp->rx_skbuff_dma[i] = | 992 | rp->rx_skbuff_dma[i] = |
993 | pci_map_single(rp->pdev, skb->tail, rp->rx_buf_sz, | 993 | pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, |
994 | PCI_DMA_FROMDEVICE); | 994 | PCI_DMA_FROMDEVICE); |
995 | 995 | ||
996 | rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]); | 996 | rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]); |
@@ -1518,7 +1518,7 @@ static void rhine_rx(struct net_device *dev) | |||
1518 | PCI_DMA_FROMDEVICE); | 1518 | PCI_DMA_FROMDEVICE); |
1519 | 1519 | ||
1520 | eth_copy_and_sum(skb, | 1520 | eth_copy_and_sum(skb, |
1521 | rp->rx_skbuff[entry]->tail, | 1521 | rp->rx_skbuff[entry]->data, |
1522 | pkt_len, 0); | 1522 | pkt_len, 0); |
1523 | skb_put(skb, pkt_len); | 1523 | skb_put(skb, pkt_len); |
1524 | pci_dma_sync_single_for_device(rp->pdev, | 1524 | pci_dma_sync_single_for_device(rp->pdev, |
@@ -1561,7 +1561,7 @@ static void rhine_rx(struct net_device *dev) | |||
1561 | break; /* Better luck next round. */ | 1561 | break; /* Better luck next round. */ |
1562 | skb->dev = dev; /* Mark as being used by this device. */ | 1562 | skb->dev = dev; /* Mark as being used by this device. */ |
1563 | rp->rx_skbuff_dma[entry] = | 1563 | rp->rx_skbuff_dma[entry] = |
1564 | pci_map_single(rp->pdev, skb->tail, | 1564 | pci_map_single(rp->pdev, skb->data, |
1565 | rp->rx_buf_sz, | 1565 | rp->rx_buf_sz, |
1566 | PCI_DMA_FROMDEVICE); | 1566 | PCI_DMA_FROMDEVICE); |
1567 | rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]); | 1567 | rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]); |
@@ -1895,9 +1895,8 @@ static void __devexit rhine_remove_one(struct pci_dev *pdev) | |||
1895 | pci_set_drvdata(pdev, NULL); | 1895 | pci_set_drvdata(pdev, NULL); |
1896 | } | 1896 | } |
1897 | 1897 | ||
1898 | static void rhine_shutdown (struct device *gendev) | 1898 | static void rhine_shutdown (struct pci_dev *pdev) |
1899 | { | 1899 | { |
1900 | struct pci_dev *pdev = to_pci_dev(gendev); | ||
1901 | struct net_device *dev = pci_get_drvdata(pdev); | 1900 | struct net_device *dev = pci_get_drvdata(pdev); |
1902 | struct rhine_private *rp = netdev_priv(dev); | 1901 | struct rhine_private *rp = netdev_priv(dev); |
1903 | void __iomem *ioaddr = rp->base; | 1902 | void __iomem *ioaddr = rp->base; |
@@ -1956,7 +1955,7 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1956 | pci_save_state(pdev); | 1955 | pci_save_state(pdev); |
1957 | 1956 | ||
1958 | spin_lock_irqsave(&rp->lock, flags); | 1957 | spin_lock_irqsave(&rp->lock, flags); |
1959 | rhine_shutdown(&pdev->dev); | 1958 | rhine_shutdown(pdev); |
1960 | spin_unlock_irqrestore(&rp->lock, flags); | 1959 | spin_unlock_irqrestore(&rp->lock, flags); |
1961 | 1960 | ||
1962 | free_irq(dev->irq, dev); | 1961 | free_irq(dev->irq, dev); |
@@ -2010,9 +2009,7 @@ static struct pci_driver rhine_driver = { | |||
2010 | .suspend = rhine_suspend, | 2009 | .suspend = rhine_suspend, |
2011 | .resume = rhine_resume, | 2010 | .resume = rhine_resume, |
2012 | #endif /* CONFIG_PM */ | 2011 | #endif /* CONFIG_PM */ |
2013 | .driver = { | 2012 | .shutdown = rhine_shutdown, |
2014 | .shutdown = rhine_shutdown, | ||
2015 | } | ||
2016 | }; | 2013 | }; |
2017 | 2014 | ||
2018 | 2015 | ||
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 15e710283493..abc5cee6eedc 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -1335,7 +1335,7 @@ static inline int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size, | |||
1335 | if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) | 1335 | if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) |
1336 | skb_reserve(new_skb, 2); | 1336 | skb_reserve(new_skb, 2); |
1337 | 1337 | ||
1338 | memcpy(new_skb->data, rx_skb[0]->tail, pkt_size); | 1338 | memcpy(new_skb->data, rx_skb[0]->data, pkt_size); |
1339 | *rx_skb = new_skb; | 1339 | *rx_skb = new_skb; |
1340 | ret = 0; | 1340 | ret = 0; |
1341 | } | 1341 | } |
@@ -1456,9 +1456,9 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx) | |||
1456 | * Do the gymnastics to get the buffer head for data at | 1456 | * Do the gymnastics to get the buffer head for data at |
1457 | * 64byte alignment. | 1457 | * 64byte alignment. |
1458 | */ | 1458 | */ |
1459 | skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63); | 1459 | skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63); |
1460 | rd_info->skb->dev = vptr->dev; | 1460 | rd_info->skb->dev = vptr->dev; |
1461 | rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1461 | rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1462 | 1462 | ||
1463 | /* | 1463 | /* |
1464 | * Fill in the descriptor to match | 1464 | * Fill in the descriptor to match |
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index c1b6896d7007..87496843681a 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c | |||
@@ -72,7 +72,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, | |||
72 | } | 72 | } |
73 | skb_reserve(skb, 4); | 73 | skb_reserve(skb, 4); |
74 | cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); | 74 | cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); |
75 | data = (cisco_packet*)skb->tail; | 75 | data = (cisco_packet*)skb->data; |
76 | 76 | ||
77 | data->type = htonl(type); | 77 | data->type = htonl(type); |
78 | data->par1 = htonl(par1); | 78 | data->par1 = htonl(par1); |
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 9da925430109..1c2506535f7e 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -786,7 +786,7 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
786 | skb->dev = dev; /* Mark as being used by this device. */ | 786 | skb->dev = dev; /* Mark as being used by this device. */ |
787 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ | 787 | skb_reserve(skb, 2); /* 16 byte align the IP header. */ |
788 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, | 788 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, |
789 | skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 789 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
790 | } | 790 | } |
791 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); | 791 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); |
792 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); | 792 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); |
@@ -1111,7 +1111,7 @@ static int yellowfin_rx(struct net_device *dev) | |||
1111 | pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr, | 1111 | pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr, |
1112 | yp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1112 | yp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1113 | desc_status = le32_to_cpu(desc->result_status) >> 16; | 1113 | desc_status = le32_to_cpu(desc->result_status) >> 16; |
1114 | buf_addr = rx_skb->tail; | 1114 | buf_addr = rx_skb->data; |
1115 | data_size = (le32_to_cpu(desc->dbdma_cmd) - | 1115 | data_size = (le32_to_cpu(desc->dbdma_cmd) - |
1116 | le32_to_cpu(desc->result_status)) & 0xffff; | 1116 | le32_to_cpu(desc->result_status)) & 0xffff; |
1117 | frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2]))); | 1117 | frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2]))); |
@@ -1185,7 +1185,7 @@ static int yellowfin_rx(struct net_device *dev) | |||
1185 | break; | 1185 | break; |
1186 | skb->dev = dev; | 1186 | skb->dev = dev; |
1187 | skb_reserve(skb, 2); /* 16 byte align the IP header */ | 1187 | skb_reserve(skb, 2); /* 16 byte align the IP header */ |
1188 | eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0); | 1188 | eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0); |
1189 | skb_put(skb, pkt_len); | 1189 | skb_put(skb, pkt_len); |
1190 | pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, | 1190 | pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, |
1191 | yp->rx_buf_sz, | 1191 | yp->rx_buf_sz, |
@@ -1211,7 +1211,7 @@ static int yellowfin_rx(struct net_device *dev) | |||
1211 | skb->dev = dev; /* Mark as being used by this device. */ | 1211 | skb->dev = dev; /* Mark as being used by this device. */ |
1212 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1212 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
1213 | yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, | 1213 | yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, |
1214 | skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 1214 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
1215 | } | 1215 | } |
1216 | yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP); | 1216 | yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP); |
1217 | yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */ | 1217 | yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */ |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index b0d2a73d1d47..2f2dbef2c3b7 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_device *dev) | |||
993 | bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, | 993 | bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, |
994 | &dino_cfg_ops, NULL); | 994 | &dino_cfg_ops, NULL); |
995 | if(bus) { | 995 | if(bus) { |
996 | pci_bus_add_devices(bus); | ||
996 | /* This code *depends* on scanning being single threaded | 997 | /* This code *depends* on scanning being single threaded |
997 | * if it isn't, this global bus number count will fail | 998 | * if it isn't, this global bus number count will fail |
998 | */ | 999 | */ |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index dc838804c0dd..7fdd80b7eb47 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *dev) | |||
1570 | lba_bus = lba_dev->hba.hba_bus = | 1570 | lba_bus = lba_dev->hba.hba_bus = |
1571 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, | 1571 | pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, |
1572 | cfg_ops, NULL); | 1572 | cfg_ops, NULL); |
1573 | if (lba_bus) | ||
1574 | pci_bus_add_devices(lba_bus); | ||
1573 | 1575 | ||
1574 | /* This is in lieu of calling pci_assign_unassigned_resources() */ | 1576 | /* This is in lieu of calling pci_assign_unassigned_resources() */ |
1575 | if (is_pdc_pat()) { | 1577 | if (is_pdc_pat()) { |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index dbd33605cc10..fedae89d8f7d 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) | |||
121 | * If there is an unattached subordinate bus, attach | 121 | * If there is an unattached subordinate bus, attach |
122 | * it and then scan for unattached PCI devices. | 122 | * it and then scan for unattached PCI devices. |
123 | */ | 123 | */ |
124 | if (dev->subordinate && list_empty(&dev->subordinate->node)) { | 124 | if (dev->subordinate) { |
125 | spin_lock(&pci_bus_lock); | 125 | if (list_empty(&dev->subordinate->node)) { |
126 | list_add_tail(&dev->subordinate->node, &dev->bus->children); | 126 | spin_lock(&pci_bus_lock); |
127 | spin_unlock(&pci_bus_lock); | 127 | list_add_tail(&dev->subordinate->node, |
128 | &dev->bus->children); | ||
129 | spin_unlock(&pci_bus_lock); | ||
130 | } | ||
128 | pci_bus_add_devices(dev->subordinate); | 131 | pci_bus_add_devices(dev->subordinate); |
129 | 132 | ||
130 | sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); | 133 | sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); |
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 93c120ddbd39..3e632ff8c717 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -36,9 +36,7 @@ ibmphp-objs := ibmphp_core.o \ | |||
36 | ibmphp_hpc.o | 36 | ibmphp_hpc.o |
37 | 37 | ||
38 | acpiphp-objs := acpiphp_core.o \ | 38 | acpiphp-objs := acpiphp_core.o \ |
39 | acpiphp_glue.o \ | 39 | acpiphp_glue.o |
40 | acpiphp_pci.o \ | ||
41 | acpiphp_res.o | ||
42 | 40 | ||
43 | rpaphp-objs := rpaphp_core.o \ | 41 | rpaphp-objs := rpaphp_core.o \ |
44 | rpaphp_pci.o \ | 42 | rpaphp_pci.o \ |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index d9499874c8a9..293603e1b7c3 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -7,6 +7,8 @@ | |||
7 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) | 7 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) |
8 | * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) | 8 | * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) |
9 | * Copyright (C) 2002,2003 NEC Corporation | 9 | * Copyright (C) 2002,2003 NEC Corporation |
10 | * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) | ||
11 | * Copyright (C) 2003-2005 Hewlett Packard | ||
10 | * | 12 | * |
11 | * All rights reserved. | 13 | * All rights reserved. |
12 | * | 14 | * |
@@ -52,7 +54,6 @@ | |||
52 | 54 | ||
53 | struct acpiphp_bridge; | 55 | struct acpiphp_bridge; |
54 | struct acpiphp_slot; | 56 | struct acpiphp_slot; |
55 | struct pci_resource; | ||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * struct slot - slot information for each *physical* slot | 59 | * struct slot - slot information for each *physical* slot |
@@ -65,15 +66,6 @@ struct slot { | |||
65 | struct acpiphp_slot *acpi_slot; | 66 | struct acpiphp_slot *acpi_slot; |
66 | }; | 67 | }; |
67 | 68 | ||
68 | /* | ||
69 | * struct pci_resource - describes pci resource (mem, pfmem, io, bus) | ||
70 | */ | ||
71 | struct pci_resource { | ||
72 | struct pci_resource * next; | ||
73 | u64 base; | ||
74 | u32 length; | ||
75 | }; | ||
76 | |||
77 | /** | 69 | /** |
78 | * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters | 70 | * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters |
79 | * @cache_line_size in DWORD | 71 | * @cache_line_size in DWORD |
@@ -101,10 +93,6 @@ struct acpiphp_bridge { | |||
101 | int type; | 93 | int type; |
102 | int nr_slots; | 94 | int nr_slots; |
103 | 95 | ||
104 | u8 seg; | ||
105 | u8 bus; | ||
106 | u8 sub; | ||
107 | |||
108 | u32 flags; | 96 | u32 flags; |
109 | 97 | ||
110 | /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ | 98 | /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ |
@@ -117,12 +105,6 @@ struct acpiphp_bridge { | |||
117 | struct hpp_param hpp; | 105 | struct hpp_param hpp; |
118 | 106 | ||
119 | spinlock_t res_lock; | 107 | spinlock_t res_lock; |
120 | |||
121 | /* available resources on this bus */ | ||
122 | struct pci_resource *mem_head; | ||
123 | struct pci_resource *p_mem_head; | ||
124 | struct pci_resource *io_head; | ||
125 | struct pci_resource *bus_head; | ||
126 | }; | 108 | }; |
127 | 109 | ||
128 | 110 | ||
@@ -163,12 +145,6 @@ struct acpiphp_func { | |||
163 | 145 | ||
164 | u8 function; /* pci function# */ | 146 | u8 function; /* pci function# */ |
165 | u32 flags; /* see below */ | 147 | u32 flags; /* see below */ |
166 | |||
167 | /* resources used for this function */ | ||
168 | struct pci_resource *mem_head; | ||
169 | struct pci_resource *p_mem_head; | ||
170 | struct pci_resource *io_head; | ||
171 | struct pci_resource *bus_head; | ||
172 | }; | 148 | }; |
173 | 149 | ||
174 | /** | 150 | /** |
@@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); | |||
243 | extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); | 219 | extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); |
244 | extern u32 acpiphp_get_address (struct acpiphp_slot *slot); | 220 | extern u32 acpiphp_get_address (struct acpiphp_slot *slot); |
245 | 221 | ||
246 | /* acpiphp_pci.c */ | ||
247 | extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn); | ||
248 | extern int acpiphp_configure_slot (struct acpiphp_slot *slot); | ||
249 | extern int acpiphp_configure_function (struct acpiphp_func *func); | ||
250 | extern void acpiphp_unconfigure_function (struct acpiphp_func *func); | ||
251 | extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge); | ||
252 | extern int acpiphp_init_func_resource (struct acpiphp_func *func); | ||
253 | |||
254 | /* acpiphp_res.c */ | ||
255 | extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size); | ||
256 | extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size); | ||
257 | extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size); | ||
258 | extern int acpiphp_resource_sort_and_combine (struct pci_resource **head); | ||
259 | extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length); | ||
260 | extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to); | ||
261 | extern void acpiphp_free_resource (struct pci_resource **res); | ||
262 | extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */ | ||
263 | extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */ | ||
264 | |||
265 | /* variables */ | 222 | /* variables */ |
266 | extern int acpiphp_debug; | 223 | extern int acpiphp_debug; |
267 | 224 | ||
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4539e61a3dc1..60c4c38047a3 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) | 7 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) |
8 | * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) | 8 | * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) |
9 | * Copyright (C) 2002,2003 NEC Corporation | 9 | * Copyright (C) 2002,2003 NEC Corporation |
10 | * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) | ||
11 | * Copyright (C) 2003-2005 Hewlett Packard | ||
10 | * | 12 | * |
11 | * All rights reserved. | 13 | * All rights reserved. |
12 | * | 14 | * |
@@ -53,8 +55,8 @@ int acpiphp_debug; | |||
53 | static int num_slots; | 55 | static int num_slots; |
54 | static struct acpiphp_attention_info *attention_info; | 56 | static struct acpiphp_attention_info *attention_info; |
55 | 57 | ||
56 | #define DRIVER_VERSION "0.4" | 58 | #define DRIVER_VERSION "0.5" |
57 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>" | 59 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>" |
58 | #define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver" | 60 | #define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver" |
59 | 61 | ||
60 | MODULE_AUTHOR(DRIVER_AUTHOR); | 62 | MODULE_AUTHOR(DRIVER_AUTHOR); |
@@ -281,8 +283,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
281 | /** | 283 | /** |
282 | * get_address - get pci address of a slot | 284 | * get_address - get pci address of a slot |
283 | * @hotplug_slot: slot to get status | 285 | * @hotplug_slot: slot to get status |
284 | * @busdev: pointer to struct pci_busdev (seg, bus, dev) | 286 | * @value: pointer to struct pci_busdev (seg, bus, dev) |
285 | * | ||
286 | */ | 287 | */ |
287 | static int get_address(struct hotplug_slot *hotplug_slot, u32 *value) | 288 | static int get_address(struct hotplug_slot *hotplug_slot, u32 *value) |
288 | { | 289 | { |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index e7f41294f811..424e7de181ae 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -4,6 +4,10 @@ | |||
4 | * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) | 4 | * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) |
5 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) | 5 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) |
6 | * Copyright (C) 2002,2003 NEC Corporation | 6 | * Copyright (C) 2002,2003 NEC Corporation |
7 | * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) | ||
8 | * Copyright (C) 2003-2005 Hewlett Packard | ||
9 | * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com) | ||
10 | * Copyright (C) 2005 Intel Corporation | ||
7 | * | 11 | * |
8 | * All rights reserved. | 12 | * All rights reserved. |
9 | * | 13 | * |
@@ -26,6 +30,16 @@ | |||
26 | * | 30 | * |
27 | */ | 31 | */ |
28 | 32 | ||
33 | /* | ||
34 | * Lifetime rules for pci_dev: | ||
35 | * - The one in acpiphp_func has its refcount elevated by pci_get_slot() | ||
36 | * when the driver is loaded or when an insertion event occurs. It loses | ||
37 | * a refcount when its ejected or the driver unloads. | ||
38 | * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() | ||
39 | * when the bridge is scanned and it loses a refcount when the bridge | ||
40 | * is removed. | ||
41 | */ | ||
42 | |||
29 | #include <linux/init.h> | 43 | #include <linux/init.h> |
30 | #include <linux/module.h> | 44 | #include <linux/module.h> |
31 | 45 | ||
@@ -178,21 +192,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
178 | 192 | ||
179 | bridge->nr_slots++; | 193 | bridge->nr_slots++; |
180 | 194 | ||
181 | dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n", | 195 | dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n", |
182 | slot->bridge->bus, slot->device, slot->sun); | 196 | slot->sun, pci_domain_nr(bridge->pci_bus), |
197 | bridge->pci_bus->number, slot->device); | ||
183 | } | 198 | } |
184 | 199 | ||
185 | newfunc->slot = slot; | 200 | newfunc->slot = slot; |
186 | list_add_tail(&newfunc->sibling, &slot->funcs); | 201 | list_add_tail(&newfunc->sibling, &slot->funcs); |
187 | 202 | ||
188 | /* associate corresponding pci_dev */ | 203 | /* associate corresponding pci_dev */ |
189 | newfunc->pci_dev = pci_find_slot(bridge->bus, | 204 | newfunc->pci_dev = pci_get_slot(bridge->pci_bus, |
190 | PCI_DEVFN(device, function)); | 205 | PCI_DEVFN(device, function)); |
191 | if (newfunc->pci_dev) { | 206 | if (newfunc->pci_dev) { |
192 | if (acpiphp_init_func_resource(newfunc) < 0) { | ||
193 | kfree(newfunc); | ||
194 | return AE_ERROR; | ||
195 | } | ||
196 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 207 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
197 | } | 208 | } |
198 | 209 | ||
@@ -227,62 +238,6 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle) | |||
227 | } | 238 | } |
228 | 239 | ||
229 | 240 | ||
230 | /* decode ACPI _CRS data and convert into our internal resource list | ||
231 | * TBD: _TRA, etc. | ||
232 | */ | ||
233 | static acpi_status | ||
234 | decode_acpi_resource(struct acpi_resource *resource, void *context) | ||
235 | { | ||
236 | struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context; | ||
237 | struct acpi_resource_address64 address; | ||
238 | struct pci_resource *res; | ||
239 | |||
240 | if (resource->id != ACPI_RSTYPE_ADDRESS16 && | ||
241 | resource->id != ACPI_RSTYPE_ADDRESS32 && | ||
242 | resource->id != ACPI_RSTYPE_ADDRESS64) | ||
243 | return AE_OK; | ||
244 | |||
245 | acpi_resource_to_address64(resource, &address); | ||
246 | |||
247 | if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) { | ||
248 | dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, | ||
249 | (unsigned long long)address.min_address_range, | ||
250 | (unsigned long long)address.max_address_range); | ||
251 | res = acpiphp_make_resource(address.min_address_range, | ||
252 | address.address_length); | ||
253 | if (!res) { | ||
254 | err("out of memory\n"); | ||
255 | return AE_OK; | ||
256 | } | ||
257 | |||
258 | switch (address.resource_type) { | ||
259 | case ACPI_MEMORY_RANGE: | ||
260 | if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) { | ||
261 | res->next = bridge->p_mem_head; | ||
262 | bridge->p_mem_head = res; | ||
263 | } else { | ||
264 | res->next = bridge->mem_head; | ||
265 | bridge->mem_head = res; | ||
266 | } | ||
267 | break; | ||
268 | case ACPI_IO_RANGE: | ||
269 | res->next = bridge->io_head; | ||
270 | bridge->io_head = res; | ||
271 | break; | ||
272 | case ACPI_BUS_NUMBER_RANGE: | ||
273 | res->next = bridge->bus_head; | ||
274 | bridge->bus_head = res; | ||
275 | break; | ||
276 | default: | ||
277 | /* invalid type */ | ||
278 | kfree(res); | ||
279 | break; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | return AE_OK; | ||
284 | } | ||
285 | |||
286 | /* decode ACPI 2.0 _HPP hot plug parameters */ | 241 | /* decode ACPI 2.0 _HPP hot plug parameters */ |
287 | static void decode_hpp(struct acpiphp_bridge *bridge) | 242 | static void decode_hpp(struct acpiphp_bridge *bridge) |
288 | { | 243 | { |
@@ -346,34 +301,29 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
346 | /* decode ACPI 2.0 _HPP (hot plug parameters) */ | 301 | /* decode ACPI 2.0 _HPP (hot plug parameters) */ |
347 | decode_hpp(bridge); | 302 | decode_hpp(bridge); |
348 | 303 | ||
349 | /* subtract all resources already allocated */ | ||
350 | acpiphp_detect_pci_resource(bridge); | ||
351 | |||
352 | /* register all slot objects under this bridge */ | 304 | /* register all slot objects under this bridge */ |
353 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, | 305 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, |
354 | register_slot, bridge, NULL); | 306 | register_slot, bridge, NULL); |
355 | 307 | ||
356 | /* install notify handler */ | 308 | /* install notify handler */ |
357 | status = acpi_install_notify_handler(bridge->handle, | 309 | if (bridge->type != BRIDGE_TYPE_HOST) { |
310 | status = acpi_install_notify_handler(bridge->handle, | ||
358 | ACPI_SYSTEM_NOTIFY, | 311 | ACPI_SYSTEM_NOTIFY, |
359 | handle_hotplug_event_bridge, | 312 | handle_hotplug_event_bridge, |
360 | bridge); | 313 | bridge); |
361 | 314 | ||
362 | if (ACPI_FAILURE(status)) { | 315 | if (ACPI_FAILURE(status)) { |
363 | err("failed to register interrupt notify handler\n"); | 316 | err("failed to register interrupt notify handler\n"); |
317 | } | ||
364 | } | 318 | } |
365 | 319 | ||
366 | list_add(&bridge->list, &bridge_list); | 320 | list_add(&bridge->list, &bridge_list); |
367 | |||
368 | dbg("Bridge resource:\n"); | ||
369 | acpiphp_dump_resource(bridge); | ||
370 | } | 321 | } |
371 | 322 | ||
372 | 323 | ||
373 | /* allocate and initialize host bridge data structure */ | 324 | /* allocate and initialize host bridge data structure */ |
374 | static void add_host_bridge(acpi_handle *handle, int seg, int bus) | 325 | static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) |
375 | { | 326 | { |
376 | acpi_status status; | ||
377 | struct acpiphp_bridge *bridge; | 327 | struct acpiphp_bridge *bridge; |
378 | 328 | ||
379 | bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | 329 | bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); |
@@ -384,52 +334,19 @@ static void add_host_bridge(acpi_handle *handle, int seg, int bus) | |||
384 | 334 | ||
385 | bridge->type = BRIDGE_TYPE_HOST; | 335 | bridge->type = BRIDGE_TYPE_HOST; |
386 | bridge->handle = handle; | 336 | bridge->handle = handle; |
387 | bridge->seg = seg; | ||
388 | bridge->bus = bus; | ||
389 | 337 | ||
390 | bridge->pci_bus = pci_find_bus(seg, bus); | 338 | bridge->pci_bus = pci_bus; |
391 | 339 | ||
392 | spin_lock_init(&bridge->res_lock); | 340 | spin_lock_init(&bridge->res_lock); |
393 | 341 | ||
394 | /* to be overridden when we decode _CRS */ | ||
395 | bridge->sub = bridge->bus; | ||
396 | |||
397 | /* decode resources */ | ||
398 | |||
399 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
400 | decode_acpi_resource, bridge); | ||
401 | |||
402 | if (ACPI_FAILURE(status)) { | ||
403 | err("failed to decode bridge resources\n"); | ||
404 | kfree(bridge); | ||
405 | return; | ||
406 | } | ||
407 | |||
408 | acpiphp_resource_sort_and_combine(&bridge->io_head); | ||
409 | acpiphp_resource_sort_and_combine(&bridge->mem_head); | ||
410 | acpiphp_resource_sort_and_combine(&bridge->p_mem_head); | ||
411 | acpiphp_resource_sort_and_combine(&bridge->bus_head); | ||
412 | |||
413 | dbg("ACPI _CRS resource:\n"); | ||
414 | acpiphp_dump_resource(bridge); | ||
415 | |||
416 | if (bridge->bus_head) { | ||
417 | bridge->bus = bridge->bus_head->base; | ||
418 | bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1; | ||
419 | } | ||
420 | |||
421 | init_bridge_misc(bridge); | 342 | init_bridge_misc(bridge); |
422 | } | 343 | } |
423 | 344 | ||
424 | 345 | ||
425 | /* allocate and initialize PCI-to-PCI bridge data structure */ | 346 | /* allocate and initialize PCI-to-PCI bridge data structure */ |
426 | static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn) | 347 | static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) |
427 | { | 348 | { |
428 | struct acpiphp_bridge *bridge; | 349 | struct acpiphp_bridge *bridge; |
429 | u8 tmp8; | ||
430 | u16 tmp16; | ||
431 | u64 base64, limit64; | ||
432 | u32 base, limit, base32u, limit32u; | ||
433 | 350 | ||
434 | bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | 351 | bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); |
435 | if (bridge == NULL) { | 352 | if (bridge == NULL) { |
@@ -441,133 +358,22 @@ static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int f | |||
441 | 358 | ||
442 | bridge->type = BRIDGE_TYPE_P2P; | 359 | bridge->type = BRIDGE_TYPE_P2P; |
443 | bridge->handle = handle; | 360 | bridge->handle = handle; |
444 | bridge->seg = seg; | ||
445 | |||
446 | bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn)); | ||
447 | if (!bridge->pci_dev) { | ||
448 | err("Can't get pci_dev\n"); | ||
449 | kfree(bridge); | ||
450 | return; | ||
451 | } | ||
452 | 361 | ||
453 | bridge->pci_bus = bridge->pci_dev->subordinate; | 362 | bridge->pci_dev = pci_dev_get(pci_dev); |
363 | bridge->pci_bus = pci_dev->subordinate; | ||
454 | if (!bridge->pci_bus) { | 364 | if (!bridge->pci_bus) { |
455 | err("This is not a PCI-to-PCI bridge!\n"); | 365 | err("This is not a PCI-to-PCI bridge!\n"); |
456 | kfree(bridge); | 366 | goto err; |
457 | return; | ||
458 | } | 367 | } |
459 | 368 | ||
460 | spin_lock_init(&bridge->res_lock); | 369 | spin_lock_init(&bridge->res_lock); |
461 | 370 | ||
462 | bridge->bus = bridge->pci_bus->number; | ||
463 | bridge->sub = bridge->pci_bus->subordinate; | ||
464 | |||
465 | /* | ||
466 | * decode resources under this P2P bridge | ||
467 | */ | ||
468 | |||
469 | /* I/O resources */ | ||
470 | pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8); | ||
471 | base = tmp8; | ||
472 | pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8); | ||
473 | limit = tmp8; | ||
474 | |||
475 | switch (base & PCI_IO_RANGE_TYPE_MASK) { | ||
476 | case PCI_IO_RANGE_TYPE_16: | ||
477 | base = (base << 8) & 0xf000; | ||
478 | limit = ((limit << 8) & 0xf000) + 0xfff; | ||
479 | bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); | ||
480 | if (!bridge->io_head) { | ||
481 | err("out of memory\n"); | ||
482 | kfree(bridge); | ||
483 | return; | ||
484 | } | ||
485 | dbg("16bit I/O range: %04x-%04x\n", | ||
486 | (u32)bridge->io_head->base, | ||
487 | (u32)(bridge->io_head->base + bridge->io_head->length - 1)); | ||
488 | break; | ||
489 | case PCI_IO_RANGE_TYPE_32: | ||
490 | pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16); | ||
491 | base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000); | ||
492 | pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16); | ||
493 | limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff; | ||
494 | bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); | ||
495 | if (!bridge->io_head) { | ||
496 | err("out of memory\n"); | ||
497 | kfree(bridge); | ||
498 | return; | ||
499 | } | ||
500 | dbg("32bit I/O range: %08x-%08x\n", | ||
501 | (u32)bridge->io_head->base, | ||
502 | (u32)(bridge->io_head->base + bridge->io_head->length - 1)); | ||
503 | break; | ||
504 | case 0x0f: | ||
505 | dbg("I/O space unsupported\n"); | ||
506 | break; | ||
507 | default: | ||
508 | warn("Unknown I/O range type\n"); | ||
509 | } | ||
510 | |||
511 | /* Memory resources (mandatory for P2P bridge) */ | ||
512 | pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16); | ||
513 | base = (tmp16 & 0xfff0) << 16; | ||
514 | pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16); | ||
515 | limit = ((tmp16 & 0xfff0) << 16) | 0xfffff; | ||
516 | bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1); | ||
517 | if (!bridge->mem_head) { | ||
518 | err("out of memory\n"); | ||
519 | kfree(bridge); | ||
520 | return; | ||
521 | } | ||
522 | dbg("32bit Memory range: %08x-%08x\n", | ||
523 | (u32)bridge->mem_head->base, | ||
524 | (u32)(bridge->mem_head->base + bridge->mem_head->length-1)); | ||
525 | |||
526 | /* Prefetchable Memory resources (optional) */ | ||
527 | pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16); | ||
528 | base = tmp16; | ||
529 | pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16); | ||
530 | limit = tmp16; | ||
531 | |||
532 | switch (base & PCI_MEMORY_RANGE_TYPE_MASK) { | ||
533 | case PCI_PREF_RANGE_TYPE_32: | ||
534 | base = (base & 0xfff0) << 16; | ||
535 | limit = ((limit & 0xfff0) << 16) | 0xfffff; | ||
536 | bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1); | ||
537 | if (!bridge->p_mem_head) { | ||
538 | err("out of memory\n"); | ||
539 | kfree(bridge); | ||
540 | return; | ||
541 | } | ||
542 | dbg("32bit Prefetchable memory range: %08x-%08x\n", | ||
543 | (u32)bridge->p_mem_head->base, | ||
544 | (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1)); | ||
545 | break; | ||
546 | case PCI_PREF_RANGE_TYPE_64: | ||
547 | pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u); | ||
548 | pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u); | ||
549 | base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16); | ||
550 | limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff; | ||
551 | |||
552 | bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1); | ||
553 | if (!bridge->p_mem_head) { | ||
554 | err("out of memory\n"); | ||
555 | kfree(bridge); | ||
556 | return; | ||
557 | } | ||
558 | dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n", | ||
559 | (u32)(bridge->p_mem_head->base >> 32), | ||
560 | (u32)(bridge->p_mem_head->base & 0xffffffff), | ||
561 | (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32), | ||
562 | (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff)); | ||
563 | break; | ||
564 | case 0x0f: | ||
565 | break; | ||
566 | default: | ||
567 | warn("Unknown prefetchale memory type\n"); | ||
568 | } | ||
569 | |||
570 | init_bridge_misc(bridge); | 371 | init_bridge_misc(bridge); |
372 | return; | ||
373 | err: | ||
374 | pci_dev_put(pci_dev); | ||
375 | kfree(bridge); | ||
376 | return; | ||
571 | } | 377 | } |
572 | 378 | ||
573 | 379 | ||
@@ -577,14 +383,10 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
577 | { | 383 | { |
578 | acpi_status status; | 384 | acpi_status status; |
579 | acpi_handle dummy_handle; | 385 | acpi_handle dummy_handle; |
580 | unsigned long *segbus = context; | ||
581 | unsigned long tmp; | 386 | unsigned long tmp; |
582 | int seg, bus, device, function; | 387 | int device, function; |
583 | struct pci_dev *dev; | 388 | struct pci_dev *dev; |
584 | 389 | struct pci_bus *pci_bus = context; | |
585 | /* get PCI address */ | ||
586 | seg = (*segbus >> 8) & 0xff; | ||
587 | bus = *segbus & 0xff; | ||
588 | 390 | ||
589 | status = acpi_get_handle(handle, "_ADR", &dummy_handle); | 391 | status = acpi_get_handle(handle, "_ADR", &dummy_handle); |
590 | if (ACPI_FAILURE(status)) | 392 | if (ACPI_FAILURE(status)) |
@@ -599,20 +401,19 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
599 | device = (tmp >> 16) & 0xffff; | 401 | device = (tmp >> 16) & 0xffff; |
600 | function = tmp & 0xffff; | 402 | function = tmp & 0xffff; |
601 | 403 | ||
602 | dev = pci_find_slot(bus, PCI_DEVFN(device, function)); | 404 | dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function)); |
603 | 405 | ||
604 | if (!dev) | 406 | if (!dev || !dev->subordinate) |
605 | return AE_OK; | 407 | goto out; |
606 | |||
607 | if (!dev->subordinate) | ||
608 | return AE_OK; | ||
609 | 408 | ||
610 | /* check if this bridge has ejectable slots */ | 409 | /* check if this bridge has ejectable slots */ |
611 | if (detect_ejectable_slots(handle) > 0) { | 410 | if (detect_ejectable_slots(handle) > 0) { |
612 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); | 411 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); |
613 | add_p2p_bridge(handle, seg, bus, device, function); | 412 | add_p2p_bridge(handle, dev); |
614 | } | 413 | } |
615 | 414 | ||
415 | out: | ||
416 | pci_dev_put(dev); | ||
616 | return AE_OK; | 417 | return AE_OK; |
617 | } | 418 | } |
618 | 419 | ||
@@ -624,6 +425,7 @@ static int add_bridge(acpi_handle handle) | |||
624 | unsigned long tmp; | 425 | unsigned long tmp; |
625 | int seg, bus; | 426 | int seg, bus; |
626 | acpi_handle dummy_handle; | 427 | acpi_handle dummy_handle; |
428 | struct pci_bus *pci_bus; | ||
627 | 429 | ||
628 | /* if the bridge doesn't have _STA, we assume it is always there */ | 430 | /* if the bridge doesn't have _STA, we assume it is always there */ |
629 | status = acpi_get_handle(handle, "_STA", &dummy_handle); | 431 | status = acpi_get_handle(handle, "_STA", &dummy_handle); |
@@ -653,18 +455,22 @@ static int add_bridge(acpi_handle handle) | |||
653 | bus = 0; | 455 | bus = 0; |
654 | } | 456 | } |
655 | 457 | ||
458 | pci_bus = pci_find_bus(seg, bus); | ||
459 | if (!pci_bus) { | ||
460 | err("Can't find bus %04x:%02x\n", seg, bus); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
656 | /* check if this bridge has ejectable slots */ | 464 | /* check if this bridge has ejectable slots */ |
657 | if (detect_ejectable_slots(handle) > 0) { | 465 | if (detect_ejectable_slots(handle) > 0) { |
658 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); | 466 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); |
659 | add_host_bridge(handle, seg, bus); | 467 | add_host_bridge(handle, pci_bus); |
660 | return 0; | 468 | return 0; |
661 | } | 469 | } |
662 | 470 | ||
663 | tmp = seg << 8 | bus; | ||
664 | |||
665 | /* search P2P bridges under this host bridge */ | 471 | /* search P2P bridges under this host bridge */ |
666 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | 472 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, |
667 | find_p2p_bridge, &tmp, NULL); | 473 | find_p2p_bridge, pci_bus, NULL); |
668 | 474 | ||
669 | if (ACPI_FAILURE(status)) | 475 | if (ACPI_FAILURE(status)) |
670 | warn("find_p2p_bridge faied (error code = 0x%x)\n",status); | 476 | warn("find_p2p_bridge faied (error code = 0x%x)\n",status); |
@@ -672,12 +478,205 @@ static int add_bridge(acpi_handle handle) | |||
672 | return 0; | 478 | return 0; |
673 | } | 479 | } |
674 | 480 | ||
481 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | ||
482 | { | ||
483 | struct list_head *head; | ||
484 | list_for_each(head, &bridge_list) { | ||
485 | struct acpiphp_bridge *bridge = list_entry(head, | ||
486 | struct acpiphp_bridge, list); | ||
487 | if (bridge->handle == handle) | ||
488 | return bridge; | ||
489 | } | ||
490 | |||
491 | return NULL; | ||
492 | } | ||
493 | |||
494 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | ||
495 | { | ||
496 | struct list_head *list, *tmp; | ||
497 | struct acpiphp_slot *slot; | ||
498 | acpi_status status; | ||
499 | acpi_handle handle = bridge->handle; | ||
500 | |||
501 | status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
502 | handle_hotplug_event_bridge); | ||
503 | if (ACPI_FAILURE(status)) | ||
504 | err("failed to remove notify handler\n"); | ||
505 | |||
506 | slot = bridge->slots; | ||
507 | while (slot) { | ||
508 | struct acpiphp_slot *next = slot->next; | ||
509 | list_for_each_safe (list, tmp, &slot->funcs) { | ||
510 | struct acpiphp_func *func; | ||
511 | func = list_entry(list, struct acpiphp_func, sibling); | ||
512 | status = acpi_remove_notify_handler(func->handle, | ||
513 | ACPI_SYSTEM_NOTIFY, | ||
514 | handle_hotplug_event_func); | ||
515 | if (ACPI_FAILURE(status)) | ||
516 | err("failed to remove notify handler\n"); | ||
517 | pci_dev_put(func->pci_dev); | ||
518 | list_del(list); | ||
519 | kfree(func); | ||
520 | } | ||
521 | kfree(slot); | ||
522 | slot = next; | ||
523 | } | ||
524 | |||
525 | pci_dev_put(bridge->pci_dev); | ||
526 | list_del(&bridge->list); | ||
527 | kfree(bridge); | ||
528 | } | ||
529 | |||
530 | static acpi_status | ||
531 | cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
532 | { | ||
533 | struct acpiphp_bridge *bridge; | ||
534 | |||
535 | if (!(bridge = acpiphp_handle_to_bridge(handle))) | ||
536 | return AE_OK; | ||
537 | cleanup_bridge(bridge); | ||
538 | return AE_OK; | ||
539 | } | ||
675 | 540 | ||
676 | static void remove_bridge(acpi_handle handle) | 541 | static void remove_bridge(acpi_handle handle) |
677 | { | 542 | { |
678 | /* No-op for now .. */ | 543 | struct acpiphp_bridge *bridge; |
544 | |||
545 | bridge = acpiphp_handle_to_bridge(handle); | ||
546 | if (bridge) { | ||
547 | cleanup_bridge(bridge); | ||
548 | } else { | ||
549 | /* clean-up p2p bridges under this host bridge */ | ||
550 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
551 | (u32)1, cleanup_p2p_bridge, NULL, NULL); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | static struct pci_dev * get_apic_pci_info(acpi_handle handle) | ||
556 | { | ||
557 | struct acpi_pci_id id; | ||
558 | struct pci_bus *bus; | ||
559 | struct pci_dev *dev; | ||
560 | |||
561 | if (ACPI_FAILURE(acpi_get_pci_id(handle, &id))) | ||
562 | return NULL; | ||
563 | |||
564 | bus = pci_find_bus(id.segment, id.bus); | ||
565 | if (!bus) | ||
566 | return NULL; | ||
567 | |||
568 | dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function)); | ||
569 | if (!dev) | ||
570 | return NULL; | ||
571 | |||
572 | if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) && | ||
573 | (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC)) | ||
574 | { | ||
575 | pci_dev_put(dev); | ||
576 | return NULL; | ||
577 | } | ||
578 | |||
579 | return dev; | ||
580 | } | ||
581 | |||
582 | static int get_gsi_base(acpi_handle handle, u32 *gsi_base) | ||
583 | { | ||
584 | acpi_status status; | ||
585 | int result = -1; | ||
586 | unsigned long gsb; | ||
587 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
588 | union acpi_object *obj; | ||
589 | void *table; | ||
590 | |||
591 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
592 | if (ACPI_SUCCESS(status)) { | ||
593 | *gsi_base = (u32)gsb; | ||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer); | ||
598 | if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer) | ||
599 | return -1; | ||
600 | |||
601 | obj = buffer.pointer; | ||
602 | if (obj->type != ACPI_TYPE_BUFFER) | ||
603 | goto out; | ||
604 | |||
605 | table = obj->buffer.pointer; | ||
606 | switch (((acpi_table_entry_header *)table)->type) { | ||
607 | case ACPI_MADT_IOSAPIC: | ||
608 | *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base; | ||
609 | result = 0; | ||
610 | break; | ||
611 | case ACPI_MADT_IOAPIC: | ||
612 | *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base; | ||
613 | result = 0; | ||
614 | break; | ||
615 | default: | ||
616 | break; | ||
617 | } | ||
618 | out: | ||
619 | acpi_os_free(buffer.pointer); | ||
620 | return result; | ||
621 | } | ||
622 | |||
623 | static acpi_status | ||
624 | ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
625 | { | ||
626 | acpi_status status; | ||
627 | unsigned long sta; | ||
628 | acpi_handle tmp; | ||
629 | struct pci_dev *pdev; | ||
630 | u32 gsi_base; | ||
631 | u64 phys_addr; | ||
632 | |||
633 | /* Evaluate _STA if present */ | ||
634 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
635 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
636 | return AE_CTRL_DEPTH; | ||
637 | |||
638 | /* Scan only PCI bus scope */ | ||
639 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
640 | if (ACPI_SUCCESS(status)) | ||
641 | return AE_CTRL_DEPTH; | ||
642 | |||
643 | if (get_gsi_base(handle, &gsi_base)) | ||
644 | return AE_OK; | ||
645 | |||
646 | pdev = get_apic_pci_info(handle); | ||
647 | if (!pdev) | ||
648 | return AE_OK; | ||
649 | |||
650 | if (pci_enable_device(pdev)) { | ||
651 | pci_dev_put(pdev); | ||
652 | return AE_OK; | ||
653 | } | ||
654 | |||
655 | pci_set_master(pdev); | ||
656 | |||
657 | if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) { | ||
658 | pci_disable_device(pdev); | ||
659 | pci_dev_put(pdev); | ||
660 | return AE_OK; | ||
661 | } | ||
662 | |||
663 | phys_addr = pci_resource_start(pdev, 0); | ||
664 | if (acpi_register_ioapic(handle, phys_addr, gsi_base)) { | ||
665 | pci_release_region(pdev, 0); | ||
666 | pci_disable_device(pdev); | ||
667 | pci_dev_put(pdev); | ||
668 | return AE_OK; | ||
669 | } | ||
670 | |||
671 | return AE_OK; | ||
679 | } | 672 | } |
680 | 673 | ||
674 | static int acpiphp_configure_ioapics(acpi_handle handle) | ||
675 | { | ||
676 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
677 | ACPI_UINT32_MAX, ioapic_add, NULL, NULL); | ||
678 | return 0; | ||
679 | } | ||
681 | 680 | ||
682 | static int power_on_slot(struct acpiphp_slot *slot) | 681 | static int power_on_slot(struct acpiphp_slot *slot) |
683 | { | 682 | { |
@@ -719,8 +718,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
719 | acpi_status status; | 718 | acpi_status status; |
720 | struct acpiphp_func *func; | 719 | struct acpiphp_func *func; |
721 | struct list_head *l; | 720 | struct list_head *l; |
722 | struct acpi_object_list arg_list; | ||
723 | union acpi_object arg; | ||
724 | 721 | ||
725 | int retval = 0; | 722 | int retval = 0; |
726 | 723 | ||
@@ -731,7 +728,7 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
731 | list_for_each (l, &slot->funcs) { | 728 | list_for_each (l, &slot->funcs) { |
732 | func = list_entry(l, struct acpiphp_func, sibling); | 729 | func = list_entry(l, struct acpiphp_func, sibling); |
733 | 730 | ||
734 | if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) { | 731 | if (func->flags & FUNC_HAS_PS3) { |
735 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); | 732 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); |
736 | if (ACPI_FAILURE(status)) { | 733 | if (ACPI_FAILURE(status)) { |
737 | warn("%s: _PS3 failed\n", __FUNCTION__); | 734 | warn("%s: _PS3 failed\n", __FUNCTION__); |
@@ -742,27 +739,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
742 | } | 739 | } |
743 | } | 740 | } |
744 | 741 | ||
745 | list_for_each (l, &slot->funcs) { | ||
746 | func = list_entry(l, struct acpiphp_func, sibling); | ||
747 | |||
748 | /* We don't want to call _EJ0 on non-existing functions. */ | ||
749 | if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) { | ||
750 | /* _EJ0 method take one argument */ | ||
751 | arg_list.count = 1; | ||
752 | arg_list.pointer = &arg; | ||
753 | arg.type = ACPI_TYPE_INTEGER; | ||
754 | arg.integer.value = 1; | ||
755 | |||
756 | status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); | ||
757 | if (ACPI_FAILURE(status)) { | ||
758 | warn("%s: _EJ0 failed\n", __FUNCTION__); | ||
759 | retval = -1; | ||
760 | goto err_exit; | ||
761 | } else | ||
762 | break; | ||
763 | } | ||
764 | } | ||
765 | |||
766 | /* TBD: evaluate _STA to check if the slot is disabled */ | 742 | /* TBD: evaluate _STA to check if the slot is disabled */ |
767 | 743 | ||
768 | slot->flags &= (~SLOT_POWEREDON); | 744 | slot->flags &= (~SLOT_POWEREDON); |
@@ -782,70 +758,56 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
782 | */ | 758 | */ |
783 | static int enable_device(struct acpiphp_slot *slot) | 759 | static int enable_device(struct acpiphp_slot *slot) |
784 | { | 760 | { |
785 | u8 bus; | ||
786 | struct pci_dev *dev; | 761 | struct pci_dev *dev; |
787 | struct pci_bus *child; | 762 | struct pci_bus *bus = slot->bridge->pci_bus; |
788 | struct list_head *l; | 763 | struct list_head *l; |
789 | struct acpiphp_func *func; | 764 | struct acpiphp_func *func; |
790 | int retval = 0; | 765 | int retval = 0; |
791 | int num; | 766 | int num, max, pass; |
792 | 767 | ||
793 | if (slot->flags & SLOT_ENABLED) | 768 | if (slot->flags & SLOT_ENABLED) |
794 | goto err_exit; | 769 | goto err_exit; |
795 | 770 | ||
796 | /* sanity check: dev should be NULL when hot-plugged in */ | 771 | /* sanity check: dev should be NULL when hot-plugged in */ |
797 | dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); | 772 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); |
798 | if (dev) { | 773 | if (dev) { |
799 | /* This case shouldn't happen */ | 774 | /* This case shouldn't happen */ |
800 | err("pci_dev structure already exists.\n"); | 775 | err("pci_dev structure already exists.\n"); |
776 | pci_dev_put(dev); | ||
801 | retval = -1; | 777 | retval = -1; |
802 | goto err_exit; | 778 | goto err_exit; |
803 | } | 779 | } |
804 | 780 | ||
805 | /* allocate resources to device */ | 781 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); |
806 | retval = acpiphp_configure_slot(slot); | 782 | if (num == 0) { |
807 | if (retval) | ||
808 | goto err_exit; | ||
809 | |||
810 | /* returned `dev' is the *first function* only! */ | ||
811 | num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0)); | ||
812 | if (num) | ||
813 | pci_bus_add_devices(slot->bridge->pci_bus); | ||
814 | dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); | ||
815 | |||
816 | if (!dev) { | ||
817 | err("No new device found\n"); | 783 | err("No new device found\n"); |
818 | retval = -1; | 784 | retval = -1; |
819 | goto err_exit; | 785 | goto err_exit; |
820 | } | 786 | } |
821 | 787 | ||
822 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 788 | max = bus->secondary; |
823 | pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus); | 789 | for (pass = 0; pass < 2; pass++) { |
824 | child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus); | 790 | list_for_each_entry(dev, &bus->devices, bus_list) { |
825 | pci_do_scan_bus(child); | 791 | if (PCI_SLOT(dev->devfn) != slot->device) |
792 | continue; | ||
793 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
794 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
795 | max = pci_scan_bridge(bus, dev, max, pass); | ||
796 | } | ||
826 | } | 797 | } |
827 | 798 | ||
799 | pci_bus_assign_resources(bus); | ||
800 | pci_bus_add_devices(bus); | ||
801 | |||
828 | /* associate pci_dev to our representation */ | 802 | /* associate pci_dev to our representation */ |
829 | list_for_each (l, &slot->funcs) { | 803 | list_for_each (l, &slot->funcs) { |
830 | func = list_entry(l, struct acpiphp_func, sibling); | 804 | func = list_entry(l, struct acpiphp_func, sibling); |
831 | 805 | func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | |
832 | func->pci_dev = pci_find_slot(slot->bridge->bus, | ||
833 | PCI_DEVFN(slot->device, | ||
834 | func->function)); | 806 | func->function)); |
835 | if (!func->pci_dev) | ||
836 | continue; | ||
837 | |||
838 | /* configure device */ | ||
839 | retval = acpiphp_configure_function(func); | ||
840 | if (retval) | ||
841 | goto err_exit; | ||
842 | } | 807 | } |
843 | 808 | ||
844 | slot->flags |= SLOT_ENABLED; | 809 | slot->flags |= SLOT_ENABLED; |
845 | 810 | ||
846 | dbg("Available resources:\n"); | ||
847 | acpiphp_dump_resource(slot->bridge); | ||
848 | |||
849 | err_exit: | 811 | err_exit: |
850 | return retval; | 812 | return retval; |
851 | } | 813 | } |
@@ -866,9 +828,12 @@ static int disable_device(struct acpiphp_slot *slot) | |||
866 | 828 | ||
867 | list_for_each (l, &slot->funcs) { | 829 | list_for_each (l, &slot->funcs) { |
868 | func = list_entry(l, struct acpiphp_func, sibling); | 830 | func = list_entry(l, struct acpiphp_func, sibling); |
831 | if (!func->pci_dev) | ||
832 | continue; | ||
869 | 833 | ||
870 | if (func->pci_dev) | 834 | pci_remove_bus_device(func->pci_dev); |
871 | acpiphp_unconfigure_function(func); | 835 | pci_dev_put(func->pci_dev); |
836 | func->pci_dev = NULL; | ||
872 | } | 837 | } |
873 | 838 | ||
874 | slot->flags &= (~SLOT_ENABLED); | 839 | slot->flags &= (~SLOT_ENABLED); |
@@ -920,6 +885,39 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
920 | } | 885 | } |
921 | 886 | ||
922 | /** | 887 | /** |
888 | * acpiphp_eject_slot - physically eject the slot | ||
889 | */ | ||
890 | static int acpiphp_eject_slot(struct acpiphp_slot *slot) | ||
891 | { | ||
892 | acpi_status status; | ||
893 | struct acpiphp_func *func; | ||
894 | struct list_head *l; | ||
895 | struct acpi_object_list arg_list; | ||
896 | union acpi_object arg; | ||
897 | |||
898 | list_for_each (l, &slot->funcs) { | ||
899 | func = list_entry(l, struct acpiphp_func, sibling); | ||
900 | |||
901 | /* We don't want to call _EJ0 on non-existing functions. */ | ||
902 | if ((func->flags & FUNC_HAS_EJ0)) { | ||
903 | /* _EJ0 method take one argument */ | ||
904 | arg_list.count = 1; | ||
905 | arg_list.pointer = &arg; | ||
906 | arg.type = ACPI_TYPE_INTEGER; | ||
907 | arg.integer.value = 1; | ||
908 | |||
909 | status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); | ||
910 | if (ACPI_FAILURE(status)) { | ||
911 | warn("%s: _EJ0 failed\n", __FUNCTION__); | ||
912 | return -1; | ||
913 | } else | ||
914 | break; | ||
915 | } | ||
916 | } | ||
917 | return 0; | ||
918 | } | ||
919 | |||
920 | /** | ||
923 | * acpiphp_check_bridge - re-enumerate devices | 921 | * acpiphp_check_bridge - re-enumerate devices |
924 | * | 922 | * |
925 | * Iterate over all slots under this bridge and make sure that if a | 923 | * Iterate over all slots under this bridge and make sure that if a |
@@ -942,6 +940,8 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
942 | if (retval) { | 940 | if (retval) { |
943 | err("Error occurred in disabling\n"); | 941 | err("Error occurred in disabling\n"); |
944 | goto err_exit; | 942 | goto err_exit; |
943 | } else { | ||
944 | acpiphp_eject_slot(slot); | ||
945 | } | 945 | } |
946 | disabled++; | 946 | disabled++; |
947 | } else { | 947 | } else { |
@@ -962,6 +962,144 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
962 | return retval; | 962 | return retval; |
963 | } | 963 | } |
964 | 964 | ||
965 | static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) | ||
966 | { | ||
967 | u16 pci_cmd, pci_bctl; | ||
968 | struct pci_dev *cdev; | ||
969 | |||
970 | /* Program hpp values for this device */ | ||
971 | if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || | ||
972 | (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
973 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) | ||
974 | return; | ||
975 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, | ||
976 | bridge->hpp.cache_line_size); | ||
977 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, | ||
978 | bridge->hpp.latency_timer); | ||
979 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
980 | if (bridge->hpp.enable_SERR) | ||
981 | pci_cmd |= PCI_COMMAND_SERR; | ||
982 | else | ||
983 | pci_cmd &= ~PCI_COMMAND_SERR; | ||
984 | if (bridge->hpp.enable_PERR) | ||
985 | pci_cmd |= PCI_COMMAND_PARITY; | ||
986 | else | ||
987 | pci_cmd &= ~PCI_COMMAND_PARITY; | ||
988 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
989 | |||
990 | /* Program bridge control value and child devices */ | ||
991 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
992 | pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, | ||
993 | bridge->hpp.latency_timer); | ||
994 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); | ||
995 | if (bridge->hpp.enable_SERR) | ||
996 | pci_bctl |= PCI_BRIDGE_CTL_SERR; | ||
997 | else | ||
998 | pci_bctl &= ~PCI_BRIDGE_CTL_SERR; | ||
999 | if (bridge->hpp.enable_PERR) | ||
1000 | pci_bctl |= PCI_BRIDGE_CTL_PARITY; | ||
1001 | else | ||
1002 | pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; | ||
1003 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); | ||
1004 | if (dev->subordinate) { | ||
1005 | list_for_each_entry(cdev, &dev->subordinate->devices, | ||
1006 | bus_list) | ||
1007 | program_hpp(cdev, bridge); | ||
1008 | } | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus) | ||
1013 | { | ||
1014 | struct acpiphp_bridge bridge; | ||
1015 | struct pci_dev *dev; | ||
1016 | |||
1017 | memset(&bridge, 0, sizeof(bridge)); | ||
1018 | bridge.handle = handle; | ||
1019 | decode_hpp(&bridge); | ||
1020 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1021 | program_hpp(dev, &bridge); | ||
1022 | |||
1023 | } | ||
1024 | |||
1025 | /* | ||
1026 | * Remove devices for which we could not assign resources, call | ||
1027 | * arch specific code to fix-up the bus | ||
1028 | */ | ||
1029 | static void acpiphp_sanitize_bus(struct pci_bus *bus) | ||
1030 | { | ||
1031 | struct pci_dev *dev; | ||
1032 | int i; | ||
1033 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
1034 | |||
1035 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
1036 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | ||
1037 | struct resource *res = &dev->resource[i]; | ||
1038 | if ((res->flags & type_mask) && !res->start && | ||
1039 | res->end) { | ||
1040 | /* Could not assign a required resources | ||
1041 | * for this device, remove it */ | ||
1042 | pci_remove_bus_device(dev); | ||
1043 | break; | ||
1044 | } | ||
1045 | } | ||
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | /* Program resources in newly inserted bridge */ | ||
1050 | static int acpiphp_configure_bridge (acpi_handle handle) | ||
1051 | { | ||
1052 | struct acpi_pci_id pci_id; | ||
1053 | struct pci_bus *bus; | ||
1054 | |||
1055 | if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) { | ||
1056 | err("cannot get PCI domain and bus number for bridge\n"); | ||
1057 | return -EINVAL; | ||
1058 | } | ||
1059 | bus = pci_find_bus(pci_id.segment, pci_id.bus); | ||
1060 | if (!bus) { | ||
1061 | err("cannot find bus %d:%d\n", | ||
1062 | pci_id.segment, pci_id.bus); | ||
1063 | return -EINVAL; | ||
1064 | } | ||
1065 | |||
1066 | pci_bus_size_bridges(bus); | ||
1067 | pci_bus_assign_resources(bus); | ||
1068 | acpiphp_sanitize_bus(bus); | ||
1069 | acpiphp_set_hpp_values(handle, bus); | ||
1070 | pci_enable_bridges(bus); | ||
1071 | acpiphp_configure_ioapics(handle); | ||
1072 | return 0; | ||
1073 | } | ||
1074 | |||
1075 | static void handle_bridge_insertion(acpi_handle handle, u32 type) | ||
1076 | { | ||
1077 | struct acpi_device *device, *pdevice; | ||
1078 | acpi_handle phandle; | ||
1079 | |||
1080 | if ((type != ACPI_NOTIFY_BUS_CHECK) && | ||
1081 | (type != ACPI_NOTIFY_DEVICE_CHECK)) { | ||
1082 | err("unexpected notification type %d\n", type); | ||
1083 | return; | ||
1084 | } | ||
1085 | |||
1086 | acpi_get_parent(handle, &phandle); | ||
1087 | if (acpi_bus_get_device(phandle, &pdevice)) { | ||
1088 | dbg("no parent device, assuming NULL\n"); | ||
1089 | pdevice = NULL; | ||
1090 | } | ||
1091 | if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) { | ||
1092 | err("cannot add bridge to acpi list\n"); | ||
1093 | return; | ||
1094 | } | ||
1095 | if (!acpiphp_configure_bridge(handle) && | ||
1096 | !acpi_bus_start(device)) | ||
1097 | add_bridge(handle); | ||
1098 | else | ||
1099 | err("cannot configure and start bridge\n"); | ||
1100 | |||
1101 | } | ||
1102 | |||
965 | /* | 1103 | /* |
966 | * ACPI event handlers | 1104 | * ACPI event handlers |
967 | */ | 1105 | */ |
@@ -982,8 +1120,19 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
982 | char objname[64]; | 1120 | char objname[64]; |
983 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1121 | struct acpi_buffer buffer = { .length = sizeof(objname), |
984 | .pointer = objname }; | 1122 | .pointer = objname }; |
1123 | struct acpi_device *device; | ||
985 | 1124 | ||
986 | bridge = (struct acpiphp_bridge *)context; | 1125 | if (acpi_bus_get_device(handle, &device)) { |
1126 | /* This bridge must have just been physically inserted */ | ||
1127 | handle_bridge_insertion(handle, type); | ||
1128 | return; | ||
1129 | } | ||
1130 | |||
1131 | bridge = acpiphp_handle_to_bridge(handle); | ||
1132 | if (!bridge) { | ||
1133 | err("cannot get bridge info\n"); | ||
1134 | return; | ||
1135 | } | ||
987 | 1136 | ||
988 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1137 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
989 | 1138 | ||
@@ -1031,7 +1180,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1031 | } | 1180 | } |
1032 | } | 1181 | } |
1033 | 1182 | ||
1034 | |||
1035 | /** | 1183 | /** |
1036 | * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) | 1184 | * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) |
1037 | * | 1185 | * |
@@ -1074,7 +1222,8 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex | |||
1074 | case ACPI_NOTIFY_EJECT_REQUEST: | 1222 | case ACPI_NOTIFY_EJECT_REQUEST: |
1075 | /* request device eject */ | 1223 | /* request device eject */ |
1076 | dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); | 1224 | dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); |
1077 | acpiphp_disable_slot(func->slot); | 1225 | if (!(acpiphp_disable_slot(func->slot))) |
1226 | acpiphp_eject_slot(func->slot); | ||
1078 | break; | 1227 | break; |
1079 | 1228 | ||
1080 | default: | 1229 | default: |
@@ -1083,6 +1232,47 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex | |||
1083 | } | 1232 | } |
1084 | } | 1233 | } |
1085 | 1234 | ||
1235 | static int is_root_bridge(acpi_handle handle) | ||
1236 | { | ||
1237 | acpi_status status; | ||
1238 | struct acpi_device_info *info; | ||
1239 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
1240 | int i; | ||
1241 | |||
1242 | status = acpi_get_object_info(handle, &buffer); | ||
1243 | if (ACPI_SUCCESS(status)) { | ||
1244 | info = buffer.pointer; | ||
1245 | if ((info->valid & ACPI_VALID_HID) && | ||
1246 | !strcmp(PCI_ROOT_HID_STRING, | ||
1247 | info->hardware_id.value)) { | ||
1248 | acpi_os_free(buffer.pointer); | ||
1249 | return 1; | ||
1250 | } | ||
1251 | if (info->valid & ACPI_VALID_CID) { | ||
1252 | for (i=0; i < info->compatibility_id.count; i++) { | ||
1253 | if (!strcmp(PCI_ROOT_HID_STRING, | ||
1254 | info->compatibility_id.id[i].value)) { | ||
1255 | acpi_os_free(buffer.pointer); | ||
1256 | return 1; | ||
1257 | } | ||
1258 | } | ||
1259 | } | ||
1260 | } | ||
1261 | return 0; | ||
1262 | } | ||
1263 | |||
1264 | static acpi_status | ||
1265 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1266 | { | ||
1267 | int *count = (int *)context; | ||
1268 | |||
1269 | if (is_root_bridge(handle)) { | ||
1270 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
1271 | handle_hotplug_event_bridge, NULL); | ||
1272 | (*count)++; | ||
1273 | } | ||
1274 | return AE_OK ; | ||
1275 | } | ||
1086 | 1276 | ||
1087 | static struct acpi_pci_driver acpi_pci_hp_driver = { | 1277 | static struct acpi_pci_driver acpi_pci_hp_driver = { |
1088 | .add = add_bridge, | 1278 | .add = add_bridge, |
@@ -1095,15 +1285,15 @@ static struct acpi_pci_driver acpi_pci_hp_driver = { | |||
1095 | */ | 1285 | */ |
1096 | int __init acpiphp_glue_init(void) | 1286 | int __init acpiphp_glue_init(void) |
1097 | { | 1287 | { |
1098 | int num; | 1288 | int num = 0; |
1099 | |||
1100 | if (list_empty(&pci_root_buses)) | ||
1101 | return -1; | ||
1102 | 1289 | ||
1103 | num = acpi_pci_register_driver(&acpi_pci_hp_driver); | 1290 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
1291 | ACPI_UINT32_MAX, find_root_bridges, &num, NULL); | ||
1104 | 1292 | ||
1105 | if (num <= 0) | 1293 | if (num <= 0) |
1106 | return -1; | 1294 | return -1; |
1295 | else | ||
1296 | acpi_pci_register_driver(&acpi_pci_hp_driver); | ||
1107 | 1297 | ||
1108 | return 0; | 1298 | return 0; |
1109 | } | 1299 | } |
@@ -1116,46 +1306,6 @@ int __init acpiphp_glue_init(void) | |||
1116 | */ | 1306 | */ |
1117 | void __exit acpiphp_glue_exit(void) | 1307 | void __exit acpiphp_glue_exit(void) |
1118 | { | 1308 | { |
1119 | struct list_head *l1, *l2, *n1, *n2; | ||
1120 | struct acpiphp_bridge *bridge; | ||
1121 | struct acpiphp_slot *slot, *next; | ||
1122 | struct acpiphp_func *func; | ||
1123 | acpi_status status; | ||
1124 | |||
1125 | list_for_each_safe (l1, n1, &bridge_list) { | ||
1126 | bridge = (struct acpiphp_bridge *)l1; | ||
1127 | slot = bridge->slots; | ||
1128 | while (slot) { | ||
1129 | next = slot->next; | ||
1130 | list_for_each_safe (l2, n2, &slot->funcs) { | ||
1131 | func = list_entry(l2, struct acpiphp_func, sibling); | ||
1132 | acpiphp_free_resource(&func->io_head); | ||
1133 | acpiphp_free_resource(&func->mem_head); | ||
1134 | acpiphp_free_resource(&func->p_mem_head); | ||
1135 | acpiphp_free_resource(&func->bus_head); | ||
1136 | status = acpi_remove_notify_handler(func->handle, | ||
1137 | ACPI_SYSTEM_NOTIFY, | ||
1138 | handle_hotplug_event_func); | ||
1139 | if (ACPI_FAILURE(status)) | ||
1140 | err("failed to remove notify handler\n"); | ||
1141 | kfree(func); | ||
1142 | } | ||
1143 | kfree(slot); | ||
1144 | slot = next; | ||
1145 | } | ||
1146 | status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY, | ||
1147 | handle_hotplug_event_bridge); | ||
1148 | if (ACPI_FAILURE(status)) | ||
1149 | err("failed to remove notify handler\n"); | ||
1150 | |||
1151 | acpiphp_free_resource(&bridge->io_head); | ||
1152 | acpiphp_free_resource(&bridge->mem_head); | ||
1153 | acpiphp_free_resource(&bridge->p_mem_head); | ||
1154 | acpiphp_free_resource(&bridge->bus_head); | ||
1155 | |||
1156 | kfree(bridge); | ||
1157 | } | ||
1158 | |||
1159 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1309 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); |
1160 | } | 1310 | } |
1161 | 1311 | ||
@@ -1173,11 +1323,14 @@ int __init acpiphp_get_num_slots(void) | |||
1173 | 1323 | ||
1174 | list_for_each (node, &bridge_list) { | 1324 | list_for_each (node, &bridge_list) { |
1175 | bridge = (struct acpiphp_bridge *)node; | 1325 | bridge = (struct acpiphp_bridge *)node; |
1176 | dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots); | 1326 | dbg("Bus %04x:%02x has %d slot%s\n", |
1327 | pci_domain_nr(bridge->pci_bus), | ||
1328 | bridge->pci_bus->number, bridge->nr_slots, | ||
1329 | bridge->nr_slots == 1 ? "" : "s"); | ||
1177 | num_slots += bridge->nr_slots; | 1330 | num_slots += bridge->nr_slots; |
1178 | } | 1331 | } |
1179 | 1332 | ||
1180 | dbg("Total %dslots\n", num_slots); | 1333 | dbg("Total %d slots\n", num_slots); |
1181 | return num_slots; | 1334 | return num_slots; |
1182 | } | 1335 | } |
1183 | 1336 | ||
@@ -1254,7 +1407,6 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) | |||
1254 | return retval; | 1407 | return retval; |
1255 | } | 1408 | } |
1256 | 1409 | ||
1257 | |||
1258 | /** | 1410 | /** |
1259 | * acpiphp_disable_slot - power off slot | 1411 | * acpiphp_disable_slot - power off slot |
1260 | */ | 1412 | */ |
@@ -1274,13 +1426,6 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) | |||
1274 | if (retval) | 1426 | if (retval) |
1275 | goto err_exit; | 1427 | goto err_exit; |
1276 | 1428 | ||
1277 | acpiphp_resource_sort_and_combine(&slot->bridge->io_head); | ||
1278 | acpiphp_resource_sort_and_combine(&slot->bridge->mem_head); | ||
1279 | acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head); | ||
1280 | acpiphp_resource_sort_and_combine(&slot->bridge->bus_head); | ||
1281 | dbg("Available resources:\n"); | ||
1282 | acpiphp_dump_resource(slot->bridge); | ||
1283 | |||
1284 | err_exit: | 1429 | err_exit: |
1285 | up(&slot->crit_sect); | 1430 | up(&slot->crit_sect); |
1286 | return retval; | 1431 | return retval; |
@@ -1293,11 +1438,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) | |||
1293 | */ | 1438 | */ |
1294 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot) | 1439 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot) |
1295 | { | 1440 | { |
1296 | unsigned int sta; | 1441 | return (slot->flags & SLOT_POWEREDON); |
1297 | |||
1298 | sta = get_slot_status(slot); | ||
1299 | |||
1300 | return (sta & ACPI_STA_ENABLED) ? 1 : 0; | ||
1301 | } | 1442 | } |
1302 | 1443 | ||
1303 | 1444 | ||
@@ -1335,9 +1476,10 @@ u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot) | |||
1335 | u32 acpiphp_get_address(struct acpiphp_slot *slot) | 1476 | u32 acpiphp_get_address(struct acpiphp_slot *slot) |
1336 | { | 1477 | { |
1337 | u32 address; | 1478 | u32 address; |
1479 | struct pci_bus *pci_bus = slot->bridge->pci_bus; | ||
1338 | 1480 | ||
1339 | address = ((slot->bridge->seg) << 16) | | 1481 | address = (pci_domain_nr(pci_bus) << 16) | |
1340 | ((slot->bridge->bus) << 8) | | 1482 | (pci_bus->number << 8) | |
1341 | slot->device; | 1483 | slot->device; |
1342 | 1484 | ||
1343 | return address; | 1485 | return address; |
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c deleted file mode 100644 index 54d97c9d1dff..000000000000 --- a/drivers/pci/hotplug/acpiphp_pci.c +++ /dev/null | |||
@@ -1,449 +0,0 @@ | |||
1 | /* | ||
2 | * ACPI PCI HotPlug PCI configuration space management | ||
3 | * | ||
4 | * Copyright (C) 1995,2001 Compaq Computer Corporation | ||
5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | ||
6 | * Copyright (C) 2001,2002 IBM Corp. | ||
7 | * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) | ||
8 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) | ||
9 | * Copyright (C) 2002 NEC Corporation | ||
10 | * | ||
11 | * All rights reserved. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or (at | ||
16 | * your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, but | ||
19 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
21 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
22 | * 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | * | ||
28 | * Send feedback to <t-kochi@bq.jp.nec.com> | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/pci.h> | ||
37 | #include <linux/acpi.h> | ||
38 | #include "../pci.h" | ||
39 | #include "pci_hotplug.h" | ||
40 | #include "acpiphp.h" | ||
41 | |||
42 | #define MY_NAME "acpiphp_pci" | ||
43 | |||
44 | |||
45 | /* allocate mem/pmem/io resource to a new function */ | ||
46 | static int init_config_space (struct acpiphp_func *func) | ||
47 | { | ||
48 | u32 bar, len; | ||
49 | u32 address[] = { | ||
50 | PCI_BASE_ADDRESS_0, | ||
51 | PCI_BASE_ADDRESS_1, | ||
52 | PCI_BASE_ADDRESS_2, | ||
53 | PCI_BASE_ADDRESS_3, | ||
54 | PCI_BASE_ADDRESS_4, | ||
55 | PCI_BASE_ADDRESS_5, | ||
56 | 0 | ||
57 | }; | ||
58 | int count; | ||
59 | struct acpiphp_bridge *bridge; | ||
60 | struct pci_resource *res; | ||
61 | struct pci_bus *pbus; | ||
62 | int bus, device, function; | ||
63 | unsigned int devfn; | ||
64 | u16 tmp; | ||
65 | |||
66 | bridge = func->slot->bridge; | ||
67 | pbus = bridge->pci_bus; | ||
68 | bus = bridge->bus; | ||
69 | device = func->slot->device; | ||
70 | function = func->function; | ||
71 | devfn = PCI_DEVFN(device, function); | ||
72 | |||
73 | for (count = 0; address[count]; count++) { /* for 6 BARs */ | ||
74 | pci_bus_write_config_dword(pbus, devfn, | ||
75 | address[count], 0xFFFFFFFF); | ||
76 | pci_bus_read_config_dword(pbus, devfn, address[count], &bar); | ||
77 | |||
78 | if (!bar) /* This BAR is not implemented */ | ||
79 | continue; | ||
80 | |||
81 | dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar); | ||
82 | |||
83 | if (bar & PCI_BASE_ADDRESS_SPACE_IO) { | ||
84 | /* This is IO */ | ||
85 | |||
86 | len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); | ||
87 | len = len & ~(len - 1); | ||
88 | |||
89 | dbg("len in IO %x, BAR %d\n", len, count); | ||
90 | |||
91 | spin_lock(&bridge->res_lock); | ||
92 | res = acpiphp_get_io_resource(&bridge->io_head, len); | ||
93 | spin_unlock(&bridge->res_lock); | ||
94 | |||
95 | if (!res) { | ||
96 | err("cannot allocate requested io for %02x:%02x.%d len %x\n", | ||
97 | bus, device, function, len); | ||
98 | return -1; | ||
99 | } | ||
100 | pci_bus_write_config_dword(pbus, devfn, | ||
101 | address[count], | ||
102 | (u32)res->base); | ||
103 | res->next = func->io_head; | ||
104 | func->io_head = res; | ||
105 | |||
106 | } else { | ||
107 | /* This is Memory */ | ||
108 | if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) { | ||
109 | /* pfmem */ | ||
110 | |||
111 | len = bar & 0xFFFFFFF0; | ||
112 | len = ~len + 1; | ||
113 | |||
114 | dbg("len in PFMEM %x, BAR %d\n", len, count); | ||
115 | |||
116 | spin_lock(&bridge->res_lock); | ||
117 | res = acpiphp_get_resource(&bridge->p_mem_head, len); | ||
118 | spin_unlock(&bridge->res_lock); | ||
119 | |||
120 | if (!res) { | ||
121 | err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n", | ||
122 | bus, device, function, len); | ||
123 | return -1; | ||
124 | } | ||
125 | |||
126 | pci_bus_write_config_dword(pbus, devfn, | ||
127 | address[count], | ||
128 | (u32)res->base); | ||
129 | |||
130 | if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ | ||
131 | dbg("inside the pfmem 64 case, count %d\n", count); | ||
132 | count += 1; | ||
133 | pci_bus_write_config_dword(pbus, devfn, | ||
134 | address[count], | ||
135 | (u32)(res->base >> 32)); | ||
136 | } | ||
137 | |||
138 | res->next = func->p_mem_head; | ||
139 | func->p_mem_head = res; | ||
140 | |||
141 | } else { | ||
142 | /* regular memory */ | ||
143 | |||
144 | len = bar & 0xFFFFFFF0; | ||
145 | len = ~len + 1; | ||
146 | |||
147 | dbg("len in MEM %x, BAR %d\n", len, count); | ||
148 | |||
149 | spin_lock(&bridge->res_lock); | ||
150 | res = acpiphp_get_resource(&bridge->mem_head, len); | ||
151 | spin_unlock(&bridge->res_lock); | ||
152 | |||
153 | if (!res) { | ||
154 | err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n", | ||
155 | bus, device, function, len); | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | pci_bus_write_config_dword(pbus, devfn, | ||
160 | address[count], | ||
161 | (u32)res->base); | ||
162 | |||
163 | if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { | ||
164 | /* takes up another dword */ | ||
165 | dbg("inside mem 64 case, reg. mem, count %d\n", count); | ||
166 | count += 1; | ||
167 | pci_bus_write_config_dword(pbus, devfn, | ||
168 | address[count], | ||
169 | (u32)(res->base >> 32)); | ||
170 | } | ||
171 | |||
172 | res->next = func->mem_head; | ||
173 | func->mem_head = res; | ||
174 | |||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /* disable expansion rom */ | ||
180 | pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000); | ||
181 | |||
182 | /* set PCI parameters from _HPP */ | ||
183 | pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE, | ||
184 | bridge->hpp.cache_line_size); | ||
185 | pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER, | ||
186 | bridge->hpp.latency_timer); | ||
187 | |||
188 | pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp); | ||
189 | if (bridge->hpp.enable_SERR) | ||
190 | tmp |= PCI_COMMAND_SERR; | ||
191 | if (bridge->hpp.enable_PERR) | ||
192 | tmp |= PCI_COMMAND_PARITY; | ||
193 | pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /* detect_used_resource - subtract resource under dev from bridge */ | ||
199 | static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev) | ||
200 | { | ||
201 | int count; | ||
202 | |||
203 | dbg("Device %s\n", pci_name(dev)); | ||
204 | |||
205 | for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) { | ||
206 | struct pci_resource *res; | ||
207 | struct pci_resource **head; | ||
208 | unsigned long base = dev->resource[count].start; | ||
209 | unsigned long len = dev->resource[count].end - base + 1; | ||
210 | unsigned long flags = dev->resource[count].flags; | ||
211 | |||
212 | if (!flags) | ||
213 | continue; | ||
214 | |||
215 | dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base, | ||
216 | base + len - 1, flags); | ||
217 | |||
218 | if (flags & IORESOURCE_IO) { | ||
219 | head = &bridge->io_head; | ||
220 | } else if (flags & IORESOURCE_PREFETCH) { | ||
221 | head = &bridge->p_mem_head; | ||
222 | } else { | ||
223 | head = &bridge->mem_head; | ||
224 | } | ||
225 | |||
226 | spin_lock(&bridge->res_lock); | ||
227 | res = acpiphp_get_resource_with_base(head, base, len); | ||
228 | spin_unlock(&bridge->res_lock); | ||
229 | if (res) | ||
230 | kfree(res); | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | |||
237 | /** | ||
238 | * acpiphp_detect_pci_resource - detect resources under bridge | ||
239 | * @bridge: detect all resources already used under this bridge | ||
240 | * | ||
241 | * collect all resources already allocated for all devices under a bridge. | ||
242 | */ | ||
243 | int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge) | ||
244 | { | ||
245 | struct list_head *l; | ||
246 | struct pci_dev *dev; | ||
247 | |||
248 | list_for_each (l, &bridge->pci_bus->devices) { | ||
249 | dev = pci_dev_b(l); | ||
250 | detect_used_resource(bridge, dev); | ||
251 | } | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | |||
257 | /** | ||
258 | * acpiphp_init_slot_resource - gather resource usage information of a slot | ||
259 | * @slot: ACPI slot object to be checked, should have valid pci_dev member | ||
260 | * | ||
261 | * TBD: PCI-to-PCI bridge case | ||
262 | * use pci_dev->resource[] | ||
263 | */ | ||
264 | int acpiphp_init_func_resource (struct acpiphp_func *func) | ||
265 | { | ||
266 | u64 base; | ||
267 | u32 bar, len; | ||
268 | u32 address[] = { | ||
269 | PCI_BASE_ADDRESS_0, | ||
270 | PCI_BASE_ADDRESS_1, | ||
271 | PCI_BASE_ADDRESS_2, | ||
272 | PCI_BASE_ADDRESS_3, | ||
273 | PCI_BASE_ADDRESS_4, | ||
274 | PCI_BASE_ADDRESS_5, | ||
275 | 0 | ||
276 | }; | ||
277 | int count; | ||
278 | struct pci_resource *res; | ||
279 | struct pci_dev *dev; | ||
280 | |||
281 | dev = func->pci_dev; | ||
282 | dbg("Hot-pluggable device %s\n", pci_name(dev)); | ||
283 | |||
284 | for (count = 0; address[count]; count++) { /* for 6 BARs */ | ||
285 | pci_read_config_dword(dev, address[count], &bar); | ||
286 | |||
287 | if (!bar) /* This BAR is not implemented */ | ||
288 | continue; | ||
289 | |||
290 | pci_write_config_dword(dev, address[count], 0xFFFFFFFF); | ||
291 | pci_read_config_dword(dev, address[count], &len); | ||
292 | |||
293 | if (len & PCI_BASE_ADDRESS_SPACE_IO) { | ||
294 | /* This is IO */ | ||
295 | base = bar & 0xFFFFFFFC; | ||
296 | len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); | ||
297 | len = len & ~(len - 1); | ||
298 | |||
299 | dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1); | ||
300 | |||
301 | res = acpiphp_make_resource(base, len); | ||
302 | if (!res) | ||
303 | goto no_memory; | ||
304 | |||
305 | res->next = func->io_head; | ||
306 | func->io_head = res; | ||
307 | |||
308 | } else { | ||
309 | /* This is Memory */ | ||
310 | base = bar & 0xFFFFFFF0; | ||
311 | if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) { | ||
312 | /* pfmem */ | ||
313 | |||
314 | len &= 0xFFFFFFF0; | ||
315 | len = ~len + 1; | ||
316 | |||
317 | if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ | ||
318 | dbg("prefetch mem 64\n"); | ||
319 | count += 1; | ||
320 | } | ||
321 | dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1); | ||
322 | res = acpiphp_make_resource(base, len); | ||
323 | if (!res) | ||
324 | goto no_memory; | ||
325 | |||
326 | res->next = func->p_mem_head; | ||
327 | func->p_mem_head = res; | ||
328 | |||
329 | } else { | ||
330 | /* regular memory */ | ||
331 | |||
332 | len &= 0xFFFFFFF0; | ||
333 | len = ~len + 1; | ||
334 | |||
335 | if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { | ||
336 | /* takes up another dword */ | ||
337 | dbg("mem 64\n"); | ||
338 | count += 1; | ||
339 | } | ||
340 | dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1); | ||
341 | res = acpiphp_make_resource(base, len); | ||
342 | if (!res) | ||
343 | goto no_memory; | ||
344 | |||
345 | res->next = func->mem_head; | ||
346 | func->mem_head = res; | ||
347 | |||
348 | } | ||
349 | } | ||
350 | |||
351 | pci_write_config_dword(dev, address[count], bar); | ||
352 | } | ||
353 | #if 1 | ||
354 | acpiphp_dump_func_resource(func); | ||
355 | #endif | ||
356 | |||
357 | return 0; | ||
358 | |||
359 | no_memory: | ||
360 | err("out of memory\n"); | ||
361 | acpiphp_free_resource(&func->io_head); | ||
362 | acpiphp_free_resource(&func->mem_head); | ||
363 | acpiphp_free_resource(&func->p_mem_head); | ||
364 | |||
365 | return -1; | ||
366 | } | ||
367 | |||
368 | |||
369 | /** | ||
370 | * acpiphp_configure_slot - allocate PCI resources | ||
371 | * @slot: slot to be configured | ||
372 | * | ||
373 | * initializes a PCI functions on a device inserted | ||
374 | * into the slot | ||
375 | * | ||
376 | */ | ||
377 | int acpiphp_configure_slot (struct acpiphp_slot *slot) | ||
378 | { | ||
379 | struct acpiphp_func *func; | ||
380 | struct list_head *l; | ||
381 | u8 hdr; | ||
382 | u32 dvid; | ||
383 | int retval = 0; | ||
384 | int is_multi = 0; | ||
385 | |||
386 | pci_bus_read_config_byte(slot->bridge->pci_bus, | ||
387 | PCI_DEVFN(slot->device, 0), | ||
388 | PCI_HEADER_TYPE, &hdr); | ||
389 | |||
390 | if (hdr & 0x80) | ||
391 | is_multi = 1; | ||
392 | |||
393 | list_for_each (l, &slot->funcs) { | ||
394 | func = list_entry(l, struct acpiphp_func, sibling); | ||
395 | if (is_multi || func->function == 0) { | ||
396 | pci_bus_read_config_dword(slot->bridge->pci_bus, | ||
397 | PCI_DEVFN(slot->device, | ||
398 | func->function), | ||
399 | PCI_VENDOR_ID, &dvid); | ||
400 | if (dvid != 0xffffffff) { | ||
401 | retval = init_config_space(func); | ||
402 | if (retval) | ||
403 | break; | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
408 | return retval; | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * acpiphp_configure_function - configure PCI function | ||
413 | * @func: function to be configured | ||
414 | * | ||
415 | * initializes a PCI functions on a device inserted | ||
416 | * into the slot | ||
417 | * | ||
418 | */ | ||
419 | int acpiphp_configure_function (struct acpiphp_func *func) | ||
420 | { | ||
421 | /* all handled by the pci core now */ | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | /** | ||
426 | * acpiphp_unconfigure_function - unconfigure PCI function | ||
427 | * @func: function to be unconfigured | ||
428 | * | ||
429 | */ | ||
430 | void acpiphp_unconfigure_function (struct acpiphp_func *func) | ||
431 | { | ||
432 | struct acpiphp_bridge *bridge; | ||
433 | |||
434 | /* if pci_dev is NULL, ignore it */ | ||
435 | if (!func->pci_dev) | ||
436 | return; | ||
437 | |||
438 | pci_remove_bus_device(func->pci_dev); | ||
439 | |||
440 | /* free all resources */ | ||
441 | bridge = func->slot->bridge; | ||
442 | |||
443 | spin_lock(&bridge->res_lock); | ||
444 | acpiphp_move_resource(&func->io_head, &bridge->io_head); | ||
445 | acpiphp_move_resource(&func->mem_head, &bridge->mem_head); | ||
446 | acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head); | ||
447 | acpiphp_move_resource(&func->bus_head, &bridge->bus_head); | ||
448 | spin_unlock(&bridge->res_lock); | ||
449 | } | ||
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c deleted file mode 100644 index f54b1fa7b75a..000000000000 --- a/drivers/pci/hotplug/acpiphp_res.c +++ /dev/null | |||
@@ -1,700 +0,0 @@ | |||
1 | /* | ||
2 | * ACPI PCI HotPlug Utility functions | ||
3 | * | ||
4 | * Copyright (C) 1995,2001 Compaq Computer Corporation | ||
5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | ||
6 | * Copyright (C) 2001 IBM Corp. | ||
7 | * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) | ||
8 | * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) | ||
9 | * Copyright (C) 2002 NEC Corporation | ||
10 | * | ||
11 | * All rights reserved. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or (at | ||
16 | * your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, but | ||
19 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
21 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
22 | * 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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | * | ||
28 | * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com> | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/types.h> | ||
37 | #include <linux/proc_fs.h> | ||
38 | #include <linux/sysctl.h> | ||
39 | #include <linux/pci.h> | ||
40 | #include <linux/smp.h> | ||
41 | #include <linux/smp_lock.h> | ||
42 | |||
43 | #include <linux/string.h> | ||
44 | #include <linux/mm.h> | ||
45 | #include <linux/errno.h> | ||
46 | #include <linux/ioport.h> | ||
47 | #include <linux/slab.h> | ||
48 | #include <linux/interrupt.h> | ||
49 | #include <linux/timer.h> | ||
50 | |||
51 | #include <linux/ioctl.h> | ||
52 | #include <linux/fcntl.h> | ||
53 | |||
54 | #include <linux/list.h> | ||
55 | |||
56 | #include "pci_hotplug.h" | ||
57 | #include "acpiphp.h" | ||
58 | |||
59 | #define MY_NAME "acpiphp_res" | ||
60 | |||
61 | |||
62 | /* | ||
63 | * sort_by_size - sort nodes by their length, smallest first | ||
64 | */ | ||
65 | static int sort_by_size(struct pci_resource **head) | ||
66 | { | ||
67 | struct pci_resource *current_res; | ||
68 | struct pci_resource *next_res; | ||
69 | int out_of_order = 1; | ||
70 | |||
71 | if (!(*head)) | ||
72 | return 1; | ||
73 | |||
74 | if (!((*head)->next)) | ||
75 | return 0; | ||
76 | |||
77 | while (out_of_order) { | ||
78 | out_of_order = 0; | ||
79 | |||
80 | /* Special case for swapping list head */ | ||
81 | if (((*head)->next) && | ||
82 | ((*head)->length > (*head)->next->length)) { | ||
83 | out_of_order++; | ||
84 | current_res = *head; | ||
85 | *head = (*head)->next; | ||
86 | current_res->next = (*head)->next; | ||
87 | (*head)->next = current_res; | ||
88 | } | ||
89 | |||
90 | current_res = *head; | ||
91 | |||
92 | while (current_res->next && current_res->next->next) { | ||
93 | if (current_res->next->length > current_res->next->next->length) { | ||
94 | out_of_order++; | ||
95 | next_res = current_res->next; | ||
96 | current_res->next = current_res->next->next; | ||
97 | current_res = current_res->next; | ||
98 | next_res->next = current_res->next; | ||
99 | current_res->next = next_res; | ||
100 | } else | ||
101 | current_res = current_res->next; | ||
102 | } | ||
103 | } /* End of out_of_order loop */ | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | #if 0 | ||
109 | /* | ||
110 | * sort_by_max_size - sort nodes by their length, largest first | ||
111 | */ | ||
112 | static int sort_by_max_size(struct pci_resource **head) | ||
113 | { | ||
114 | struct pci_resource *current_res; | ||
115 | struct pci_resource *next_res; | ||
116 | int out_of_order = 1; | ||
117 | |||
118 | if (!(*head)) | ||
119 | return 1; | ||
120 | |||
121 | if (!((*head)->next)) | ||
122 | return 0; | ||
123 | |||
124 | while (out_of_order) { | ||
125 | out_of_order = 0; | ||
126 | |||
127 | /* Special case for swapping list head */ | ||
128 | if (((*head)->next) && | ||
129 | ((*head)->length < (*head)->next->length)) { | ||
130 | out_of_order++; | ||
131 | current_res = *head; | ||
132 | *head = (*head)->next; | ||
133 | current_res->next = (*head)->next; | ||
134 | (*head)->next = current_res; | ||
135 | } | ||
136 | |||
137 | current_res = *head; | ||
138 | |||
139 | while (current_res->next && current_res->next->next) { | ||
140 | if (current_res->next->length < current_res->next->next->length) { | ||
141 | out_of_order++; | ||
142 | next_res = current_res->next; | ||
143 | current_res->next = current_res->next->next; | ||
144 | current_res = current_res->next; | ||
145 | next_res->next = current_res->next; | ||
146 | current_res->next = next_res; | ||
147 | } else | ||
148 | current_res = current_res->next; | ||
149 | } | ||
150 | } /* End of out_of_order loop */ | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | #endif | ||
155 | |||
156 | /** | ||
157 | * get_io_resource - get resource for I/O ports | ||
158 | * | ||
159 | * this function sorts the resource list by size and then | ||
160 | * returns the first node of "size" length that is not in the | ||
161 | * ISA aliasing window. If it finds a node larger than "size" | ||
162 | * it will split it up. | ||
163 | * | ||
164 | * size must be a power of two. | ||
165 | * | ||
166 | * difference from get_resource is handling of ISA aliasing space. | ||
167 | * | ||
168 | */ | ||
169 | struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size) | ||
170 | { | ||
171 | struct pci_resource *prevnode; | ||
172 | struct pci_resource *node; | ||
173 | struct pci_resource *split_node; | ||
174 | u64 temp_qword; | ||
175 | |||
176 | if (!(*head)) | ||
177 | return NULL; | ||
178 | |||
179 | if (acpiphp_resource_sort_and_combine(head)) | ||
180 | return NULL; | ||
181 | |||
182 | if (sort_by_size(head)) | ||
183 | return NULL; | ||
184 | |||
185 | for (node = *head; node; node = node->next) { | ||
186 | if (node->length < size) | ||
187 | continue; | ||
188 | |||
189 | if (node->base & (size - 1)) { | ||
190 | /* this one isn't base aligned properly | ||
191 | so we'll make a new entry and split it up */ | ||
192 | temp_qword = (node->base | (size-1)) + 1; | ||
193 | |||
194 | /* Short circuit if adjusted size is too small */ | ||
195 | if ((node->length - (temp_qword - node->base)) < size) | ||
196 | continue; | ||
197 | |||
198 | split_node = acpiphp_make_resource(node->base, temp_qword - node->base); | ||
199 | |||
200 | if (!split_node) | ||
201 | return NULL; | ||
202 | |||
203 | node->base = temp_qword; | ||
204 | node->length -= split_node->length; | ||
205 | |||
206 | /* Put it in the list */ | ||
207 | split_node->next = node->next; | ||
208 | node->next = split_node; | ||
209 | } /* End of non-aligned base */ | ||
210 | |||
211 | /* Don't need to check if too small since we already did */ | ||
212 | if (node->length > size) { | ||
213 | /* this one is longer than we need | ||
214 | so we'll make a new entry and split it up */ | ||
215 | split_node = acpiphp_make_resource(node->base + size, node->length - size); | ||
216 | |||
217 | if (!split_node) | ||
218 | return NULL; | ||
219 | |||
220 | node->length = size; | ||
221 | |||
222 | /* Put it in the list */ | ||
223 | split_node->next = node->next; | ||
224 | node->next = split_node; | ||
225 | } /* End of too big on top end */ | ||
226 | |||
227 | /* For IO make sure it's not in the ISA aliasing space */ | ||
228 | if ((node->base & 0x300L) && !(node->base & 0xfffff000)) | ||
229 | continue; | ||
230 | |||
231 | /* If we got here, then it is the right size | ||
232 | Now take it out of the list */ | ||
233 | if (*head == node) { | ||
234 | *head = node->next; | ||
235 | } else { | ||
236 | prevnode = *head; | ||
237 | while (prevnode->next != node) | ||
238 | prevnode = prevnode->next; | ||
239 | |||
240 | prevnode->next = node->next; | ||
241 | } | ||
242 | node->next = NULL; | ||
243 | /* Stop looping */ | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | return node; | ||
248 | } | ||
249 | |||
250 | |||
251 | #if 0 | ||
252 | /** | ||
253 | * get_max_resource - get the largest resource | ||
254 | * | ||
255 | * Gets the largest node that is at least "size" big from the | ||
256 | * list pointed to by head. It aligns the node on top and bottom | ||
257 | * to "size" alignment before returning it. | ||
258 | */ | ||
259 | static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size) | ||
260 | { | ||
261 | struct pci_resource *max; | ||
262 | struct pci_resource *temp; | ||
263 | struct pci_resource *split_node; | ||
264 | u64 temp_qword; | ||
265 | |||
266 | if (!(*head)) | ||
267 | return NULL; | ||
268 | |||
269 | if (acpiphp_resource_sort_and_combine(head)) | ||
270 | return NULL; | ||
271 | |||
272 | if (sort_by_max_size(head)) | ||
273 | return NULL; | ||
274 | |||
275 | for (max = *head;max; max = max->next) { | ||
276 | |||
277 | /* If not big enough we could probably just bail, | ||
278 | instead we'll continue to the next. */ | ||
279 | if (max->length < size) | ||
280 | continue; | ||
281 | |||
282 | if (max->base & (size - 1)) { | ||
283 | /* this one isn't base aligned properly | ||
284 | so we'll make a new entry and split it up */ | ||
285 | temp_qword = (max->base | (size-1)) + 1; | ||
286 | |||
287 | /* Short circuit if adjusted size is too small */ | ||
288 | if ((max->length - (temp_qword - max->base)) < size) | ||
289 | continue; | ||
290 | |||
291 | split_node = acpiphp_make_resource(max->base, temp_qword - max->base); | ||
292 | |||
293 | if (!split_node) | ||
294 | return NULL; | ||
295 | |||
296 | max->base = temp_qword; | ||
297 | max->length -= split_node->length; | ||
298 | |||
299 | /* Put it next in the list */ | ||
300 | split_node->next = max->next; | ||
301 | max->next = split_node; | ||
302 | } | ||
303 | |||
304 | if ((max->base + max->length) & (size - 1)) { | ||
305 | /* this one isn't end aligned properly at the top | ||
306 | so we'll make a new entry and split it up */ | ||
307 | temp_qword = ((max->base + max->length) & ~(size - 1)); | ||
308 | |||
309 | split_node = acpiphp_make_resource(temp_qword, | ||
310 | max->length + max->base - temp_qword); | ||
311 | |||
312 | if (!split_node) | ||
313 | return NULL; | ||
314 | |||
315 | max->length -= split_node->length; | ||
316 | |||
317 | /* Put it in the list */ | ||
318 | split_node->next = max->next; | ||
319 | max->next = split_node; | ||
320 | } | ||
321 | |||
322 | /* Make sure it didn't shrink too much when we aligned it */ | ||
323 | if (max->length < size) | ||
324 | continue; | ||
325 | |||
326 | /* Now take it out of the list */ | ||
327 | temp = (struct pci_resource*) *head; | ||
328 | if (temp == max) { | ||
329 | *head = max->next; | ||
330 | } else { | ||
331 | while (temp && temp->next != max) { | ||
332 | temp = temp->next; | ||
333 | } | ||
334 | |||
335 | temp->next = max->next; | ||
336 | } | ||
337 | |||
338 | max->next = NULL; | ||
339 | return max; | ||
340 | } | ||
341 | |||
342 | /* If we get here, we couldn't find one */ | ||
343 | return NULL; | ||
344 | } | ||
345 | #endif | ||
346 | |||
347 | /** | ||
348 | * get_resource - get resource (mem, pfmem) | ||
349 | * | ||
350 | * this function sorts the resource list by size and then | ||
351 | * returns the first node of "size" length. If it finds a node | ||
352 | * larger than "size" it will split it up. | ||
353 | * | ||
354 | * size must be a power of two. | ||
355 | * | ||
356 | */ | ||
357 | struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size) | ||
358 | { | ||
359 | struct pci_resource *prevnode; | ||
360 | struct pci_resource *node; | ||
361 | struct pci_resource *split_node; | ||
362 | u64 temp_qword; | ||
363 | |||
364 | if (!(*head)) | ||
365 | return NULL; | ||
366 | |||
367 | if (acpiphp_resource_sort_and_combine(head)) | ||
368 | return NULL; | ||
369 | |||
370 | if (sort_by_size(head)) | ||
371 | return NULL; | ||
372 | |||
373 | for (node = *head; node; node = node->next) { | ||
374 | dbg("%s: req_size =%x node=%p, base=%x, length=%x\n", | ||
375 | __FUNCTION__, size, node, (u32)node->base, node->length); | ||
376 | if (node->length < size) | ||
377 | continue; | ||
378 | |||
379 | if (node->base & (size - 1)) { | ||
380 | dbg("%s: not aligned\n", __FUNCTION__); | ||
381 | /* this one isn't base aligned properly | ||
382 | so we'll make a new entry and split it up */ | ||
383 | temp_qword = (node->base | (size-1)) + 1; | ||
384 | |||
385 | /* Short circuit if adjusted size is too small */ | ||
386 | if ((node->length - (temp_qword - node->base)) < size) | ||
387 | continue; | ||
388 | |||
389 | split_node = acpiphp_make_resource(node->base, temp_qword - node->base); | ||
390 | |||
391 | if (!split_node) | ||
392 | return NULL; | ||
393 | |||
394 | node->base = temp_qword; | ||
395 | node->length -= split_node->length; | ||
396 | |||
397 | /* Put it in the list */ | ||
398 | split_node->next = node->next; | ||
399 | node->next = split_node; | ||
400 | } /* End of non-aligned base */ | ||
401 | |||
402 | /* Don't need to check if too small since we already did */ | ||
403 | if (node->length > size) { | ||
404 | dbg("%s: too big\n", __FUNCTION__); | ||
405 | /* this one is longer than we need | ||
406 | so we'll make a new entry and split it up */ | ||
407 | split_node = acpiphp_make_resource(node->base + size, node->length - size); | ||
408 | |||
409 | if (!split_node) | ||
410 | return NULL; | ||
411 | |||
412 | node->length = size; | ||
413 | |||
414 | /* Put it in the list */ | ||
415 | split_node->next = node->next; | ||
416 | node->next = split_node; | ||
417 | } /* End of too big on top end */ | ||
418 | |||
419 | dbg("%s: got one!!!\n", __FUNCTION__); | ||
420 | /* If we got here, then it is the right size | ||
421 | Now take it out of the list */ | ||
422 | if (*head == node) { | ||
423 | *head = node->next; | ||
424 | } else { | ||
425 | prevnode = *head; | ||
426 | while (prevnode->next != node) | ||
427 | prevnode = prevnode->next; | ||
428 | |||
429 | prevnode->next = node->next; | ||
430 | } | ||
431 | node->next = NULL; | ||
432 | /* Stop looping */ | ||
433 | break; | ||
434 | } | ||
435 | return node; | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * get_resource_with_base - get resource with specific base address | ||
440 | * | ||
441 | * this function | ||
442 | * returns the first node of "size" length located at specified base address. | ||
443 | * If it finds a node larger than "size" it will split it up. | ||
444 | * | ||
445 | * size must be a power of two. | ||
446 | * | ||
447 | */ | ||
448 | struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size) | ||
449 | { | ||
450 | struct pci_resource *prevnode; | ||
451 | struct pci_resource *node; | ||
452 | struct pci_resource *split_node; | ||
453 | u64 temp_qword; | ||
454 | |||
455 | if (!(*head)) | ||
456 | return NULL; | ||
457 | |||
458 | if (acpiphp_resource_sort_and_combine(head)) | ||
459 | return NULL; | ||
460 | |||
461 | for (node = *head; node; node = node->next) { | ||
462 | dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n", | ||
463 | (u32)base, size, node, (u32)node->base, node->length); | ||
464 | if (node->base > base) | ||
465 | continue; | ||
466 | |||
467 | if ((node->base + node->length) < (base + size)) | ||
468 | continue; | ||
469 | |||
470 | if (node->base < base) { | ||
471 | dbg(": split 1\n"); | ||
472 | /* this one isn't base aligned properly | ||
473 | so we'll make a new entry and split it up */ | ||
474 | temp_qword = base; | ||
475 | |||
476 | /* Short circuit if adjusted size is too small */ | ||
477 | if ((node->length - (temp_qword - node->base)) < size) | ||
478 | continue; | ||
479 | |||
480 | split_node = acpiphp_make_resource(node->base, temp_qword - node->base); | ||
481 | |||
482 | if (!split_node) | ||
483 | return NULL; | ||
484 | |||
485 | node->base = temp_qword; | ||
486 | node->length -= split_node->length; | ||
487 | |||
488 | /* Put it in the list */ | ||
489 | split_node->next = node->next; | ||
490 | node->next = split_node; | ||
491 | } | ||
492 | |||
493 | dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n", | ||
494 | (u32)base, size, node, (u32)node->base, node->length); | ||
495 | |||
496 | /* Don't need to check if too small since we already did */ | ||
497 | if (node->length > size) { | ||
498 | dbg(": split 2\n"); | ||
499 | /* this one is longer than we need | ||
500 | so we'll make a new entry and split it up */ | ||
501 | split_node = acpiphp_make_resource(node->base + size, node->length - size); | ||
502 | |||
503 | if (!split_node) | ||
504 | return NULL; | ||
505 | |||
506 | node->length = size; | ||
507 | |||
508 | /* Put it in the list */ | ||
509 | split_node->next = node->next; | ||
510 | node->next = split_node; | ||
511 | } /* End of too big on top end */ | ||
512 | |||
513 | dbg(": got one!!!\n"); | ||
514 | /* If we got here, then it is the right size | ||
515 | Now take it out of the list */ | ||
516 | if (*head == node) { | ||
517 | *head = node->next; | ||
518 | } else { | ||
519 | prevnode = *head; | ||
520 | while (prevnode->next != node) | ||
521 | prevnode = prevnode->next; | ||
522 | |||
523 | prevnode->next = node->next; | ||
524 | } | ||
525 | node->next = NULL; | ||
526 | /* Stop looping */ | ||
527 | break; | ||
528 | } | ||
529 | return node; | ||
530 | } | ||
531 | |||
532 | |||
533 | /** | ||
534 | * acpiphp_resource_sort_and_combine | ||
535 | * | ||
536 | * Sorts all of the nodes in the list in ascending order by | ||
537 | * their base addresses. Also does garbage collection by | ||
538 | * combining adjacent nodes. | ||
539 | * | ||
540 | * returns 0 if success | ||
541 | */ | ||
542 | int acpiphp_resource_sort_and_combine (struct pci_resource **head) | ||
543 | { | ||
544 | struct pci_resource *node1; | ||
545 | struct pci_resource *node2; | ||
546 | int out_of_order = 1; | ||
547 | |||
548 | if (!(*head)) | ||
549 | return 1; | ||
550 | |||
551 | dbg("*head->next = %p\n",(*head)->next); | ||
552 | |||
553 | if (!(*head)->next) | ||
554 | return 0; /* only one item on the list, already sorted! */ | ||
555 | |||
556 | dbg("*head->base = 0x%x\n",(u32)(*head)->base); | ||
557 | dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base); | ||
558 | while (out_of_order) { | ||
559 | out_of_order = 0; | ||
560 | |||
561 | /* Special case for swapping list head */ | ||
562 | if (((*head)->next) && | ||
563 | ((*head)->base > (*head)->next->base)) { | ||
564 | node1 = *head; | ||
565 | (*head) = (*head)->next; | ||
566 | node1->next = (*head)->next; | ||
567 | (*head)->next = node1; | ||
568 | out_of_order++; | ||
569 | } | ||
570 | |||
571 | node1 = (*head); | ||
572 | |||
573 | while (node1->next && node1->next->next) { | ||
574 | if (node1->next->base > node1->next->next->base) { | ||
575 | out_of_order++; | ||
576 | node2 = node1->next; | ||
577 | node1->next = node1->next->next; | ||
578 | node1 = node1->next; | ||
579 | node2->next = node1->next; | ||
580 | node1->next = node2; | ||
581 | } else | ||
582 | node1 = node1->next; | ||
583 | } | ||
584 | } /* End of out_of_order loop */ | ||
585 | |||
586 | node1 = *head; | ||
587 | |||
588 | while (node1 && node1->next) { | ||
589 | if ((node1->base + node1->length) == node1->next->base) { | ||
590 | /* Combine */ | ||
591 | dbg("8..\n"); | ||
592 | node1->length += node1->next->length; | ||
593 | node2 = node1->next; | ||
594 | node1->next = node1->next->next; | ||
595 | kfree(node2); | ||
596 | } else | ||
597 | node1 = node1->next; | ||
598 | } | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | |||
604 | /** | ||
605 | * acpiphp_make_resource - make resource structure | ||
606 | * @base: base address of a resource | ||
607 | * @length: length of a resource | ||
608 | */ | ||
609 | struct pci_resource *acpiphp_make_resource (u64 base, u32 length) | ||
610 | { | ||
611 | struct pci_resource *res; | ||
612 | |||
613 | res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); | ||
614 | if (res) { | ||
615 | memset(res, 0, sizeof(struct pci_resource)); | ||
616 | res->base = base; | ||
617 | res->length = length; | ||
618 | } | ||
619 | |||
620 | return res; | ||
621 | } | ||
622 | |||
623 | |||
624 | /** | ||
625 | * acpiphp_move_resource - move linked resources from one to another | ||
626 | * @from: head of linked resource list | ||
627 | * @to: head of linked resource list | ||
628 | */ | ||
629 | void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to) | ||
630 | { | ||
631 | struct pci_resource *tmp; | ||
632 | |||
633 | while (*from) { | ||
634 | tmp = (*from)->next; | ||
635 | (*from)->next = *to; | ||
636 | *to = *from; | ||
637 | *from = tmp; | ||
638 | } | ||
639 | |||
640 | /* *from = NULL is guaranteed */ | ||
641 | } | ||
642 | |||
643 | |||
644 | /** | ||
645 | * acpiphp_free_resource - free all linked resources | ||
646 | * @res: head of linked resource list | ||
647 | */ | ||
648 | void acpiphp_free_resource (struct pci_resource **res) | ||
649 | { | ||
650 | struct pci_resource *tmp; | ||
651 | |||
652 | while (*res) { | ||
653 | tmp = (*res)->next; | ||
654 | kfree(*res); | ||
655 | *res = tmp; | ||
656 | } | ||
657 | |||
658 | /* *res = NULL is guaranteed */ | ||
659 | } | ||
660 | |||
661 | |||
662 | /* debug support functions; will go away sometime :) */ | ||
663 | static void dump_resource(struct pci_resource *head) | ||
664 | { | ||
665 | struct pci_resource *p; | ||
666 | int cnt; | ||
667 | |||
668 | p = head; | ||
669 | cnt = 0; | ||
670 | |||
671 | while (p) { | ||
672 | dbg("[%02d] %08x - %08x\n", | ||
673 | cnt++, (u32)p->base, (u32)p->base + p->length - 1); | ||
674 | p = p->next; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | void acpiphp_dump_resource(struct acpiphp_bridge *bridge) | ||
679 | { | ||
680 | dbg("I/O resource:\n"); | ||
681 | dump_resource(bridge->io_head); | ||
682 | dbg("MEM resource:\n"); | ||
683 | dump_resource(bridge->mem_head); | ||
684 | dbg("PMEM resource:\n"); | ||
685 | dump_resource(bridge->p_mem_head); | ||
686 | dbg("BUS resource:\n"); | ||
687 | dump_resource(bridge->bus_head); | ||
688 | } | ||
689 | |||
690 | void acpiphp_dump_func_resource(struct acpiphp_func *func) | ||
691 | { | ||
692 | dbg("I/O resource:\n"); | ||
693 | dump_resource(func->io_head); | ||
694 | dbg("MEM resource:\n"); | ||
695 | dump_resource(func->mem_head); | ||
696 | dbg("PMEM resource:\n"); | ||
697 | dump_resource(func->p_mem_head); | ||
698 | dbg("BUS resource:\n"); | ||
699 | dump_resource(func->bus_head); | ||
700 | } | ||
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index afbccfa5217d..8c6d3987d461 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -60,6 +60,7 @@ static void __iomem *smbios_start; | |||
60 | static void __iomem *cpqhp_rom_start; | 60 | static void __iomem *cpqhp_rom_start; |
61 | static int power_mode; | 61 | static int power_mode; |
62 | static int debug; | 62 | static int debug; |
63 | static int initialized; | ||
63 | 64 | ||
64 | #define DRIVER_VERSION "0.9.8" | 65 | #define DRIVER_VERSION "0.9.8" |
65 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>" | 66 | #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>" |
@@ -1271,7 +1272,6 @@ static int one_time_init(void) | |||
1271 | { | 1272 | { |
1272 | int loop; | 1273 | int loop; |
1273 | int retval = 0; | 1274 | int retval = 0; |
1274 | static int initialized = 0; | ||
1275 | 1275 | ||
1276 | if (initialized) | 1276 | if (initialized) |
1277 | return 0; | 1277 | return 0; |
@@ -1441,7 +1441,8 @@ static void __exit unload_cpqphpd(void) | |||
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | // Stop the notification mechanism | 1443 | // Stop the notification mechanism |
1444 | cpqhp_event_stop_thread(); | 1444 | if (initialized) |
1445 | cpqhp_event_stop_thread(); | ||
1445 | 1446 | ||
1446 | //unmap the rom address | 1447 | //unmap the rom address |
1447 | if (cpqhp_rom_start) | 1448 | if (cpqhp_rom_start) |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 30206ac43c44..b5ab9aa6ff7c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; | |||
28 | static kmem_cache_t* msi_cachep; | 28 | static kmem_cache_t* msi_cachep; |
29 | 29 | ||
30 | static int pci_msi_enable = 1; | 30 | static int pci_msi_enable = 1; |
31 | static int last_alloc_vector = 0; | 31 | static int last_alloc_vector; |
32 | static int nr_released_vectors = 0; | 32 | static int nr_released_vectors; |
33 | static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; | 33 | static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; |
34 | static int nr_msix_devices = 0; | 34 | static int nr_msix_devices; |
35 | 35 | ||
36 | #ifndef CONFIG_X86_IO_APIC | 36 | #ifndef CONFIG_X86_IO_APIC |
37 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; | 37 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; |
@@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) | |||
170 | return 0; /* never anything pending */ | 170 | return 0; /* never anything pending */ |
171 | } | 171 | } |
172 | 172 | ||
173 | static void release_msi(unsigned int vector); | 173 | static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) |
174 | static void shutdown_msi_irq(unsigned int vector) | ||
175 | { | ||
176 | release_msi(vector); | ||
177 | } | ||
178 | |||
179 | #define shutdown_msi_irq_wo_maskbit shutdown_msi_irq | ||
180 | static void enable_msi_irq_wo_maskbit(unsigned int vector) {} | ||
181 | static void disable_msi_irq_wo_maskbit(unsigned int vector) {} | ||
182 | static void ack_msi_irq_wo_maskbit(unsigned int vector) {} | ||
183 | static void end_msi_irq_wo_maskbit(unsigned int vector) | ||
184 | { | 174 | { |
185 | move_msi(vector); | 175 | startup_msi_irq_wo_maskbit(vector); |
186 | ack_APIC_irq(); | 176 | unmask_MSI_irq(vector); |
177 | return 0; /* never anything pending */ | ||
187 | } | 178 | } |
188 | 179 | ||
189 | static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) | 180 | static void shutdown_msi_irq(unsigned int vector) |
190 | { | 181 | { |
191 | struct msi_desc *entry; | 182 | struct msi_desc *entry; |
192 | unsigned long flags; | 183 | unsigned long flags; |
193 | 184 | ||
194 | spin_lock_irqsave(&msi_lock, flags); | 185 | spin_lock_irqsave(&msi_lock, flags); |
195 | entry = msi_desc[vector]; | 186 | entry = msi_desc[vector]; |
196 | if (!entry || !entry->dev) { | 187 | if (entry && entry->dev) |
197 | spin_unlock_irqrestore(&msi_lock, flags); | 188 | entry->msi_attrib.state = 0; /* Mark it not active */ |
198 | return 0; | ||
199 | } | ||
200 | entry->msi_attrib.state = 1; /* Mark it active */ | ||
201 | spin_unlock_irqrestore(&msi_lock, flags); | 189 | spin_unlock_irqrestore(&msi_lock, flags); |
202 | |||
203 | unmask_MSI_irq(vector); | ||
204 | return 0; /* never anything pending */ | ||
205 | } | 190 | } |
206 | 191 | ||
207 | #define shutdown_msi_irq_w_maskbit shutdown_msi_irq | 192 | static void end_msi_irq_wo_maskbit(unsigned int vector) |
208 | #define enable_msi_irq_w_maskbit unmask_MSI_irq | 193 | { |
209 | #define disable_msi_irq_w_maskbit mask_MSI_irq | 194 | move_msi(vector); |
210 | #define ack_msi_irq_w_maskbit mask_MSI_irq | 195 | ack_APIC_irq(); |
196 | } | ||
211 | 197 | ||
212 | static void end_msi_irq_w_maskbit(unsigned int vector) | 198 | static void end_msi_irq_w_maskbit(unsigned int vector) |
213 | { | 199 | { |
@@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector) | |||
216 | ack_APIC_irq(); | 202 | ack_APIC_irq(); |
217 | } | 203 | } |
218 | 204 | ||
205 | static void do_nothing(unsigned int vector) | ||
206 | { | ||
207 | } | ||
208 | |||
219 | /* | 209 | /* |
220 | * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices, | 210 | * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices, |
221 | * which implement the MSI-X Capability Structure. | 211 | * which implement the MSI-X Capability Structure. |
@@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector) | |||
223 | static struct hw_interrupt_type msix_irq_type = { | 213 | static struct hw_interrupt_type msix_irq_type = { |
224 | .typename = "PCI-MSI-X", | 214 | .typename = "PCI-MSI-X", |
225 | .startup = startup_msi_irq_w_maskbit, | 215 | .startup = startup_msi_irq_w_maskbit, |
226 | .shutdown = shutdown_msi_irq_w_maskbit, | 216 | .shutdown = shutdown_msi_irq, |
227 | .enable = enable_msi_irq_w_maskbit, | 217 | .enable = unmask_MSI_irq, |
228 | .disable = disable_msi_irq_w_maskbit, | 218 | .disable = mask_MSI_irq, |
229 | .ack = ack_msi_irq_w_maskbit, | 219 | .ack = mask_MSI_irq, |
230 | .end = end_msi_irq_w_maskbit, | 220 | .end = end_msi_irq_w_maskbit, |
231 | .set_affinity = set_msi_irq_affinity | 221 | .set_affinity = set_msi_irq_affinity |
232 | }; | 222 | }; |
@@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq_type = { | |||
239 | static struct hw_interrupt_type msi_irq_w_maskbit_type = { | 229 | static struct hw_interrupt_type msi_irq_w_maskbit_type = { |
240 | .typename = "PCI-MSI", | 230 | .typename = "PCI-MSI", |
241 | .startup = startup_msi_irq_w_maskbit, | 231 | .startup = startup_msi_irq_w_maskbit, |
242 | .shutdown = shutdown_msi_irq_w_maskbit, | 232 | .shutdown = shutdown_msi_irq, |
243 | .enable = enable_msi_irq_w_maskbit, | 233 | .enable = unmask_MSI_irq, |
244 | .disable = disable_msi_irq_w_maskbit, | 234 | .disable = mask_MSI_irq, |
245 | .ack = ack_msi_irq_w_maskbit, | 235 | .ack = mask_MSI_irq, |
246 | .end = end_msi_irq_w_maskbit, | 236 | .end = end_msi_irq_w_maskbit, |
247 | .set_affinity = set_msi_irq_affinity | 237 | .set_affinity = set_msi_irq_affinity |
248 | }; | 238 | }; |
@@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = { | |||
255 | static struct hw_interrupt_type msi_irq_wo_maskbit_type = { | 245 | static struct hw_interrupt_type msi_irq_wo_maskbit_type = { |
256 | .typename = "PCI-MSI", | 246 | .typename = "PCI-MSI", |
257 | .startup = startup_msi_irq_wo_maskbit, | 247 | .startup = startup_msi_irq_wo_maskbit, |
258 | .shutdown = shutdown_msi_irq_wo_maskbit, | 248 | .shutdown = shutdown_msi_irq, |
259 | .enable = enable_msi_irq_wo_maskbit, | 249 | .enable = do_nothing, |
260 | .disable = disable_msi_irq_wo_maskbit, | 250 | .disable = do_nothing, |
261 | .ack = ack_msi_irq_wo_maskbit, | 251 | .ack = do_nothing, |
262 | .end = end_msi_irq_wo_maskbit, | 252 | .end = end_msi_irq_wo_maskbit, |
263 | .set_affinity = set_msi_irq_affinity | 253 | .set_affinity = set_msi_irq_affinity |
264 | }; | 254 | }; |
@@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(void) | |||
407 | { | 397 | { |
408 | struct msi_desc *entry; | 398 | struct msi_desc *entry; |
409 | 399 | ||
410 | entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL); | 400 | entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL); |
411 | if (!entry) | 401 | if (!entry) |
412 | return NULL; | 402 | return NULL; |
413 | 403 | ||
@@ -796,18 +786,6 @@ void pci_disable_msi(struct pci_dev* dev) | |||
796 | } | 786 | } |
797 | } | 787 | } |
798 | 788 | ||
799 | static void release_msi(unsigned int vector) | ||
800 | { | ||
801 | struct msi_desc *entry; | ||
802 | unsigned long flags; | ||
803 | |||
804 | spin_lock_irqsave(&msi_lock, flags); | ||
805 | entry = msi_desc[vector]; | ||
806 | if (entry && entry->dev) | ||
807 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
808 | spin_unlock_irqrestore(&msi_lock, flags); | ||
809 | } | ||
810 | |||
811 | static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) | 789 | static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) |
812 | { | 790 | { |
813 | struct msi_desc *entry; | 791 | struct msi_desc *entry; |
@@ -924,7 +902,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) | |||
924 | /** | 902 | /** |
925 | * pci_enable_msix - configure device's MSI-X capability structure | 903 | * pci_enable_msix - configure device's MSI-X capability structure |
926 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 904 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
927 | * @data: pointer to an array of MSI-X entries | 905 | * @entries: pointer to an array of MSI-X entries |
928 | * @nvec: number of MSI-X vectors requested for allocation by device driver | 906 | * @nvec: number of MSI-X vectors requested for allocation by device driver |
929 | * | 907 | * |
930 | * Setup the MSI-X capability structure of device function with the number | 908 | * Setup the MSI-X capability structure of device function with the number |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index bef21ae3cbd0..390f1851c0f1 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
@@ -41,11 +41,11 @@ static inline void move_msi(int vector) {} | |||
41 | #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) | 41 | #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) |
42 | #define PCI_MSIX_FLAGS_BITMASK (1 << 0) | 42 | #define PCI_MSIX_FLAGS_BITMASK (1 << 0) |
43 | 43 | ||
44 | #define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 | ||
45 | #define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 | ||
46 | #define PCI_MSIX_ENTRY_DATA_OFFSET 8 | ||
47 | #define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 | ||
48 | #define PCI_MSIX_ENTRY_SIZE 16 | 44 | #define PCI_MSIX_ENTRY_SIZE 16 |
45 | #define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 | ||
46 | #define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 | ||
47 | #define PCI_MSIX_ENTRY_DATA_OFFSET 8 | ||
48 | #define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 | ||
49 | 49 | ||
50 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | 50 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) |
51 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) | 51 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) |
@@ -64,7 +64,6 @@ static inline void move_msi(int vector) {} | |||
64 | #define msi_enable(control, num) multi_msi_enable(control, num); \ | 64 | #define msi_enable(control, num) multi_msi_enable(control, num); \ |
65 | control |= PCI_MSI_FLAGS_ENABLE | 65 | control |= PCI_MSI_FLAGS_ENABLE |
66 | 66 | ||
67 | #define msix_control_reg msi_control_reg | ||
68 | #define msix_table_offset_reg(base) (base + 0x04) | 67 | #define msix_table_offset_reg(base) (base + 0x04) |
69 | #define msix_pba_offset_reg(base) (base + 0x08) | 68 | #define msix_pba_offset_reg(base) (base + 0x08) |
70 | #define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE | 69 | #define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a15f94072a6f..cc9d65388e62 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -60,15 +60,18 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) | |||
60 | char * str = buf; | 60 | char * str = buf; |
61 | int i; | 61 | int i; |
62 | int max = 7; | 62 | int max = 7; |
63 | u64 start, end; | ||
63 | 64 | ||
64 | if (pci_dev->subordinate) | 65 | if (pci_dev->subordinate) |
65 | max = DEVICE_COUNT_RESOURCE; | 66 | max = DEVICE_COUNT_RESOURCE; |
66 | 67 | ||
67 | for (i = 0; i < max; i++) { | 68 | for (i = 0; i < max; i++) { |
68 | str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n", | 69 | struct resource *res = &pci_dev->resource[i]; |
69 | pci_resource_start(pci_dev,i), | 70 | pci_resource_to_user(pci_dev, i, res, &start, &end); |
70 | pci_resource_end(pci_dev,i), | 71 | str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n", |
71 | pci_resource_flags(pci_dev,i)); | 72 | (unsigned long long)start, |
73 | (unsigned long long)end, | ||
74 | (unsigned long long)res->flags); | ||
72 | } | 75 | } |
73 | return (str - buf); | 76 | return (str - buf); |
74 | } | 77 | } |
@@ -313,8 +316,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
313 | struct device, kobj)); | 316 | struct device, kobj)); |
314 | struct resource *res = (struct resource *)attr->private; | 317 | struct resource *res = (struct resource *)attr->private; |
315 | enum pci_mmap_state mmap_type; | 318 | enum pci_mmap_state mmap_type; |
319 | u64 start, end; | ||
320 | int i; | ||
316 | 321 | ||
317 | vma->vm_pgoff += res->start >> PAGE_SHIFT; | 322 | for (i = 0; i < PCI_ROM_RESOURCE; i++) |
323 | if (res == &pdev->resource[i]) | ||
324 | break; | ||
325 | if (i >= PCI_ROM_RESOURCE) | ||
326 | return -ENODEV; | ||
327 | |||
328 | /* pci_mmap_page_range() expects the same kind of entry as coming | ||
329 | * from /proc/bus/pci/ which is a "user visible" value. If this is | ||
330 | * different from the resource itself, arch will do necessary fixup. | ||
331 | */ | ||
332 | pci_resource_to_user(pdev, i, res, &start, &end); | ||
333 | vma->vm_pgoff += start >> PAGE_SHIFT; | ||
318 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; | 334 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; |
319 | 335 | ||
320 | return pci_mmap_page_range(pdev, vma, mmap_type, 0); | 336 | return pci_mmap_page_range(pdev, vma, mmap_type, 0); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fd48b201eb53..6a0a82f0508b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -374,8 +374,11 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de | |||
374 | struct pci_bus *child; | 374 | struct pci_bus *child; |
375 | 375 | ||
376 | child = pci_alloc_child_bus(parent, dev, busnr); | 376 | child = pci_alloc_child_bus(parent, dev, busnr); |
377 | if (child) | 377 | if (child) { |
378 | spin_lock(&pci_bus_lock); | ||
378 | list_add_tail(&child->node, &parent->children); | 379 | list_add_tail(&child->node, &parent->children); |
380 | spin_unlock(&pci_bus_lock); | ||
381 | } | ||
379 | return child; | 382 | return child; |
380 | } | 383 | } |
381 | 384 | ||
@@ -411,7 +414,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
411 | { | 414 | { |
412 | struct pci_bus *child; | 415 | struct pci_bus *child; |
413 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 416 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
414 | u32 buses; | 417 | u32 buses, i; |
415 | u16 bctl; | 418 | u16 bctl; |
416 | 419 | ||
417 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 420 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
@@ -447,7 +450,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
447 | return max; | 450 | return max; |
448 | } | 451 | } |
449 | 452 | ||
450 | child = pci_alloc_child_bus(bus, dev, busnr); | 453 | child = pci_add_new_bus(bus, dev, busnr); |
451 | if (!child) | 454 | if (!child) |
452 | return max; | 455 | return max; |
453 | child->primary = buses & 0xFF; | 456 | child->primary = buses & 0xFF; |
@@ -470,7 +473,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
470 | /* Clear errors */ | 473 | /* Clear errors */ |
471 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 474 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
472 | 475 | ||
473 | child = pci_alloc_child_bus(bus, dev, ++max); | 476 | /* Prevent assigning a bus number that already exists. |
477 | * This can happen when a bridge is hot-plugged */ | ||
478 | if (pci_find_bus(pci_domain_nr(bus), max+1)) | ||
479 | return max; | ||
480 | child = pci_add_new_bus(bus, dev, ++max); | ||
474 | buses = (buses & 0xff000000) | 481 | buses = (buses & 0xff000000) |
475 | | ((unsigned int)(child->primary) << 0) | 482 | | ((unsigned int)(child->primary) << 0) |
476 | | ((unsigned int)(child->secondary) << 8) | 483 | | ((unsigned int)(child->secondary) << 8) |
@@ -501,7 +508,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
501 | * as cards with a PCI-to-PCI bridge can be | 508 | * as cards with a PCI-to-PCI bridge can be |
502 | * inserted later. | 509 | * inserted later. |
503 | */ | 510 | */ |
504 | max += CARDBUS_RESERVE_BUSNR; | 511 | for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) |
512 | if (pci_find_bus(pci_domain_nr(bus), | ||
513 | max+i+1)) | ||
514 | break; | ||
515 | max += i; | ||
505 | } | 516 | } |
506 | /* | 517 | /* |
507 | * Set the subordinate bus number to its real value. | 518 | * Set the subordinate bus number to its real value. |
@@ -757,7 +768,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
757 | * and the bus list for fixup functions, etc. | 768 | * and the bus list for fixup functions, etc. |
758 | */ | 769 | */ |
759 | INIT_LIST_HEAD(&dev->global_list); | 770 | INIT_LIST_HEAD(&dev->global_list); |
771 | spin_lock(&pci_bus_lock); | ||
760 | list_add_tail(&dev->bus_list, &bus->devices); | 772 | list_add_tail(&dev->bus_list, &bus->devices); |
773 | spin_unlock(&pci_bus_lock); | ||
761 | 774 | ||
762 | return dev; | 775 | return dev; |
763 | } | 776 | } |
@@ -878,7 +891,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, | |||
878 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); | 891 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); |
879 | goto err_out; | 892 | goto err_out; |
880 | } | 893 | } |
894 | spin_lock(&pci_bus_lock); | ||
881 | list_add_tail(&b->node, &pci_root_buses); | 895 | list_add_tail(&b->node, &pci_root_buses); |
896 | spin_unlock(&pci_bus_lock); | ||
882 | 897 | ||
883 | memset(dev, 0, sizeof(*dev)); | 898 | memset(dev, 0, sizeof(*dev)); |
884 | dev->parent = parent; | 899 | dev->parent = parent; |
@@ -911,8 +926,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, | |||
911 | 926 | ||
912 | b->subordinate = pci_scan_child_bus(b); | 927 | b->subordinate = pci_scan_child_bus(b); |
913 | 928 | ||
914 | pci_bus_add_devices(b); | ||
915 | |||
916 | return b; | 929 | return b; |
917 | 930 | ||
918 | sys_create_link_err: | 931 | sys_create_link_err: |
@@ -922,7 +935,9 @@ class_dev_create_file_err: | |||
922 | class_dev_reg_err: | 935 | class_dev_reg_err: |
923 | device_unregister(dev); | 936 | device_unregister(dev); |
924 | dev_reg_err: | 937 | dev_reg_err: |
938 | spin_lock(&pci_bus_lock); | ||
925 | list_del(&b->node); | 939 | list_del(&b->node); |
940 | spin_unlock(&pci_bus_lock); | ||
926 | err_out: | 941 | err_out: |
927 | kfree(dev); | 942 | kfree(dev); |
928 | kfree(b); | 943 | kfree(b); |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index e68bbfb1e7c3..7988fc8df3fd 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -355,14 +355,20 @@ static int show_device(struct seq_file *m, void *v) | |||
355 | dev->device, | 355 | dev->device, |
356 | dev->irq); | 356 | dev->irq); |
357 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ | 357 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ |
358 | for(i=0; i<7; i++) | 358 | for (i=0; i<7; i++) { |
359 | u64 start, end; | ||
360 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | ||
359 | seq_printf(m, LONG_FORMAT, | 361 | seq_printf(m, LONG_FORMAT, |
360 | dev->resource[i].start | | 362 | ((unsigned long)start) | |
361 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); | 363 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); |
362 | for(i=0; i<7; i++) | 364 | } |
365 | for (i=0; i<7; i++) { | ||
366 | u64 start, end; | ||
367 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | ||
363 | seq_printf(m, LONG_FORMAT, | 368 | seq_printf(m, LONG_FORMAT, |
364 | dev->resource[i].start < dev->resource[i].end ? | 369 | dev->resource[i].start < dev->resource[i].end ? |
365 | dev->resource[i].end - dev->resource[i].start + 1 : 0); | 370 | (unsigned long)(end - start) + 1 : 0); |
371 | } | ||
366 | seq_putc(m, '\t'); | 372 | seq_putc(m, '\t'); |
367 | if (drv) | 373 | if (drv) |
368 | seq_printf(m, "%s", drv->name); | 374 | seq_printf(m, "%s", drv->name); |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 96f077f9a659..27a294b6965d 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -18,17 +18,21 @@ static void pci_free_resources(struct pci_dev *dev) | |||
18 | 18 | ||
19 | static void pci_destroy_dev(struct pci_dev *dev) | 19 | static void pci_destroy_dev(struct pci_dev *dev) |
20 | { | 20 | { |
21 | pci_proc_detach_device(dev); | 21 | if (!list_empty(&dev->global_list)) { |
22 | pci_remove_sysfs_dev_files(dev); | 22 | pci_proc_detach_device(dev); |
23 | device_unregister(&dev->dev); | 23 | pci_remove_sysfs_dev_files(dev); |
24 | device_unregister(&dev->dev); | ||
25 | spin_lock(&pci_bus_lock); | ||
26 | list_del(&dev->global_list); | ||
27 | dev->global_list.next = dev->global_list.prev = NULL; | ||
28 | spin_unlock(&pci_bus_lock); | ||
29 | } | ||
24 | 30 | ||
25 | /* Remove the device from the device lists, and prevent any further | 31 | /* Remove the device from the device lists, and prevent any further |
26 | * list accesses from this device */ | 32 | * list accesses from this device */ |
27 | spin_lock(&pci_bus_lock); | 33 | spin_lock(&pci_bus_lock); |
28 | list_del(&dev->bus_list); | 34 | list_del(&dev->bus_list); |
29 | list_del(&dev->global_list); | ||
30 | dev->bus_list.next = dev->bus_list.prev = NULL; | 35 | dev->bus_list.next = dev->bus_list.prev = NULL; |
31 | dev->global_list.next = dev->global_list.prev = NULL; | ||
32 | spin_unlock(&pci_bus_lock); | 36 | spin_unlock(&pci_bus_lock); |
33 | 37 | ||
34 | pci_free_resources(dev); | 38 | pci_free_resources(dev); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1ba84be0b4c0..6b628de948af 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -72,7 +72,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus) | |||
72 | for (list = head.next; list;) { | 72 | for (list = head.next; list;) { |
73 | res = list->res; | 73 | res = list->res; |
74 | idx = res - &list->dev->resource[0]; | 74 | idx = res - &list->dev->resource[0]; |
75 | pci_assign_resource(list->dev, idx); | 75 | if (pci_assign_resource(list->dev, idx)) { |
76 | res->start = 0; | ||
77 | res->flags = 0; | ||
78 | } | ||
76 | tmp = list; | 79 | tmp = list; |
77 | list = list->next; | 80 | list = list->next; |
78 | kfree(tmp); | 81 | kfree(tmp); |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 34dbc37a79d4..bc6e4627c7a1 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -1916,9 +1916,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev) | |||
1916 | } /* End __twa_shutdown() */ | 1916 | } /* End __twa_shutdown() */ |
1917 | 1917 | ||
1918 | /* Wrapper for __twa_shutdown */ | 1918 | /* Wrapper for __twa_shutdown */ |
1919 | static void twa_shutdown(struct device *dev) | 1919 | static void twa_shutdown(struct pci_dev *pdev) |
1920 | { | 1920 | { |
1921 | struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); | 1921 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
1922 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; | 1922 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; |
1923 | 1923 | ||
1924 | __twa_shutdown(tw_dev); | 1924 | __twa_shutdown(tw_dev); |
@@ -2140,9 +2140,7 @@ static struct pci_driver twa_driver = { | |||
2140 | .id_table = twa_pci_tbl, | 2140 | .id_table = twa_pci_tbl, |
2141 | .probe = twa_probe, | 2141 | .probe = twa_probe, |
2142 | .remove = twa_remove, | 2142 | .remove = twa_remove, |
2143 | .driver = { | 2143 | .shutdown = twa_shutdown |
2144 | .shutdown = twa_shutdown | ||
2145 | } | ||
2146 | }; | 2144 | }; |
2147 | 2145 | ||
2148 | /* This function is called on driver initialization */ | 2146 | /* This function is called on driver initialization */ |
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index b6dc576da430..973c51fb0fe2 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -2264,9 +2264,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev) | |||
2264 | } /* End __tw_shutdown() */ | 2264 | } /* End __tw_shutdown() */ |
2265 | 2265 | ||
2266 | /* Wrapper for __tw_shutdown */ | 2266 | /* Wrapper for __tw_shutdown */ |
2267 | static void tw_shutdown(struct device *dev) | 2267 | static void tw_shutdown(struct pci_dev *pdev) |
2268 | { | 2268 | { |
2269 | struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); | 2269 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
2270 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; | 2270 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; |
2271 | 2271 | ||
2272 | __tw_shutdown(tw_dev); | 2272 | __tw_shutdown(tw_dev); |
@@ -2451,9 +2451,7 @@ static struct pci_driver tw_driver = { | |||
2451 | .id_table = tw_pci_tbl, | 2451 | .id_table = tw_pci_tbl, |
2452 | .probe = tw_probe, | 2452 | .probe = tw_probe, |
2453 | .remove = tw_remove, | 2453 | .remove = tw_remove, |
2454 | .driver = { | 2454 | .shutdown = tw_shutdown, |
2455 | .shutdown = tw_shutdown | ||
2456 | } | ||
2457 | }; | 2455 | }; |
2458 | 2456 | ||
2459 | /* This function is called on driver initialization */ | 2457 | /* This function is called on driver initialization */ |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 9a547ca9c864..c5623694d10f 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -304,26 +304,19 @@ static int ahci_port_start(struct ata_port *ap) | |||
304 | struct device *dev = ap->host_set->dev; | 304 | struct device *dev = ap->host_set->dev; |
305 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | 305 | struct ahci_host_priv *hpriv = ap->host_set->private_data; |
306 | struct ahci_port_priv *pp; | 306 | struct ahci_port_priv *pp; |
307 | int rc; | ||
308 | void *mem, *mmio = ap->host_set->mmio_base; | 307 | void *mem, *mmio = ap->host_set->mmio_base; |
309 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | 308 | void *port_mmio = ahci_port_base(mmio, ap->port_no); |
310 | dma_addr_t mem_dma; | 309 | dma_addr_t mem_dma; |
311 | 310 | ||
312 | rc = ata_port_start(ap); | ||
313 | if (rc) | ||
314 | return rc; | ||
315 | |||
316 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | 311 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); |
317 | if (!pp) { | 312 | if (!pp) |
318 | rc = -ENOMEM; | 313 | return -ENOMEM; |
319 | goto err_out; | ||
320 | } | ||
321 | memset(pp, 0, sizeof(*pp)); | 314 | memset(pp, 0, sizeof(*pp)); |
322 | 315 | ||
323 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | 316 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); |
324 | if (!mem) { | 317 | if (!mem) { |
325 | rc = -ENOMEM; | 318 | kfree(pp); |
326 | goto err_out_kfree; | 319 | return -ENOMEM; |
327 | } | 320 | } |
328 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | 321 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); |
329 | 322 | ||
@@ -373,12 +366,6 @@ static int ahci_port_start(struct ata_port *ap) | |||
373 | readl(port_mmio + PORT_CMD); /* flush */ | 366 | readl(port_mmio + PORT_CMD); /* flush */ |
374 | 367 | ||
375 | return 0; | 368 | return 0; |
376 | |||
377 | err_out_kfree: | ||
378 | kfree(pp); | ||
379 | err_out: | ||
380 | ata_port_stop(ap); | ||
381 | return rc; | ||
382 | } | 369 | } |
383 | 370 | ||
384 | 371 | ||
@@ -404,7 +391,6 @@ static void ahci_port_stop(struct ata_port *ap) | |||
404 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | 391 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, |
405 | pp->cmd_slot, pp->cmd_slot_dma); | 392 | pp->cmd_slot, pp->cmd_slot_dma); |
406 | kfree(pp); | 393 | kfree(pp); |
407 | ata_port_stop(ap); | ||
408 | } | 394 | } |
409 | 395 | ||
410 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) | 396 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 80d022625c82..babd48363402 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -6012,7 +6012,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev, | |||
6012 | 6012 | ||
6013 | /** | 6013 | /** |
6014 | * ipr_shutdown - Shutdown handler. | 6014 | * ipr_shutdown - Shutdown handler. |
6015 | * @dev: device struct | 6015 | * @pdev: pci device struct |
6016 | * | 6016 | * |
6017 | * This function is invoked upon system shutdown/reboot. It will issue | 6017 | * This function is invoked upon system shutdown/reboot. It will issue |
6018 | * an adapter shutdown to the adapter to flush the write cache. | 6018 | * an adapter shutdown to the adapter to flush the write cache. |
@@ -6020,9 +6020,9 @@ static int __devinit ipr_probe(struct pci_dev *pdev, | |||
6020 | * Return value: | 6020 | * Return value: |
6021 | * none | 6021 | * none |
6022 | **/ | 6022 | **/ |
6023 | static void ipr_shutdown(struct device *dev) | 6023 | static void ipr_shutdown(struct pci_dev *pdev) |
6024 | { | 6024 | { |
6025 | struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev)); | 6025 | struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); |
6026 | unsigned long lock_flags = 0; | 6026 | unsigned long lock_flags = 0; |
6027 | 6027 | ||
6028 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 6028 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
@@ -6068,9 +6068,7 @@ static struct pci_driver ipr_driver = { | |||
6068 | .id_table = ipr_pci_table, | 6068 | .id_table = ipr_pci_table, |
6069 | .probe = ipr_probe, | 6069 | .probe = ipr_probe, |
6070 | .remove = ipr_remove, | 6070 | .remove = ipr_remove, |
6071 | .driver = { | 6071 | .shutdown = ipr_shutdown, |
6072 | .shutdown = ipr_shutdown, | ||
6073 | }, | ||
6074 | }; | 6072 | }; |
6075 | 6073 | ||
6076 | /** | 6074 | /** |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 36b401fee1f1..cb535fa185b9 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1408,7 +1408,9 @@ void __sata_phy_reset(struct ata_port *ap) | |||
1408 | if (ap->flags & ATA_FLAG_SATA_RESET) { | 1408 | if (ap->flags & ATA_FLAG_SATA_RESET) { |
1409 | /* issue phy wake/reset */ | 1409 | /* issue phy wake/reset */ |
1410 | scr_write_flush(ap, SCR_CONTROL, 0x301); | 1410 | scr_write_flush(ap, SCR_CONTROL, 0x301); |
1411 | udelay(400); /* FIXME: a guess */ | 1411 | /* Couldn't find anything in SATA I/II specs, but |
1412 | * AHCI-1.1 10.4.2 says at least 1 ms. */ | ||
1413 | mdelay(1); | ||
1412 | } | 1414 | } |
1413 | scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ | 1415 | scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ |
1414 | 1416 | ||
@@ -1920,6 +1922,7 @@ static const char * ata_dma_blacklist [] = { | |||
1920 | "HITACHI CDR-8335", | 1922 | "HITACHI CDR-8335", |
1921 | "HITACHI CDR-8435", | 1923 | "HITACHI CDR-8435", |
1922 | "Toshiba CD-ROM XM-6202B", | 1924 | "Toshiba CD-ROM XM-6202B", |
1925 | "TOSHIBA CD-ROM XM-1702BC", | ||
1923 | "CD-532E-A", | 1926 | "CD-532E-A", |
1924 | "E-IDE CD-ROM CR-840", | 1927 | "E-IDE CD-ROM CR-840", |
1925 | "CD-ROM Drive/F5A", | 1928 | "CD-ROM Drive/F5A", |
@@ -1927,7 +1930,6 @@ static const char * ata_dma_blacklist [] = { | |||
1927 | "SAMSUNG CD-ROM SC-148C", | 1930 | "SAMSUNG CD-ROM SC-148C", |
1928 | "SAMSUNG CD-ROM SC", | 1931 | "SAMSUNG CD-ROM SC", |
1929 | "SanDisk SDP3B-64", | 1932 | "SanDisk SDP3B-64", |
1930 | "SAMSUNG CD-ROM SN-124", | ||
1931 | "ATAPI CD-ROM DRIVE 40X MAXIMUM", | 1933 | "ATAPI CD-ROM DRIVE 40X MAXIMUM", |
1932 | "_NEC DV5800A", | 1934 | "_NEC DV5800A", |
1933 | }; | 1935 | }; |
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index ec81532eb845..a70cdf31311c 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -5036,9 +5036,9 @@ megaraid_remove_one(struct pci_dev *pdev) | |||
5036 | } | 5036 | } |
5037 | 5037 | ||
5038 | static void | 5038 | static void |
5039 | megaraid_shutdown(struct device *dev) | 5039 | megaraid_shutdown(struct pci_dev *pdev) |
5040 | { | 5040 | { |
5041 | struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); | 5041 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
5042 | adapter_t *adapter = (adapter_t *)host->hostdata; | 5042 | adapter_t *adapter = (adapter_t *)host->hostdata; |
5043 | 5043 | ||
5044 | __megaraid_shutdown(adapter); | 5044 | __megaraid_shutdown(adapter); |
@@ -5070,9 +5070,7 @@ static struct pci_driver megaraid_pci_driver = { | |||
5070 | .id_table = megaraid_pci_tbl, | 5070 | .id_table = megaraid_pci_tbl, |
5071 | .probe = megaraid_probe_one, | 5071 | .probe = megaraid_probe_one, |
5072 | .remove = __devexit_p(megaraid_remove_one), | 5072 | .remove = __devexit_p(megaraid_remove_one), |
5073 | .driver = { | 5073 | .shutdown = megaraid_shutdown, |
5074 | .shutdown = megaraid_shutdown, | ||
5075 | }, | ||
5076 | }; | 5074 | }; |
5077 | 5075 | ||
5078 | static int __init megaraid_init(void) | 5076 | static int __init megaraid_init(void) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 621dee8b8cb2..10506f9cd0c9 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -632,7 +632,7 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) | |||
632 | { | 632 | { |
633 | struct scsi_host_sg_pool *sgp; | 633 | struct scsi_host_sg_pool *sgp; |
634 | 634 | ||
635 | BUG_ON(index > SG_MEMPOOL_NR); | 635 | BUG_ON(index >= SG_MEMPOOL_NR); |
636 | 636 | ||
637 | sgp = scsi_sg_pools + index; | 637 | sgp = scsi_sg_pools + index; |
638 | mempool_free(sgl, sgp->pool); | 638 | mempool_free(sgl, sgp->pool); |
@@ -58,6 +58,7 @@ static DEFINE_SPINLOCK(fput_lock); | |||
58 | static LIST_HEAD(fput_head); | 58 | static LIST_HEAD(fput_head); |
59 | 59 | ||
60 | static void aio_kick_handler(void *); | 60 | static void aio_kick_handler(void *); |
61 | static void aio_queue_work(struct kioctx *); | ||
61 | 62 | ||
62 | /* aio_setup | 63 | /* aio_setup |
63 | * Creates the slab caches used by the aio routines, panic on | 64 | * Creates the slab caches used by the aio routines, panic on |
@@ -747,6 +748,14 @@ out: | |||
747 | * has already been kicked */ | 748 | * has already been kicked */ |
748 | if (kiocbIsKicked(iocb)) { | 749 | if (kiocbIsKicked(iocb)) { |
749 | __queue_kicked_iocb(iocb); | 750 | __queue_kicked_iocb(iocb); |
751 | |||
752 | /* | ||
753 | * __queue_kicked_iocb will always return 1 here, because | ||
754 | * iocb->ki_run_list is empty at this point so it should | ||
755 | * be safe to unconditionally queue the context into the | ||
756 | * work queue. | ||
757 | */ | ||
758 | aio_queue_work(ctx); | ||
750 | } | 759 | } |
751 | } | 760 | } |
752 | return ret; | 761 | return ret; |
diff --git a/fs/buffer.c b/fs/buffer.c index 13e5938a64f6..561e63a14966 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(thaw_bdev); | |||
278 | */ | 278 | */ |
279 | static void do_sync(unsigned long wait) | 279 | static void do_sync(unsigned long wait) |
280 | { | 280 | { |
281 | wakeup_bdflush(0); | 281 | wakeup_pdflush(0); |
282 | sync_inodes(0); /* All mappings, inodes and their blockdevs */ | 282 | sync_inodes(0); /* All mappings, inodes and their blockdevs */ |
283 | DQUOT_SYNC(NULL); | 283 | DQUOT_SYNC(NULL); |
284 | sync_supers(); /* Write the superblocks */ | 284 | sync_supers(); /* Write the superblocks */ |
@@ -497,7 +497,7 @@ static void free_more_memory(void) | |||
497 | struct zone **zones; | 497 | struct zone **zones; |
498 | pg_data_t *pgdat; | 498 | pg_data_t *pgdat; |
499 | 499 | ||
500 | wakeup_bdflush(1024); | 500 | wakeup_pdflush(1024); |
501 | yield(); | 501 | yield(); |
502 | 502 | ||
503 | for_each_pgdat(pgdat) { | 503 | for_each_pgdat(pgdat) { |
diff --git a/fs/char_dev.c b/fs/char_dev.c index e82aac9cc2f5..a69a5d8a406f 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) | |||
150 | struct char_device_struct *cd = NULL, **cp; | 150 | struct char_device_struct *cd = NULL, **cp; |
151 | int i = major_to_index(major); | 151 | int i = major_to_index(major); |
152 | 152 | ||
153 | up(&chrdevs_lock); | 153 | down(&chrdevs_lock); |
154 | for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) | 154 | for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) |
155 | if ((*cp)->major == major && | 155 | if ((*cp)->major == major && |
156 | (*cp)->baseminor == baseminor && | 156 | (*cp)->baseminor == baseminor && |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index ccd632fcc6d8..e463dca008e4 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -749,24 +749,24 @@ fail_access: | |||
749 | * to find a free region that is of my size and has not | 749 | * to find a free region that is of my size and has not |
750 | * been reserved. | 750 | * been reserved. |
751 | * | 751 | * |
752 | * on succeed, it returns the reservation window to be appended to. | ||
753 | * failed, return NULL. | ||
754 | */ | 752 | */ |
755 | static struct ext3_reserve_window_node *find_next_reservable_window( | 753 | static int find_next_reservable_window( |
756 | struct ext3_reserve_window_node *search_head, | 754 | struct ext3_reserve_window_node *search_head, |
757 | unsigned long size, int *start_block, | 755 | struct ext3_reserve_window_node *my_rsv, |
756 | struct super_block * sb, int start_block, | ||
758 | int last_block) | 757 | int last_block) |
759 | { | 758 | { |
760 | struct rb_node *next; | 759 | struct rb_node *next; |
761 | struct ext3_reserve_window_node *rsv, *prev; | 760 | struct ext3_reserve_window_node *rsv, *prev; |
762 | int cur; | 761 | int cur; |
762 | int size = my_rsv->rsv_goal_size; | ||
763 | 763 | ||
764 | /* TODO: make the start of the reservation window byte-aligned */ | 764 | /* TODO: make the start of the reservation window byte-aligned */ |
765 | /* cur = *start_block & ~7;*/ | 765 | /* cur = *start_block & ~7;*/ |
766 | cur = *start_block; | 766 | cur = start_block; |
767 | rsv = search_head; | 767 | rsv = search_head; |
768 | if (!rsv) | 768 | if (!rsv) |
769 | return NULL; | 769 | return -1; |
770 | 770 | ||
771 | while (1) { | 771 | while (1) { |
772 | if (cur <= rsv->rsv_end) | 772 | if (cur <= rsv->rsv_end) |
@@ -782,11 +782,11 @@ static struct ext3_reserve_window_node *find_next_reservable_window( | |||
782 | * space with expected-size (or more)... | 782 | * space with expected-size (or more)... |
783 | */ | 783 | */ |
784 | if (cur > last_block) | 784 | if (cur > last_block) |
785 | return NULL; /* fail */ | 785 | return -1; /* fail */ |
786 | 786 | ||
787 | prev = rsv; | 787 | prev = rsv; |
788 | next = rb_next(&rsv->rsv_node); | 788 | next = rb_next(&rsv->rsv_node); |
789 | rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); | 789 | rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); |
790 | 790 | ||
791 | /* | 791 | /* |
792 | * Reached the last reservation, we can just append to the | 792 | * Reached the last reservation, we can just append to the |
@@ -813,8 +813,25 @@ static struct ext3_reserve_window_node *find_next_reservable_window( | |||
813 | * return the reservation window that we could append to. | 813 | * return the reservation window that we could append to. |
814 | * succeed. | 814 | * succeed. |
815 | */ | 815 | */ |
816 | *start_block = cur; | 816 | |
817 | return prev; | 817 | if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window))) |
818 | rsv_window_remove(sb, my_rsv); | ||
819 | |||
820 | /* | ||
821 | * Let's book the whole avaliable window for now. We will check the | ||
822 | * disk bitmap later and then, if there are free blocks then we adjust | ||
823 | * the window size if it's larger than requested. | ||
824 | * Otherwise, we will remove this node from the tree next time | ||
825 | * call find_next_reservable_window. | ||
826 | */ | ||
827 | my_rsv->rsv_start = cur; | ||
828 | my_rsv->rsv_end = cur + size - 1; | ||
829 | my_rsv->rsv_alloc_hit = 0; | ||
830 | |||
831 | if (prev != my_rsv) | ||
832 | ext3_rsv_window_add(sb, my_rsv); | ||
833 | |||
834 | return 0; | ||
818 | } | 835 | } |
819 | 836 | ||
820 | /** | 837 | /** |
@@ -852,6 +869,7 @@ static struct ext3_reserve_window_node *find_next_reservable_window( | |||
852 | * @sb: the super block | 869 | * @sb: the super block |
853 | * @group: the group we are trying to allocate in | 870 | * @group: the group we are trying to allocate in |
854 | * @bitmap_bh: the block group block bitmap | 871 | * @bitmap_bh: the block group block bitmap |
872 | * | ||
855 | */ | 873 | */ |
856 | static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | 874 | static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, |
857 | int goal, struct super_block *sb, | 875 | int goal, struct super_block *sb, |
@@ -860,10 +878,10 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | |||
860 | struct ext3_reserve_window_node *search_head; | 878 | struct ext3_reserve_window_node *search_head; |
861 | int group_first_block, group_end_block, start_block; | 879 | int group_first_block, group_end_block, start_block; |
862 | int first_free_block; | 880 | int first_free_block; |
863 | int reservable_space_start; | ||
864 | struct ext3_reserve_window_node *prev_rsv; | ||
865 | struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root; | 881 | struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root; |
866 | unsigned long size; | 882 | unsigned long size; |
883 | int ret; | ||
884 | spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; | ||
867 | 885 | ||
868 | group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + | 886 | group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + |
869 | group * EXT3_BLOCKS_PER_GROUP(sb); | 887 | group * EXT3_BLOCKS_PER_GROUP(sb); |
@@ -875,6 +893,7 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | |||
875 | start_block = goal + group_first_block; | 893 | start_block = goal + group_first_block; |
876 | 894 | ||
877 | size = my_rsv->rsv_goal_size; | 895 | size = my_rsv->rsv_goal_size; |
896 | |||
878 | if (!rsv_is_empty(&my_rsv->rsv_window)) { | 897 | if (!rsv_is_empty(&my_rsv->rsv_window)) { |
879 | /* | 898 | /* |
880 | * if the old reservation is cross group boundary | 899 | * if the old reservation is cross group boundary |
@@ -908,6 +927,8 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | |||
908 | my_rsv->rsv_goal_size= size; | 927 | my_rsv->rsv_goal_size= size; |
909 | } | 928 | } |
910 | } | 929 | } |
930 | |||
931 | spin_lock(rsv_lock); | ||
911 | /* | 932 | /* |
912 | * shift the search start to the window near the goal block | 933 | * shift the search start to the window near the goal block |
913 | */ | 934 | */ |
@@ -921,11 +942,16 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, | |||
921 | * need to check the bitmap after we found a reservable window. | 942 | * need to check the bitmap after we found a reservable window. |
922 | */ | 943 | */ |
923 | retry: | 944 | retry: |
924 | prev_rsv = find_next_reservable_window(search_head, size, | 945 | ret = find_next_reservable_window(search_head, my_rsv, sb, |
925 | &start_block, group_end_block); | 946 | start_block, group_end_block); |
926 | if (prev_rsv == NULL) | 947 | |
927 | goto failed; | 948 | if (ret == -1) { |
928 | reservable_space_start = start_block; | 949 | if (!rsv_is_empty(&my_rsv->rsv_window)) |
950 | rsv_window_remove(sb, my_rsv); | ||
951 | spin_unlock(rsv_lock); | ||
952 | return -1; | ||
953 | } | ||
954 | |||
929 | /* | 955 | /* |
930 | * On success, find_next_reservable_window() returns the | 956 | * On success, find_next_reservable_window() returns the |
931 | * reservation window where there is a reservable space after it. | 957 | * reservation window where there is a reservable space after it. |
@@ -937,8 +963,9 @@ retry: | |||
937 | * block. Search start from the start block of the reservable space | 963 | * block. Search start from the start block of the reservable space |
938 | * we just found. | 964 | * we just found. |
939 | */ | 965 | */ |
966 | spin_unlock(rsv_lock); | ||
940 | first_free_block = bitmap_search_next_usable_block( | 967 | first_free_block = bitmap_search_next_usable_block( |
941 | reservable_space_start - group_first_block, | 968 | my_rsv->rsv_start - group_first_block, |
942 | bitmap_bh, group_end_block - group_first_block + 1); | 969 | bitmap_bh, group_end_block - group_first_block + 1); |
943 | 970 | ||
944 | if (first_free_block < 0) { | 971 | if (first_free_block < 0) { |
@@ -946,54 +973,29 @@ retry: | |||
946 | * no free block left on the bitmap, no point | 973 | * no free block left on the bitmap, no point |
947 | * to reserve the space. return failed. | 974 | * to reserve the space. return failed. |
948 | */ | 975 | */ |
949 | goto failed; | 976 | spin_lock(rsv_lock); |
977 | if (!rsv_is_empty(&my_rsv->rsv_window)) | ||
978 | rsv_window_remove(sb, my_rsv); | ||
979 | spin_unlock(rsv_lock); | ||
980 | return -1; /* failed */ | ||
950 | } | 981 | } |
982 | |||
951 | start_block = first_free_block + group_first_block; | 983 | start_block = first_free_block + group_first_block; |
952 | /* | 984 | /* |
953 | * check if the first free block is within the | 985 | * check if the first free block is within the |
954 | * free space we just found | 986 | * free space we just reserved |
955 | */ | 987 | */ |
956 | if ((start_block >= reservable_space_start) && | 988 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) |
957 | (start_block < reservable_space_start + size)) | 989 | return 0; /* success */ |
958 | goto found_rsv_window; | ||
959 | /* | 990 | /* |
960 | * if the first free bit we found is out of the reservable space | 991 | * if the first free bit we found is out of the reservable space |
961 | * this means there is no free block on the reservable space | 992 | * continue search for next reservable space, |
962 | * we should continue search for next reservable space, | ||
963 | * start from where the free block is, | 993 | * start from where the free block is, |
964 | * we also shift the list head to where we stopped last time | 994 | * we also shift the list head to where we stopped last time |
965 | */ | 995 | */ |
966 | search_head = prev_rsv; | 996 | search_head = my_rsv; |
997 | spin_lock(rsv_lock); | ||
967 | goto retry; | 998 | goto retry; |
968 | |||
969 | found_rsv_window: | ||
970 | /* | ||
971 | * great! the reservable space contains some free blocks. | ||
972 | * if the search returns that we should add the new | ||
973 | * window just next to where the old window, we don't | ||
974 | * need to remove the old window first then add it to the | ||
975 | * same place, just update the new start and new end. | ||
976 | */ | ||
977 | if (my_rsv != prev_rsv) { | ||
978 | if (!rsv_is_empty(&my_rsv->rsv_window)) | ||
979 | rsv_window_remove(sb, my_rsv); | ||
980 | } | ||
981 | my_rsv->rsv_start = reservable_space_start; | ||
982 | my_rsv->rsv_end = my_rsv->rsv_start + size - 1; | ||
983 | my_rsv->rsv_alloc_hit = 0; | ||
984 | if (my_rsv != prev_rsv) { | ||
985 | ext3_rsv_window_add(sb, my_rsv); | ||
986 | } | ||
987 | return 0; /* succeed */ | ||
988 | failed: | ||
989 | /* | ||
990 | * failed to find a new reservation window in the current | ||
991 | * group, remove the current(stale) reservation window | ||
992 | * if there is any | ||
993 | */ | ||
994 | if (!rsv_is_empty(&my_rsv->rsv_window)) | ||
995 | rsv_window_remove(sb, my_rsv); | ||
996 | return -1; /* failed */ | ||
997 | } | 999 | } |
998 | 1000 | ||
999 | /* | 1001 | /* |
@@ -1023,7 +1025,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1023 | int goal, struct ext3_reserve_window_node * my_rsv, | 1025 | int goal, struct ext3_reserve_window_node * my_rsv, |
1024 | int *errp) | 1026 | int *errp) |
1025 | { | 1027 | { |
1026 | spinlock_t *rsv_lock; | ||
1027 | unsigned long group_first_block; | 1028 | unsigned long group_first_block; |
1028 | int ret = 0; | 1029 | int ret = 0; |
1029 | int fatal; | 1030 | int fatal; |
@@ -1052,7 +1053,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1052 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL); | 1053 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL); |
1053 | goto out; | 1054 | goto out; |
1054 | } | 1055 | } |
1055 | rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; | ||
1056 | /* | 1056 | /* |
1057 | * goal is a group relative block number (if there is a goal) | 1057 | * goal is a group relative block number (if there is a goal) |
1058 | * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb) | 1058 | * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb) |
@@ -1078,30 +1078,21 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1078 | * then we could go to allocate from the reservation window directly. | 1078 | * then we could go to allocate from the reservation window directly. |
1079 | */ | 1079 | */ |
1080 | while (1) { | 1080 | while (1) { |
1081 | struct ext3_reserve_window rsv_copy; | 1081 | if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || |
1082 | 1082 | !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) { | |
1083 | rsv_copy._rsv_start = my_rsv->rsv_start; | ||
1084 | rsv_copy._rsv_end = my_rsv->rsv_end; | ||
1085 | |||
1086 | if (rsv_is_empty(&rsv_copy) || (ret < 0) || | ||
1087 | !goal_in_my_reservation(&rsv_copy, goal, group, sb)) { | ||
1088 | spin_lock(rsv_lock); | ||
1089 | ret = alloc_new_reservation(my_rsv, goal, sb, | 1083 | ret = alloc_new_reservation(my_rsv, goal, sb, |
1090 | group, bitmap_bh); | 1084 | group, bitmap_bh); |
1091 | rsv_copy._rsv_start = my_rsv->rsv_start; | ||
1092 | rsv_copy._rsv_end = my_rsv->rsv_end; | ||
1093 | spin_unlock(rsv_lock); | ||
1094 | if (ret < 0) | 1085 | if (ret < 0) |
1095 | break; /* failed */ | 1086 | break; /* failed */ |
1096 | 1087 | ||
1097 | if (!goal_in_my_reservation(&rsv_copy, goal, group, sb)) | 1088 | if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) |
1098 | goal = -1; | 1089 | goal = -1; |
1099 | } | 1090 | } |
1100 | if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) | 1091 | if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) |
1101 | || (rsv_copy._rsv_end < group_first_block)) | 1092 | || (my_rsv->rsv_end < group_first_block)) |
1102 | BUG(); | 1093 | BUG(); |
1103 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, | 1094 | ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, |
1104 | &rsv_copy); | 1095 | &my_rsv->rsv_window); |
1105 | if (ret >= 0) { | 1096 | if (ret >= 0) { |
1106 | my_rsv->rsv_alloc_hit++; | 1097 | my_rsv->rsv_alloc_hit++; |
1107 | break; /* succeed */ | 1098 | break; /* succeed */ |
diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 5ad8cf0292df..98e78345ead9 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c | |||
@@ -36,7 +36,11 @@ static int ext3_release_file (struct inode * inode, struct file * filp) | |||
36 | /* if we are the last writer on the inode, drop the block reservation */ | 36 | /* if we are the last writer on the inode, drop the block reservation */ |
37 | if ((filp->f_mode & FMODE_WRITE) && | 37 | if ((filp->f_mode & FMODE_WRITE) && |
38 | (atomic_read(&inode->i_writecount) == 1)) | 38 | (atomic_read(&inode->i_writecount) == 1)) |
39 | { | ||
40 | down(&EXT3_I(inode)->truncate_sem); | ||
39 | ext3_discard_reservation(inode); | 41 | ext3_discard_reservation(inode); |
42 | up(&EXT3_I(inode)->truncate_sem); | ||
43 | } | ||
40 | if (is_dx(inode) && filp->private_data) | 44 | if (is_dx(inode) && filp->private_data) |
41 | ext3_htree_free_dir_info(filp->private_data); | 45 | ext3_htree_free_dir_info(filp->private_data); |
42 | 46 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index b4b3e8a39131..a6d1779d7de4 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -944,7 +944,8 @@ clear_qf_name: | |||
944 | "for remount\n"); | 944 | "for remount\n"); |
945 | return 0; | 945 | return 0; |
946 | } | 946 | } |
947 | match_int(&args[0], &option); | 947 | if (match_int(&args[0], &option) != 0) |
948 | return 0; | ||
948 | *n_blocks_count = option; | 949 | *n_blocks_count = option; |
949 | break; | 950 | break; |
950 | case Opt_nobh: | 951 | case Opt_nobh: |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index ee3536fc84a3..1b7a3ef2f813 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -2,7 +2,7 @@ | |||
2 | #include <linux/nfs.h> | 2 | #include <linux/nfs.h> |
3 | #include <linux/nfs3.h> | 3 | #include <linux/nfs3.h> |
4 | #include <linux/nfs_fs.h> | 4 | #include <linux/nfs_fs.h> |
5 | #include <linux/xattr_acl.h> | 5 | #include <linux/posix_acl_xattr.h> |
6 | #include <linux/nfsacl.h> | 6 | #include <linux/nfsacl.h> |
7 | 7 | ||
8 | #define NFSDBG_FACILITY NFSDBG_PROC | 8 | #define NFSDBG_FACILITY NFSDBG_PROC |
@@ -53,9 +53,9 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name, | |||
53 | struct posix_acl *acl; | 53 | struct posix_acl *acl; |
54 | int type, error = 0; | 54 | int type, error = 0; |
55 | 55 | ||
56 | if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) | 56 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) |
57 | type = ACL_TYPE_ACCESS; | 57 | type = ACL_TYPE_ACCESS; |
58 | else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) | 58 | else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) |
59 | type = ACL_TYPE_DEFAULT; | 59 | type = ACL_TYPE_DEFAULT; |
60 | else | 60 | else |
61 | return -EOPNOTSUPP; | 61 | return -EOPNOTSUPP; |
@@ -82,9 +82,9 @@ int nfs3_setxattr(struct dentry *dentry, const char *name, | |||
82 | struct posix_acl *acl; | 82 | struct posix_acl *acl; |
83 | int type, error; | 83 | int type, error; |
84 | 84 | ||
85 | if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) | 85 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) |
86 | type = ACL_TYPE_ACCESS; | 86 | type = ACL_TYPE_ACCESS; |
87 | else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) | 87 | else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) |
88 | type = ACL_TYPE_DEFAULT; | 88 | type = ACL_TYPE_DEFAULT; |
89 | else | 89 | else |
90 | return -EOPNOTSUPP; | 90 | return -EOPNOTSUPP; |
@@ -103,9 +103,9 @@ int nfs3_removexattr(struct dentry *dentry, const char *name) | |||
103 | struct inode *inode = dentry->d_inode; | 103 | struct inode *inode = dentry->d_inode; |
104 | int type; | 104 | int type; |
105 | 105 | ||
106 | if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) | 106 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) |
107 | type = ACL_TYPE_ACCESS; | 107 | type = ACL_TYPE_ACCESS; |
108 | else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) | 108 | else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) |
109 | type = ACL_TYPE_DEFAULT; | 109 | type = ACL_TYPE_DEFAULT; |
110 | else | 110 | else |
111 | return -EOPNOTSUPP; | 111 | return -EOPNOTSUPP; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index de340ffd33c3..be24ead89d94 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -46,10 +46,9 @@ | |||
46 | #include <linux/nfsd/nfsfh.h> | 46 | #include <linux/nfsd/nfsfh.h> |
47 | #include <linux/quotaops.h> | 47 | #include <linux/quotaops.h> |
48 | #include <linux/dnotify.h> | 48 | #include <linux/dnotify.h> |
49 | #include <linux/xattr_acl.h> | ||
50 | #include <linux/posix_acl.h> | 49 | #include <linux/posix_acl.h> |
51 | #ifdef CONFIG_NFSD_V4 | ||
52 | #include <linux/posix_acl_xattr.h> | 50 | #include <linux/posix_acl_xattr.h> |
51 | #ifdef CONFIG_NFSD_V4 | ||
53 | #include <linux/xattr.h> | 52 | #include <linux/xattr.h> |
54 | #include <linux/nfs4.h> | 53 | #include <linux/nfs4.h> |
55 | #include <linux/nfs4_acl.h> | 54 | #include <linux/nfs4_acl.h> |
@@ -1872,10 +1871,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type) | |||
1872 | return ERR_PTR(-EOPNOTSUPP); | 1871 | return ERR_PTR(-EOPNOTSUPP); |
1873 | switch(type) { | 1872 | switch(type) { |
1874 | case ACL_TYPE_ACCESS: | 1873 | case ACL_TYPE_ACCESS: |
1875 | name = XATTR_NAME_ACL_ACCESS; | 1874 | name = POSIX_ACL_XATTR_ACCESS; |
1876 | break; | 1875 | break; |
1877 | case ACL_TYPE_DEFAULT: | 1876 | case ACL_TYPE_DEFAULT: |
1878 | name = XATTR_NAME_ACL_DEFAULT; | 1877 | name = POSIX_ACL_XATTR_DEFAULT; |
1879 | break; | 1878 | break; |
1880 | default: | 1879 | default: |
1881 | return ERR_PTR(-EOPNOTSUPP); | 1880 | return ERR_PTR(-EOPNOTSUPP); |
@@ -1919,17 +1918,17 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) | |||
1919 | return -EOPNOTSUPP; | 1918 | return -EOPNOTSUPP; |
1920 | switch(type) { | 1919 | switch(type) { |
1921 | case ACL_TYPE_ACCESS: | 1920 | case ACL_TYPE_ACCESS: |
1922 | name = XATTR_NAME_ACL_ACCESS; | 1921 | name = POSIX_ACL_XATTR_ACCESS; |
1923 | break; | 1922 | break; |
1924 | case ACL_TYPE_DEFAULT: | 1923 | case ACL_TYPE_DEFAULT: |
1925 | name = XATTR_NAME_ACL_DEFAULT; | 1924 | name = POSIX_ACL_XATTR_DEFAULT; |
1926 | break; | 1925 | break; |
1927 | default: | 1926 | default: |
1928 | return -EOPNOTSUPP; | 1927 | return -EOPNOTSUPP; |
1929 | } | 1928 | } |
1930 | 1929 | ||
1931 | if (acl && acl->a_count) { | 1930 | if (acl && acl->a_count) { |
1932 | size = xattr_acl_size(acl->a_count); | 1931 | size = posix_acl_xattr_size(acl->a_count); |
1933 | value = kmalloc(size, GFP_KERNEL); | 1932 | value = kmalloc(size, GFP_KERNEL); |
1934 | if (!value) | 1933 | if (!value) |
1935 | return -ENOMEM; | 1934 | return -ENOMEM; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 3f6dc7112bc6..4673157b262f 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -159,7 +159,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
159 | char *nameptr; | 159 | char *nameptr; |
160 | uint8_t lfi; | 160 | uint8_t lfi; |
161 | uint16_t liu; | 161 | uint16_t liu; |
162 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 162 | loff_t size; |
163 | kernel_lb_addr bloc, eloc; | 163 | kernel_lb_addr bloc, eloc; |
164 | uint32_t extoffset, elen, offset; | 164 | uint32_t extoffset, elen, offset; |
165 | struct buffer_head *bh = NULL; | 165 | struct buffer_head *bh = NULL; |
@@ -167,6 +167,8 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, | |||
167 | if (!dir) | 167 | if (!dir) |
168 | return NULL; | 168 | return NULL; |
169 | 169 | ||
170 | size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | ||
171 | |||
170 | f_pos = (udf_ext0_offset(dir) >> 2); | 172 | f_pos = (udf_ext0_offset(dir) >> 2); |
171 | 173 | ||
172 | fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; | 174 | fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c627bc408a6b..9ad142476f33 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind) (struct acpi_device *device); | |||
108 | typedef int (*acpi_op_match) (struct acpi_device *device, | 108 | typedef int (*acpi_op_match) (struct acpi_device *device, |
109 | struct acpi_driver *driver); | 109 | struct acpi_driver *driver); |
110 | 110 | ||
111 | struct acpi_bus_ops { | ||
112 | u32 acpi_op_add:1; | ||
113 | u32 acpi_op_remove:1; | ||
114 | u32 acpi_op_lock:1; | ||
115 | u32 acpi_op_start:1; | ||
116 | u32 acpi_op_stop:1; | ||
117 | u32 acpi_op_suspend:1; | ||
118 | u32 acpi_op_resume:1; | ||
119 | u32 acpi_op_scan:1; | ||
120 | u32 acpi_op_bind:1; | ||
121 | u32 acpi_op_unbind:1; | ||
122 | u32 acpi_op_match:1; | ||
123 | u32 reserved:21; | ||
124 | }; | ||
125 | |||
111 | struct acpi_device_ops { | 126 | struct acpi_device_ops { |
112 | acpi_op_add add; | 127 | acpi_op_add add; |
113 | acpi_op_remove remove; | 128 | acpi_op_remove remove; |
@@ -327,9 +342,9 @@ int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data); | |||
327 | int acpi_bus_receive_event (struct acpi_bus_event *event); | 342 | int acpi_bus_receive_event (struct acpi_bus_event *event); |
328 | int acpi_bus_register_driver (struct acpi_driver *driver); | 343 | int acpi_bus_register_driver (struct acpi_driver *driver); |
329 | int acpi_bus_unregister_driver (struct acpi_driver *driver); | 344 | int acpi_bus_unregister_driver (struct acpi_driver *driver); |
330 | int acpi_bus_scan (struct acpi_device *start); | ||
331 | int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent, | 345 | int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent, |
332 | acpi_handle handle, int type); | 346 | acpi_handle handle, int type); |
347 | int acpi_bus_start (struct acpi_device *device); | ||
333 | 348 | ||
334 | 349 | ||
335 | int acpi_match_ids (struct acpi_device *device, char *ids); | 350 | int acpi_match_ids (struct acpi_device *device, char *ids); |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index c62e92ec43b2..4ec722d73381 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -68,6 +68,7 @@ void acpi_pci_irq_del_prt (int segment, int bus); | |||
68 | 68 | ||
69 | struct pci_bus; | 69 | struct pci_bus; |
70 | 70 | ||
71 | acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id); | ||
71 | int acpi_pci_bind (struct acpi_device *device); | 72 | int acpi_pci_bind (struct acpi_device *device); |
72 | int acpi_pci_unbind (struct acpi_device *device); | 73 | int acpi_pci_unbind (struct acpi_device *device); |
73 | int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); | 74 | int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); |
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 0c7b57bc043a..b7806aa3785c 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h | |||
@@ -223,6 +223,25 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, | |||
223 | /* Nothing to do. */ | 223 | /* Nothing to do. */ |
224 | } | 224 | } |
225 | 225 | ||
226 | #ifdef CONFIG_PCI | ||
227 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
228 | enum pci_dma_burst_strategy *strat, | ||
229 | unsigned long *strategy_parameter) | ||
230 | { | ||
231 | unsigned long cacheline_size; | ||
232 | u8 byte; | ||
233 | |||
234 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
235 | if (byte == 0) | ||
236 | cacheline_size = 1024; | ||
237 | else | ||
238 | cacheline_size = (int) byte * 4; | ||
239 | |||
240 | *strat = PCI_DMA_BURST_BOUNDARY; | ||
241 | *strategy_parameter = cacheline_size; | ||
242 | } | ||
243 | #endif | ||
244 | |||
226 | /* TODO: integrate with include/asm-generic/pci.h ? */ | 245 | /* TODO: integrate with include/asm-generic/pci.h ? */ |
227 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | 246 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) |
228 | { | 247 | { |
diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h new file mode 100644 index 000000000000..0d276e67f2fb --- /dev/null +++ b/include/asm-arm/arch-s3c2410/audio.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* linux/include/asm-arm/arch-s3c2410/audio.h | ||
2 | * | ||
3 | * (c) 2004-2005 Simtec Electronics | ||
4 | * http://www.simtec.co.uk/products/SWLINUX/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX - Audio platfrom_device info | ||
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 | * Changelog: | ||
14 | * 20-Nov-2004 BJD Created file | ||
15 | * 07-Mar-2005 BJD Added suspend/resume calls | ||
16 | */ | ||
17 | |||
18 | #ifndef __ASM_ARCH_AUDIO_H | ||
19 | #define __ASM_ARCH_AUDIO_H __FILE__ | ||
20 | |||
21 | /* struct s3c24xx_iis_ops | ||
22 | * | ||
23 | * called from the s3c24xx audio core to deal with the architecture | ||
24 | * or the codec's setup and control. | ||
25 | * | ||
26 | * the pointer to itself is passed through in case the caller wants to | ||
27 | * embed this in an larger structure for easy reference to it's context. | ||
28 | */ | ||
29 | |||
30 | struct s3c24xx_iis_ops { | ||
31 | struct module *owner; | ||
32 | |||
33 | int (*startup)(struct s3c24xx_iis_ops *me); | ||
34 | void (*shutdown)(struct s3c24xx_iis_ops *me); | ||
35 | int (*suspend)(struct s3c24xx_iis_ops *me); | ||
36 | int (*resume)(struct s3c24xx_iis_ops *me); | ||
37 | |||
38 | int (*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm); | ||
39 | int (*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm); | ||
40 | int (*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt); | ||
41 | }; | ||
42 | |||
43 | struct s3c24xx_platdata_iis { | ||
44 | const char *codec_clk; | ||
45 | struct s3c24xx_iis_ops *ops; | ||
46 | int (*match_dev)(struct device *dev); | ||
47 | }; | ||
48 | |||
49 | #endif /* __ASM_ARCH_AUDIO_H */ | ||
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index 40ffaefbeb1a..e300646fe650 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h | |||
@@ -42,6 +42,16 @@ static inline void pcibios_penalize_isa_irq(int irq) | |||
42 | #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) | 42 | #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) |
43 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) | 43 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) |
44 | 44 | ||
45 | #ifdef CONFIG_PCI | ||
46 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
47 | enum pci_dma_burst_strategy *strat, | ||
48 | unsigned long *strategy_parameter) | ||
49 | { | ||
50 | *strat = PCI_DMA_BURST_INFINITY; | ||
51 | *strategy_parameter = ~0UL; | ||
52 | } | ||
53 | #endif | ||
54 | |||
45 | #define HAVE_PCI_MMAP | 55 | #define HAVE_PCI_MMAP |
46 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 56 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
47 | enum pci_mmap_state mmap_state, int write_combine); | 57 | enum pci_mmap_state mmap_state, int write_combine); |
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h index a6a469231f62..b4efe5e3591a 100644 --- a/include/asm-frv/pci.h +++ b/include/asm-frv/pci.h | |||
@@ -57,6 +57,16 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, | |||
57 | */ | 57 | */ |
58 | #define PCI_DMA_BUS_IS_PHYS (1) | 58 | #define PCI_DMA_BUS_IS_PHYS (1) |
59 | 59 | ||
60 | #ifdef CONFIG_PCI | ||
61 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
62 | enum pci_dma_burst_strategy *strat, | ||
63 | unsigned long *strategy_parameter) | ||
64 | { | ||
65 | *strat = PCI_DMA_BURST_INFINITY; | ||
66 | *strategy_parameter = ~0UL; | ||
67 | } | ||
68 | #endif | ||
69 | |||
60 | /* | 70 | /* |
61 | * These are pretty much arbitary with the CoMEM implementation. | 71 | * These are pretty much arbitary with the CoMEM implementation. |
62 | * We have the whole address space to ourselves. | 72 | * We have the whole address space to ourselves. |
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index fb749b85a739..3561899eb826 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h | |||
@@ -99,6 +99,16 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev) | |||
99 | { | 99 | { |
100 | } | 100 | } |
101 | 101 | ||
102 | #ifdef CONFIG_PCI | ||
103 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
104 | enum pci_dma_burst_strategy *strat, | ||
105 | unsigned long *strategy_parameter) | ||
106 | { | ||
107 | *strat = PCI_DMA_BURST_INFINITY; | ||
108 | *strategy_parameter = ~0UL; | ||
109 | } | ||
110 | #endif | ||
111 | |||
102 | #endif /* __KERNEL__ */ | 112 | #endif /* __KERNEL__ */ |
103 | 113 | ||
104 | /* implement the pci_ DMA API in terms of the generic device dma_ one */ | 114 | /* implement the pci_ DMA API in terms of the generic device dma_ one */ |
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h index 38a7a72791cc..1093f35b3b90 100644 --- a/include/asm-ia64/iosapic.h +++ b/include/asm-ia64/iosapic.h | |||
@@ -71,8 +71,11 @@ static inline void iosapic_eoi(char __iomem *iosapic, u32 vector) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | extern void __init iosapic_system_init (int pcat_compat); | 73 | extern void __init iosapic_system_init (int pcat_compat); |
74 | extern void __init iosapic_init (unsigned long address, | 74 | extern int __devinit iosapic_init (unsigned long address, |
75 | unsigned int gsi_base); | 75 | unsigned int gsi_base); |
76 | #ifdef CONFIG_HOTPLUG | ||
77 | extern int iosapic_remove (unsigned int gsi_base); | ||
78 | #endif /* CONFIG_HOTPLUG */ | ||
76 | extern int gsi_to_vector (unsigned int gsi); | 79 | extern int gsi_to_vector (unsigned int gsi); |
77 | extern int gsi_to_irq (unsigned int gsi); | 80 | extern int gsi_to_irq (unsigned int gsi); |
78 | extern void iosapic_enable_intr (unsigned int vector); | 81 | extern void iosapic_enable_intr (unsigned int vector); |
@@ -94,11 +97,14 @@ extern unsigned int iosapic_version (char __iomem *addr); | |||
94 | 97 | ||
95 | extern void iosapic_pci_fixup (int); | 98 | extern void iosapic_pci_fixup (int); |
96 | #ifdef CONFIG_NUMA | 99 | #ifdef CONFIG_NUMA |
97 | extern void __init map_iosapic_to_node (unsigned int, int); | 100 | extern void __devinit map_iosapic_to_node (unsigned int, int); |
98 | #endif | 101 | #endif |
99 | #else | 102 | #else |
100 | #define iosapic_system_init(pcat_compat) do { } while (0) | 103 | #define iosapic_system_init(pcat_compat) do { } while (0) |
101 | #define iosapic_init(address,gsi_base) do { } while (0) | 104 | #define iosapic_init(address,gsi_base) (-EINVAL) |
105 | #ifdef CONFIG_HOTPLUG | ||
106 | #define iosapic_remove(gsi_base) (-ENODEV) | ||
107 | #endif /* CONFIG_HOTPLUG */ | ||
102 | #define iosapic_register_intr(gsi,polarity,trigger) (gsi) | 108 | #define iosapic_register_intr(gsi,polarity,trigger) (gsi) |
103 | #define iosapic_unregister_intr(irq) do { } while (0) | 109 | #define iosapic_unregister_intr(irq) do { } while (0) |
104 | #define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0) | 110 | #define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0) |
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index a8314ee4e7d2..0c4c5d801d3f 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h | |||
@@ -82,6 +82,25 @@ extern int pcibios_prep_mwi (struct pci_dev *); | |||
82 | #define sg_dma_len(sg) ((sg)->dma_length) | 82 | #define sg_dma_len(sg) ((sg)->dma_length) |
83 | #define sg_dma_address(sg) ((sg)->dma_address) | 83 | #define sg_dma_address(sg) ((sg)->dma_address) |
84 | 84 | ||
85 | #ifdef CONFIG_PCI | ||
86 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
87 | enum pci_dma_burst_strategy *strat, | ||
88 | unsigned long *strategy_parameter) | ||
89 | { | ||
90 | unsigned long cacheline_size; | ||
91 | u8 byte; | ||
92 | |||
93 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
94 | if (byte == 0) | ||
95 | cacheline_size = 1024; | ||
96 | else | ||
97 | cacheline_size = (int) byte * 4; | ||
98 | |||
99 | *strat = PCI_DMA_BURST_MULTIPLE; | ||
100 | *strategy_parameter = cacheline_size; | ||
101 | } | ||
102 | #endif | ||
103 | |||
85 | #define HAVE_PCI_MMAP | 104 | #define HAVE_PCI_MMAP |
86 | extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, | 105 | extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, |
87 | enum pci_mmap_state mmap_state, int write_combine); | 106 | enum pci_mmap_state mmap_state, int write_combine); |
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index c9c576b48556..2d323b6e147d 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h | |||
@@ -130,6 +130,16 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, | |||
130 | extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, | 130 | extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, |
131 | dma64_addr_t dma_addr, size_t len, int direction); | 131 | dma64_addr_t dma_addr, size_t len, int direction); |
132 | 132 | ||
133 | #ifdef CONFIG_PCI | ||
134 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
135 | enum pci_dma_burst_strategy *strat, | ||
136 | unsigned long *strategy_parameter) | ||
137 | { | ||
138 | *strat = PCI_DMA_BURST_INFINITY; | ||
139 | *strategy_parameter = ~0UL; | ||
140 | } | ||
141 | #endif | ||
142 | |||
133 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | 143 | extern void pcibios_resource_to_bus(struct pci_dev *dev, |
134 | struct pci_bus_region *region, struct resource *res); | 144 | struct pci_bus_region *region, struct resource *res); |
135 | 145 | ||
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index 0763c2982fb0..ee741c150176 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h | |||
@@ -230,6 +230,25 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x) | |||
230 | /* export the pci_ DMA API in terms of the dma_ one */ | 230 | /* export the pci_ DMA API in terms of the dma_ one */ |
231 | #include <asm-generic/pci-dma-compat.h> | 231 | #include <asm-generic/pci-dma-compat.h> |
232 | 232 | ||
233 | #ifdef CONFIG_PCI | ||
234 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
235 | enum pci_dma_burst_strategy *strat, | ||
236 | unsigned long *strategy_parameter) | ||
237 | { | ||
238 | unsigned long cacheline_size; | ||
239 | u8 byte; | ||
240 | |||
241 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
242 | if (byte == 0) | ||
243 | cacheline_size = 1024; | ||
244 | else | ||
245 | cacheline_size = (int) byte * 4; | ||
246 | |||
247 | *strat = PCI_DMA_BURST_MULTIPLE; | ||
248 | *strategy_parameter = cacheline_size; | ||
249 | } | ||
250 | #endif | ||
251 | |||
233 | extern void | 252 | extern void |
234 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | 253 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
235 | struct resource *res); | 254 | struct resource *res); |
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index ce5ae6d048f5..db0a2a0ec74d 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h | |||
@@ -69,6 +69,16 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); | |||
69 | #define pci_unmap_len(PTR, LEN_NAME) (0) | 69 | #define pci_unmap_len(PTR, LEN_NAME) (0) |
70 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) | 70 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) |
71 | 71 | ||
72 | #ifdef CONFIG_PCI | ||
73 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
74 | enum pci_dma_burst_strategy *strat, | ||
75 | unsigned long *strategy_parameter) | ||
76 | { | ||
77 | *strat = PCI_DMA_BURST_INFINITY; | ||
78 | *strategy_parameter = ~0UL; | ||
79 | } | ||
80 | #endif | ||
81 | |||
72 | /* | 82 | /* |
73 | * At present there are very few 32-bit PPC machines that can have | 83 | * At present there are very few 32-bit PPC machines that can have |
74 | * memory above the 4GB point, and we don't support that. | 84 | * memory above the 4GB point, and we don't support that. |
@@ -103,6 +113,12 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
103 | unsigned long size, | 113 | unsigned long size, |
104 | pgprot_t prot); | 114 | pgprot_t prot); |
105 | 115 | ||
116 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | ||
117 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
118 | const struct resource *rsrc, | ||
119 | u64 *start, u64 *end); | ||
120 | |||
121 | |||
106 | #endif /* __KERNEL__ */ | 122 | #endif /* __KERNEL__ */ |
107 | 123 | ||
108 | #endif /* __PPC_PCI_H */ | 124 | #endif /* __PPC_PCI_H */ |
diff --git a/include/asm-ppc64/byteorder.h b/include/asm-ppc64/byteorder.h index 80327532de64..8b57da62b674 100644 --- a/include/asm-ppc64/byteorder.h +++ b/include/asm-ppc64/byteorder.h | |||
@@ -40,7 +40,6 @@ static __inline__ void st_le32(volatile __u32 *addr, const __u32 val) | |||
40 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); | 40 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); |
41 | } | 41 | } |
42 | 42 | ||
43 | #if 0 | ||
44 | static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) | 43 | static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) |
45 | { | 44 | { |
46 | __u16 result; | 45 | __u16 result; |
@@ -63,17 +62,8 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) | |||
63 | return result; | 62 | return result; |
64 | } | 63 | } |
65 | 64 | ||
66 | static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value) | ||
67 | { | ||
68 | __u64 result; | ||
69 | #error implement me | ||
70 | } | ||
71 | |||
72 | #define __arch__swab16(x) ___arch__swab16(x) | 65 | #define __arch__swab16(x) ___arch__swab16(x) |
73 | #define __arch__swab32(x) ___arch__swab32(x) | 66 | #define __arch__swab32(x) ___arch__swab32(x) |
74 | #define __arch__swab64(x) ___arch__swab64(x) | ||
75 | |||
76 | #endif | ||
77 | 67 | ||
78 | /* The same, but returns converted value from the location pointer by addr. */ | 68 | /* The same, but returns converted value from the location pointer by addr. */ |
79 | #define __arch__swab16p(addr) ld_le16(addr) | 69 | #define __arch__swab16p(addr) ld_le16(addr) |
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index 6cd593f660a0..d12dfce21e20 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h | |||
@@ -78,6 +78,25 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) | |||
78 | return 0; | 78 | return 0; |
79 | } | 79 | } |
80 | 80 | ||
81 | #ifdef CONFIG_PCI | ||
82 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
83 | enum pci_dma_burst_strategy *strat, | ||
84 | unsigned long *strategy_parameter) | ||
85 | { | ||
86 | unsigned long cacheline_size; | ||
87 | u8 byte; | ||
88 | |||
89 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
90 | if (byte == 0) | ||
91 | cacheline_size = 1024; | ||
92 | else | ||
93 | cacheline_size = (int) byte * 4; | ||
94 | |||
95 | *strat = PCI_DMA_BURST_MULTIPLE; | ||
96 | *strategy_parameter = cacheline_size; | ||
97 | } | ||
98 | #endif | ||
99 | |||
81 | extern int pci_domain_nr(struct pci_bus *bus); | 100 | extern int pci_domain_nr(struct pci_bus *bus); |
82 | 101 | ||
83 | /* Decide whether to display the domain number in /proc */ | 102 | /* Decide whether to display the domain number in /proc */ |
@@ -136,6 +155,13 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
136 | unsigned long size, | 155 | unsigned long size, |
137 | pgprot_t prot); | 156 | pgprot_t prot); |
138 | 157 | ||
158 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
159 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | ||
160 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
161 | const struct resource *rsrc, | ||
162 | u64 *start, u64 *end); | ||
163 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
164 | |||
139 | 165 | ||
140 | #endif /* __KERNEL__ */ | 166 | #endif /* __KERNEL__ */ |
141 | 167 | ||
diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 9c3b63d0105e..26044889c770 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h | |||
@@ -96,6 +96,16 @@ static inline void pcibios_penalize_isa_irq(int irq) | |||
96 | #define sg_dma_address(sg) (virt_to_bus((sg)->dma_address)) | 96 | #define sg_dma_address(sg) (virt_to_bus((sg)->dma_address)) |
97 | #define sg_dma_len(sg) ((sg)->length) | 97 | #define sg_dma_len(sg) ((sg)->length) |
98 | 98 | ||
99 | #ifdef CONFIG_PCI | ||
100 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
101 | enum pci_dma_burst_strategy *strat, | ||
102 | unsigned long *strategy_parameter) | ||
103 | { | ||
104 | *strat = PCI_DMA_BURST_INFINITY; | ||
105 | *strategy_parameter = ~0UL; | ||
106 | } | ||
107 | #endif | ||
108 | |||
99 | /* Board-specific fixup routines. */ | 109 | /* Board-specific fixup routines. */ |
100 | extern void pcibios_fixup(void); | 110 | extern void pcibios_fixup(void); |
101 | extern void pcibios_fixup_irqs(void); | 111 | extern void pcibios_fixup_irqs(void); |
diff --git a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h index 8cc14e139750..c68870e02d91 100644 --- a/include/asm-sh64/pci.h +++ b/include/asm-sh64/pci.h | |||
@@ -86,6 +86,16 @@ static inline void pcibios_penalize_isa_irq(int irq) | |||
86 | #define sg_dma_address(sg) ((sg)->dma_address) | 86 | #define sg_dma_address(sg) ((sg)->dma_address) |
87 | #define sg_dma_len(sg) ((sg)->length) | 87 | #define sg_dma_len(sg) ((sg)->length) |
88 | 88 | ||
89 | #ifdef CONFIG_PCI | ||
90 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
91 | enum pci_dma_burst_strategy *strat, | ||
92 | unsigned long *strategy_parameter) | ||
93 | { | ||
94 | *strat = PCI_DMA_BURST_INFINITY; | ||
95 | *strategy_parameter = ~0UL; | ||
96 | } | ||
97 | #endif | ||
98 | |||
89 | /* Board-specific fixup routines. */ | 99 | /* Board-specific fixup routines. */ |
90 | extern void pcibios_fixup(void); | 100 | extern void pcibios_fixup(void); |
91 | extern void pcibios_fixup_irqs(void); | 101 | extern void pcibios_fixup_irqs(void); |
diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h index d200a25a7373..44bb38758c96 100644 --- a/include/asm-sparc/pci.h +++ b/include/asm-sparc/pci.h | |||
@@ -144,6 +144,16 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) | |||
144 | 144 | ||
145 | #define pci_dac_dma_supported(dev, mask) (0) | 145 | #define pci_dac_dma_supported(dev, mask) (0) |
146 | 146 | ||
147 | #ifdef CONFIG_PCI | ||
148 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
149 | enum pci_dma_burst_strategy *strat, | ||
150 | unsigned long *strategy_parameter) | ||
151 | { | ||
152 | *strat = PCI_DMA_BURST_INFINITY; | ||
153 | *strategy_parameter = ~0UL; | ||
154 | } | ||
155 | #endif | ||
156 | |||
147 | static inline void pcibios_add_platform_entries(struct pci_dev *dev) | 157 | static inline void pcibios_add_platform_entries(struct pci_dev *dev) |
148 | { | 158 | { |
149 | } | 159 | } |
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 2a0c85cd1c11..84e41c1ef3f8 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h | |||
@@ -220,6 +220,25 @@ static inline int pci_dma_mapping_error(dma_addr_t dma_addr) | |||
220 | return (dma_addr == PCI_DMA_ERROR_CODE); | 220 | return (dma_addr == PCI_DMA_ERROR_CODE); |
221 | } | 221 | } |
222 | 222 | ||
223 | #ifdef CONFIG_PCI | ||
224 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
225 | enum pci_dma_burst_strategy *strat, | ||
226 | unsigned long *strategy_parameter) | ||
227 | { | ||
228 | unsigned long cacheline_size; | ||
229 | u8 byte; | ||
230 | |||
231 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
232 | if (byte == 0) | ||
233 | cacheline_size = 1024; | ||
234 | else | ||
235 | cacheline_size = (int) byte * 4; | ||
236 | |||
237 | *strat = PCI_DMA_BURST_BOUNDARY; | ||
238 | *strategy_parameter = cacheline_size; | ||
239 | } | ||
240 | #endif | ||
241 | |||
223 | /* Return the index of the PCI controller for device PDEV. */ | 242 | /* Return the index of the PCI controller for device PDEV. */ |
224 | 243 | ||
225 | extern int pci_domain_nr(struct pci_bus *bus); | 244 | extern int pci_domain_nr(struct pci_bus *bus); |
diff --git a/include/asm-v850/pci.h b/include/asm-v850/pci.h index e41941447b49..8e79be0fe99d 100644 --- a/include/asm-v850/pci.h +++ b/include/asm-v850/pci.h | |||
@@ -81,6 +81,16 @@ extern void | |||
81 | pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr, | 81 | pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr, |
82 | dma_addr_t dma_addr); | 82 | dma_addr_t dma_addr); |
83 | 83 | ||
84 | #ifdef CONFIG_PCI | ||
85 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
86 | enum pci_dma_burst_strategy *strat, | ||
87 | unsigned long *strategy_parameter) | ||
88 | { | ||
89 | *strat = PCI_DMA_BURST_INFINITY; | ||
90 | *strategy_parameter = ~0UL; | ||
91 | } | ||
92 | #endif | ||
93 | |||
84 | static inline void pcibios_add_platform_entries(struct pci_dev *dev) | 94 | static inline void pcibios_add_platform_entries(struct pci_dev *dev) |
85 | { | 95 | { |
86 | } | 96 | } |
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 8712520ca47f..c1961db88fac 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h | |||
@@ -123,6 +123,16 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, | |||
123 | flush_write_buffers(); | 123 | flush_write_buffers(); |
124 | } | 124 | } |
125 | 125 | ||
126 | #ifdef CONFIG_PCI | ||
127 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | ||
128 | enum pci_dma_burst_strategy *strat, | ||
129 | unsigned long *strategy_parameter) | ||
130 | { | ||
131 | *strat = PCI_DMA_BURST_INFINITY; | ||
132 | *strategy_parameter = ~0UL; | ||
133 | } | ||
134 | #endif | ||
135 | |||
126 | #define HAVE_PCI_MMAP | 136 | #define HAVE_PCI_MMAP |
127 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 137 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
128 | enum pci_mmap_state mmap_state, int write_combine); | 138 | enum pci_mmap_state mmap_state, int write_combine); |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b123cc08773d..ef8483673aa3 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -342,11 +342,19 @@ struct acpi_table_ecdt { | |||
342 | 342 | ||
343 | /* PCI MMCONFIG */ | 343 | /* PCI MMCONFIG */ |
344 | 344 | ||
345 | /* Defined in PCI Firmware Specification 3.0 */ | ||
346 | struct acpi_table_mcfg_config { | ||
347 | u32 base_address; | ||
348 | u32 base_reserved; | ||
349 | u16 pci_segment_group_number; | ||
350 | u8 start_bus_number; | ||
351 | u8 end_bus_number; | ||
352 | u8 reserved[4]; | ||
353 | } __attribute__ ((packed)); | ||
345 | struct acpi_table_mcfg { | 354 | struct acpi_table_mcfg { |
346 | struct acpi_table_header header; | 355 | struct acpi_table_header header; |
347 | u8 reserved[8]; | 356 | u8 reserved[8]; |
348 | u32 base_address; | 357 | struct acpi_table_mcfg_config config[0]; |
349 | u32 base_reserved; | ||
350 | } __attribute__ ((packed)); | 358 | } __attribute__ ((packed)); |
351 | 359 | ||
352 | /* Table Handlers */ | 360 | /* Table Handlers */ |
@@ -391,6 +399,7 @@ int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler); | |||
391 | int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); | 399 | int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); |
392 | int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); | 400 | int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); |
393 | int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); | 401 | int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); |
402 | int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size); | ||
394 | void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); | 403 | void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); |
395 | void acpi_table_print_madt_entry (acpi_table_entry_header *madt); | 404 | void acpi_table_print_madt_entry (acpi_table_entry_header *madt); |
396 | void acpi_table_print_srat_entry (acpi_table_entry_header *srat); | 405 | void acpi_table_print_srat_entry (acpi_table_entry_header *srat); |
@@ -407,9 +416,13 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu); | |||
407 | int acpi_unmap_lsapic(int cpu); | 416 | int acpi_unmap_lsapic(int cpu); |
408 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 417 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
409 | 418 | ||
419 | int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); | ||
420 | int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); | ||
421 | |||
410 | extern int acpi_mp_config; | 422 | extern int acpi_mp_config; |
411 | 423 | ||
412 | extern u32 pci_mmcfg_base_addr; | 424 | extern struct acpi_table_mcfg_config *pci_mmcfg_config; |
425 | extern int pci_mmcfg_config_num; | ||
413 | 426 | ||
414 | extern int sbf_port ; | 427 | extern int sbf_port ; |
415 | 428 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 21a8674cd149..0881b5cdee3d 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -96,6 +96,7 @@ struct io_context { | |||
96 | 96 | ||
97 | void put_io_context(struct io_context *ioc); | 97 | void put_io_context(struct io_context *ioc); |
98 | void exit_io_context(void); | 98 | void exit_io_context(void); |
99 | struct io_context *current_io_context(int gfp_flags); | ||
99 | struct io_context *get_io_context(int gfp_flags); | 100 | struct io_context *get_io_context(int gfp_flags); |
100 | void copy_io_context(struct io_context **pdst, struct io_context **psrc); | 101 | void copy_io_context(struct io_context **pdst, struct io_context **psrc); |
101 | void swap_io_context(struct io_context **ioc1, struct io_context **ioc2); | 102 | void swap_io_context(struct io_context **ioc1, struct io_context **ioc2); |
diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h index d28d9a804d3b..d5f2a3205109 100644 --- a/include/linux/byteorder/swabb.h +++ b/include/linux/byteorder/swabb.h | |||
@@ -92,29 +92,32 @@ | |||
92 | #endif /* OPTIMIZE */ | 92 | #endif /* OPTIMIZE */ |
93 | 93 | ||
94 | 94 | ||
95 | static __inline__ __const__ __u32 __fswahw32(__u32 x) | 95 | static inline __u32 __fswahw32(__u32 x) |
96 | { | 96 | { |
97 | return __arch__swahw32(x); | 97 | return __arch__swahw32(x); |
98 | } | 98 | } |
99 | static __inline__ __u32 __swahw32p(__u32 *x) | 99 | |
100 | static inline __u32 __swahw32p(__u32 *x) | ||
100 | { | 101 | { |
101 | return __arch__swahw32p(x); | 102 | return __arch__swahw32p(x); |
102 | } | 103 | } |
103 | static __inline__ void __swahw32s(__u32 *addr) | 104 | |
105 | static inline void __swahw32s(__u32 *addr) | ||
104 | { | 106 | { |
105 | __arch__swahw32s(addr); | 107 | __arch__swahw32s(addr); |
106 | } | 108 | } |
107 | 109 | ||
108 | 110 | static inline __u32 __fswahb32(__u32 x) | |
109 | static __inline__ __const__ __u32 __fswahb32(__u32 x) | ||
110 | { | 111 | { |
111 | return __arch__swahb32(x); | 112 | return __arch__swahb32(x); |
112 | } | 113 | } |
113 | static __inline__ __u32 __swahb32p(__u32 *x) | 114 | |
115 | static inline __u32 __swahb32p(__u32 *x) | ||
114 | { | 116 | { |
115 | return __arch__swahb32p(x); | 117 | return __arch__swahb32p(x); |
116 | } | 118 | } |
117 | static __inline__ void __swahb32s(__u32 *addr) | 119 | |
120 | static inline void __swahb32s(__u32 *addr) | ||
118 | { | 121 | { |
119 | __arch__swahb32s(addr); | 122 | __arch__swahb32s(addr); |
120 | } | 123 | } |
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index a1478258d002..cf3847edc50f 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define _LINUX_ETHERDEVICE_H | 25 | #define _LINUX_ETHERDEVICE_H |
26 | 26 | ||
27 | #include <linux/if_ether.h> | 27 | #include <linux/if_ether.h> |
28 | #include <linux/netdevice.h> | ||
28 | #include <linux/random.h> | 29 | #include <linux/random.h> |
29 | 30 | ||
30 | #ifdef __KERNEL__ | 31 | #ifdef __KERNEL__ |
@@ -65,7 +66,7 @@ static inline int is_zero_ether_addr(const u8 *addr) | |||
65 | */ | 66 | */ |
66 | static inline int is_multicast_ether_addr(const u8 *addr) | 67 | static inline int is_multicast_ether_addr(const u8 *addr) |
67 | { | 68 | { |
68 | return addr[0] & 0x01; | 69 | return ((addr[0] != 0xff) && (0x01 & addr[0])); |
69 | } | 70 | } |
70 | 71 | ||
71 | /** | 72 | /** |
diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h index d228230ffe5d..541695679762 100644 --- a/include/linux/i2c-dev.h +++ b/include/linux/i2c-dev.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define _LINUX_I2C_DEV_H | 25 | #define _LINUX_I2C_DEV_H |
26 | 26 | ||
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/compiler.h> | ||
28 | 29 | ||
29 | /* Some IOCTL commands are defined in <linux/i2c.h> */ | 30 | /* Some IOCTL commands are defined in <linux/i2c.h> */ |
30 | /* Note: 10-bit addresses are NOT supported! */ | 31 | /* Note: 10-bit addresses are NOT supported! */ |
diff --git a/include/linux/in6.h b/include/linux/in6.h index f8256c582845..dcf5720ffcbb 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h | |||
@@ -156,7 +156,7 @@ struct in6_flowlabel_req | |||
156 | #define IPV6_CHECKSUM 7 | 156 | #define IPV6_CHECKSUM 7 |
157 | #define IPV6_HOPLIMIT 8 | 157 | #define IPV6_HOPLIMIT 8 |
158 | #define IPV6_NEXTHOP 9 | 158 | #define IPV6_NEXTHOP 9 |
159 | #define IPV6_AUTHHDR 10 | 159 | #define IPV6_AUTHHDR 10 /* obsolete */ |
160 | #define IPV6_FLOWINFO 11 | 160 | #define IPV6_FLOWINFO 11 |
161 | 161 | ||
162 | #define IPV6_UNICAST_HOPS 16 | 162 | #define IPV6_UNICAST_HOPS 16 |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 12277799c007..069d3b84d311 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -85,9 +85,10 @@ extern int no_irq_affinity; | |||
85 | extern int noirqdebug_setup(char *str); | 85 | extern int noirqdebug_setup(char *str); |
86 | 86 | ||
87 | extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, | 87 | extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, |
88 | struct irqaction *action); | 88 | struct irqaction *action); |
89 | extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); | 89 | extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); |
90 | extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret); | 90 | extern void note_interrupt(unsigned int irq, irq_desc_t *desc, |
91 | int action_ret, struct pt_regs *regs); | ||
91 | extern int can_request_irq(unsigned int irq, unsigned long irqflags); | 92 | extern int can_request_irq(unsigned int irq, unsigned long irqflags); |
92 | 93 | ||
93 | extern void init_irq_proc(void); | 94 | extern void init_irq_proc(void); |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 3029cad63a01..27e4d164a108 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -168,6 +168,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags) | |||
168 | nlh->nlmsg_flags = flags; | 168 | nlh->nlmsg_flags = flags; |
169 | nlh->nlmsg_pid = pid; | 169 | nlh->nlmsg_pid = pid; |
170 | nlh->nlmsg_seq = seq; | 170 | nlh->nlmsg_seq = seq; |
171 | memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size); | ||
171 | return nlh; | 172 | return nlh; |
172 | } | 173 | } |
173 | 174 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index b5238bd18830..66798b46f308 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -734,16 +734,20 @@ void pcibios_update_irq(struct pci_dev *, int irq); | |||
734 | /* Generic PCI functions used internally */ | 734 | /* Generic PCI functions used internally */ |
735 | 735 | ||
736 | extern struct pci_bus *pci_find_bus(int domain, int busnr); | 736 | extern struct pci_bus *pci_find_bus(int domain, int busnr); |
737 | void pci_bus_add_devices(struct pci_bus *bus); | ||
737 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); | 738 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); |
738 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) | 739 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) |
739 | { | 740 | { |
740 | return pci_scan_bus_parented(NULL, bus, ops, sysdata); | 741 | struct pci_bus *root_bus; |
742 | root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); | ||
743 | if (root_bus) | ||
744 | pci_bus_add_devices(root_bus); | ||
745 | return root_bus; | ||
741 | } | 746 | } |
742 | int pci_scan_slot(struct pci_bus *bus, int devfn); | 747 | int pci_scan_slot(struct pci_bus *bus, int devfn); |
743 | struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); | 748 | struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); |
744 | unsigned int pci_scan_child_bus(struct pci_bus *bus); | 749 | unsigned int pci_scan_child_bus(struct pci_bus *bus); |
745 | void pci_bus_add_device(struct pci_dev *dev); | 750 | void pci_bus_add_device(struct pci_dev *dev); |
746 | void pci_bus_add_devices(struct pci_bus *bus); | ||
747 | void pci_name_device(struct pci_dev *dev); | 751 | void pci_name_device(struct pci_dev *dev); |
748 | char *pci_class_name(u32 class); | 752 | char *pci_class_name(u32 class); |
749 | void pci_read_bridge_bases(struct pci_bus *child); | 753 | void pci_read_bridge_bases(struct pci_bus *child); |
@@ -870,6 +874,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass | |||
870 | #define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle) | 874 | #define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle) |
871 | #define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr) | 875 | #define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr) |
872 | 876 | ||
877 | enum pci_dma_burst_strategy { | ||
878 | PCI_DMA_BURST_INFINITY, /* make bursts as large as possible, | ||
879 | strategy_parameter is N/A */ | ||
880 | PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter | ||
881 | byte boundaries */ | ||
882 | PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of | ||
883 | strategy_parameter byte boundaries */ | ||
884 | }; | ||
885 | |||
873 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | 886 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
874 | extern struct pci_dev *isa_bridge; | 887 | extern struct pci_dev *isa_bridge; |
875 | #endif | 888 | #endif |
@@ -972,6 +985,8 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
972 | } | 985 | } |
973 | #endif | 986 | #endif |
974 | 987 | ||
988 | #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) | ||
989 | |||
975 | #endif /* !CONFIG_PCI */ | 990 | #endif /* !CONFIG_PCI */ |
976 | 991 | ||
977 | /* these helpers provide future and backwards compatibility | 992 | /* these helpers provide future and backwards compatibility |
@@ -1016,6 +1031,20 @@ static inline char *pci_name(struct pci_dev *pdev) | |||
1016 | #define pci_pretty_name(dev) "" | 1031 | #define pci_pretty_name(dev) "" |
1017 | #endif | 1032 | #endif |
1018 | 1033 | ||
1034 | |||
1035 | /* Some archs don't want to expose struct resource to userland as-is | ||
1036 | * in sysfs and /proc | ||
1037 | */ | ||
1038 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER | ||
1039 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1040 | const struct resource *rsrc, u64 *start, u64 *end) | ||
1041 | { | ||
1042 | *start = rsrc->start; | ||
1043 | *end = rsrc->end; | ||
1044 | } | ||
1045 | #endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */ | ||
1046 | |||
1047 | |||
1019 | /* | 1048 | /* |
1020 | * The world is not perfect and supplies us with broken PCI devices. | 1049 | * The world is not perfect and supplies us with broken PCI devices. |
1021 | * For at least a part of these bugs we need a work-around, so both | 1050 | * For at least a part of these bugs we need a work-around, so both |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1e0bc6a8d653..c3ee1ae4545a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -62,6 +62,8 @@ | |||
62 | 62 | ||
63 | #define PCI_BASE_CLASS_SYSTEM 0x08 | 63 | #define PCI_BASE_CLASS_SYSTEM 0x08 |
64 | #define PCI_CLASS_SYSTEM_PIC 0x0800 | 64 | #define PCI_CLASS_SYSTEM_PIC 0x0800 |
65 | #define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010 | ||
66 | #define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020 | ||
65 | #define PCI_CLASS_SYSTEM_DMA 0x0801 | 67 | #define PCI_CLASS_SYSTEM_DMA 0x0801 |
66 | #define PCI_CLASS_SYSTEM_TIMER 0x0802 | 68 | #define PCI_CLASS_SYSTEM_TIMER 0x0802 |
67 | #define PCI_CLASS_SYSTEM_RTC 0x0803 | 69 | #define PCI_CLASS_SYSTEM_RTC 0x0803 |
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 25d2d67c1faf..bd2c5a2bbbf5 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h | |||
@@ -276,6 +276,7 @@ struct tc_rsvp_pinfo | |||
276 | __u8 protocol; | 276 | __u8 protocol; |
277 | __u8 tunnelid; | 277 | __u8 tunnelid; |
278 | __u8 tunnelhdr; | 278 | __u8 tunnelhdr; |
279 | __u8 pad; | ||
279 | }; | 280 | }; |
280 | 281 | ||
281 | /* ROUTE filter */ | 282 | /* ROUTE filter */ |
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 1d9da36eb9db..60ffcb9c5791 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h | |||
@@ -221,9 +221,11 @@ struct tc_gred_qopt | |||
221 | /* gred setup */ | 221 | /* gred setup */ |
222 | struct tc_gred_sopt | 222 | struct tc_gred_sopt |
223 | { | 223 | { |
224 | __u32 DPs; | 224 | __u32 DPs; |
225 | __u32 def_DP; | 225 | __u32 def_DP; |
226 | __u8 grio; | 226 | __u8 grio; |
227 | __u8 pad1; | ||
228 | __u16 pad2; | ||
227 | }; | 229 | }; |
228 | 230 | ||
229 | /* HTB section */ | 231 | /* HTB section */ |
@@ -351,6 +353,7 @@ struct tc_cbq_ovl | |||
351 | #define TC_CBQ_OVL_DROP 3 | 353 | #define TC_CBQ_OVL_DROP 3 |
352 | #define TC_CBQ_OVL_RCLASSIC 4 | 354 | #define TC_CBQ_OVL_RCLASSIC 4 |
353 | unsigned char priority2; | 355 | unsigned char priority2; |
356 | __u16 pad; | ||
354 | __u32 penalty; | 357 | __u32 penalty; |
355 | }; | 358 | }; |
356 | 359 | ||
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d021888b58f1..657c05ab8f9e 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -363,6 +363,8 @@ enum | |||
363 | struct rta_session | 363 | struct rta_session |
364 | { | 364 | { |
365 | __u8 proto; | 365 | __u8 proto; |
366 | __u8 pad1; | ||
367 | __u16 pad2; | ||
366 | 368 | ||
367 | union { | 369 | union { |
368 | struct { | 370 | struct { |
@@ -635,10 +637,13 @@ struct ifinfomsg | |||
635 | struct prefixmsg | 637 | struct prefixmsg |
636 | { | 638 | { |
637 | unsigned char prefix_family; | 639 | unsigned char prefix_family; |
640 | unsigned char prefix_pad1; | ||
641 | unsigned short prefix_pad2; | ||
638 | int prefix_ifindex; | 642 | int prefix_ifindex; |
639 | unsigned char prefix_type; | 643 | unsigned char prefix_type; |
640 | unsigned char prefix_len; | 644 | unsigned char prefix_len; |
641 | unsigned char prefix_flags; | 645 | unsigned char prefix_flags; |
646 | unsigned char prefix_pad3; | ||
642 | }; | 647 | }; |
643 | 648 | ||
644 | enum | 649 | enum |
@@ -898,7 +903,9 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi | |||
898 | memcpy(skb_put(skb, attrlen), data, attrlen); }) | 903 | memcpy(skb_put(skb, attrlen), data, attrlen); }) |
899 | 904 | ||
900 | #define RTA_PUT_NOHDR(skb, attrlen, data) \ | 905 | #define RTA_PUT_NOHDR(skb, attrlen, data) \ |
901 | RTA_APPEND(skb, RTA_ALIGN(attrlen), data) | 906 | ({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \ |
907 | memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \ | ||
908 | RTA_ALIGN(attrlen) - attrlen); }) | ||
902 | 909 | ||
903 | #define RTA_PUT_U8(skb, attrtype, value) \ | 910 | #define RTA_PUT_U8(skb, attrtype, value) \ |
904 | ({ u8 _tmp = (value); \ | 911 | ({ u8 _tmp = (value); \ |
@@ -978,6 +985,7 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) | |||
978 | rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); | 985 | rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); |
979 | rta->rta_type = attrtype; | 986 | rta->rta_type = attrtype; |
980 | rta->rta_len = size; | 987 | rta->rta_len = size; |
988 | memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); | ||
981 | return rta; | 989 | return rta; |
982 | } | 990 | } |
983 | 991 | ||
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index ebfe1250f0a4..5b5f434ac9a0 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -641,6 +641,7 @@ enum { | |||
641 | NET_SCTP_ADDIP_ENABLE = 13, | 641 | NET_SCTP_ADDIP_ENABLE = 13, |
642 | NET_SCTP_PRSCTP_ENABLE = 14, | 642 | NET_SCTP_PRSCTP_ENABLE = 14, |
643 | NET_SCTP_SNDBUF_POLICY = 15, | 643 | NET_SCTP_SNDBUF_POLICY = 15, |
644 | NET_SCTP_SACK_TIMEOUT = 16, | ||
644 | }; | 645 | }; |
645 | 646 | ||
646 | /* /proc/sys/net/bridge */ | 647 | /* /proc/sys/net/bridge */ |
diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h index 39e7ff4ffd28..ee21e6bf3867 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb_ch9.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #ifndef __LINUX_USB_CH9_H | 19 | #ifndef __LINUX_USB_CH9_H |
20 | #define __LINUX_USB_CH9_H | 20 | #define __LINUX_USB_CH9_H |
21 | 21 | ||
22 | #include <asm/types.h> /* __u8 etc */ | 22 | #include <linux/types.h> /* __u8 etc */ |
23 | 23 | ||
24 | /*-------------------------------------------------------------------------*/ | 24 | /*-------------------------------------------------------------------------*/ |
25 | 25 | ||
@@ -294,8 +294,8 @@ struct usb_endpoint_descriptor { | |||
294 | __le16 wMaxPacketSize; | 294 | __le16 wMaxPacketSize; |
295 | __u8 bInterval; | 295 | __u8 bInterval; |
296 | 296 | ||
297 | // NOTE: these two are _only_ in audio endpoints. | 297 | /* NOTE: these two are _only_ in audio endpoints. */ |
298 | // use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. | 298 | /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ |
299 | __u8 bRefresh; | 299 | __u8 bRefresh; |
300 | __u8 bSynchAddress; | 300 | __u8 bSynchAddress; |
301 | } __attribute__ ((packed)); | 301 | } __attribute__ ((packed)); |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4e0edce53760..acbfc525576d 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
@@ -221,6 +221,8 @@ struct v4l2_pix_format | |||
221 | /* Vendor-specific formats */ | 221 | /* Vendor-specific formats */ |
222 | #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ | 222 | #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ |
223 | #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ | 223 | #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ |
224 | #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ | ||
225 | #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ | ||
224 | 226 | ||
225 | /* | 227 | /* |
226 | * F O R M A T E N U M E R A T I O N | 228 | * F O R M A T E N U M E R A T I O N |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index d5c3fe1bf33d..542dbaee6512 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -85,7 +85,7 @@ static inline void wait_on_inode(struct inode *inode) | |||
85 | /* | 85 | /* |
86 | * mm/page-writeback.c | 86 | * mm/page-writeback.c |
87 | */ | 87 | */ |
88 | int wakeup_bdflush(long nr_pages); | 88 | int wakeup_pdflush(long nr_pages); |
89 | void laptop_io_completion(void); | 89 | void laptop_io_completion(void); |
90 | void laptop_sync_completion(void); | 90 | void laptop_sync_completion(void); |
91 | void throttle_vm_writeout(void); | 91 | void throttle_vm_writeout(void); |
diff --git a/include/linux/xattr_acl.h b/include/linux/xattr_acl.h deleted file mode 100644 index 7a1f9b93a45f..000000000000 --- a/include/linux/xattr_acl.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | File: linux/xattr_acl.h | ||
3 | |||
4 | (extended attribute representation of access control lists) | ||
5 | |||
6 | (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LINUX_XATTR_ACL_H | ||
10 | #define _LINUX_XATTR_ACL_H | ||
11 | |||
12 | #include <linux/posix_acl.h> | ||
13 | |||
14 | #define XATTR_NAME_ACL_ACCESS "system.posix_acl_access" | ||
15 | #define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default" | ||
16 | |||
17 | #define XATTR_ACL_VERSION 0x0002 | ||
18 | |||
19 | typedef struct { | ||
20 | __u16 e_tag; | ||
21 | __u16 e_perm; | ||
22 | __u32 e_id; | ||
23 | } xattr_acl_entry; | ||
24 | |||
25 | typedef struct { | ||
26 | __u32 a_version; | ||
27 | xattr_acl_entry a_entries[0]; | ||
28 | } xattr_acl_header; | ||
29 | |||
30 | static inline size_t xattr_acl_size(int count) | ||
31 | { | ||
32 | return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry); | ||
33 | } | ||
34 | |||
35 | static inline int xattr_acl_count(size_t size) | ||
36 | { | ||
37 | if (size < sizeof(xattr_acl_header)) | ||
38 | return -1; | ||
39 | size -= sizeof(xattr_acl_header); | ||
40 | if (size % sizeof(xattr_acl_entry)) | ||
41 | return -1; | ||
42 | return size / sizeof(xattr_acl_entry); | ||
43 | } | ||
44 | |||
45 | struct posix_acl * posix_acl_from_xattr(const void *value, size_t size); | ||
46 | int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size); | ||
47 | |||
48 | |||
49 | |||
50 | #endif /* _LINUX_XATTR_ACL_H */ | ||
diff --git a/include/media/tuner.h b/include/media/tuner.h index 2dd8310901e8..4794c5632360 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
@@ -1,5 +1,6 @@ | |||
1 | 1 | ||
2 | /* | 2 | /* $Id: tuner.h,v 1.33 2005/06/21 14:58:08 mkrufky Exp $ |
3 | * | ||
3 | tuner.h - definition for different tuners | 4 | tuner.h - definition for different tuners |
4 | 5 | ||
5 | Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de) | 6 | Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de) |
@@ -23,6 +24,8 @@ | |||
23 | #ifndef _TUNER_H | 24 | #ifndef _TUNER_H |
24 | #define _TUNER_H | 25 | #define _TUNER_H |
25 | 26 | ||
27 | #include <linux/videodev2.h> | ||
28 | |||
26 | #include "id.h" | 29 | #include "id.h" |
27 | 30 | ||
28 | #define ADDR_UNSET (255) | 31 | #define ADDR_UNSET (255) |
@@ -88,7 +91,7 @@ | |||
88 | #define TUNER_LG_NTSC_TAPE 47 | 91 | #define TUNER_LG_NTSC_TAPE 47 |
89 | 92 | ||
90 | #define TUNER_TNF_8831BGFF 48 | 93 | #define TUNER_TNF_8831BGFF 48 |
91 | #define TUNER_MICROTUNE_4042FI5 49 /* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */ | 94 | #define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */ |
92 | #define TUNER_TCL_2002N 50 | 95 | #define TUNER_TCL_2002N 50 |
93 | #define TUNER_PHILIPS_FM1256_IH3 51 | 96 | #define TUNER_PHILIPS_FM1256_IH3 51 |
94 | 97 | ||
@@ -98,18 +101,18 @@ | |||
98 | #define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ | 101 | #define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ |
99 | 102 | ||
100 | #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ | 103 | #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ |
101 | #define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ | 104 | #define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ |
102 | 105 | ||
103 | #define TUNER_YMEC_TVF_8531MF 58 | 106 | #define TUNER_YMEC_TVF_8531MF 58 |
104 | #define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ | 107 | #define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ |
105 | #define TUNER_THOMSON_DTT7611 60 | 108 | #define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */ |
106 | #define TUNER_TENA_9533_DI 61 | 109 | #define TUNER_TENA_9533_DI 61 |
110 | |||
107 | #define TUNER_TEA5767 62 /* Only FM Radio Tuner */ | 111 | #define TUNER_TEA5767 62 /* Only FM Radio Tuner */ |
112 | #define TUNER_PHILIPS_FMD1216ME_MK3 63 | ||
108 | 113 | ||
109 | #define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio" | 114 | #define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio" |
110 | 115 | ||
111 | #define TUNER_THOMSON_DTT7611 60 | ||
112 | |||
113 | #define NOTUNER 0 | 116 | #define NOTUNER 0 |
114 | #define PAL 1 /* PAL_BG */ | 117 | #define PAL 1 /* PAL_BG */ |
115 | #define PAL_I 2 | 118 | #define PAL_I 2 |
@@ -194,11 +197,15 @@ struct tuner { | |||
194 | unsigned char i2c_easy_mode[2]; | 197 | unsigned char i2c_easy_mode[2]; |
195 | unsigned char i2c_set_freq[8]; | 198 | unsigned char i2c_set_freq[8]; |
196 | 199 | ||
200 | /* used to keep track of audmode */ | ||
201 | unsigned int audmode; | ||
202 | |||
197 | /* function ptrs */ | 203 | /* function ptrs */ |
198 | void (*tv_freq)(struct i2c_client *c, unsigned int freq); | 204 | void (*tv_freq)(struct i2c_client *c, unsigned int freq); |
199 | void (*radio_freq)(struct i2c_client *c, unsigned int freq); | 205 | void (*radio_freq)(struct i2c_client *c, unsigned int freq); |
200 | int (*has_signal)(struct i2c_client *c); | 206 | int (*has_signal)(struct i2c_client *c); |
201 | int (*is_stereo)(struct i2c_client *c); | 207 | int (*is_stereo)(struct i2c_client *c); |
208 | int (*set_tuner)(struct i2c_client *c, struct v4l2_tuner *v); | ||
202 | }; | 209 | }; |
203 | 210 | ||
204 | extern unsigned int tuner_debug; | 211 | extern unsigned int tuner_debug; |
@@ -206,6 +213,7 @@ extern unsigned const int tuner_count; | |||
206 | 213 | ||
207 | extern int microtune_init(struct i2c_client *c); | 214 | extern int microtune_init(struct i2c_client *c); |
208 | extern int tda8290_init(struct i2c_client *c); | 215 | extern int tda8290_init(struct i2c_client *c); |
216 | extern int tea5767_tuner_init(struct i2c_client *c); | ||
209 | extern int default_tuner_init(struct i2c_client *c); | 217 | extern int default_tuner_init(struct i2c_client *c); |
210 | 218 | ||
211 | #define tuner_warn(fmt, arg...) \ | 219 | #define tuner_warn(fmt, arg...) \ |
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 7fe57f957a51..db09580ad14b 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h | |||
@@ -94,6 +94,8 @@ struct eapol { | |||
94 | u16 length; | 94 | u16 length; |
95 | } __attribute__ ((packed)); | 95 | } __attribute__ ((packed)); |
96 | 96 | ||
97 | #define IEEE80211_1ADDR_LEN 10 | ||
98 | #define IEEE80211_2ADDR_LEN 16 | ||
97 | #define IEEE80211_3ADDR_LEN 24 | 99 | #define IEEE80211_3ADDR_LEN 24 |
98 | #define IEEE80211_4ADDR_LEN 30 | 100 | #define IEEE80211_4ADDR_LEN 30 |
99 | #define IEEE80211_FCS_LEN 4 | 101 | #define IEEE80211_FCS_LEN 4 |
@@ -300,23 +302,6 @@ struct ieee80211_snap_hdr { | |||
300 | #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 | 302 | #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 |
301 | 303 | ||
302 | 304 | ||
303 | /* Information Element IDs */ | ||
304 | #define WLAN_EID_SSID 0 | ||
305 | #define WLAN_EID_SUPP_RATES 1 | ||
306 | #define WLAN_EID_FH_PARAMS 2 | ||
307 | #define WLAN_EID_DS_PARAMS 3 | ||
308 | #define WLAN_EID_CF_PARAMS 4 | ||
309 | #define WLAN_EID_TIM 5 | ||
310 | #define WLAN_EID_IBSS_PARAMS 6 | ||
311 | #define WLAN_EID_CHALLENGE 16 | ||
312 | #define WLAN_EID_RSN 48 | ||
313 | #define WLAN_EID_GENERIC 221 | ||
314 | |||
315 | #define IEEE80211_MGMT_HDR_LEN 24 | ||
316 | #define IEEE80211_DATA_HDR3_LEN 24 | ||
317 | #define IEEE80211_DATA_HDR4_LEN 30 | ||
318 | |||
319 | |||
320 | #define IEEE80211_STATMASK_SIGNAL (1<<0) | 305 | #define IEEE80211_STATMASK_SIGNAL (1<<0) |
321 | #define IEEE80211_STATMASK_RSSI (1<<1) | 306 | #define IEEE80211_STATMASK_RSSI (1<<1) |
322 | #define IEEE80211_STATMASK_NOISE (1<<2) | 307 | #define IEEE80211_STATMASK_NOISE (1<<2) |
@@ -441,6 +426,10 @@ struct ieee80211_stats { | |||
441 | 426 | ||
442 | struct ieee80211_device; | 427 | struct ieee80211_device; |
443 | 428 | ||
429 | #if 0 /* for later */ | ||
430 | #include "ieee80211_crypt.h" | ||
431 | #endif | ||
432 | |||
444 | #define SEC_KEY_1 (1<<0) | 433 | #define SEC_KEY_1 (1<<0) |
445 | #define SEC_KEY_2 (1<<1) | 434 | #define SEC_KEY_2 (1<<1) |
446 | #define SEC_KEY_3 (1<<2) | 435 | #define SEC_KEY_3 (1<<2) |
@@ -488,15 +477,6 @@ Total: 28-2340 bytes | |||
488 | 477 | ||
489 | */ | 478 | */ |
490 | 479 | ||
491 | struct ieee80211_header_data { | ||
492 | u16 frame_ctl; | ||
493 | u16 duration_id; | ||
494 | u8 addr1[6]; | ||
495 | u8 addr2[6]; | ||
496 | u8 addr3[6]; | ||
497 | u16 seq_ctrl; | ||
498 | }; | ||
499 | |||
500 | #define BEACON_PROBE_SSID_ID_POSITION 12 | 480 | #define BEACON_PROBE_SSID_ID_POSITION 12 |
501 | 481 | ||
502 | /* Management Frame Information Element Types */ | 482 | /* Management Frame Information Element Types */ |
@@ -541,7 +521,7 @@ struct ieee80211_info_element { | |||
541 | */ | 521 | */ |
542 | 522 | ||
543 | struct ieee80211_authentication { | 523 | struct ieee80211_authentication { |
544 | struct ieee80211_header_data header; | 524 | struct ieee80211_hdr_3addr header; |
545 | u16 algorithm; | 525 | u16 algorithm; |
546 | u16 transaction; | 526 | u16 transaction; |
547 | u16 status; | 527 | u16 status; |
@@ -550,7 +530,7 @@ struct ieee80211_authentication { | |||
550 | 530 | ||
551 | 531 | ||
552 | struct ieee80211_probe_response { | 532 | struct ieee80211_probe_response { |
553 | struct ieee80211_header_data header; | 533 | struct ieee80211_hdr_3addr header; |
554 | u32 time_stamp[2]; | 534 | u32 time_stamp[2]; |
555 | u16 beacon_interval; | 535 | u16 beacon_interval; |
556 | u16 capability; | 536 | u16 capability; |
@@ -648,12 +628,6 @@ enum ieee80211_state { | |||
648 | #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] | 628 | #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] |
649 | 629 | ||
650 | 630 | ||
651 | extern inline int is_broadcast_ether_addr(const u8 *addr) | ||
652 | { | ||
653 | return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ | ||
654 | (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); | ||
655 | } | ||
656 | |||
657 | #define CFG_IEEE80211_RESERVE_FCS (1<<0) | 631 | #define CFG_IEEE80211_RESERVE_FCS (1<<0) |
658 | #define CFG_IEEE80211_COMPUTE_FCS (1<<1) | 632 | #define CFG_IEEE80211_COMPUTE_FCS (1<<1) |
659 | 633 | ||
@@ -787,21 +761,21 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod | |||
787 | 761 | ||
788 | extern inline int ieee80211_get_hdrlen(u16 fc) | 762 | extern inline int ieee80211_get_hdrlen(u16 fc) |
789 | { | 763 | { |
790 | int hdrlen = 24; | 764 | int hdrlen = IEEE80211_3ADDR_LEN; |
791 | 765 | ||
792 | switch (WLAN_FC_GET_TYPE(fc)) { | 766 | switch (WLAN_FC_GET_TYPE(fc)) { |
793 | case IEEE80211_FTYPE_DATA: | 767 | case IEEE80211_FTYPE_DATA: |
794 | if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) | 768 | if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) |
795 | hdrlen = 30; /* Addr4 */ | 769 | hdrlen = IEEE80211_4ADDR_LEN; |
796 | break; | 770 | break; |
797 | case IEEE80211_FTYPE_CTL: | 771 | case IEEE80211_FTYPE_CTL: |
798 | switch (WLAN_FC_GET_STYPE(fc)) { | 772 | switch (WLAN_FC_GET_STYPE(fc)) { |
799 | case IEEE80211_STYPE_CTS: | 773 | case IEEE80211_STYPE_CTS: |
800 | case IEEE80211_STYPE_ACK: | 774 | case IEEE80211_STYPE_ACK: |
801 | hdrlen = 10; | 775 | hdrlen = IEEE80211_1ADDR_LEN; |
802 | break; | 776 | break; |
803 | default: | 777 | default: |
804 | hdrlen = 16; | 778 | hdrlen = IEEE80211_2ADDR_LEN; |
805 | break; | 779 | break; |
806 | } | 780 | } |
807 | break; | 781 | break; |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 771b47e30f86..69324465e8b3 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -183,7 +183,6 @@ struct ipv6_txoptions | |||
183 | struct ipv6_opt_hdr *hopopt; | 183 | struct ipv6_opt_hdr *hopopt; |
184 | struct ipv6_opt_hdr *dst0opt; | 184 | struct ipv6_opt_hdr *dst0opt; |
185 | struct ipv6_rt_hdr *srcrt; /* Routing Header */ | 185 | struct ipv6_rt_hdr *srcrt; /* Routing Header */ |
186 | struct ipv6_opt_hdr *auth; | ||
187 | struct ipv6_opt_hdr *dst1opt; | 186 | struct ipv6_opt_hdr *dst1opt; |
188 | 187 | ||
189 | /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ | 188 | /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ |
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 4868c7f7749d..5999e5684bbf 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h | |||
@@ -263,23 +263,11 @@ enum { SCTP_MIN_PMTU = 576 }; | |||
263 | enum { SCTP_MAX_DUP_TSNS = 16 }; | 263 | enum { SCTP_MAX_DUP_TSNS = 16 }; |
264 | enum { SCTP_MAX_GABS = 16 }; | 264 | enum { SCTP_MAX_GABS = 16 }; |
265 | 265 | ||
266 | /* Here we define the default timers. */ | 266 | /* Heartbeat interval - 30 secs */ |
267 | #define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ) | ||
267 | 268 | ||
268 | /* cookie timer def = ? seconds */ | 269 | /* Delayed sack timer - 200ms */ |
269 | #define SCTP_DEFAULT_TIMEOUT_T1_COOKIE (3 * HZ) | ||
270 | |||
271 | /* init timer def = 3 seconds */ | ||
272 | #define SCTP_DEFAULT_TIMEOUT_T1_INIT (3 * HZ) | ||
273 | |||
274 | /* shutdown timer def = 300 ms */ | ||
275 | #define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000) | ||
276 | |||
277 | /* 0 seconds + RTO */ | ||
278 | #define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (10 * HZ) | ||
279 | |||
280 | /* recv timer def = 200ms (in usec) */ | ||
281 | #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) | 270 | #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) |
282 | #define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */ | ||
283 | 271 | ||
284 | /* RTO.Initial - 3 seconds | 272 | /* RTO.Initial - 3 seconds |
285 | * RTO.Min - 1 second | 273 | * RTO.Min - 1 second |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index dfad4d3c581c..47727c7cc628 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -161,6 +161,9 @@ extern struct sctp_globals { | |||
161 | */ | 161 | */ |
162 | int sndbuf_policy; | 162 | int sndbuf_policy; |
163 | 163 | ||
164 | /* Delayed SACK timeout 200ms default*/ | ||
165 | int sack_timeout; | ||
166 | |||
164 | /* HB.interval - 30 seconds */ | 167 | /* HB.interval - 30 seconds */ |
165 | int hb_interval; | 168 | int hb_interval; |
166 | 169 | ||
@@ -217,6 +220,7 @@ extern struct sctp_globals { | |||
217 | #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) | 220 | #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) |
218 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) | 221 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) |
219 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) | 222 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) |
223 | #define sctp_sack_timeout (sctp_globals.sack_timeout) | ||
220 | #define sctp_hb_interval (sctp_globals.hb_interval) | 224 | #define sctp_hb_interval (sctp_globals.hb_interval) |
221 | #define sctp_max_instreams (sctp_globals.max_instreams) | 225 | #define sctp_max_instreams (sctp_globals.max_instreams) |
222 | #define sctp_max_outstreams (sctp_globals.max_outstreams) | 226 | #define sctp_max_outstreams (sctp_globals.max_outstreams) |
diff --git a/init/main.c b/init/main.c index d324801729ba..b5e421e39ede 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -383,6 +383,13 @@ static void noinline rest_init(void) | |||
383 | numa_default_policy(); | 383 | numa_default_policy(); |
384 | unlock_kernel(); | 384 | unlock_kernel(); |
385 | preempt_enable_no_resched(); | 385 | preempt_enable_no_resched(); |
386 | |||
387 | /* | ||
388 | * The boot idle thread must execute schedule() | ||
389 | * at least one to get things moving: | ||
390 | */ | ||
391 | schedule(); | ||
392 | |||
386 | cpu_idle(); | 393 | cpu_idle(); |
387 | } | 394 | } |
388 | 395 | ||
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 98d62d8efeaf..3467097ca61a 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/delay.h> | ||
12 | 13 | ||
13 | /* | 14 | /* |
14 | * Autodetection depends on the fact that any interrupt that | 15 | * Autodetection depends on the fact that any interrupt that |
@@ -26,7 +27,7 @@ static DECLARE_MUTEX(probe_sem); | |||
26 | */ | 27 | */ |
27 | unsigned long probe_irq_on(void) | 28 | unsigned long probe_irq_on(void) |
28 | { | 29 | { |
29 | unsigned long val, delay; | 30 | unsigned long val; |
30 | irq_desc_t *desc; | 31 | irq_desc_t *desc; |
31 | unsigned int i; | 32 | unsigned int i; |
32 | 33 | ||
@@ -45,8 +46,7 @@ unsigned long probe_irq_on(void) | |||
45 | } | 46 | } |
46 | 47 | ||
47 | /* Wait for longstanding interrupts to trigger. */ | 48 | /* Wait for longstanding interrupts to trigger. */ |
48 | for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) | 49 | msleep(20); |
49 | /* about 20ms delay */ barrier(); | ||
50 | 50 | ||
51 | /* | 51 | /* |
52 | * enable any unassigned irqs | 52 | * enable any unassigned irqs |
@@ -68,8 +68,7 @@ unsigned long probe_irq_on(void) | |||
68 | /* | 68 | /* |
69 | * Wait for spurious interrupts to trigger | 69 | * Wait for spurious interrupts to trigger |
70 | */ | 70 | */ |
71 | for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) | 71 | msleep(100); |
72 | /* about 100ms delay */ barrier(); | ||
73 | 72 | ||
74 | /* | 73 | /* |
75 | * Now filter out any obviously spurious interrupts | 74 | * Now filter out any obviously spurious interrupts |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 436c7d93c00a..c29f83c16497 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -172,7 +172,7 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
172 | 172 | ||
173 | spin_lock(&desc->lock); | 173 | spin_lock(&desc->lock); |
174 | if (!noirqdebug) | 174 | if (!noirqdebug) |
175 | note_interrupt(irq, desc, action_ret); | 175 | note_interrupt(irq, desc, action_ret, regs); |
176 | if (likely(!(desc->status & IRQ_PENDING))) | 176 | if (likely(!(desc->status & IRQ_PENDING))) |
177 | break; | 177 | break; |
178 | desc->status &= ~IRQ_PENDING; | 178 | desc->status &= ~IRQ_PENDING; |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index ba039e827d58..7df9abd5ec86 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -11,6 +11,83 @@ | |||
11 | #include <linux/kallsyms.h> | 11 | #include <linux/kallsyms.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | 13 | ||
14 | static int irqfixup; | ||
15 | |||
16 | /* | ||
17 | * Recovery handler for misrouted interrupts. | ||
18 | */ | ||
19 | |||
20 | static int misrouted_irq(int irq, struct pt_regs *regs) | ||
21 | { | ||
22 | int i; | ||
23 | irq_desc_t *desc; | ||
24 | int ok = 0; | ||
25 | int work = 0; /* Did we do work for a real IRQ */ | ||
26 | |||
27 | for(i = 1; i < NR_IRQS; i++) { | ||
28 | struct irqaction *action; | ||
29 | |||
30 | if (i == irq) /* Already tried */ | ||
31 | continue; | ||
32 | desc = &irq_desc[i]; | ||
33 | spin_lock(&desc->lock); | ||
34 | action = desc->action; | ||
35 | /* Already running on another processor */ | ||
36 | if (desc->status & IRQ_INPROGRESS) { | ||
37 | /* | ||
38 | * Already running: If it is shared get the other | ||
39 | * CPU to go looking for our mystery interrupt too | ||
40 | */ | ||
41 | if (desc->action && (desc->action->flags & SA_SHIRQ)) | ||
42 | desc->status |= IRQ_PENDING; | ||
43 | spin_unlock(&desc->lock); | ||
44 | continue; | ||
45 | } | ||
46 | /* Honour the normal IRQ locking */ | ||
47 | desc->status |= IRQ_INPROGRESS; | ||
48 | spin_unlock(&desc->lock); | ||
49 | while (action) { | ||
50 | /* Only shared IRQ handlers are safe to call */ | ||
51 | if (action->flags & SA_SHIRQ) { | ||
52 | if (action->handler(i, action->dev_id, regs) == | ||
53 | IRQ_HANDLED) | ||
54 | ok = 1; | ||
55 | } | ||
56 | action = action->next; | ||
57 | } | ||
58 | local_irq_disable(); | ||
59 | /* Now clean up the flags */ | ||
60 | spin_lock(&desc->lock); | ||
61 | action = desc->action; | ||
62 | |||
63 | /* | ||
64 | * While we were looking for a fixup someone queued a real | ||
65 | * IRQ clashing with our walk | ||
66 | */ | ||
67 | |||
68 | while ((desc->status & IRQ_PENDING) && action) { | ||
69 | /* | ||
70 | * Perform real IRQ processing for the IRQ we deferred | ||
71 | */ | ||
72 | work = 1; | ||
73 | spin_unlock(&desc->lock); | ||
74 | handle_IRQ_event(i, regs, action); | ||
75 | spin_lock(&desc->lock); | ||
76 | desc->status &= ~IRQ_PENDING; | ||
77 | } | ||
78 | desc->status &= ~IRQ_INPROGRESS; | ||
79 | /* | ||
80 | * If we did actual work for the real IRQ line we must let the | ||
81 | * IRQ controller clean up too | ||
82 | */ | ||
83 | if(work) | ||
84 | desc->handler->end(i); | ||
85 | spin_unlock(&desc->lock); | ||
86 | } | ||
87 | /* So the caller can adjust the irq error counts */ | ||
88 | return ok; | ||
89 | } | ||
90 | |||
14 | /* | 91 | /* |
15 | * If 99,900 of the previous 100,000 interrupts have not been handled | 92 | * If 99,900 of the previous 100,000 interrupts have not been handled |
16 | * then assume that the IRQ is stuck in some manner. Drop a diagnostic | 93 | * then assume that the IRQ is stuck in some manner. Drop a diagnostic |
@@ -31,7 +108,8 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | |||
31 | printk(KERN_ERR "irq event %d: bogus return value %x\n", | 108 | printk(KERN_ERR "irq event %d: bogus return value %x\n", |
32 | irq, action_ret); | 109 | irq, action_ret); |
33 | } else { | 110 | } else { |
34 | printk(KERN_ERR "irq %d: nobody cared!\n", irq); | 111 | printk(KERN_ERR "irq %d: nobody cared (try booting with " |
112 | "the \"irqpoll\" option)\n", irq); | ||
35 | } | 113 | } |
36 | dump_stack(); | 114 | dump_stack(); |
37 | printk(KERN_ERR "handlers:\n"); | 115 | printk(KERN_ERR "handlers:\n"); |
@@ -55,7 +133,8 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio | |||
55 | } | 133 | } |
56 | } | 134 | } |
57 | 135 | ||
58 | void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | 136 | void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, |
137 | struct pt_regs *regs) | ||
59 | { | 138 | { |
60 | if (action_ret != IRQ_HANDLED) { | 139 | if (action_ret != IRQ_HANDLED) { |
61 | desc->irqs_unhandled++; | 140 | desc->irqs_unhandled++; |
@@ -63,6 +142,15 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | |||
63 | report_bad_irq(irq, desc, action_ret); | 142 | report_bad_irq(irq, desc, action_ret); |
64 | } | 143 | } |
65 | 144 | ||
145 | if (unlikely(irqfixup)) { | ||
146 | /* Don't punish working computers */ | ||
147 | if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { | ||
148 | int ok = misrouted_irq(irq, regs); | ||
149 | if (action_ret == IRQ_NONE) | ||
150 | desc->irqs_unhandled -= ok; | ||
151 | } | ||
152 | } | ||
153 | |||
66 | desc->irq_count++; | 154 | desc->irq_count++; |
67 | if (desc->irq_count < 100000) | 155 | if (desc->irq_count < 100000) |
68 | return; | 156 | return; |
@@ -94,3 +182,24 @@ int __init noirqdebug_setup(char *str) | |||
94 | 182 | ||
95 | __setup("noirqdebug", noirqdebug_setup); | 183 | __setup("noirqdebug", noirqdebug_setup); |
96 | 184 | ||
185 | static int __init irqfixup_setup(char *str) | ||
186 | { | ||
187 | irqfixup = 1; | ||
188 | printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); | ||
189 | printk(KERN_WARNING "This may impact system performance.\n"); | ||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | __setup("irqfixup", irqfixup_setup); | ||
194 | |||
195 | static int __init irqpoll_setup(char *str) | ||
196 | { | ||
197 | irqfixup = 2; | ||
198 | printk(KERN_WARNING "Misrouted IRQ fixup and polling support " | ||
199 | "enabled\n"); | ||
200 | printk(KERN_WARNING "This may significantly impact system " | ||
201 | "performance\n"); | ||
202 | return 1; | ||
203 | } | ||
204 | |||
205 | __setup("irqpoll", irqpoll_setup); | ||
diff --git a/kernel/itimer.c b/kernel/itimer.c index 1dc988e0d2c7..a72cb0e5aa4b 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -153,11 +153,15 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) | |||
153 | 153 | ||
154 | switch (which) { | 154 | switch (which) { |
155 | case ITIMER_REAL: | 155 | case ITIMER_REAL: |
156 | again: | ||
156 | spin_lock_irq(&tsk->sighand->siglock); | 157 | spin_lock_irq(&tsk->sighand->siglock); |
157 | interval = tsk->signal->it_real_incr; | 158 | interval = tsk->signal->it_real_incr; |
158 | val = it_real_value(tsk->signal); | 159 | val = it_real_value(tsk->signal); |
159 | if (val) | 160 | /* We are sharing ->siglock with it_real_fn() */ |
160 | del_timer_sync(&tsk->signal->real_timer); | 161 | if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) { |
162 | spin_unlock_irq(&tsk->sighand->siglock); | ||
163 | goto again; | ||
164 | } | ||
161 | tsk->signal->it_real_incr = | 165 | tsk->signal->it_real_incr = |
162 | timeval_to_jiffies(&value->it_interval); | 166 | timeval_to_jiffies(&value->it_interval); |
163 | it_real_arm(tsk, timeval_to_jiffies(&value->it_value)); | 167 | it_real_arm(tsk, timeval_to_jiffies(&value->it_value)); |
diff --git a/kernel/kexec.c b/kernel/kexec.c index 7843548cf2d9..cdd4dcd8fb63 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -241,7 +241,7 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | |||
241 | 241 | ||
242 | static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, | 242 | static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, |
243 | unsigned long nr_segments, | 243 | unsigned long nr_segments, |
244 | struct kexec_segment *segments) | 244 | struct kexec_segment __user *segments) |
245 | { | 245 | { |
246 | int result; | 246 | int result; |
247 | struct kimage *image; | 247 | struct kimage *image; |
@@ -650,7 +650,7 @@ static kimage_entry_t *kimage_dst_used(struct kimage *image, | |||
650 | } | 650 | } |
651 | } | 651 | } |
652 | 652 | ||
653 | return 0; | 653 | return NULL; |
654 | } | 654 | } |
655 | 655 | ||
656 | static struct page *kimage_alloc_page(struct kimage *image, | 656 | static struct page *kimage_alloc_page(struct kimage *image, |
@@ -696,7 +696,7 @@ static struct page *kimage_alloc_page(struct kimage *image, | |||
696 | /* Allocate a page, if we run out of memory give up */ | 696 | /* Allocate a page, if we run out of memory give up */ |
697 | page = kimage_alloc_pages(gfp_mask, 0); | 697 | page = kimage_alloc_pages(gfp_mask, 0); |
698 | if (!page) | 698 | if (!page) |
699 | return 0; | 699 | return NULL; |
700 | /* If the page cannot be used file it away */ | 700 | /* If the page cannot be used file it away */ |
701 | if (page_to_pfn(page) > | 701 | if (page_to_pfn(page) > |
702 | (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { | 702 | (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { |
@@ -754,7 +754,7 @@ static int kimage_load_normal_segment(struct kimage *image, | |||
754 | unsigned long maddr; | 754 | unsigned long maddr; |
755 | unsigned long ubytes, mbytes; | 755 | unsigned long ubytes, mbytes; |
756 | int result; | 756 | int result; |
757 | unsigned char *buf; | 757 | unsigned char __user *buf; |
758 | 758 | ||
759 | result = 0; | 759 | result = 0; |
760 | buf = segment->buf; | 760 | buf = segment->buf; |
@@ -818,7 +818,7 @@ static int kimage_load_crash_segment(struct kimage *image, | |||
818 | unsigned long maddr; | 818 | unsigned long maddr; |
819 | unsigned long ubytes, mbytes; | 819 | unsigned long ubytes, mbytes; |
820 | int result; | 820 | int result; |
821 | unsigned char *buf; | 821 | unsigned char __user *buf; |
822 | 822 | ||
823 | result = 0; | 823 | result = 0; |
824 | buf = segment->buf; | 824 | buf = segment->buf; |
diff --git a/kernel/sched.c b/kernel/sched.c index e2b0d3e4dd06..5f2182d42241 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4166,6 +4166,14 @@ void show_state(void) | |||
4166 | read_unlock(&tasklist_lock); | 4166 | read_unlock(&tasklist_lock); |
4167 | } | 4167 | } |
4168 | 4168 | ||
4169 | /** | ||
4170 | * init_idle - set up an idle thread for a given CPU | ||
4171 | * @idle: task in question | ||
4172 | * @cpu: cpu the idle task belongs to | ||
4173 | * | ||
4174 | * NOTE: this function does not set the idle thread's NEED_RESCHED | ||
4175 | * flag, to make booting more robust. | ||
4176 | */ | ||
4169 | void __devinit init_idle(task_t *idle, int cpu) | 4177 | void __devinit init_idle(task_t *idle, int cpu) |
4170 | { | 4178 | { |
4171 | runqueue_t *rq = cpu_rq(cpu); | 4179 | runqueue_t *rq = cpu_rq(cpu); |
@@ -4183,7 +4191,6 @@ void __devinit init_idle(task_t *idle, int cpu) | |||
4183 | #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) | 4191 | #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) |
4184 | idle->oncpu = 1; | 4192 | idle->oncpu = 1; |
4185 | #endif | 4193 | #endif |
4186 | set_tsk_need_resched(idle); | ||
4187 | spin_unlock_irqrestore(&rq->lock, flags); | 4194 | spin_unlock_irqrestore(&rq->lock, flags); |
4188 | 4195 | ||
4189 | /* Set the preempt count _outside_ the spinlocks! */ | 4196 | /* Set the preempt count _outside_ the spinlocks! */ |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 613b99a55917..a6329fa8f862 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -354,7 +354,7 @@ static void background_writeout(unsigned long _min_pages) | |||
354 | * the whole world. Returns 0 if a pdflush thread was dispatched. Returns | 354 | * the whole world. Returns 0 if a pdflush thread was dispatched. Returns |
355 | * -1 if all pdflush threads were busy. | 355 | * -1 if all pdflush threads were busy. |
356 | */ | 356 | */ |
357 | int wakeup_bdflush(long nr_pages) | 357 | int wakeup_pdflush(long nr_pages) |
358 | { | 358 | { |
359 | if (nr_pages == 0) { | 359 | if (nr_pages == 0) { |
360 | struct writeback_state wbs; | 360 | struct writeback_state wbs; |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 1fa312a8db77..cfffe5098d53 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -972,7 +972,7 @@ int try_to_free_pages(struct zone **zones, unsigned int gfp_mask) | |||
972 | * writeout. So in laptop mode, write out the whole world. | 972 | * writeout. So in laptop mode, write out the whole world. |
973 | */ | 973 | */ |
974 | if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) { | 974 | if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) { |
975 | wakeup_bdflush(laptop_mode ? 0 : total_scanned); | 975 | wakeup_pdflush(laptop_mode ? 0 : total_scanned); |
976 | sc.may_writepage = 1; | 976 | sc.may_writepage = 1; |
977 | } | 977 | } |
978 | 978 | ||
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 03ae4edddac3..2d52fee63a8c 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, | |||
844 | * doesn't use the bridge parent of the indev by using | 844 | * doesn't use the bridge parent of the indev by using |
845 | * the BRNF_DONT_TAKE_PARENT mask. */ | 845 | * the BRNF_DONT_TAKE_PARENT mask. */ |
846 | if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { | 846 | if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { |
847 | nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; | 847 | nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; |
848 | nf_bridge->physindev = (struct net_device *)in; | 848 | nf_bridge->physindev = (struct net_device *)in; |
849 | } | 849 | } |
850 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 850 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index e4ae34b88925..662975be3d1d 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -61,8 +61,6 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
61 | { | 61 | { |
62 | struct ebt_log_info *info = (struct ebt_log_info *)data; | 62 | struct ebt_log_info *info = (struct ebt_log_info *)data; |
63 | char level_string[4] = "< >"; | 63 | char level_string[4] = "< >"; |
64 | union {struct iphdr iph; struct tcpudphdr ports; | ||
65 | struct arphdr arph; struct arppayload arpp;} u; | ||
66 | 64 | ||
67 | level_string[1] = '0' + info->loglevel; | 65 | level_string[1] = '0' + info->loglevel; |
68 | spin_lock_bh(&ebt_log_lock); | 66 | spin_lock_bh(&ebt_log_lock); |
@@ -88,7 +86,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
88 | } | 86 | } |
89 | printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", | 87 | printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", |
90 | NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); | 88 | NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); |
91 | printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos, | 89 | printk(" IP tos=0x%02X, IP proto=%d", ih->tos, |
92 | ih->protocol); | 90 | ih->protocol); |
93 | if (ih->protocol == IPPROTO_TCP || | 91 | if (ih->protocol == IPPROTO_TCP || |
94 | ih->protocol == IPPROTO_UDP) { | 92 | ih->protocol == IPPROTO_UDP) { |
@@ -127,7 +125,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
127 | ah->ar_pln == sizeof(uint32_t)) { | 125 | ah->ar_pln == sizeof(uint32_t)) { |
128 | struct arppayload _arpp, *ap; | 126 | struct arppayload _arpp, *ap; |
129 | 127 | ||
130 | ap = skb_header_pointer(skb, sizeof(u.arph), | 128 | ap = skb_header_pointer(skb, sizeof(_arph), |
131 | sizeof(_arpp), &_arpp); | 129 | sizeof(_arpp), &_arpp); |
132 | if (ap == NULL) { | 130 | if (ap == NULL) { |
133 | printk(" INCOMPLETE ARP payload"); | 131 | printk(" INCOMPLETE ARP payload"); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 851eb927ed97..1beb782ac41b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1598,6 +1598,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | |||
1598 | 1598 | ||
1599 | read_lock_bh(&tbl->lock); | 1599 | read_lock_bh(&tbl->lock); |
1600 | ndtmsg->ndtm_family = tbl->family; | 1600 | ndtmsg->ndtm_family = tbl->family; |
1601 | ndtmsg->ndtm_pad1 = 0; | ||
1602 | ndtmsg->ndtm_pad2 = 0; | ||
1601 | 1603 | ||
1602 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | 1604 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); |
1603 | RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); | 1605 | RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); |
@@ -1683,6 +1685,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, | |||
1683 | 1685 | ||
1684 | read_lock_bh(&tbl->lock); | 1686 | read_lock_bh(&tbl->lock); |
1685 | ndtmsg->ndtm_family = tbl->family; | 1687 | ndtmsg->ndtm_family = tbl->family; |
1688 | ndtmsg->ndtm_pad1 = 0; | ||
1689 | ndtmsg->ndtm_pad2 = 0; | ||
1686 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | 1690 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); |
1687 | 1691 | ||
1688 | if (neightbl_fill_parms(skb, parms) < 0) | 1692 | if (neightbl_fill_parms(skb, parms) < 0) |
@@ -1872,6 +1876,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, | |||
1872 | struct ndmsg *ndm = NLMSG_DATA(nlh); | 1876 | struct ndmsg *ndm = NLMSG_DATA(nlh); |
1873 | 1877 | ||
1874 | ndm->ndm_family = n->ops->family; | 1878 | ndm->ndm_family = n->ops->family; |
1879 | ndm->ndm_pad1 = 0; | ||
1880 | ndm->ndm_pad2 = 0; | ||
1875 | ndm->ndm_flags = n->flags; | 1881 | ndm->ndm_flags = n->flags; |
1876 | ndm->ndm_type = n->type; | 1882 | ndm->ndm_type = n->type; |
1877 | ndm->ndm_ifindex = n->dev->ifindex; | 1883 | ndm->ndm_ifindex = n->dev->ifindex; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e013d836a7ab..4b1bb30e6381 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -126,6 +126,7 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data | |||
126 | rta->rta_type = attrtype; | 126 | rta->rta_type = attrtype; |
127 | rta->rta_len = size; | 127 | rta->rta_len = size; |
128 | memcpy(RTA_DATA(rta), data, attrlen); | 128 | memcpy(RTA_DATA(rta), data, attrlen); |
129 | memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); | ||
129 | } | 130 | } |
130 | 131 | ||
131 | size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) | 132 | size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) |
@@ -188,6 +189,7 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
188 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); | 189 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); |
189 | r = NLMSG_DATA(nlh); | 190 | r = NLMSG_DATA(nlh); |
190 | r->ifi_family = AF_UNSPEC; | 191 | r->ifi_family = AF_UNSPEC; |
192 | r->__ifi_pad = 0; | ||
191 | r->ifi_type = dev->type; | 193 | r->ifi_type = dev->type; |
192 | r->ifi_index = dev->ifindex; | 194 | r->ifi_index = dev->ifindex; |
193 | r->ifi_flags = dev_get_flags(dev); | 195 | r->ifi_flags = dev_get_flags(dev); |
diff --git a/net/core/wireless.c b/net/core/wireless.c index b2fe378dfbf8..3ff5639c0b78 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -1102,6 +1102,7 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb, | |||
1102 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); | 1102 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); |
1103 | r = NLMSG_DATA(nlh); | 1103 | r = NLMSG_DATA(nlh); |
1104 | r->ifi_family = AF_UNSPEC; | 1104 | r->ifi_family = AF_UNSPEC; |
1105 | r->__ifi_pad = 0; | ||
1105 | r->ifi_type = dev->type; | 1106 | r->ifi_type = dev->type; |
1106 | r->ifi_index = dev->ifindex; | 1107 | r->ifi_index = dev->ifindex; |
1107 | r->ifi_flags = dev->flags; | 1108 | r->ifi_flags = dev->flags; |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 6617ea47d365..ab60ea63688e 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -92,10 +92,9 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, | |||
92 | * Set the source hardware address. | 92 | * Set the source hardware address. |
93 | */ | 93 | */ |
94 | 94 | ||
95 | if(saddr) | 95 | if(!saddr) |
96 | memcpy(eth->h_source,saddr,dev->addr_len); | 96 | saddr = dev->dev_addr; |
97 | else | 97 | memcpy(eth->h_source,saddr,dev->addr_len); |
98 | memcpy(eth->h_source,dev->dev_addr,dev->addr_len); | ||
99 | 98 | ||
100 | /* | 99 | /* |
101 | * Anyway, the loopback-device should never use this function... | 100 | * Anyway, the loopback-device should never use this function... |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0671569ee6f0..b56e88edf1b3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * 2 of the License, or (at your option) any later version. | 43 | * 2 of the License, or (at your option) any later version. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #define VERSION "0.323" | 46 | #define VERSION "0.324" |
47 | 47 | ||
48 | #include <linux/config.h> | 48 | #include <linux/config.h> |
49 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
@@ -341,8 +341,10 @@ static struct leaf *leaf_new(void) | |||
341 | static struct leaf_info *leaf_info_new(int plen) | 341 | static struct leaf_info *leaf_info_new(int plen) |
342 | { | 342 | { |
343 | struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); | 343 | struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); |
344 | li->plen = plen; | 344 | if(li) { |
345 | INIT_LIST_HEAD(&li->falh); | 345 | li->plen = plen; |
346 | INIT_LIST_HEAD(&li->falh); | ||
347 | } | ||
346 | return li; | 348 | return li; |
347 | } | 349 | } |
348 | 350 | ||
@@ -879,8 +881,8 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | |||
879 | return (struct node*) tn; | 881 | return (struct node*) tn; |
880 | } | 882 | } |
881 | 883 | ||
882 | static struct list_head * | 884 | static struct list_head * |
883 | fib_insert_node(struct trie *t, u32 key, int plen) | 885 | fib_insert_node(struct trie *t, int *err, u32 key, int plen) |
884 | { | 886 | { |
885 | int pos, newpos; | 887 | int pos, newpos; |
886 | struct tnode *tp = NULL, *tn = NULL; | 888 | struct tnode *tp = NULL, *tn = NULL; |
@@ -940,7 +942,6 @@ fib_insert_node(struct trie *t, u32 key, int plen) | |||
940 | if(tp && IS_LEAF(tp)) | 942 | if(tp && IS_LEAF(tp)) |
941 | BUG(); | 943 | BUG(); |
942 | 944 | ||
943 | t->revision++; | ||
944 | 945 | ||
945 | /* Case 1: n is a leaf. Compare prefixes */ | 946 | /* Case 1: n is a leaf. Compare prefixes */ |
946 | 947 | ||
@@ -949,8 +950,10 @@ fib_insert_node(struct trie *t, u32 key, int plen) | |||
949 | 950 | ||
950 | li = leaf_info_new(plen); | 951 | li = leaf_info_new(plen); |
951 | 952 | ||
952 | if(! li) | 953 | if(! li) { |
953 | BUG(); | 954 | *err = -ENOMEM; |
955 | goto err; | ||
956 | } | ||
954 | 957 | ||
955 | fa_head = &li->falh; | 958 | fa_head = &li->falh; |
956 | insert_leaf_info(&l->list, li); | 959 | insert_leaf_info(&l->list, li); |
@@ -959,14 +962,19 @@ fib_insert_node(struct trie *t, u32 key, int plen) | |||
959 | t->size++; | 962 | t->size++; |
960 | l = leaf_new(); | 963 | l = leaf_new(); |
961 | 964 | ||
962 | if(! l) | 965 | if(! l) { |
963 | BUG(); | 966 | *err = -ENOMEM; |
967 | goto err; | ||
968 | } | ||
964 | 969 | ||
965 | l->key = key; | 970 | l->key = key; |
966 | li = leaf_info_new(plen); | 971 | li = leaf_info_new(plen); |
967 | 972 | ||
968 | if(! li) | 973 | if(! li) { |
969 | BUG(); | 974 | tnode_free((struct tnode *) l); |
975 | *err = -ENOMEM; | ||
976 | goto err; | ||
977 | } | ||
970 | 978 | ||
971 | fa_head = &li->falh; | 979 | fa_head = &li->falh; |
972 | insert_leaf_info(&l->list, li); | 980 | insert_leaf_info(&l->list, li); |
@@ -1003,9 +1011,14 @@ fib_insert_node(struct trie *t, u32 key, int plen) | |||
1003 | newpos = 0; | 1011 | newpos = 0; |
1004 | tn = tnode_new(key, newpos, 1); /* First tnode */ | 1012 | tn = tnode_new(key, newpos, 1); /* First tnode */ |
1005 | } | 1013 | } |
1006 | if(!tn) | ||
1007 | trie_bug("tnode_pfx_new failed"); | ||
1008 | 1014 | ||
1015 | if(!tn) { | ||
1016 | free_leaf_info(li); | ||
1017 | tnode_free((struct tnode *) l); | ||
1018 | *err = -ENOMEM; | ||
1019 | goto err; | ||
1020 | } | ||
1021 | |||
1009 | NODE_SET_PARENT(tn, tp); | 1022 | NODE_SET_PARENT(tn, tp); |
1010 | 1023 | ||
1011 | missbit=tkey_extract_bits(key, newpos, 1); | 1024 | missbit=tkey_extract_bits(key, newpos, 1); |
@@ -1027,7 +1040,9 @@ fib_insert_node(struct trie *t, u32 key, int plen) | |||
1027 | } | 1040 | } |
1028 | /* Rebalance the trie */ | 1041 | /* Rebalance the trie */ |
1029 | t->trie = trie_rebalance(t, tp); | 1042 | t->trie = trie_rebalance(t, tp); |
1030 | done:; | 1043 | done: |
1044 | t->revision++; | ||
1045 | err:; | ||
1031 | return fa_head; | 1046 | return fa_head; |
1032 | } | 1047 | } |
1033 | 1048 | ||
@@ -1156,8 +1171,12 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1156 | * Insert new entry to the list. | 1171 | * Insert new entry to the list. |
1157 | */ | 1172 | */ |
1158 | 1173 | ||
1159 | if(!fa_head) | 1174 | if(!fa_head) { |
1160 | fa_head = fib_insert_node(t, key, plen); | 1175 | fa_head = fib_insert_node(t, &err, key, plen); |
1176 | err = 0; | ||
1177 | if(err) | ||
1178 | goto out_free_new_fa; | ||
1179 | } | ||
1161 | 1180 | ||
1162 | write_lock_bh(&fib_lock); | 1181 | write_lock_bh(&fib_lock); |
1163 | 1182 | ||
@@ -1170,6 +1189,9 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, | |||
1170 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); | 1189 | rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); |
1171 | succeeded: | 1190 | succeeded: |
1172 | return 0; | 1191 | return 0; |
1192 | |||
1193 | out_free_new_fa: | ||
1194 | kmem_cache_free(fn_alias_kmem, new_fa); | ||
1173 | out: | 1195 | out: |
1174 | fib_release_info(fi); | 1196 | fib_release_info(fi); |
1175 | err:; | 1197 | err:; |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index af2ec88bbb2f..c703528e0bcd 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -283,14 +283,18 @@ static inline int ip_rcv_finish(struct sk_buff *skb) | |||
283 | { | 283 | { |
284 | struct net_device *dev = skb->dev; | 284 | struct net_device *dev = skb->dev; |
285 | struct iphdr *iph = skb->nh.iph; | 285 | struct iphdr *iph = skb->nh.iph; |
286 | int err; | ||
286 | 287 | ||
287 | /* | 288 | /* |
288 | * Initialise the virtual path cache for the packet. It describes | 289 | * Initialise the virtual path cache for the packet. It describes |
289 | * how the packet travels inside Linux networking. | 290 | * how the packet travels inside Linux networking. |
290 | */ | 291 | */ |
291 | if (skb->dst == NULL) { | 292 | if (skb->dst == NULL) { |
292 | if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) | 293 | if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { |
294 | if (err == -EHOSTUNREACH) | ||
295 | IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); | ||
293 | goto drop; | 296 | goto drop; |
297 | } | ||
294 | } | 298 | } |
295 | 299 | ||
296 | #ifdef CONFIG_NET_CLS_ROUTE | 300 | #ifdef CONFIG_NET_CLS_ROUTE |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ee07aec215a0..6ce5c3292f9f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -188,7 +188,13 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
188 | skb = skb2; | 188 | skb = skb2; |
189 | } | 189 | } |
190 | 190 | ||
191 | nf_reset(skb); | 191 | #ifdef CONFIG_BRIDGE_NETFILTER |
192 | /* bridge-netfilter defers calling some IP hooks to the bridge layer | ||
193 | * and still needs the conntrack reference. | ||
194 | */ | ||
195 | if (skb->nf_bridge == NULL) | ||
196 | #endif | ||
197 | nf_reset(skb); | ||
192 | 198 | ||
193 | if (hh) { | 199 | if (hh) { |
194 | int hh_alen; | 200 | int hh_alen; |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f2509034ce72..d2bf8e1930a3 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -1149,8 +1149,10 @@ static int __init ic_dynamic(void) | |||
1149 | ic_rarp_cleanup(); | 1149 | ic_rarp_cleanup(); |
1150 | #endif | 1150 | #endif |
1151 | 1151 | ||
1152 | if (!ic_got_reply) | 1152 | if (!ic_got_reply) { |
1153 | ic_myaddr = INADDR_NONE; | ||
1153 | return -1; | 1154 | return -1; |
1155 | } | ||
1154 | 1156 | ||
1155 | printk("IP-Config: Got %s answer from %u.%u.%u.%u, ", | 1157 | printk("IP-Config: Got %s answer from %u.%u.%u.%u, ", |
1156 | ((ic_got_reply & IC_RARP) ? "RARP" | 1158 | ((ic_got_reply & IC_RARP) ? "RARP" |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e4f809a93f47..7833d920bdba 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -297,6 +297,7 @@ static int vif_delete(int vifi) | |||
297 | static void ipmr_destroy_unres(struct mfc_cache *c) | 297 | static void ipmr_destroy_unres(struct mfc_cache *c) |
298 | { | 298 | { |
299 | struct sk_buff *skb; | 299 | struct sk_buff *skb; |
300 | struct nlmsgerr *e; | ||
300 | 301 | ||
301 | atomic_dec(&cache_resolve_queue_len); | 302 | atomic_dec(&cache_resolve_queue_len); |
302 | 303 | ||
@@ -306,7 +307,9 @@ static void ipmr_destroy_unres(struct mfc_cache *c) | |||
306 | nlh->nlmsg_type = NLMSG_ERROR; | 307 | nlh->nlmsg_type = NLMSG_ERROR; |
307 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); | 308 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); |
308 | skb_trim(skb, nlh->nlmsg_len); | 309 | skb_trim(skb, nlh->nlmsg_len); |
309 | ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT; | 310 | e = NLMSG_DATA(nlh); |
311 | e->error = -ETIMEDOUT; | ||
312 | memset(&e->msg, 0, sizeof(e->msg)); | ||
310 | netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); | 313 | netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); |
311 | } else | 314 | } else |
312 | kfree_skb(skb); | 315 | kfree_skb(skb); |
@@ -499,6 +502,7 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void) | |||
499 | static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) | 502 | static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) |
500 | { | 503 | { |
501 | struct sk_buff *skb; | 504 | struct sk_buff *skb; |
505 | struct nlmsgerr *e; | ||
502 | 506 | ||
503 | /* | 507 | /* |
504 | * Play the pending entries through our router | 508 | * Play the pending entries through our router |
@@ -515,7 +519,9 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) | |||
515 | nlh->nlmsg_type = NLMSG_ERROR; | 519 | nlh->nlmsg_type = NLMSG_ERROR; |
516 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); | 520 | nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); |
517 | skb_trim(skb, nlh->nlmsg_len); | 521 | skb_trim(skb, nlh->nlmsg_len); |
518 | ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE; | 522 | e = NLMSG_DATA(nlh); |
523 | e->error = -EMSGSIZE; | ||
524 | memset(&e->msg, 0, sizeof(e->msg)); | ||
519 | } | 525 | } |
520 | err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); | 526 | err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); |
521 | } else | 527 | } else |
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index fd6feb5499fe..9f16ab309106 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c | |||
@@ -548,7 +548,6 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp) | |||
548 | { | 548 | { |
549 | if (del_timer(&cp->timer)) | 549 | if (del_timer(&cp->timer)) |
550 | mod_timer(&cp->timer, jiffies); | 550 | mod_timer(&cp->timer, jiffies); |
551 | __ip_vs_conn_put(cp); | ||
552 | } | 551 | } |
553 | 552 | ||
554 | 553 | ||
@@ -764,7 +763,6 @@ void ip_vs_random_dropentry(void) | |||
764 | { | 763 | { |
765 | int idx; | 764 | int idx; |
766 | struct ip_vs_conn *cp; | 765 | struct ip_vs_conn *cp; |
767 | struct ip_vs_conn *ct; | ||
768 | 766 | ||
769 | /* | 767 | /* |
770 | * Randomly scan 1/32 of the whole table every second | 768 | * Randomly scan 1/32 of the whole table every second |
@@ -801,21 +799,12 @@ void ip_vs_random_dropentry(void) | |||
801 | continue; | 799 | continue; |
802 | } | 800 | } |
803 | 801 | ||
804 | /* | ||
805 | * Drop the entry, and drop its ct if not referenced | ||
806 | */ | ||
807 | atomic_inc(&cp->refcnt); | ||
808 | ct_write_unlock(hash); | ||
809 | |||
810 | if ((ct = cp->control)) | ||
811 | atomic_inc(&ct->refcnt); | ||
812 | IP_VS_DBG(4, "del connection\n"); | 802 | IP_VS_DBG(4, "del connection\n"); |
813 | ip_vs_conn_expire_now(cp); | 803 | ip_vs_conn_expire_now(cp); |
814 | if (ct) { | 804 | if (cp->control) { |
815 | IP_VS_DBG(4, "del conn template\n"); | 805 | IP_VS_DBG(4, "del conn template\n"); |
816 | ip_vs_conn_expire_now(ct); | 806 | ip_vs_conn_expire_now(cp->control); |
817 | } | 807 | } |
818 | ct_write_lock(hash); | ||
819 | } | 808 | } |
820 | ct_write_unlock(hash); | 809 | ct_write_unlock(hash); |
821 | } | 810 | } |
@@ -829,7 +818,6 @@ static void ip_vs_conn_flush(void) | |||
829 | { | 818 | { |
830 | int idx; | 819 | int idx; |
831 | struct ip_vs_conn *cp; | 820 | struct ip_vs_conn *cp; |
832 | struct ip_vs_conn *ct; | ||
833 | 821 | ||
834 | flush_again: | 822 | flush_again: |
835 | for (idx=0; idx<IP_VS_CONN_TAB_SIZE; idx++) { | 823 | for (idx=0; idx<IP_VS_CONN_TAB_SIZE; idx++) { |
@@ -839,18 +827,13 @@ static void ip_vs_conn_flush(void) | |||
839 | ct_write_lock_bh(idx); | 827 | ct_write_lock_bh(idx); |
840 | 828 | ||
841 | list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { | 829 | list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { |
842 | atomic_inc(&cp->refcnt); | ||
843 | ct_write_unlock(idx); | ||
844 | 830 | ||
845 | if ((ct = cp->control)) | ||
846 | atomic_inc(&ct->refcnt); | ||
847 | IP_VS_DBG(4, "del connection\n"); | 831 | IP_VS_DBG(4, "del connection\n"); |
848 | ip_vs_conn_expire_now(cp); | 832 | ip_vs_conn_expire_now(cp); |
849 | if (ct) { | 833 | if (cp->control) { |
850 | IP_VS_DBG(4, "del conn template\n"); | 834 | IP_VS_DBG(4, "del conn template\n"); |
851 | ip_vs_conn_expire_now(ct); | 835 | ip_vs_conn_expire_now(cp->control); |
852 | } | 836 | } |
853 | ct_write_lock(idx); | ||
854 | } | 837 | } |
855 | ct_write_unlock_bh(idx); | 838 | ct_write_unlock_bh(idx); |
856 | } | 839 | } |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 9cde8c61f525..6706d3a1bc4f 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> | 30 | #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> |
31 | #include <linux/netfilter_ipv4/ip_conntrack.h> | 31 | #include <linux/netfilter_ipv4/ip_conntrack.h> |
32 | 32 | ||
33 | #define CLUSTERIP_VERSION "0.6" | 33 | #define CLUSTERIP_VERSION "0.7" |
34 | 34 | ||
35 | #define DEBUG_CLUSTERIP | 35 | #define DEBUG_CLUSTERIP |
36 | 36 | ||
@@ -524,8 +524,9 @@ arp_mangle(unsigned int hook, | |||
524 | || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) | 524 | || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) |
525 | return NF_ACCEPT; | 525 | return NF_ACCEPT; |
526 | 526 | ||
527 | /* we only want to mangle arp replies */ | 527 | /* we only want to mangle arp requests and replies */ |
528 | if (arp->ar_op != htons(ARPOP_REPLY)) | 528 | if (arp->ar_op != htons(ARPOP_REPLY) |
529 | && arp->ar_op != htons(ARPOP_REQUEST)) | ||
529 | return NF_ACCEPT; | 530 | return NF_ACCEPT; |
530 | 531 | ||
531 | payload = (void *)(arp+1); | 532 | payload = (void *)(arp+1); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 80cf633d9f4a..12a1cf306f67 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1909,7 +1909,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, | |||
1909 | */ | 1909 | */ |
1910 | if ((err = fib_lookup(&fl, &res)) != 0) { | 1910 | if ((err = fib_lookup(&fl, &res)) != 0) { |
1911 | if (!IN_DEV_FORWARD(in_dev)) | 1911 | if (!IN_DEV_FORWARD(in_dev)) |
1912 | goto e_inval; | 1912 | goto e_hostunreach; |
1913 | goto no_route; | 1913 | goto no_route; |
1914 | } | 1914 | } |
1915 | free_res = 1; | 1915 | free_res = 1; |
@@ -1933,7 +1933,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, | |||
1933 | } | 1933 | } |
1934 | 1934 | ||
1935 | if (!IN_DEV_FORWARD(in_dev)) | 1935 | if (!IN_DEV_FORWARD(in_dev)) |
1936 | goto e_inval; | 1936 | goto e_hostunreach; |
1937 | if (res.type != RTN_UNICAST) | 1937 | if (res.type != RTN_UNICAST) |
1938 | goto martian_destination; | 1938 | goto martian_destination; |
1939 | 1939 | ||
@@ -2025,6 +2025,11 @@ martian_destination: | |||
2025 | "%u.%u.%u.%u, dev %s\n", | 2025 | "%u.%u.%u.%u, dev %s\n", |
2026 | NIPQUAD(daddr), NIPQUAD(saddr), dev->name); | 2026 | NIPQUAD(daddr), NIPQUAD(saddr), dev->name); |
2027 | #endif | 2027 | #endif |
2028 | |||
2029 | e_hostunreach: | ||
2030 | err = -EHOSTUNREACH; | ||
2031 | goto done; | ||
2032 | |||
2028 | e_inval: | 2033 | e_inval: |
2029 | err = -EINVAL; | 2034 | err = -EINVAL; |
2030 | goto done; | 2035 | goto done; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a54d4ef3fd35..77004b9456c0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2777,7 +2777,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
2777 | read_lock_bh(&idev->lock); | 2777 | read_lock_bh(&idev->lock); |
2778 | switch (type) { | 2778 | switch (type) { |
2779 | case UNICAST_ADDR: | 2779 | case UNICAST_ADDR: |
2780 | /* unicast address */ | 2780 | /* unicast address incl. temp addr */ |
2781 | for (ifa = idev->addr_list; ifa; | 2781 | for (ifa = idev->addr_list; ifa; |
2782 | ifa = ifa->if_next, ip_idx++) { | 2782 | ifa = ifa->if_next, ip_idx++) { |
2783 | if (ip_idx < s_ip_idx) | 2783 | if (ip_idx < s_ip_idx) |
@@ -2788,19 +2788,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
2788 | NLM_F_MULTI)) <= 0) | 2788 | NLM_F_MULTI)) <= 0) |
2789 | goto done; | 2789 | goto done; |
2790 | } | 2790 | } |
2791 | /* temp addr */ | ||
2792 | #ifdef CONFIG_IPV6_PRIVACY | ||
2793 | for (ifa = idev->tempaddr_list; ifa; | ||
2794 | ifa = ifa->tmp_next, ip_idx++) { | ||
2795 | if (ip_idx < s_ip_idx) | ||
2796 | continue; | ||
2797 | if ((err = inet6_fill_ifaddr(skb, ifa, | ||
2798 | NETLINK_CB(cb->skb).pid, | ||
2799 | cb->nlh->nlmsg_seq, RTM_NEWADDR, | ||
2800 | NLM_F_MULTI)) <= 0) | ||
2801 | goto done; | ||
2802 | } | ||
2803 | #endif | ||
2804 | break; | 2791 | break; |
2805 | case MULTICAST_ADDR: | 2792 | case MULTICAST_ADDR: |
2806 | /* multicast address */ | 2793 | /* multicast address */ |
@@ -2923,6 +2910,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, | |||
2923 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); | 2910 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); |
2924 | r = NLMSG_DATA(nlh); | 2911 | r = NLMSG_DATA(nlh); |
2925 | r->ifi_family = AF_INET6; | 2912 | r->ifi_family = AF_INET6; |
2913 | r->__ifi_pad = 0; | ||
2926 | r->ifi_type = dev->type; | 2914 | r->ifi_type = dev->type; |
2927 | r->ifi_index = dev->ifindex; | 2915 | r->ifi_index = dev->ifindex; |
2928 | r->ifi_flags = dev_get_flags(dev); | 2916 | r->ifi_flags = dev_get_flags(dev); |
@@ -3030,9 +3018,12 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, | |||
3030 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); | 3018 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); |
3031 | pmsg = NLMSG_DATA(nlh); | 3019 | pmsg = NLMSG_DATA(nlh); |
3032 | pmsg->prefix_family = AF_INET6; | 3020 | pmsg->prefix_family = AF_INET6; |
3021 | pmsg->prefix_pad1 = 0; | ||
3022 | pmsg->prefix_pad2 = 0; | ||
3033 | pmsg->prefix_ifindex = idev->dev->ifindex; | 3023 | pmsg->prefix_ifindex = idev->dev->ifindex; |
3034 | pmsg->prefix_len = pinfo->prefix_len; | 3024 | pmsg->prefix_len = pinfo->prefix_len; |
3035 | pmsg->prefix_type = pinfo->type; | 3025 | pmsg->prefix_type = pinfo->type; |
3026 | pmsg->prefix_pad3 = 0; | ||
3036 | 3027 | ||
3037 | pmsg->prefix_flags = 0; | 3028 | pmsg->prefix_flags = 0; |
3038 | if (pinfo->onlink) | 3029 | if (pinfo->onlink) |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 0e5f7499debb..b6c73da5ff35 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -244,7 +244,6 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, | |||
244 | opt_space->opt_nflen = 0; | 244 | opt_space->opt_nflen = 0; |
245 | } | 245 | } |
246 | opt_space->dst1opt = fopt->dst1opt; | 246 | opt_space->dst1opt = fopt->dst1opt; |
247 | opt_space->auth = fopt->auth; | ||
248 | opt_space->opt_flen = fopt->opt_flen; | 247 | opt_space->opt_flen = fopt->opt_flen; |
249 | return opt_space; | 248 | return opt_space; |
250 | } | 249 | } |
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 9594206e6035..249c61936ea0 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -439,6 +439,8 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, | |||
439 | 439 | ||
440 | t = NLMSG_DATA(nlh); | 440 | t = NLMSG_DATA(nlh); |
441 | t->tca_family = AF_UNSPEC; | 441 | t->tca_family = AF_UNSPEC; |
442 | t->tca__pad1 = 0; | ||
443 | t->tca__pad2 = 0; | ||
442 | 444 | ||
443 | x = (struct rtattr*) skb->tail; | 445 | x = (struct rtattr*) skb->tail; |
444 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); | 446 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); |
@@ -580,6 +582,8 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) | |||
580 | nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); | 582 | nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); |
581 | t = NLMSG_DATA(nlh); | 583 | t = NLMSG_DATA(nlh); |
582 | t->tca_family = AF_UNSPEC; | 584 | t->tca_family = AF_UNSPEC; |
585 | t->tca__pad1 = 0; | ||
586 | t->tca__pad2 = 0; | ||
583 | 587 | ||
584 | x = (struct rtattr *) skb->tail; | 588 | x = (struct rtattr *) skb->tail; |
585 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); | 589 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); |
@@ -687,7 +691,9 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, | |||
687 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); | 691 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); |
688 | t = NLMSG_DATA(nlh); | 692 | t = NLMSG_DATA(nlh); |
689 | t->tca_family = AF_UNSPEC; | 693 | t->tca_family = AF_UNSPEC; |
690 | 694 | t->tca__pad1 = 0; | |
695 | t->tca__pad2 = 0; | ||
696 | |||
691 | x = (struct rtattr*) skb->tail; | 697 | x = (struct rtattr*) skb->tail; |
692 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); | 698 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); |
693 | 699 | ||
@@ -842,6 +848,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
842 | cb->nlh->nlmsg_type, sizeof(*t)); | 848 | cb->nlh->nlmsg_type, sizeof(*t)); |
843 | t = NLMSG_DATA(nlh); | 849 | t = NLMSG_DATA(nlh); |
844 | t->tca_family = AF_UNSPEC; | 850 | t->tca_family = AF_UNSPEC; |
851 | t->tca__pad1 = 0; | ||
852 | t->tca__pad2 = 0; | ||
845 | 853 | ||
846 | x = (struct rtattr *) skb->tail; | 854 | x = (struct rtattr *) skb->tail; |
847 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); | 855 | RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 1616bf5c9627..3b5714ef4d1a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -331,6 +331,8 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh, | |||
331 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); | 331 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); |
332 | tcm = NLMSG_DATA(nlh); | 332 | tcm = NLMSG_DATA(nlh); |
333 | tcm->tcm_family = AF_UNSPEC; | 333 | tcm->tcm_family = AF_UNSPEC; |
334 | tcm->tcm__pad1 = 0; | ||
335 | tcm->tcm__pad1 = 0; | ||
334 | tcm->tcm_ifindex = tp->q->dev->ifindex; | 336 | tcm->tcm_ifindex = tp->q->dev->ifindex; |
335 | tcm->tcm_parent = tp->classid; | 337 | tcm->tcm_parent = tp->classid; |
336 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); | 338 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); |
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 232fb9196810..006168d69376 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h | |||
@@ -618,6 +618,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, | |||
618 | pinfo.protocol = s->protocol; | 618 | pinfo.protocol = s->protocol; |
619 | pinfo.tunnelid = s->tunnelid; | 619 | pinfo.tunnelid = s->tunnelid; |
620 | pinfo.tunnelhdr = f->tunnelhdr; | 620 | pinfo.tunnelhdr = f->tunnelhdr; |
621 | pinfo.pad = 0; | ||
621 | RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); | 622 | RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); |
622 | if (f->res.classid) | 623 | if (f->res.classid) |
623 | RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); | 624 | RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 97c1c75d5c78..05e6e0a799da 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -770,6 +770,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, | |||
770 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); | 770 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); |
771 | tcm = NLMSG_DATA(nlh); | 771 | tcm = NLMSG_DATA(nlh); |
772 | tcm->tcm_family = AF_UNSPEC; | 772 | tcm->tcm_family = AF_UNSPEC; |
773 | tcm->tcm__pad1 = 0; | ||
774 | tcm->tcm__pad2 = 0; | ||
773 | tcm->tcm_ifindex = q->dev->ifindex; | 775 | tcm->tcm_ifindex = q->dev->ifindex; |
774 | tcm->tcm_parent = clid; | 776 | tcm->tcm_parent = clid; |
775 | tcm->tcm_handle = q->handle; | 777 | tcm->tcm_handle = q->handle; |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index d43e3b8cbf6a..09453f997d8c 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -1528,6 +1528,7 @@ static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl) | |||
1528 | 1528 | ||
1529 | opt.strategy = cl->ovl_strategy; | 1529 | opt.strategy = cl->ovl_strategy; |
1530 | opt.priority2 = cl->priority2+1; | 1530 | opt.priority2 = cl->priority2+1; |
1531 | opt.pad = 0; | ||
1531 | opt.penalty = (cl->penalty*1000)/HZ; | 1532 | opt.penalty = (cl->penalty*1000)/HZ; |
1532 | RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt); | 1533 | RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt); |
1533 | return skb->len; | 1534 | return skb->len; |
@@ -1563,6 +1564,8 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl) | |||
1563 | 1564 | ||
1564 | if (cl->police) { | 1565 | if (cl->police) { |
1565 | opt.police = cl->police; | 1566 | opt.police = cl->police; |
1567 | opt.__res1 = 0; | ||
1568 | opt.__res2 = 0; | ||
1566 | RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt); | 1569 | RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt); |
1567 | } | 1570 | } |
1568 | return skb->len; | 1571 | return skb->len; |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 2ec0320fac3b..c44bf4165c6e 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -102,9 +102,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
102 | /* Set up the base timeout information. */ | 102 | /* Set up the base timeout information. */ |
103 | ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; | 103 | ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; |
104 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = | 104 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = |
105 | SCTP_DEFAULT_TIMEOUT_T1_COOKIE; | 105 | msecs_to_jiffies(sp->rtoinfo.srto_initial); |
106 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = | 106 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = |
107 | SCTP_DEFAULT_TIMEOUT_T1_INIT; | 107 | msecs_to_jiffies(sp->rtoinfo.srto_initial); |
108 | ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = | 108 | ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = |
109 | msecs_to_jiffies(sp->rtoinfo.srto_initial); | 109 | msecs_to_jiffies(sp->rtoinfo.srto_initial); |
110 | ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; | 110 | ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; |
@@ -117,12 +117,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
117 | ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] | 117 | ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] |
118 | = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); | 118 | = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); |
119 | 119 | ||
120 | ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = | 120 | ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
121 | SCTP_DEFAULT_TIMEOUT_HEARTBEAT; | 121 | ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout; |
122 | ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | 122 | ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; |
123 | SCTP_DEFAULT_TIMEOUT_SACK; | ||
124 | ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | ||
125 | sp->autoclose * HZ; | ||
126 | 123 | ||
127 | /* Use SCTP specific send buffer space queues. */ | 124 | /* Use SCTP specific send buffer space queues. */ |
128 | ep->sndbuf_policy = sctp_sndbuf_policy; | 125 | ep->sndbuf_policy = sctp_sndbuf_policy; |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5135e1a25d25..e7f37faba7c0 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1050,7 +1050,10 @@ SCTP_STATIC __init int sctp_init(void) | |||
1050 | sctp_sndbuf_policy = 0; | 1050 | sctp_sndbuf_policy = 0; |
1051 | 1051 | ||
1052 | /* HB.interval - 30 seconds */ | 1052 | /* HB.interval - 30 seconds */ |
1053 | sctp_hb_interval = 30 * HZ; | 1053 | sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; |
1054 | |||
1055 | /* delayed SACK timeout */ | ||
1056 | sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK; | ||
1054 | 1057 | ||
1055 | /* Implementation specific variables. */ | 1058 | /* Implementation specific variables. */ |
1056 | 1059 | ||
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 7fc31849312b..dc4893474f18 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -47,6 +47,8 @@ | |||
47 | static ctl_handler sctp_sysctl_jiffies_ms; | 47 | static ctl_handler sctp_sysctl_jiffies_ms; |
48 | static long rto_timer_min = 1; | 48 | static long rto_timer_min = 1; |
49 | static long rto_timer_max = 86400000; /* One day */ | 49 | static long rto_timer_max = 86400000; /* One day */ |
50 | static long sack_timer_min = 1; | ||
51 | static long sack_timer_max = 500; | ||
50 | 52 | ||
51 | static ctl_table sctp_table[] = { | 53 | static ctl_table sctp_table[] = { |
52 | { | 54 | { |
@@ -187,6 +189,17 @@ static ctl_table sctp_table[] = { | |||
187 | .mode = 0644, | 189 | .mode = 0644, |
188 | .proc_handler = &proc_dointvec | 190 | .proc_handler = &proc_dointvec |
189 | }, | 191 | }, |
192 | { | ||
193 | .ctl_name = NET_SCTP_SACK_TIMEOUT, | ||
194 | .procname = "sack_timeout", | ||
195 | .data = &sctp_sack_timeout, | ||
196 | .maxlen = sizeof(long), | ||
197 | .mode = 0644, | ||
198 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | ||
199 | .strategy = &sctp_sysctl_jiffies_ms, | ||
200 | .extra1 = &sack_timer_min, | ||
201 | .extra2 = &sack_timer_max, | ||
202 | }, | ||
190 | { .ctl_name = 0 } | 203 | { .ctl_name = 0 } |
191 | }; | 204 | }; |
192 | 205 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 0ec0fde6e6c5..a63b69179607 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -103,7 +103,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
103 | 103 | ||
104 | /* Set up the heartbeat timer. */ | 104 | /* Set up the heartbeat timer. */ |
105 | init_timer(&peer->hb_timer); | 105 | init_timer(&peer->hb_timer); |
106 | peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; | ||
107 | peer->hb_timer.function = sctp_generate_heartbeat_event; | 106 | peer->hb_timer.function = sctp_generate_heartbeat_event; |
108 | peer->hb_timer.data = (unsigned long)peer; | 107 | peer->hb_timer.data = (unsigned long)peer; |
109 | 108 | ||