diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-11 12:51:40 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-11 12:51:40 -0400 |
commit | 10a5fd5e6b7e2d464c9f95f67cade4ddbd63f4e1 (patch) | |
tree | eddf856286234f28cac747d20eb59d918e1bc8b5 | |
parent | c2a6585296009379e0f4eff39cdcb108b457ebf2 (diff) | |
parent | a145410dccdb44f81d3b56763ef9b6f721f4e47c (diff) |
Merge branch 'master'
Conflicts:
drivers/scsi/libata-scsi.c
include/linux/libata.h
500 files changed, 7795 insertions, 7424 deletions
@@ -3382,7 +3382,7 @@ S: Germany | |||
3382 | 3382 | ||
3383 | N: Geert Uytterhoeven | 3383 | N: Geert Uytterhoeven |
3384 | E: geert@linux-m68k.org | 3384 | E: geert@linux-m68k.org |
3385 | W: http://home.tvd.be/cr26864/ | 3385 | W: http://users.telenet.be/geertu/ |
3386 | P: 1024/862678A6 C51D 361C 0BD1 4C90 B275 C553 6EEA 11BA 8626 78A6 | 3386 | P: 1024/862678A6 C51D 361C 0BD1 4C90 B275 C553 6EEA 11BA 8626 78A6 |
3387 | D: m68k/Amiga and PPC/CHRP Longtrail coordinator | 3387 | D: m68k/Amiga and PPC/CHRP Longtrail coordinator |
3388 | D: Frame buffer device and XF68_FBDev maintainer | 3388 | D: Frame buffer device and XF68_FBDev maintainer |
@@ -3392,8 +3392,8 @@ D: Amiga Buddha and Catweasel chipset IDE | |||
3392 | D: Atari Falcon chipset IDE | 3392 | D: Atari Falcon chipset IDE |
3393 | D: Amiga Gayle chipset IDE | 3393 | D: Amiga Gayle chipset IDE |
3394 | D: mipsel NEC DDB Vrc-5074 | 3394 | D: mipsel NEC DDB Vrc-5074 |
3395 | S: Emiel Vlieberghlaan 2A/21 | 3395 | S: Haterbeekstraat 55B |
3396 | S: B-3010 Kessel-Lo | 3396 | S: B-3200 Aarschot |
3397 | S: Belgium | 3397 | S: Belgium |
3398 | 3398 | ||
3399 | N: Chris Vance | 3399 | N: Chris Vance |
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt index ee4bb73683cd..10bf4deb96aa 100644 --- a/Documentation/DMA-mapping.txt +++ b/Documentation/DMA-mapping.txt | |||
@@ -194,7 +194,7 @@ document for how to handle this case. | |||
194 | Finally, if your device can only drive the low 24-bits of | 194 | Finally, if your device can only drive the low 24-bits of |
195 | address during PCI bus mastering you might do something like: | 195 | address during PCI bus mastering you might do something like: |
196 | 196 | ||
197 | if (pci_set_dma_mask(pdev, 0x00ffffff)) { | 197 | if (pci_set_dma_mask(pdev, DMA_24BIT_MASK)) { |
198 | printk(KERN_WARNING | 198 | printk(KERN_WARNING |
199 | "mydev: 24-bit DMA addressing not available.\n"); | 199 | "mydev: 24-bit DMA addressing not available.\n"); |
200 | goto ignore_this_device; | 200 | goto ignore_this_device; |
@@ -212,7 +212,7 @@ functions (for example a sound card provides playback and record | |||
212 | functions) and the various different functions have _different_ | 212 | functions) and the various different functions have _different_ |
213 | DMA addressing limitations, you may wish to probe each mask and | 213 | DMA addressing limitations, you may wish to probe each mask and |
214 | only provide the functionality which the machine can handle. It | 214 | only provide the functionality which the machine can handle. It |
215 | is important that the last call to pci_set_dma_mask() be for the | 215 | is important that the last call to pci_set_dma_mask() be for the |
216 | most specific mask. | 216 | most specific mask. |
217 | 217 | ||
218 | Here is pseudo-code showing how this might be done: | 218 | Here is pseudo-code showing how this might be done: |
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 5bcbb6ee3bc0..f869b03929db 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl | |||
@@ -705,7 +705,7 @@ and other resources, etc. | |||
705 | 705 | ||
706 | <sect1><title>ata_scsi_error()</title> | 706 | <sect1><title>ata_scsi_error()</title> |
707 | <para> | 707 | <para> |
708 | ata_scsi_error() is the current hostt->eh_strategy_handler() | 708 | ata_scsi_error() is the current transportt->eh_strategy_handler() |
709 | for libata. As discussed above, this will be entered in two | 709 | for libata. As discussed above, this will be entered in two |
710 | cases - timeout and ATAPI error completion. This function | 710 | cases - timeout and ATAPI error completion. This function |
711 | calls low level libata driver's eng_timeout() callback, the | 711 | calls low level libata driver's eng_timeout() callback, the |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 59d0c74c79c9..293fed113dff 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -71,14 +71,6 @@ Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br> | |||
71 | 71 | ||
72 | --------------------------- | 72 | --------------------------- |
73 | 73 | ||
74 | What: remove EXPORT_SYMBOL(panic_timeout) | ||
75 | When: April 2006 | ||
76 | Files: kernel/panic.c | ||
77 | Why: No modular usage in the kernel. | ||
78 | Who: Adrian Bunk <bunk@stusta.de> | ||
79 | |||
80 | --------------------------- | ||
81 | |||
82 | What: remove EXPORT_SYMBOL(insert_resource) | 74 | What: remove EXPORT_SYMBOL(insert_resource) |
83 | When: April 2006 | 75 | When: April 2006 |
84 | Files: kernel/resource.c | 76 | Files: kernel/resource.c |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index adaa899e5c90..3a2e5520c1e3 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -694,7 +694,7 @@ struct file_operations | |||
694 | ---------------------- | 694 | ---------------------- |
695 | 695 | ||
696 | This describes how the VFS can manipulate an open file. As of kernel | 696 | This describes how the VFS can manipulate an open file. As of kernel |
697 | 2.6.13, the following members are defined: | 697 | 2.6.17, the following members are defined: |
698 | 698 | ||
699 | struct file_operations { | 699 | struct file_operations { |
700 | loff_t (*llseek) (struct file *, loff_t, int); | 700 | loff_t (*llseek) (struct file *, loff_t, int); |
@@ -723,6 +723,10 @@ struct file_operations { | |||
723 | int (*check_flags)(int); | 723 | int (*check_flags)(int); |
724 | int (*dir_notify)(struct file *filp, unsigned long arg); | 724 | int (*dir_notify)(struct file *filp, unsigned long arg); |
725 | int (*flock) (struct file *, int, struct file_lock *); | 725 | int (*flock) (struct file *, int, struct file_lock *); |
726 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned | ||
727 | int); | ||
728 | ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned | ||
729 | int); | ||
726 | }; | 730 | }; |
727 | 731 | ||
728 | Again, all methods are called without any locks being held, unless | 732 | Again, all methods are called without any locks being held, unless |
@@ -790,6 +794,12 @@ otherwise noted. | |||
790 | 794 | ||
791 | flock: called by the flock(2) system call | 795 | flock: called by the flock(2) system call |
792 | 796 | ||
797 | splice_write: called by the VFS to splice data from a pipe to a file. This | ||
798 | method is used by the splice(2) system call | ||
799 | |||
800 | splice_read: called by the VFS to splice data from file to a pipe. This | ||
801 | method is used by the splice(2) system call | ||
802 | |||
793 | Note that the file operations are implemented by the specific | 803 | Note that the file operations are implemented by the specific |
794 | filesystem in which the inode resides. When opening a device node | 804 | filesystem in which the inode resides. When opening a device node |
795 | (character or block special) most filesystems will call special | 805 | (character or block special) most filesystems will call special |
diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset new file mode 100644 index 000000000000..85a64defd385 --- /dev/null +++ b/Documentation/isdn/README.gigaset | |||
@@ -0,0 +1,286 @@ | |||
1 | GigaSet 307x Device Driver | ||
2 | ========================== | ||
3 | |||
4 | 1. Requirements | ||
5 | ------------ | ||
6 | 1.1. Hardware | ||
7 | -------- | ||
8 | This release supports the connection of the Gigaset 307x/417x family of | ||
9 | ISDN DECT bases via Gigaset M101 Data, Gigaset M105 Data or direct USB | ||
10 | connection. The following devices are reported to be compatible: | ||
11 | 307x/417x: | ||
12 | Gigaset SX255isdn | ||
13 | Gigaset SX353isdn | ||
14 | Sinus 45 [AB] isdn (Deutsche Telekom) | ||
15 | Sinus 721X/XA | ||
16 | Vox Chicago 390 ISDN (KPN Telecom) | ||
17 | M101: | ||
18 | Sinus 45 Data 1 (Telekom) | ||
19 | M105: | ||
20 | Gigaset USB Adapter DECT | ||
21 | Sinus 45 Data 2 (Telekom) | ||
22 | Sinus 721 data | ||
23 | Chicago 390 USB (KPN) | ||
24 | See also http://www.erbze.info/sinus_gigaset.htm and | ||
25 | http://gigaset307x.sourceforge.net/ | ||
26 | |||
27 | We had also reports from users of Gigaset M105 who could use the drivers | ||
28 | with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.4.) | ||
29 | If you have another device that works with our driver, please let us know. | ||
30 | For example, Gigaset SX205isdn/Sinus 721 X SE and Gigaset SX303isdn bases | ||
31 | are just versions without answering machine of models known to work, so | ||
32 | they should work just as well; but so far we are lacking positive reports | ||
33 | on these. | ||
34 | |||
35 | Chances of getting an USB device to work are good if the output of | ||
36 | lsusb | ||
37 | at the command line contains one of the following: | ||
38 | ID 0681:0001 | ||
39 | ID 0681:0002 | ||
40 | ID 0681:0009 | ||
41 | ID 0681:0021 | ||
42 | ID 0681:0022 | ||
43 | |||
44 | 1.2. Software | ||
45 | -------- | ||
46 | The driver works with ISDN4linux and so can be used with any software | ||
47 | which is able to use ISDN4linux for ISDN connections (voice or data). | ||
48 | CAPI4Linux support is planned but not yet available. | ||
49 | |||
50 | There are some user space tools available at | ||
51 | http://sourceforge.net/projects/gigaset307x/ | ||
52 | which provide access to additional device specific functions like SMS, | ||
53 | phonebook or call journal. | ||
54 | |||
55 | |||
56 | 2. How to use the driver | ||
57 | --------------------- | ||
58 | 2.1. Modules | ||
59 | ------- | ||
60 | To get the device working, you have to load the proper kernel module. You | ||
61 | can do this using | ||
62 | modprobe modulename | ||
63 | where modulename is usb_gigaset (M105) or bas_gigaset (direct USB | ||
64 | connection to the base). | ||
65 | |||
66 | 2.2. Device nodes for user space programs | ||
67 | ------------------------------------ | ||
68 | The device can be accessed from user space (eg. by the user space tools | ||
69 | mentioned in 1.2.) through the device nodes: | ||
70 | |||
71 | - /dev/ttyGU0 for M105 (USB data boxes) | ||
72 | - /dev/ttyGB0 for the base driver (direct USB connection) | ||
73 | |||
74 | You can also select a "default device" which is used by the frontends when | ||
75 | no device node is given as parameter, by creating a symlink /dev/ttyG to | ||
76 | one of them, eg.: | ||
77 | |||
78 | ln -s /dev/ttyGB0 /dev/ttyG | ||
79 | |||
80 | 2.3. ISDN4linux | ||
81 | ---------- | ||
82 | This is the "normal" mode of operation. After loading the module you can | ||
83 | set up the ISDN system just as you'd do with any ISDN card. | ||
84 | Your distribution should provide some configuration utility. | ||
85 | If not, you can use some HOWTOs like | ||
86 | http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html | ||
87 | If this doesn't work, because you have some recent device like SX100 where | ||
88 | debug output (see section 3.2.) shows something like this when dialing | ||
89 | CMD Received: ERROR | ||
90 | Available Params: 0 | ||
91 | Connection State: 0, Response: -1 | ||
92 | gigaset_process_response: resp_code -1 in ConState 0 ! | ||
93 | Timeout occurred | ||
94 | you might need to use unimodem mode: | ||
95 | |||
96 | 2.4. Unimodem mode | ||
97 | ------------- | ||
98 | This is needed for some devices [e.g. SX100] as they have problems with | ||
99 | the "normal" commands. | ||
100 | |||
101 | If you have installed the command line tool gigacontr, you can enter | ||
102 | unimodem mode using | ||
103 | gigacontr --mode unimodem | ||
104 | You can switch back using | ||
105 | gigacontr --mode isdn | ||
106 | |||
107 | You can also load the driver using e.g. | ||
108 | modprobe usb_gigaset startmode=0 | ||
109 | to prevent the driver from starting in "isdn4linux mode". | ||
110 | |||
111 | In this mode the device works like a modem connected to a serial port | ||
112 | (the /dev/ttyGU0, ... mentioned above) which understands the commands | ||
113 | ATZ init, reset | ||
114 | => OK or ERROR | ||
115 | ATD | ||
116 | ATDT dial | ||
117 | => OK, CONNECT, | ||
118 | BUSY, | ||
119 | NO DIAL TONE, | ||
120 | NO CARRIER, | ||
121 | NO ANSWER | ||
122 | <pause>+++<pause> change to command mode when connected | ||
123 | ATH hangup | ||
124 | |||
125 | You can use some configuration tool of your distribution to configure this | ||
126 | "modem" or configure pppd/wvdial manually. There are some example ppp | ||
127 | configuration files and chat scripts in the gigaset-VERSION/ppp directory. | ||
128 | Please note that the USB drivers are not able to change the state of the | ||
129 | control lines (the M105 driver can be configured to use some undocumented | ||
130 | control requests, if you really need the control lines, though). This means | ||
131 | you must use "Stupid Mode" if you are using wvdial or you should use the | ||
132 | nocrtscts option of pppd. | ||
133 | You must also assure that the ppp_async module is loaded with the parameter | ||
134 | flag_time=0. You can do this e.g. by adding a line like | ||
135 | |||
136 | options ppp_async flag_time=0 | ||
137 | |||
138 | to /etc/modprobe.conf. If your distribution has some local module | ||
139 | configuration file like /etc/modprobe.conf.local, | ||
140 | using that should be preferred. | ||
141 | |||
142 | 2.5. Call-ID (CID) mode | ||
143 | ------------------ | ||
144 | Call-IDs are numbers used to tag commands to, and responses from, the | ||
145 | Gigaset base in order to support the simultaneous handling of multiple | ||
146 | ISDN calls. Their use can be enabled ("CID mode") or disabled ("Unimodem | ||
147 | mode"). Without Call-IDs (in Unimodem mode), only a very limited set of | ||
148 | functions is available. It allows outgoing data connections only, but | ||
149 | does not signal incoming calls or other base events. | ||
150 | |||
151 | DECT cordless data devices (M10x) permanently occupy the cordless | ||
152 | connection to the base while Call-IDs are activated. As the Gigaset | ||
153 | bases only support one DECT data connection at a time, this prevents | ||
154 | other DECT cordless data devices from accessing the base. | ||
155 | |||
156 | During active operation, the driver switches to the necessary mode | ||
157 | automatically. However, for the reasons above, the mode chosen when | ||
158 | the device is not in use (idle) can be selected by the user. | ||
159 | - If you want to receive incoming calls, you can use the default | ||
160 | settings (CID mode). | ||
161 | - If you have several DECT data devices (M10x) which you want to use | ||
162 | in turn, select Unimodem mode by passing the parameter "cidmode=0" to | ||
163 | the driver ("modprobe usb_gigaset cidmode=0" or modprobe.conf). | ||
164 | |||
165 | If you want both of these at once, you are out of luck. | ||
166 | |||
167 | You can also use /sys/module/<name>/parameters/cidmode for changing | ||
168 | the CID mode setting (<name> is usb_gigaset or bas_gigaset). | ||
169 | |||
170 | |||
171 | 3. Troubleshooting | ||
172 | --------------- | ||
173 | 3.1. Solutions to frequently reported problems | ||
174 | ----------------------------------------- | ||
175 | Problem: | ||
176 | You have a slow provider and isdn4linux gives up dialing too early. | ||
177 | Solution: | ||
178 | Load the isdn module using the dialtimeout option. You can do this e.g. | ||
179 | by adding a line like | ||
180 | |||
181 | options isdn dialtimeout=15 | ||
182 | |||
183 | to /etc/modprobe.conf. If your distribution has some local module | ||
184 | configuration file like /etc/modprobe.conf.local, | ||
185 | using that should be preferred. | ||
186 | |||
187 | Problem: | ||
188 | Your isdn script aborts with a message about isdnlog. | ||
189 | Solution: | ||
190 | Try deactivating (or commenting out) isdnlog. This driver does not | ||
191 | support it. | ||
192 | |||
193 | Problem: | ||
194 | You have two or more DECT data adapters (M101/M105) and only the | ||
195 | first one you turn on works. | ||
196 | Solution: | ||
197 | Select Unimodem mode for all DECT data adapters. (see section 2.4.) | ||
198 | |||
199 | 3.2. Telling the driver to provide more information | ||
200 | ---------------------------------------------- | ||
201 | Building the driver with the "Gigaset debugging" kernel configuration | ||
202 | option (CONFIG_GIGASET_DEBUG) gives it the ability to produce additional | ||
203 | information useful for debugging. | ||
204 | |||
205 | You can control the amount of debugging information the driver produces by | ||
206 | writing an appropriate value to /sys/module/gigaset/parameters/debug, e.g. | ||
207 | echo 0 > /sys/module/gigaset/parameters/debug | ||
208 | switches off debugging output completely, | ||
209 | echo 0x10a020 > /sys/module/gigaset/parameters/debug | ||
210 | enables the standard set of debugging output messages. These values are | ||
211 | bit patterns where every bit controls a certain type of debugging output. | ||
212 | See the constants DEBUG_* in the source file gigaset.h for details. | ||
213 | |||
214 | The initial value can be set using the debug parameter when loading the | ||
215 | module "gigaset", e.g. by adding a line | ||
216 | options gigaset debug=0 | ||
217 | to /etc/modprobe.conf, ... | ||
218 | |||
219 | Generated debugging information can be found | ||
220 | - as output of the command | ||
221 | dmesg | ||
222 | - in system log files written by your syslog daemon, usually | ||
223 | in /var/log/, e.g. /var/log/messages. | ||
224 | |||
225 | 3.3. Reporting problems and bugs | ||
226 | --------------------------- | ||
227 | If you can't solve problems with the driver on your own, feel free to | ||
228 | use one of the forums, bug trackers, or mailing lists on | ||
229 | http://sourceforge.net/projects/gigaset307x | ||
230 | or write an electronic mail to the maintainers. | ||
231 | |||
232 | Try to provide as much information as possible, such as | ||
233 | - distribution | ||
234 | - kernel version (uname -r) | ||
235 | - gcc version (gcc --version) | ||
236 | - hardware architecture (uname -m, ...) | ||
237 | - type and firmware version of your device (base and wireless module, | ||
238 | if any) | ||
239 | - output of "lsusb -v" (if using an USB device) | ||
240 | - error messages | ||
241 | - relevant system log messages (it would help if you activate debug | ||
242 | output as described in 3.2.) | ||
243 | |||
244 | For help with general configuration problems not specific to our driver, | ||
245 | such as isdn4linux and network configuration issues, please refer to the | ||
246 | appropriate forums and newsgroups. | ||
247 | |||
248 | 3.4. Reporting problem solutions | ||
249 | --------------------------- | ||
250 | If you solved a problem with our drivers, wrote startup scripts for your | ||
251 | distribution, ... feel free to contact us (using one of the places | ||
252 | mentioned in 3.3.). We'd like to add scripts, hints, documentation | ||
253 | to the driver and/or the project web page. | ||
254 | |||
255 | |||
256 | 4. Links, other software | ||
257 | --------------------- | ||
258 | - Sourceforge project developing this driver and associated tools | ||
259 | http://sourceforge.net/projects/gigaset307x | ||
260 | - Yahoo! Group on the Siemens Gigaset family of devices | ||
261 | http://de.groups.yahoo.com/group/Siemens-Gigaset | ||
262 | - Siemens Gigaset/T-Sinus compatibility table | ||
263 | http://www.erbze.info/sinus_gigaset.htm | ||
264 | |||
265 | |||
266 | 5. Credits | ||
267 | ------- | ||
268 | Thanks to | ||
269 | |||
270 | Karsten Keil | ||
271 | for his help with isdn4linux | ||
272 | Deti Fliegl | ||
273 | for his base driver code | ||
274 | Dennis Dietrich | ||
275 | for his kernel 2.6 patches | ||
276 | Andreas Rummel | ||
277 | for his work and logs to get unimodem mode working | ||
278 | Andreas Degert | ||
279 | for his logs and patches to get cx 100 working | ||
280 | Dietrich Feist | ||
281 | for his generous donation of one M105 and two M101 cordless adapters | ||
282 | Christoph Schweers | ||
283 | for his generous donation of a M34 device | ||
284 | |||
285 | and all the other people who sent logs and other information. | ||
286 | |||
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt index fcccf2432f98..61fc079eb966 100644 --- a/Documentation/kbuild/modules.txt +++ b/Documentation/kbuild/modules.txt | |||
@@ -44,7 +44,7 @@ What is covered within this file is mainly information to authors | |||
44 | of modules. The author of an external modules should supply | 44 | of modules. The author of an external modules should supply |
45 | a makefile that hides most of the complexity so one only has to type | 45 | a makefile that hides most of the complexity so one only has to type |
46 | 'make' to build the module. A complete example will be present in | 46 | 'make' to build the module. A complete example will be present in |
47 | chapter ¤. Creating a kbuild file for an external module". | 47 | chapter 4, "Creating a kbuild file for an external module". |
48 | 48 | ||
49 | 49 | ||
50 | === 2. How to build external modules | 50 | === 2. How to build external modules |
diff --git a/Documentation/laptop-mode.txt b/Documentation/laptop-mode.txt index b18e21675906..5696e879449b 100644 --- a/Documentation/laptop-mode.txt +++ b/Documentation/laptop-mode.txt | |||
@@ -919,11 +919,11 @@ int main(int argc, char **argv) | |||
919 | int settle_time = 60; | 919 | int settle_time = 60; |
920 | 920 | ||
921 | /* Parse the simple command-line */ | 921 | /* Parse the simple command-line */ |
922 | if (ac == 2) | 922 | if (argc == 2) |
923 | disk = av[1]; | 923 | disk = argv[1]; |
924 | else if (ac == 4) { | 924 | else if (argc == 4) { |
925 | settle_time = atoi(av[2]); | 925 | settle_time = atoi(argv[2]); |
926 | disk = av[3]; | 926 | disk = argv[3]; |
927 | } else | 927 | } else |
928 | usage(); | 928 | usage(); |
929 | 929 | ||
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index f8550310a6d5..92f0056d928c 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt | |||
@@ -610,6 +610,7 @@ loads. Consider the following sequence of events: | |||
610 | 610 | ||
611 | CPU 1 CPU 2 | 611 | CPU 1 CPU 2 |
612 | ======================= ======================= | 612 | ======================= ======================= |
613 | { B = 7; X = 9; Y = 8; C = &Y } | ||
613 | STORE A = 1 | 614 | STORE A = 1 |
614 | STORE B = 2 | 615 | STORE B = 2 |
615 | <write barrier> | 616 | <write barrier> |
@@ -651,7 +652,20 @@ In the above example, CPU 2 perceives that B is 7, despite the load of *C | |||
651 | (which would be B) coming after the the LOAD of C. | 652 | (which would be B) coming after the the LOAD of C. |
652 | 653 | ||
653 | If, however, a data dependency barrier were to be placed between the load of C | 654 | If, however, a data dependency barrier were to be placed between the load of C |
654 | and the load of *C (ie: B) on CPU 2, then the following will occur: | 655 | and the load of *C (ie: B) on CPU 2: |
656 | |||
657 | CPU 1 CPU 2 | ||
658 | ======================= ======================= | ||
659 | { B = 7; X = 9; Y = 8; C = &Y } | ||
660 | STORE A = 1 | ||
661 | STORE B = 2 | ||
662 | <write barrier> | ||
663 | STORE C = &B LOAD X | ||
664 | STORE D = 4 LOAD C (gets &B) | ||
665 | <data dependency barrier> | ||
666 | LOAD *C (reads B) | ||
667 | |||
668 | then the following will occur: | ||
655 | 669 | ||
656 | +-------+ : : : : | 670 | +-------+ : : : : |
657 | | | +------+ +-------+ | 671 | | | +------+ +-------+ |
@@ -829,8 +843,8 @@ There are some more advanced barrier functions: | |||
829 | (*) smp_mb__after_atomic_inc(); | 843 | (*) smp_mb__after_atomic_inc(); |
830 | 844 | ||
831 | These are for use with atomic add, subtract, increment and decrement | 845 | These are for use with atomic add, subtract, increment and decrement |
832 | functions, especially when used for reference counting. These functions | 846 | functions that don't return a value, especially when used for reference |
833 | do not imply memory barriers. | 847 | counting. These functions do not imply memory barriers. |
834 | 848 | ||
835 | As an example, consider a piece of code that marks an object as being dead | 849 | As an example, consider a piece of code that marks an object as being dead |
836 | and then decrements the object's reference count: | 850 | and then decrements the object's reference count: |
@@ -1263,15 +1277,17 @@ else. | |||
1263 | ATOMIC OPERATIONS | 1277 | ATOMIC OPERATIONS |
1264 | ----------------- | 1278 | ----------------- |
1265 | 1279 | ||
1266 | Though they are technically interprocessor interaction considerations, atomic | 1280 | Whilst they are technically interprocessor interaction considerations, atomic |
1267 | operations are noted specially as they do _not_ generally imply memory | 1281 | operations are noted specially as some of them imply full memory barriers and |
1268 | barriers. The possible offenders include: | 1282 | some don't, but they're very heavily relied on as a group throughout the |
1283 | kernel. | ||
1284 | |||
1285 | Any atomic operation that modifies some state in memory and returns information | ||
1286 | about the state (old or new) implies an SMP-conditional general memory barrier | ||
1287 | (smp_mb()) on each side of the actual operation. These include: | ||
1269 | 1288 | ||
1270 | xchg(); | 1289 | xchg(); |
1271 | cmpxchg(); | 1290 | cmpxchg(); |
1272 | test_and_set_bit(); | ||
1273 | test_and_clear_bit(); | ||
1274 | test_and_change_bit(); | ||
1275 | atomic_cmpxchg(); | 1291 | atomic_cmpxchg(); |
1276 | atomic_inc_return(); | 1292 | atomic_inc_return(); |
1277 | atomic_dec_return(); | 1293 | atomic_dec_return(); |
@@ -1282,21 +1298,31 @@ barriers. The possible offenders include: | |||
1282 | atomic_sub_and_test(); | 1298 | atomic_sub_and_test(); |
1283 | atomic_add_negative(); | 1299 | atomic_add_negative(); |
1284 | atomic_add_unless(); | 1300 | atomic_add_unless(); |
1301 | test_and_set_bit(); | ||
1302 | test_and_clear_bit(); | ||
1303 | test_and_change_bit(); | ||
1285 | 1304 | ||
1286 | These may be used for such things as implementing LOCK operations or controlling | 1305 | These are used for such things as implementing LOCK-class and UNLOCK-class |
1287 | the lifetime of objects by decreasing their reference counts. In such cases | 1306 | operations and adjusting reference counters towards object destruction, and as |
1288 | they need preceding memory barriers. | 1307 | such the implicit memory barrier effects are necessary. |
1289 | 1308 | ||
1290 | The following may also be possible offenders as they may be used as UNLOCK | ||
1291 | operations. | ||
1292 | 1309 | ||
1310 | The following operation are potential problems as they do _not_ imply memory | ||
1311 | barriers, but might be used for implementing such things as UNLOCK-class | ||
1312 | operations: | ||
1313 | |||
1314 | atomic_set(); | ||
1293 | set_bit(); | 1315 | set_bit(); |
1294 | clear_bit(); | 1316 | clear_bit(); |
1295 | change_bit(); | 1317 | change_bit(); |
1296 | atomic_set(); | ||
1297 | 1318 | ||
1319 | With these the appropriate explicit memory barrier should be used if necessary | ||
1320 | (smp_mb__before_clear_bit() for instance). | ||
1298 | 1321 | ||
1299 | The following are a little tricky: | 1322 | |
1323 | The following also do _not_ imply memory barriers, and so may require explicit | ||
1324 | memory barriers under some circumstances (smp_mb__before_atomic_dec() for | ||
1325 | instance)): | ||
1300 | 1326 | ||
1301 | atomic_add(); | 1327 | atomic_add(); |
1302 | atomic_sub(); | 1328 | atomic_sub(); |
@@ -1317,10 +1343,12 @@ specific order. | |||
1317 | 1343 | ||
1318 | 1344 | ||
1319 | Basically, each usage case has to be carefully considered as to whether memory | 1345 | Basically, each usage case has to be carefully considered as to whether memory |
1320 | barriers are needed or not. The simplest rule is probably: if the atomic | 1346 | barriers are needed or not. |
1321 | operation is protected by a lock, then it does not require a barrier unless | 1347 | |
1322 | there's another operation within the critical section with respect to which an | 1348 | [!] Note that special memory barrier primitives are available for these |
1323 | ordering must be maintained. | 1349 | situations because on some CPUs the atomic instructions used imply full memory |
1350 | barriers, and so barrier instructions are superfluous in conjunction with them, | ||
1351 | and in such cases the special barrier primitives will be no-ops. | ||
1324 | 1352 | ||
1325 | See Documentation/atomic_ops.txt for more information. | 1353 | See Documentation/atomic_ops.txt for more information. |
1326 | 1354 | ||
diff --git a/Documentation/mtrr.txt b/Documentation/mtrr.txt index b78af1c32996..c39ac395970e 100644 --- a/Documentation/mtrr.txt +++ b/Documentation/mtrr.txt | |||
@@ -138,19 +138,29 @@ Reading MTRRs from a C program using ioctl()'s: | |||
138 | 138 | ||
139 | */ | 139 | */ |
140 | #include <stdio.h> | 140 | #include <stdio.h> |
141 | #include <stdlib.h> | ||
141 | #include <string.h> | 142 | #include <string.h> |
142 | #include <sys/types.h> | 143 | #include <sys/types.h> |
143 | #include <sys/stat.h> | 144 | #include <sys/stat.h> |
144 | #include <fcntl.h> | 145 | #include <fcntl.h> |
145 | #include <sys/ioctl.h> | 146 | #include <sys/ioctl.h> |
146 | #include <errno.h> | 147 | #include <errno.h> |
147 | #define MTRR_NEED_STRINGS | ||
148 | #include <asm/mtrr.h> | 148 | #include <asm/mtrr.h> |
149 | 149 | ||
150 | #define TRUE 1 | 150 | #define TRUE 1 |
151 | #define FALSE 0 | 151 | #define FALSE 0 |
152 | #define ERRSTRING strerror (errno) | 152 | #define ERRSTRING strerror (errno) |
153 | 153 | ||
154 | static char *mtrr_strings[MTRR_NUM_TYPES] = | ||
155 | { | ||
156 | "uncachable", /* 0 */ | ||
157 | "write-combining", /* 1 */ | ||
158 | "?", /* 2 */ | ||
159 | "?", /* 3 */ | ||
160 | "write-through", /* 4 */ | ||
161 | "write-protect", /* 5 */ | ||
162 | "write-back", /* 6 */ | ||
163 | }; | ||
154 | 164 | ||
155 | int main () | 165 | int main () |
156 | { | 166 | { |
@@ -232,13 +242,22 @@ Creating MTRRs from a C programme using ioctl()'s: | |||
232 | #include <fcntl.h> | 242 | #include <fcntl.h> |
233 | #include <sys/ioctl.h> | 243 | #include <sys/ioctl.h> |
234 | #include <errno.h> | 244 | #include <errno.h> |
235 | #define MTRR_NEED_STRINGS | ||
236 | #include <asm/mtrr.h> | 245 | #include <asm/mtrr.h> |
237 | 246 | ||
238 | #define TRUE 1 | 247 | #define TRUE 1 |
239 | #define FALSE 0 | 248 | #define FALSE 0 |
240 | #define ERRSTRING strerror (errno) | 249 | #define ERRSTRING strerror (errno) |
241 | 250 | ||
251 | static char *mtrr_strings[MTRR_NUM_TYPES] = | ||
252 | { | ||
253 | "uncachable", /* 0 */ | ||
254 | "write-combining", /* 1 */ | ||
255 | "?", /* 2 */ | ||
256 | "?", /* 3 */ | ||
257 | "write-through", /* 4 */ | ||
258 | "write-protect", /* 5 */ | ||
259 | "write-back", /* 6 */ | ||
260 | }; | ||
242 | 261 | ||
243 | int main (int argc, char **argv) | 262 | int main (int argc, char **argv) |
244 | { | 263 | { |
diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt index 331afd791cbb..ce767b90bb0d 100644 --- a/Documentation/scsi/scsi_eh.txt +++ b/Documentation/scsi/scsi_eh.txt | |||
@@ -19,9 +19,9 @@ TABLE OF CONTENTS | |||
19 | [2-1-1] Overview | 19 | [2-1-1] Overview |
20 | [2-1-2] Flow of scmds through EH | 20 | [2-1-2] Flow of scmds through EH |
21 | [2-1-3] Flow of control | 21 | [2-1-3] Flow of control |
22 | [2-2] EH through hostt->eh_strategy_handler() | 22 | [2-2] EH through transportt->eh_strategy_handler() |
23 | [2-2-1] Pre hostt->eh_strategy_handler() SCSI midlayer conditions | 23 | [2-2-1] Pre transportt->eh_strategy_handler() SCSI midlayer conditions |
24 | [2-2-2] Post hostt->eh_strategy_handler() SCSI midlayer conditions | 24 | [2-2-2] Post transportt->eh_strategy_handler() SCSI midlayer conditions |
25 | [2-2-3] Things to consider | 25 | [2-2-3] Things to consider |
26 | 26 | ||
27 | 27 | ||
@@ -413,9 +413,9 @@ scmd->allowed. | |||
413 | layer of failure of the scmds. | 413 | layer of failure of the scmds. |
414 | 414 | ||
415 | 415 | ||
416 | [2-2] EH through hostt->eh_strategy_handler() | 416 | [2-2] EH through transportt->eh_strategy_handler() |
417 | 417 | ||
418 | hostt->eh_strategy_handler() is invoked in the place of | 418 | transportt->eh_strategy_handler() is invoked in the place of |
419 | scsi_unjam_host() and it is responsible for whole recovery process. | 419 | scsi_unjam_host() and it is responsible for whole recovery process. |
420 | On completion, the handler should have made lower layers forget about | 420 | On completion, the handler should have made lower layers forget about |
421 | all failed scmds and either ready for new commands or offline. Also, | 421 | all failed scmds and either ready for new commands or offline. Also, |
@@ -424,7 +424,7 @@ SCSI midlayer. IOW, of the steps described in [2-1-2], all steps | |||
424 | except for #1 must be implemented by eh_strategy_handler(). | 424 | except for #1 must be implemented by eh_strategy_handler(). |
425 | 425 | ||
426 | 426 | ||
427 | [2-2-1] Pre hostt->eh_strategy_handler() SCSI midlayer conditions | 427 | [2-2-1] Pre transportt->eh_strategy_handler() SCSI midlayer conditions |
428 | 428 | ||
429 | The following conditions are true on entry to the handler. | 429 | The following conditions are true on entry to the handler. |
430 | 430 | ||
@@ -437,7 +437,7 @@ except for #1 must be implemented by eh_strategy_handler(). | |||
437 | - shost->host_failed == shost->host_busy | 437 | - shost->host_failed == shost->host_busy |
438 | 438 | ||
439 | 439 | ||
440 | [2-2-2] Post hostt->eh_strategy_handler() SCSI midlayer conditions | 440 | [2-2-2] Post transportt->eh_strategy_handler() SCSI midlayer conditions |
441 | 441 | ||
442 | The following conditions must be true on exit from the handler. | 442 | The following conditions must be true on exit from the handler. |
443 | 443 | ||
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 8bbae3e1abdf..75a535a975c3 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt | |||
@@ -804,7 +804,6 @@ Summary: | |||
804 | eh_bus_reset_handler - issue SCSI bus reset | 804 | eh_bus_reset_handler - issue SCSI bus reset |
805 | eh_device_reset_handler - issue SCSI device reset | 805 | eh_device_reset_handler - issue SCSI device reset |
806 | eh_host_reset_handler - reset host (host bus adapter) | 806 | eh_host_reset_handler - reset host (host bus adapter) |
807 | eh_strategy_handler - driver supplied alternate to scsi_unjam_host() | ||
808 | info - supply information about given host | 807 | info - supply information about given host |
809 | ioctl - driver can respond to ioctls | 808 | ioctl - driver can respond to ioctls |
810 | proc_info - supports /proc/scsi/{driver_name}/{host_no} | 809 | proc_info - supports /proc/scsi/{driver_name}/{host_no} |
@@ -970,24 +969,6 @@ Details: | |||
970 | 969 | ||
971 | 970 | ||
972 | /** | 971 | /** |
973 | * eh_strategy_handler - driver supplied alternate to scsi_unjam_host() | ||
974 | * @shp: host on which error has occurred | ||
975 | * | ||
976 | * Returns TRUE if host unjammed, else FALSE. | ||
977 | * | ||
978 | * Locks: none | ||
979 | * | ||
980 | * Calling context: kernel thread | ||
981 | * | ||
982 | * Notes: Invoked from scsi_eh thread. LLD supplied alternate to | ||
983 | * scsi_unjam_host() found in scsi_error.c | ||
984 | * | ||
985 | * Optionally defined in: LLD | ||
986 | **/ | ||
987 | int eh_strategy_handler(struct Scsi_Host * shp) | ||
988 | |||
989 | |||
990 | /** | ||
991 | * info - supply information about given host: driver name plus data | 972 | * info - supply information about given host: driver name plus data |
992 | * to distinguish given host | 973 | * to distinguish given host |
993 | * @shp: host to supply information about | 974 | * @shp: host to supply information about |
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 6feef9e82b63..68eeebc17ff4 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl | |||
@@ -1123,8 +1123,8 @@ | |||
1123 | if ((err = pci_enable_device(pci)) < 0) | 1123 | if ((err = pci_enable_device(pci)) < 0) |
1124 | return err; | 1124 | return err; |
1125 | /* check PCI availability (28bit DMA) */ | 1125 | /* check PCI availability (28bit DMA) */ |
1126 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 1126 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
1127 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 1127 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
1128 | printk(KERN_ERR "error to set 28bit mask DMA\n"); | 1128 | printk(KERN_ERR "error to set 28bit mask DMA\n"); |
1129 | pci_disable_device(pci); | 1129 | pci_disable_device(pci); |
1130 | return -ENXIO; | 1130 | return -ENXIO; |
@@ -1216,7 +1216,7 @@ | |||
1216 | The allocation of PCI resources is done in the | 1216 | The allocation of PCI resources is done in the |
1217 | <function>probe()</function> function, and usually an extra | 1217 | <function>probe()</function> function, and usually an extra |
1218 | <function>xxx_create()</function> function is written for this | 1218 | <function>xxx_create()</function> function is written for this |
1219 | purpose. | 1219 | purpose. |
1220 | </para> | 1220 | </para> |
1221 | 1221 | ||
1222 | <para> | 1222 | <para> |
@@ -1225,7 +1225,7 @@ | |||
1225 | allocating resources. Also, you need to set the proper PCI DMA | 1225 | allocating resources. Also, you need to set the proper PCI DMA |
1226 | mask to limit the accessed i/o range. In some cases, you might | 1226 | mask to limit the accessed i/o range. In some cases, you might |
1227 | need to call <function>pci_set_master()</function> function, | 1227 | need to call <function>pci_set_master()</function> function, |
1228 | too. | 1228 | too. |
1229 | </para> | 1229 | </para> |
1230 | 1230 | ||
1231 | <para> | 1231 | <para> |
@@ -1236,8 +1236,8 @@ | |||
1236 | <![CDATA[ | 1236 | <![CDATA[ |
1237 | if ((err = pci_enable_device(pci)) < 0) | 1237 | if ((err = pci_enable_device(pci)) < 0) |
1238 | return err; | 1238 | return err; |
1239 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 1239 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
1240 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 1240 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
1241 | printk(KERN_ERR "error to set 28bit mask DMA\n"); | 1241 | printk(KERN_ERR "error to set 28bit mask DMA\n"); |
1242 | pci_disable_device(pci); | 1242 | pci_disable_device(pci); |
1243 | return -ENXIO; | 1243 | return -ENXIO; |
@@ -1256,13 +1256,13 @@ | |||
1256 | functions. Unlike ALSA ver.0.5.x., there are no helpers for | 1256 | functions. Unlike ALSA ver.0.5.x., there are no helpers for |
1257 | that. And these resources must be released in the destructor | 1257 | that. And these resources must be released in the destructor |
1258 | function (see below). Also, on ALSA 0.9.x, you don't need to | 1258 | function (see below). Also, on ALSA 0.9.x, you don't need to |
1259 | allocate (pseudo-)DMA for PCI like ALSA 0.5.x. | 1259 | allocate (pseudo-)DMA for PCI like ALSA 0.5.x. |
1260 | </para> | 1260 | </para> |
1261 | 1261 | ||
1262 | <para> | 1262 | <para> |
1263 | Now assume that this PCI device has an I/O port with 8 bytes | 1263 | Now assume that this PCI device has an I/O port with 8 bytes |
1264 | and an interrupt. Then struct <structname>mychip</structname> will have the | 1264 | and an interrupt. Then struct <structname>mychip</structname> will have the |
1265 | following fields: | 1265 | following fields: |
1266 | 1266 | ||
1267 | <informalexample> | 1267 | <informalexample> |
1268 | <programlisting> | 1268 | <programlisting> |
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index 1ad9af1ca4d0..2803f63c1a27 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt | |||
@@ -27,7 +27,7 @@ number of free hugetlb pages at any time. It also displays information about | |||
27 | the configured hugepage size - this is needed for generating the proper | 27 | the configured hugepage size - this is needed for generating the proper |
28 | alignment and size of the arguments to the above system calls. | 28 | alignment and size of the arguments to the above system calls. |
29 | 29 | ||
30 | The output of "cat /proc/meminfo" will have output like: | 30 | The output of "cat /proc/meminfo" will have lines like: |
31 | 31 | ||
32 | ..... | 32 | ..... |
33 | HugePages_Total: xxx | 33 | HugePages_Total: xxx |
@@ -42,11 +42,11 @@ pages in the kernel. Super user can dynamically request more (or free some | |||
42 | pre-configured) hugepages. | 42 | pre-configured) hugepages. |
43 | The allocation (or deallocation) of hugetlb pages is possible only if there are | 43 | The allocation (or deallocation) of hugetlb pages is possible only if there are |
44 | enough physically contiguous free pages in system (freeing of hugepages is | 44 | enough physically contiguous free pages in system (freeing of hugepages is |
45 | possible only if there are enough hugetlb pages free that can be transfered | 45 | possible only if there are enough hugetlb pages free that can be transferred |
46 | back to regular memory pool). | 46 | back to regular memory pool). |
47 | 47 | ||
48 | Pages that are used as hugetlb pages are reserved inside the kernel and can | 48 | Pages that are used as hugetlb pages are reserved inside the kernel and cannot |
49 | not be used for other purposes. | 49 | be used for other purposes. |
50 | 50 | ||
51 | Once the kernel with Hugetlb page support is built and running, a user can | 51 | Once the kernel with Hugetlb page support is built and running, a user can |
52 | use either the mmap system call or shared memory system calls to start using | 52 | use either the mmap system call or shared memory system calls to start using |
@@ -60,7 +60,7 @@ Use the following command to dynamically allocate/deallocate hugepages: | |||
60 | This command will try to configure 20 hugepages in the system. The success | 60 | This command will try to configure 20 hugepages in the system. The success |
61 | or failure of allocation depends on the amount of physically contiguous | 61 | or failure of allocation depends on the amount of physically contiguous |
62 | memory that is preset in system at this time. System administrators may want | 62 | memory that is preset in system at this time. System administrators may want |
63 | to put this command in one of the local rc init file. This will enable the | 63 | to put this command in one of the local rc init files. This will enable the |
64 | kernel to request huge pages early in the boot process (when the possibility | 64 | kernel to request huge pages early in the boot process (when the possibility |
65 | of getting physical contiguous pages is still very high). | 65 | of getting physical contiguous pages is still very high). |
66 | 66 | ||
@@ -78,8 +78,8 @@ the uid and gid of the current process are taken. The mode option sets the | |||
78 | mode of root of file system to value & 0777. This value is given in octal. | 78 | mode of root of file system to value & 0777. This value is given in octal. |
79 | By default the value 0755 is picked. The size option sets the maximum value of | 79 | By default the value 0755 is picked. The size option sets the maximum value of |
80 | memory (huge pages) allowed for that filesystem (/mnt/huge). The size is | 80 | memory (huge pages) allowed for that filesystem (/mnt/huge). The size is |
81 | rounded down to HPAGE_SIZE. The option nr_inode sets the maximum number of | 81 | rounded down to HPAGE_SIZE. The option nr_inodes sets the maximum number of |
82 | inodes that /mnt/huge can use. If the size or nr_inode options are not | 82 | inodes that /mnt/huge can use. If the size or nr_inodes options are not |
83 | provided on command line then no limits are set. For size and nr_inodes | 83 | provided on command line then no limits are set. For size and nr_inodes |
84 | options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For | 84 | options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For |
85 | example, size=2K has the same meaning as size=2048. An example is given at | 85 | example, size=2K has the same meaning as size=2048. An example is given at |
@@ -88,7 +88,7 @@ the end of this document. | |||
88 | read and write system calls are not supported on files that reside on hugetlb | 88 | read and write system calls are not supported on files that reside on hugetlb |
89 | file systems. | 89 | file systems. |
90 | 90 | ||
91 | A regular chown, chgrp and chmod commands (with right permissions) could be | 91 | Regular chown, chgrp, and chmod commands (with right permissions) could be |
92 | used to change the file attributes on hugetlbfs. | 92 | used to change the file attributes on hugetlbfs. |
93 | 93 | ||
94 | Also, it is important to note that no such mount command is required if the | 94 | Also, it is important to note that no such mount command is required if the |
@@ -96,8 +96,8 @@ applications are going to use only shmat/shmget system calls. Users who | |||
96 | wish to use hugetlb page via shared memory segment should be a member of | 96 | wish to use hugetlb page via shared memory segment should be a member of |
97 | a supplementary group and system admin needs to configure that gid into | 97 | a supplementary group and system admin needs to configure that gid into |
98 | /proc/sys/vm/hugetlb_shm_group. It is possible for same or different | 98 | /proc/sys/vm/hugetlb_shm_group. It is possible for same or different |
99 | applications to use any combination of mmaps and shm* calls. Though the | 99 | applications to use any combination of mmaps and shm* calls, though the |
100 | mount of filesystem will be required for using mmaps. | 100 | mount of filesystem will be required for using mmap calls. |
101 | 101 | ||
102 | ******************************************************************* | 102 | ******************************************************************* |
103 | 103 | ||
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 1921353259ae..f2cd6ef53ff3 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt | |||
@@ -151,6 +151,11 @@ NUMA | |||
151 | 151 | ||
152 | numa=fake=X Fake X nodes and ignore NUMA setup of the actual machine. | 152 | numa=fake=X Fake X nodes and ignore NUMA setup of the actual machine. |
153 | 153 | ||
154 | numa=hotadd=percent | ||
155 | Only allow hotadd memory to preallocate page structures upto | ||
156 | percent of already available memory. | ||
157 | numa=hotadd=0 will disable hotadd memory. | ||
158 | |||
154 | ACPI | 159 | ACPI |
155 | 160 | ||
156 | acpi=off Don't enable ACPI | 161 | acpi=off Don't enable ACPI |
@@ -18,7 +18,7 @@ define sed-y | |||
18 | "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" | 18 | "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" |
19 | endef | 19 | endef |
20 | # Override default regexp for specific architectures | 20 | # Override default regexp for specific architectures |
21 | sed-$(CONFIG_MIPS) := "/^@@@/s///p" | 21 | sed-$(CONFIG_MIPS) := "/^@@@/{s/^@@@//; s/ \#.*\$$//; p;}" |
22 | 22 | ||
23 | quiet_cmd_offsets = GEN $@ | 23 | quiet_cmd_offsets = GEN $@ |
24 | define cmd_offsets | 24 | define cmd_offsets |
diff --git a/MAINTAINERS b/MAINTAINERS index f97657b7e2c7..d00dea52123f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1556,9 +1556,7 @@ S: Maintained | |||
1556 | 1556 | ||
1557 | KEXEC | 1557 | KEXEC |
1558 | P: Eric Biederman | 1558 | P: Eric Biederman |
1559 | P: Randy Dunlap | ||
1560 | M: ebiederm@xmission.com | 1559 | M: ebiederm@xmission.com |
1561 | M: rdunlap@xenotime.net | ||
1562 | W: http://www.xmission.com/~ebiederm/files/kexec/ | 1560 | W: http://www.xmission.com/~ebiederm/files/kexec/ |
1563 | L: linux-kernel@vger.kernel.org | 1561 | L: linux-kernel@vger.kernel.org |
1564 | L: fastboot@osdl.org | 1562 | L: fastboot@osdl.org |
@@ -1112,7 +1112,6 @@ modules_install: _emodinst_ _emodinst_post | |||
1112 | install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra) | 1112 | install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra) |
1113 | PHONY += _emodinst_ | 1113 | PHONY += _emodinst_ |
1114 | _emodinst_: | 1114 | _emodinst_: |
1115 | $(Q)rm -rf $(MODLIB)/$(install-dir) | ||
1116 | $(Q)mkdir -p $(MODLIB)/$(install-dir) | 1115 | $(Q)mkdir -p $(MODLIB)/$(install-dir) |
1117 | $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst | 1116 | $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst |
1118 | 1117 | ||
@@ -1275,40 +1274,43 @@ kernelversion: | |||
1275 | 1274 | ||
1276 | # Single targets | 1275 | # Single targets |
1277 | # --------------------------------------------------------------------------- | 1276 | # --------------------------------------------------------------------------- |
1278 | # The directory part is taken from first prerequisite, so this | 1277 | # Single targets are compatible with: |
1279 | # works even with external modules | 1278 | # - build whith mixed source and output |
1279 | # - build with separate output dir 'make O=...' | ||
1280 | # - external modules | ||
1281 | # | ||
1282 | # target-dir => where to store outputfile | ||
1283 | # build-dir => directory in kernel source tree to use | ||
1284 | |||
1285 | ifeq ($(KBUILD_EXTMOD),) | ||
1286 | build-dir = $(patsubst %/,%,$(dir $@)) | ||
1287 | target-dir = $(dir $@) | ||
1288 | else | ||
1289 | zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@))) | ||
1290 | build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash)) | ||
1291 | target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) | ||
1292 | endif | ||
1293 | |||
1280 | %.s: %.c prepare scripts FORCE | 1294 | %.s: %.c prepare scripts FORCE |
1281 | $(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@) | 1295 | $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
1282 | %.i: %.c prepare scripts FORCE | 1296 | %.i: %.c prepare scripts FORCE |
1283 | $(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@) | 1297 | $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
1284 | %.o: %.c prepare scripts FORCE | 1298 | %.o: %.c prepare scripts FORCE |
1285 | $(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@) | 1299 | $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
1286 | %.lst: %.c prepare scripts FORCE | 1300 | %.lst: %.c prepare scripts FORCE |
1287 | $(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@) | 1301 | $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
1288 | %.s: %.S prepare scripts FORCE | 1302 | %.s: %.S prepare scripts FORCE |
1289 | $(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@) | 1303 | $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
1290 | %.o: %.S prepare scripts FORCE | 1304 | %.o: %.S prepare scripts FORCE |
1291 | $(Q)$(MAKE) $(build)=$(dir $<) $(dir $<)$(notdir $@) | 1305 | $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
1292 | |||
1293 | # For external modules we shall include any directory of the target, | ||
1294 | # but usual case there is no directory part. | ||
1295 | # make M=`pwd` module.o => $(dir $@)=./ | ||
1296 | # make M=`pwd` foo/module.o => $(dir $@)=foo/ | ||
1297 | # make M=`pwd` / => $(dir $@)=/ | ||
1298 | |||
1299 | ifeq ($(KBUILD_EXTMOD),) | ||
1300 | target-dir = $(@D) | ||
1301 | else | ||
1302 | zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@))) | ||
1303 | target-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash)) | ||
1304 | endif | ||
1305 | 1306 | ||
1306 | / %/: scripts prepare FORCE | 1307 | # Modules |
1308 | / %/: prepare scripts FORCE | ||
1307 | $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ | 1309 | $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ |
1308 | $(build)=$(target-dir) | 1310 | $(build)=$(build-dir) |
1309 | %.ko: scripts FORCE | 1311 | %.ko: prepare scripts FORCE |
1310 | $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ | 1312 | $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ |
1311 | $(build)=$(target-dir) $(@:.ko=.o) | 1313 | $(build)=$(build-dir) $(@:.ko=.o) |
1312 | $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost | 1314 | $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost |
1313 | 1315 | ||
1314 | # FIXME Should go into a make.lib or something | 1316 | # FIXME Should go into a make.lib or something |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 9bef61b30367..8290b69da202 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -549,6 +549,11 @@ config NUMA | |||
549 | Access). This option is for configuring high-end multiprocessor | 549 | Access). This option is for configuring high-end multiprocessor |
550 | server machines. If in doubt, say N. | 550 | server machines. If in doubt, say N. |
551 | 551 | ||
552 | config NODES_SHIFT | ||
553 | int | ||
554 | default "7" | ||
555 | depends on NEED_MULTIPLE_NODES | ||
556 | |||
552 | # LARGE_VMALLOC is racy, if you *really* need it then fix it first | 557 | # LARGE_VMALLOC is racy, if you *really* need it then fix it first |
553 | config ALPHA_LARGE_VMALLOC | 558 | config ALPHA_LARGE_VMALLOC |
554 | bool | 559 | bool |
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 9d6186d50245..c645c5e14786 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c | |||
@@ -76,7 +76,6 @@ EXPORT_SYMBOL(strncpy); | |||
76 | EXPORT_SYMBOL(strnlen); | 76 | EXPORT_SYMBOL(strnlen); |
77 | EXPORT_SYMBOL(strncat); | 77 | EXPORT_SYMBOL(strncat); |
78 | EXPORT_SYMBOL(strstr); | 78 | EXPORT_SYMBOL(strstr); |
79 | EXPORT_SYMBOL(strpbrk); | ||
80 | EXPORT_SYMBOL(strchr); | 79 | EXPORT_SYMBOL(strchr); |
81 | EXPORT_SYMBOL(strrchr); | 80 | EXPORT_SYMBOL(strrchr); |
82 | EXPORT_SYMBOL(memcmp); | 81 | EXPORT_SYMBOL(memcmp); |
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index a15e18a00258..558b83368559 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ | 24 | #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ |
25 | #include <linux/mc146818rtc.h> | 25 | #include <linux/mc146818rtc.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/cpu.h> | ||
27 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
28 | #include <linux/init.h> | 29 | #include <linux/init.h> |
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
@@ -471,6 +472,22 @@ page_is_ram(unsigned long pfn) | |||
471 | return 0; | 472 | return 0; |
472 | } | 473 | } |
473 | 474 | ||
475 | static int __init | ||
476 | register_cpus(void) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for_each_possible_cpu(i) { | ||
481 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
482 | if (!p) | ||
483 | return -ENOMEM; | ||
484 | register_cpu(p, i, NULL); | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | arch_initcall(register_cpus); | ||
490 | |||
474 | void __init | 491 | void __init |
475 | setup_arch(char **cmdline_p) | 492 | setup_arch(char **cmdline_p) |
476 | { | 493 | { |
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 02c2db08114a..185255416e85 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
@@ -439,7 +439,7 @@ setup_smp(void) | |||
439 | if ((cpu->flags & 0x1cc) == 0x1cc) { | 439 | if ((cpu->flags & 0x1cc) == 0x1cc) { |
440 | smp_num_probed++; | 440 | smp_num_probed++; |
441 | /* Assume here that "whami" == index */ | 441 | /* Assume here that "whami" == index */ |
442 | cpu_set(i, cpu_possible_map); | 442 | cpu_set(i, cpu_present_mask); |
443 | cpu->pal_revision = boot_cpu_palrev; | 443 | cpu->pal_revision = boot_cpu_palrev; |
444 | } | 444 | } |
445 | 445 | ||
@@ -450,9 +450,8 @@ setup_smp(void) | |||
450 | } | 450 | } |
451 | } else { | 451 | } else { |
452 | smp_num_probed = 1; | 452 | smp_num_probed = 1; |
453 | cpu_set(boot_cpuid, cpu_possible_map); | 453 | cpu_set(boot_cpuid, cpu_present_mask); |
454 | } | 454 | } |
455 | cpu_present_mask = cpumask_of_cpu(boot_cpuid); | ||
456 | 455 | ||
457 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", | 456 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", |
458 | smp_num_probed, cpu_possible_map.bits[0]); | 457 | smp_num_probed, cpu_possible_map.bits[0]); |
@@ -488,9 +487,8 @@ void __devinit | |||
488 | smp_prepare_boot_cpu(void) | 487 | smp_prepare_boot_cpu(void) |
489 | { | 488 | { |
490 | /* | 489 | /* |
491 | * Mark the boot cpu (current cpu) as both present and online | 490 | * Mark the boot cpu (current cpu) as online |
492 | */ | 491 | */ |
493 | cpu_set(smp_processor_id(), cpu_present_mask); | ||
494 | cpu_set(smp_processor_id(), cpu_online_map); | 492 | cpu_set(smp_processor_id(), cpu_online_map); |
495 | } | 493 | } |
496 | 494 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dc5a9332c915..1dbf6ddb300d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -512,6 +512,12 @@ config ARCH_DISCONTIGMEM_ENABLE | |||
512 | or have huge holes in the physical address space for other reasons. | 512 | or have huge holes in the physical address space for other reasons. |
513 | See <file:Documentation/vm/numa> for more. | 513 | See <file:Documentation/vm/numa> for more. |
514 | 514 | ||
515 | config NODES_SHIFT | ||
516 | int | ||
517 | default "4" if ARCH_LH7A40X | ||
518 | default "2" | ||
519 | depends on NEED_MULTIPLE_NODES | ||
520 | |||
515 | source "mm/Kconfig" | 521 | source "mm/Kconfig" |
516 | 522 | ||
517 | config LEDS | 523 | config LEDS |
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index eed616113e47..153a07e7222b 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in | |||
@@ -18,6 +18,7 @@ SECTIONS | |||
18 | _start = .; | 18 | _start = .; |
19 | *(.start) | 19 | *(.start) |
20 | *(.text) | 20 | *(.text) |
21 | *(.text.*) | ||
21 | *(.fixup) | 22 | *(.fixup) |
22 | *(.gnu.warning) | 23 | *(.gnu.warning) |
23 | *(.rodata) | 24 | *(.rodata) |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index ee083b3f0522..c49b5d4d7fca 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -101,7 +101,6 @@ EXPORT_SYMBOL(__raw_writesl); | |||
101 | 101 | ||
102 | /* string / mem functions */ | 102 | /* string / mem functions */ |
103 | EXPORT_SYMBOL(strchr); | 103 | EXPORT_SYMBOL(strchr); |
104 | EXPORT_SYMBOL(strpbrk); | ||
105 | EXPORT_SYMBOL(strrchr); | 104 | EXPORT_SYMBOL(strrchr); |
106 | EXPORT_SYMBOL(memset); | 105 | EXPORT_SYMBOL(memset); |
107 | EXPORT_SYMBOL(memcpy); | 106 | EXPORT_SYMBOL(memcpy); |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 437528403959..8cff73e668b3 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -322,6 +322,12 @@ static void __init setup_processor(void) | |||
322 | sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); | 322 | sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); |
323 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); | 323 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); |
324 | elf_hwcap = list->elf_hwcap; | 324 | elf_hwcap = list->elf_hwcap; |
325 | #ifndef CONFIG_ARM_THUMB | ||
326 | elf_hwcap &= ~HWCAP_THUMB; | ||
327 | #endif | ||
328 | #ifndef CONFIG_VFP | ||
329 | elf_hwcap &= ~HWCAP_VFP; | ||
330 | #endif | ||
325 | 331 | ||
326 | cpu_proc_init(); | 332 | cpu_proc_init(); |
327 | } | 333 | } |
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 876c38da14f7..847329cafc5c 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c | |||
@@ -25,10 +25,6 @@ | |||
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | 27 | ||
28 | extern void omap_nop_release(struct device *dev); | ||
29 | |||
30 | /*-------------------------------------------------------------------------*/ | ||
31 | |||
32 | #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) | 28 | #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) |
33 | 29 | ||
34 | static u64 irda_dmamask = 0xffffffff; | 30 | static u64 irda_dmamask = 0xffffffff; |
@@ -37,7 +33,6 @@ static struct platform_device omap1610ir_device = { | |||
37 | .name = "omap1610-ir", | 33 | .name = "omap1610-ir", |
38 | .id = -1, | 34 | .id = -1, |
39 | .dev = { | 35 | .dev = { |
40 | .release = omap_nop_release, | ||
41 | .dma_mask = &irda_dmamask, | 36 | .dma_mask = &irda_dmamask, |
42 | }, | 37 | }, |
43 | }; | 38 | }; |
@@ -84,9 +79,6 @@ static struct resource rtc_resources[] = { | |||
84 | static struct platform_device omap_rtc_device = { | 79 | static struct platform_device omap_rtc_device = { |
85 | .name = "omap_rtc", | 80 | .name = "omap_rtc", |
86 | .id = -1, | 81 | .id = -1, |
87 | .dev = { | ||
88 | .release = omap_nop_release, | ||
89 | }, | ||
90 | .num_resources = ARRAY_SIZE(rtc_resources), | 82 | .num_resources = ARRAY_SIZE(rtc_resources), |
91 | .resource = rtc_resources, | 83 | .resource = rtc_resources, |
92 | }; | 84 | }; |
@@ -124,9 +116,6 @@ static struct resource sti_resources[] = { | |||
124 | static struct platform_device sti_device = { | 116 | static struct platform_device sti_device = { |
125 | .name = "sti", | 117 | .name = "sti", |
126 | .id = -1, | 118 | .id = -1, |
127 | .dev = { | ||
128 | .release = omap_nop_release, | ||
129 | }, | ||
130 | .num_resources = ARRAY_SIZE(sti_resources), | 119 | .num_resources = ARRAY_SIZE(sti_resources), |
131 | .resource = sti_resources, | 120 | .resource = sti_resources, |
132 | }; | 121 | }; |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index def9e5370edf..fb7f91da1aad 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -25,10 +25,6 @@ | |||
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | 27 | ||
28 | extern void omap_nop_release(struct device *dev); | ||
29 | |||
30 | /*-------------------------------------------------------------------------*/ | ||
31 | |||
32 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | 28 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) |
33 | 29 | ||
34 | #define OMAP2_I2C_BASE2 0x48072000 | 30 | #define OMAP2_I2C_BASE2 0x48072000 |
@@ -49,9 +45,6 @@ static struct resource i2c_resources2[] = { | |||
49 | static struct platform_device omap_i2c_device2 = { | 45 | static struct platform_device omap_i2c_device2 = { |
50 | .name = "i2c_omap", | 46 | .name = "i2c_omap", |
51 | .id = 2, | 47 | .id = 2, |
52 | .dev = { | ||
53 | .release = omap_nop_release, | ||
54 | }, | ||
55 | .num_resources = ARRAY_SIZE(i2c_resources2), | 48 | .num_resources = ARRAY_SIZE(i2c_resources2), |
56 | .resource = i2c_resources2, | 49 | .resource = i2c_resources2, |
57 | }; | 50 | }; |
@@ -100,9 +93,6 @@ static struct resource sti_resources[] = { | |||
100 | static struct platform_device sti_device = { | 93 | static struct platform_device sti_device = { |
101 | .name = "sti", | 94 | .name = "sti", |
102 | .id = -1, | 95 | .id = -1, |
103 | .dev = { | ||
104 | .release = omap_nop_release, | ||
105 | }, | ||
106 | .num_resources = ARRAY_SIZE(sti_resources), | 96 | .num_resources = ARRAY_SIZE(sti_resources), |
107 | .resource = sti_resources, | 97 | .resource = sti_resources, |
108 | }; | 98 | }; |
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index b7f85e6d6b76..6de713ad319a 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
@@ -367,6 +367,8 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) | |||
367 | source = S3C2410_MISCCR_CLK0_UPLL; | 367 | source = S3C2410_MISCCR_CLK0_UPLL; |
368 | else if (parent == &clk_f) | 368 | else if (parent == &clk_f) |
369 | source = S3C2410_MISCCR_CLK0_FCLK; | 369 | source = S3C2410_MISCCR_CLK0_FCLK; |
370 | else if (parent == &clk_h) | ||
371 | source = S3C2410_MISCCR_CLK0_HCLK; | ||
370 | else if (parent == &clk_p) | 372 | else if (parent == &clk_p) |
371 | source = S3C2410_MISCCR_CLK0_PCLK; | 373 | source = S3C2410_MISCCR_CLK0_PCLK; |
372 | else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) | 374 | else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) |
@@ -376,6 +378,8 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) | |||
376 | else | 378 | else |
377 | return -EINVAL; | 379 | return -EINVAL; |
378 | 380 | ||
381 | clk->parent = parent; | ||
382 | |||
379 | if (clk == &s3c24xx_dclk0) | 383 | if (clk == &s3c24xx_dclk0) |
380 | mask = S3C2410_MISCCR_CLK0_MASK; | 384 | mask = S3C2410_MISCCR_CLK0_MASK; |
381 | else { | 385 | else { |
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c index 36b8291b5e03..f372fbda124e 100644 --- a/arch/arm/mach-s3c2410/common-smdk.c +++ b/arch/arm/mach-s3c2410/common-smdk.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include <asm/arch/nand.h> | 38 | #include <asm/arch/nand.h> |
39 | 39 | ||
40 | #include "common-smdk.h" | ||
40 | #include "devs.h" | 41 | #include "devs.h" |
41 | #include "pm.h" | 42 | #include "pm.h" |
42 | 43 | ||
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 5c4055b62d97..54e3c5bb5186 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <asm/hardware.h> | 13 | #include <asm/memory.h> |
14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
15 | #include "proc-macros.S" | 15 | #include "proc-macros.S" |
16 | 16 | ||
@@ -46,6 +46,11 @@ | |||
46 | */ | 46 | */ |
47 | #define CACHE_DLIMIT (CACHE_DSIZE * 4) | 47 | #define CACHE_DLIMIT (CACHE_DSIZE * 4) |
48 | 48 | ||
49 | .data | ||
50 | flush_base: | ||
51 | .long FLUSH_BASE | ||
52 | .text | ||
53 | |||
49 | /* | 54 | /* |
50 | * flush_user_cache_all() | 55 | * flush_user_cache_all() |
51 | * | 56 | * |
@@ -63,11 +68,21 @@ ENTRY(v4wb_flush_kern_cache_all) | |||
63 | mov ip, #0 | 68 | mov ip, #0 |
64 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache | 69 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache |
65 | __flush_whole_cache: | 70 | __flush_whole_cache: |
66 | mov r0, #FLUSH_BASE | 71 | ldr r3, =flush_base |
67 | add r1, r0, #CACHE_DSIZE | 72 | ldr r1, [r3, #0] |
68 | 1: ldr r2, [r0], #32 | 73 | eor r1, r1, #CACHE_DSIZE |
69 | cmp r0, r1 | 74 | str r1, [r3, #0] |
75 | add r2, r1, #CACHE_DSIZE | ||
76 | 1: ldr r3, [r1], #32 | ||
77 | cmp r1, r2 | ||
78 | blo 1b | ||
79 | #ifdef FLUSH_BASE_MINICACHE | ||
80 | add r2, r2, #FLUSH_BASE_MINICACHE - FLUSH_BASE | ||
81 | sub r1, r2, #512 @ only 512 bytes | ||
82 | 1: ldr r3, [r1], #32 | ||
83 | cmp r1, r2 | ||
70 | blo 1b | 84 | blo 1b |
85 | #endif | ||
71 | mcr p15, 0, ip, c7, c10, 4 @ drain write buffer | 86 | mcr p15, 0, ip, c7, c10, 4 @ drain write buffer |
72 | mov pc, lr | 87 | mov pc, lr |
73 | 88 | ||
@@ -82,6 +97,7 @@ __flush_whole_cache: | |||
82 | * - flags - vma_area_struct flags describing address space | 97 | * - flags - vma_area_struct flags describing address space |
83 | */ | 98 | */ |
84 | ENTRY(v4wb_flush_user_cache_range) | 99 | ENTRY(v4wb_flush_user_cache_range) |
100 | mov ip, #0 | ||
85 | sub r3, r1, r0 @ calculate total size | 101 | sub r3, r1, r0 @ calculate total size |
86 | tst r2, #VM_EXEC @ executable region? | 102 | tst r2, #VM_EXEC @ executable region? |
87 | mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache | 103 | mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 88279124317a..9ea1f87a7079 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
22 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
23 | #include <asm/sizes.h> | ||
23 | #include <asm/tlb.h> | 24 | #include <asm/tlb.h> |
24 | 25 | ||
25 | #include <asm/mach/arch.h> | 26 | #include <asm/mach/arch.h> |
@@ -455,14 +456,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
455 | #ifdef FLUSH_BASE | 456 | #ifdef FLUSH_BASE |
456 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); | 457 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); |
457 | map.virtual = FLUSH_BASE; | 458 | map.virtual = FLUSH_BASE; |
458 | map.length = PGDIR_SIZE; | 459 | map.length = SZ_1M; |
459 | map.type = MT_CACHECLEAN; | 460 | map.type = MT_CACHECLEAN; |
460 | create_mapping(&map); | 461 | create_mapping(&map); |
461 | #endif | 462 | #endif |
462 | #ifdef FLUSH_BASE_MINICACHE | 463 | #ifdef FLUSH_BASE_MINICACHE |
463 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE); | 464 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); |
464 | map.virtual = FLUSH_BASE_MINICACHE; | 465 | map.virtual = FLUSH_BASE_MINICACHE; |
465 | map.length = PGDIR_SIZE; | 466 | map.length = SZ_1M; |
466 | map.type = MT_MINICLEAN; | 467 | map.type = MT_MINICLEAN; |
467 | create_mapping(&map); | 468 | create_mapping(&map); |
468 | #endif | 469 | #endif |
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index c916a6cae404..a2dd5ae1077d 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S | |||
@@ -26,22 +26,7 @@ | |||
26 | * the cache line size of the I and D cache | 26 | * the cache line size of the I and D cache |
27 | */ | 27 | */ |
28 | #define DCACHELINESIZE 32 | 28 | #define DCACHELINESIZE 32 |
29 | #define FLUSH_OFFSET 32768 | ||
30 | 29 | ||
31 | .macro flush_110_dcache rd, ra, re | ||
32 | ldr \rd, =flush_base | ||
33 | ldr \ra, [\rd] | ||
34 | eor \ra, \ra, #FLUSH_OFFSET | ||
35 | str \ra, [\rd] | ||
36 | add \re, \ra, #16384 @ only necessary for 16k | ||
37 | 1001: ldr \rd, [\ra], #DCACHELINESIZE | ||
38 | teq \re, \ra | ||
39 | bne 1001b | ||
40 | .endm | ||
41 | |||
42 | .data | ||
43 | flush_base: | ||
44 | .long FLUSH_BASE | ||
45 | .text | 30 | .text |
46 | 31 | ||
47 | /* | 32 | /* |
@@ -145,13 +130,11 @@ ENTRY(cpu_sa110_dcache_clean_area) | |||
145 | */ | 130 | */ |
146 | .align 5 | 131 | .align 5 |
147 | ENTRY(cpu_sa110_switch_mm) | 132 | ENTRY(cpu_sa110_switch_mm) |
148 | flush_110_dcache r3, ip, r1 | 133 | str lr, [sp, #-4]! |
149 | mov r1, #0 | 134 | bl v4wb_flush_kern_cache_all @ clears IP |
150 | mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache | ||
151 | mcr p15, 0, r1, c7, c10, 4 @ drain WB | ||
152 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | 135 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer |
153 | mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs | 136 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
154 | mov pc, lr | 137 | ldr pc, [sp], #4 |
155 | 138 | ||
156 | /* | 139 | /* |
157 | * cpu_sa110_set_pte(ptep, pte) | 140 | * cpu_sa110_set_pte(ptep, pte) |
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 41f21f2dd8ff..777ad99c1439 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S | |||
@@ -30,30 +30,6 @@ | |||
30 | * the cache line size of the I and D cache | 30 | * the cache line size of the I and D cache |
31 | */ | 31 | */ |
32 | #define DCACHELINESIZE 32 | 32 | #define DCACHELINESIZE 32 |
33 | #define FLUSH_OFFSET 32768 | ||
34 | |||
35 | .macro flush_1100_dcache rd, ra, re | ||
36 | ldr \rd, =flush_base | ||
37 | ldr \ra, [\rd] | ||
38 | eor \ra, \ra, #FLUSH_OFFSET | ||
39 | str \ra, [\rd] | ||
40 | add \re, \ra, #8192 @ only necessary for 8k | ||
41 | 1001: ldr \rd, [\ra], #DCACHELINESIZE | ||
42 | teq \re, \ra | ||
43 | bne 1001b | ||
44 | #ifdef FLUSH_BASE_MINICACHE | ||
45 | add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE | ||
46 | add \re, \ra, #512 @ only 512 bytes | ||
47 | 1002: ldr \rd, [\ra], #DCACHELINESIZE | ||
48 | teq \re, \ra | ||
49 | bne 1002b | ||
50 | #endif | ||
51 | .endm | ||
52 | |||
53 | .data | ||
54 | flush_base: | ||
55 | .long FLUSH_BASE | ||
56 | .text | ||
57 | 33 | ||
58 | __INIT | 34 | __INIT |
59 | 35 | ||
@@ -79,9 +55,8 @@ ENTRY(cpu_sa1100_proc_fin) | |||
79 | stmfd sp!, {lr} | 55 | stmfd sp!, {lr} |
80 | mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE | 56 | mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE |
81 | msr cpsr_c, ip | 57 | msr cpsr_c, ip |
82 | flush_1100_dcache r0, r1, r2 @ clean caches | 58 | bl v4wb_flush_kern_cache_all |
83 | mov r0, #0 | 59 | mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching |
84 | mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching | ||
85 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register | 60 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register |
86 | bic r0, r0, #0x1000 @ ...i............ | 61 | bic r0, r0, #0x1000 @ ...i............ |
87 | bic r0, r0, #0x000e @ ............wca. | 62 | bic r0, r0, #0x000e @ ............wca. |
@@ -167,14 +142,12 @@ ENTRY(cpu_sa1100_dcache_clean_area) | |||
167 | */ | 142 | */ |
168 | .align 5 | 143 | .align 5 |
169 | ENTRY(cpu_sa1100_switch_mm) | 144 | ENTRY(cpu_sa1100_switch_mm) |
170 | flush_1100_dcache r3, ip, r1 | 145 | str lr, [sp, #-4]! |
171 | mov ip, #0 | 146 | bl v4wb_flush_kern_cache_all @ clears IP |
172 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache | ||
173 | mcr p15, 0, ip, c9, c0, 0 @ invalidate RB | 147 | mcr p15, 0, ip, c9, c0, 0 @ invalidate RB |
174 | mcr p15, 0, ip, c7, c10, 4 @ drain WB | ||
175 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | 148 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer |
176 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | 149 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
177 | mov pc, lr | 150 | ldr pc, [sp], #4 |
178 | 151 | ||
179 | /* | 152 | /* |
180 | * cpu_sa1100_set_pte(ptep, pte) | 153 | * cpu_sa1100_set_pte(ptep, pte) |
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 06485c193ee3..32ec04c58bcd 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -58,7 +58,7 @@ struct clk * clk_get(struct device *dev, const char *id) | |||
58 | if (p->id == idno && | 58 | if (p->id == idno && |
59 | strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | 59 | strcmp(id, p->name) == 0 && try_module_get(p->owner)) { |
60 | clk = p; | 60 | clk = p; |
61 | break; | 61 | goto found; |
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
@@ -69,6 +69,7 @@ struct clk * clk_get(struct device *dev, const char *id) | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | found: | ||
72 | mutex_unlock(&clocks_mutex); | 73 | mutex_unlock(&clocks_mutex); |
73 | 74 | ||
74 | return clk; | 75 | return clk; |
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 079b67deac0f..5d5d6eb222dd 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
@@ -26,14 +26,6 @@ | |||
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | #include <asm/arch/menelaus.h> | 27 | #include <asm/arch/menelaus.h> |
28 | 28 | ||
29 | |||
30 | void omap_nop_release(struct device *dev) | ||
31 | { | ||
32 | /* Nothing */ | ||
33 | } | ||
34 | |||
35 | /*-------------------------------------------------------------------------*/ | ||
36 | |||
37 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | 29 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) |
38 | 30 | ||
39 | #define OMAP1_I2C_BASE 0xfffb3800 | 31 | #define OMAP1_I2C_BASE 0xfffb3800 |
@@ -59,9 +51,6 @@ static struct resource i2c_resources1[] = { | |||
59 | static struct platform_device omap_i2c_device1 = { | 51 | static struct platform_device omap_i2c_device1 = { |
60 | .name = "i2c_omap", | 52 | .name = "i2c_omap", |
61 | .id = 1, | 53 | .id = 1, |
62 | .dev = { | ||
63 | .release = omap_nop_release, | ||
64 | }, | ||
65 | .num_resources = ARRAY_SIZE(i2c_resources1), | 54 | .num_resources = ARRAY_SIZE(i2c_resources1), |
66 | .resource = i2c_resources1, | 55 | .resource = i2c_resources1, |
67 | }; | 56 | }; |
@@ -187,7 +176,6 @@ static struct platform_device mmc_omap_device1 = { | |||
187 | .name = "mmci-omap", | 176 | .name = "mmci-omap", |
188 | .id = 1, | 177 | .id = 1, |
189 | .dev = { | 178 | .dev = { |
190 | .release = omap_nop_release, | ||
191 | .dma_mask = &mmc1_dmamask, | 179 | .dma_mask = &mmc1_dmamask, |
192 | .platform_data = &mmc1_conf, | 180 | .platform_data = &mmc1_conf, |
193 | }, | 181 | }, |
@@ -217,7 +205,6 @@ static struct platform_device mmc_omap_device2 = { | |||
217 | .name = "mmci-omap", | 205 | .name = "mmci-omap", |
218 | .id = 2, | 206 | .id = 2, |
219 | .dev = { | 207 | .dev = { |
220 | .release = omap_nop_release, | ||
221 | .dma_mask = &mmc2_dmamask, | 208 | .dma_mask = &mmc2_dmamask, |
222 | .platform_data = &mmc2_conf, | 209 | .platform_data = &mmc2_conf, |
223 | }, | 210 | }, |
@@ -321,9 +308,6 @@ static struct resource uwire_resources[] = { | |||
321 | static struct platform_device omap_uwire_device = { | 308 | static struct platform_device omap_uwire_device = { |
322 | .name = "omap_uwire", | 309 | .name = "omap_uwire", |
323 | .id = -1, | 310 | .id = -1, |
324 | .dev = { | ||
325 | .release = omap_nop_release, | ||
326 | }, | ||
327 | .num_resources = ARRAY_SIZE(uwire_resources), | 311 | .num_resources = ARRAY_SIZE(uwire_resources), |
328 | .resource = uwire_resources, | 312 | .resource = uwire_resources, |
329 | }; | 313 | }; |
@@ -365,9 +349,6 @@ static struct resource wdt_resources[] = { | |||
365 | static struct platform_device omap_wdt_device = { | 349 | static struct platform_device omap_wdt_device = { |
366 | .name = "omap_wdt", | 350 | .name = "omap_wdt", |
367 | .id = -1, | 351 | .id = -1, |
368 | .dev = { | ||
369 | .release = omap_nop_release, | ||
370 | }, | ||
371 | .num_resources = ARRAY_SIZE(wdt_resources), | 352 | .num_resources = ARRAY_SIZE(wdt_resources), |
372 | .resource = wdt_resources, | 353 | .resource = wdt_resources, |
373 | }; | 354 | }; |
@@ -401,9 +382,6 @@ static struct resource rng_resources[] = { | |||
401 | static struct platform_device omap_rng_device = { | 382 | static struct platform_device omap_rng_device = { |
402 | .name = "omap_rng", | 383 | .name = "omap_rng", |
403 | .id = -1, | 384 | .id = -1, |
404 | .dev = { | ||
405 | .release = omap_nop_release, | ||
406 | }, | ||
407 | .num_resources = ARRAY_SIZE(rng_resources), | 385 | .num_resources = ARRAY_SIZE(rng_resources), |
408 | .resource = rng_resources, | 386 | .resource = rng_resources, |
409 | }; | 387 | }; |
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 9b367a65cb4d..febd115dba28 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c | |||
@@ -588,6 +588,7 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) | |||
588 | struct vfp_double vdm; | 588 | struct vfp_double vdm; |
589 | u32 d, exceptions = 0; | 589 | u32 d, exceptions = 0; |
590 | int rmode = fpscr & FPSCR_RMODE_MASK; | 590 | int rmode = fpscr & FPSCR_RMODE_MASK; |
591 | int tm; | ||
591 | 592 | ||
592 | vfp_double_unpack(&vdm, vfp_get_double(dm)); | 593 | vfp_double_unpack(&vdm, vfp_get_double(dm)); |
593 | vfp_double_dump("VDM", &vdm); | 594 | vfp_double_dump("VDM", &vdm); |
@@ -595,10 +596,14 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) | |||
595 | /* | 596 | /* |
596 | * Do we have denormalised number? | 597 | * Do we have denormalised number? |
597 | */ | 598 | */ |
598 | if (vfp_double_type(&vdm) & VFP_DENORMAL) | 599 | tm = vfp_double_type(&vdm); |
600 | if (tm & VFP_DENORMAL) | ||
599 | exceptions |= FPSCR_IDC; | 601 | exceptions |= FPSCR_IDC; |
600 | 602 | ||
601 | if (vdm.exponent >= 1023 + 32) { | 603 | if (tm & VFP_NAN) { |
604 | d = 0; | ||
605 | exceptions |= FPSCR_IOC; | ||
606 | } else if (vdm.exponent >= 1023 + 32) { | ||
602 | d = 0x7fffffff; | 607 | d = 0x7fffffff; |
603 | if (vdm.sign) | 608 | if (vdm.sign) |
604 | d = ~d; | 609 | d = ~d; |
@@ -1122,9 +1127,9 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1122 | { | 1127 | { |
1123 | u32 op = inst & FOP_MASK; | 1128 | u32 op = inst & FOP_MASK; |
1124 | u32 exceptions = 0; | 1129 | u32 exceptions = 0; |
1125 | unsigned int dd = vfp_get_sd(inst); | 1130 | unsigned int dd = vfp_get_dd(inst); |
1126 | unsigned int dn = vfp_get_sn(inst); | 1131 | unsigned int dn = vfp_get_dn(inst); |
1127 | unsigned int dm = vfp_get_sm(inst); | 1132 | unsigned int dm = vfp_get_dm(inst); |
1128 | unsigned int vecitr, veclen, vecstride; | 1133 | unsigned int vecitr, veclen, vecstride; |
1129 | u32 (*fop)(int, int, s32, u32); | 1134 | u32 (*fop)(int, int, s32, u32); |
1130 | 1135 | ||
@@ -1141,7 +1146,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1141 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, | 1146 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, |
1142 | (veclen >> FPSCR_LENGTH_BIT) + 1); | 1147 | (veclen >> FPSCR_LENGTH_BIT) + 1); |
1143 | 1148 | ||
1144 | fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; | 1149 | fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; |
1145 | if (!fop) | 1150 | if (!fop) |
1146 | goto invalid; | 1151 | goto invalid; |
1147 | 1152 | ||
@@ -1149,17 +1154,13 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1149 | u32 except; | 1154 | u32 except; |
1150 | 1155 | ||
1151 | if (op == FOP_EXT) | 1156 | if (op == FOP_EXT) |
1152 | pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", | 1157 | pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", |
1153 | vecitr >> FPSCR_LENGTH_BIT, | 1158 | vecitr >> FPSCR_LENGTH_BIT, |
1154 | dd >> 1, dd & 1, dn, | 1159 | dd, dn, dm); |
1155 | dm >> 1, dm & 1); | ||
1156 | else | 1160 | else |
1157 | pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", | 1161 | pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", |
1158 | vecitr >> FPSCR_LENGTH_BIT, | 1162 | vecitr >> FPSCR_LENGTH_BIT, |
1159 | dd >> 1, dd & 1, | 1163 | dd, dn, FOP_TO_IDX(op), dm); |
1160 | dn >> 1, dn & 1, | ||
1161 | FOP_TO_IDX(op), | ||
1162 | dm >> 1, dm & 1); | ||
1163 | 1164 | ||
1164 | except = fop(dd, dn, dm, fpscr); | 1165 | except = fop(dd, dn, dm, fpscr); |
1165 | pr_debug("VFP: itr%d: exceptions=%08x\n", | 1166 | pr_debug("VFP: itr%d: exceptions=%08x\n", |
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index b7ed57e00cd4..a3f65b47aea9 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -189,11 +189,10 @@ vfp_put_float: | |||
189 | 189 | ||
190 | .globl vfp_get_double | 190 | .globl vfp_get_double |
191 | vfp_get_double: | 191 | vfp_get_double: |
192 | mov r0, r0, lsr #1 | ||
193 | add pc, pc, r0, lsl #3 | 192 | add pc, pc, r0, lsl #3 |
194 | mov r0, r0 | 193 | mov r0, r0 |
195 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 194 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
196 | mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr | 195 | mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr |
197 | mov pc, lr | 196 | mov pc, lr |
198 | .endr | 197 | .endr |
199 | 198 | ||
@@ -204,10 +203,9 @@ vfp_get_double: | |||
204 | 203 | ||
205 | .globl vfp_put_double | 204 | .globl vfp_put_double |
206 | vfp_put_double: | 205 | vfp_put_double: |
207 | mov r0, r0, lsr #1 | ||
208 | add pc, pc, r0, lsl #3 | 206 | add pc, pc, r0, lsl #3 |
209 | mov r0, r0 | 207 | mov r0, r0 |
210 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 208 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
211 | mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr | 209 | mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr |
212 | mov pc, lr | 210 | mov pc, lr |
213 | .endr | 211 | .endr |
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 14dd696ddeb1..4ac27f193934 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c | |||
@@ -632,6 +632,7 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) | |||
632 | struct vfp_single vsm; | 632 | struct vfp_single vsm; |
633 | u32 d, exceptions = 0; | 633 | u32 d, exceptions = 0; |
634 | int rmode = fpscr & FPSCR_RMODE_MASK; | 634 | int rmode = fpscr & FPSCR_RMODE_MASK; |
635 | int tm; | ||
635 | 636 | ||
636 | vfp_single_unpack(&vsm, m); | 637 | vfp_single_unpack(&vsm, m); |
637 | vfp_single_dump("VSM", &vsm); | 638 | vfp_single_dump("VSM", &vsm); |
@@ -639,10 +640,14 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) | |||
639 | /* | 640 | /* |
640 | * Do we have a denormalised number? | 641 | * Do we have a denormalised number? |
641 | */ | 642 | */ |
643 | tm = vfp_single_type(&vsm); | ||
642 | if (vfp_single_type(&vsm) & VFP_DENORMAL) | 644 | if (vfp_single_type(&vsm) & VFP_DENORMAL) |
643 | exceptions |= FPSCR_IDC; | 645 | exceptions |= FPSCR_IDC; |
644 | 646 | ||
645 | if (vsm.exponent >= 127 + 32) { | 647 | if (tm & VFP_NAN) { |
648 | d = 0; | ||
649 | exceptions |= FPSCR_IOC; | ||
650 | } else if (vsm.exponent >= 127 + 32) { | ||
646 | /* | 651 | /* |
647 | * m >= 2^31-2^7: invalid | 652 | * m >= 2^31-2^7: invalid |
648 | */ | 653 | */ |
@@ -1188,7 +1193,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) | |||
1188 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, | 1193 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, |
1189 | (veclen >> FPSCR_LENGTH_BIT) + 1); | 1194 | (veclen >> FPSCR_LENGTH_BIT) + 1); |
1190 | 1195 | ||
1191 | fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; | 1196 | fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; |
1192 | if (!fop) | 1197 | if (!fop) |
1193 | goto invalid; | 1198 | goto invalid; |
1194 | 1199 | ||
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c index a6a1b3373444..9d66c27f2724 100644 --- a/arch/arm26/kernel/armksyms.c +++ b/arch/arm26/kernel/armksyms.c | |||
@@ -152,7 +152,6 @@ EXPORT_SYMBOL(strncmp); | |||
152 | EXPORT_SYMBOL(strchr); | 152 | EXPORT_SYMBOL(strchr); |
153 | EXPORT_SYMBOL(strlen); | 153 | EXPORT_SYMBOL(strlen); |
154 | EXPORT_SYMBOL(strnlen); | 154 | EXPORT_SYMBOL(strnlen); |
155 | EXPORT_SYMBOL(strpbrk); | ||
156 | EXPORT_SYMBOL(strrchr); | 155 | EXPORT_SYMBOL(strrchr); |
157 | EXPORT_SYMBOL(strstr); | 156 | EXPORT_SYMBOL(strstr); |
158 | EXPORT_SYMBOL(memset); | 157 | EXPORT_SYMBOL(memset); |
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c index de39725da920..d57859053ce7 100644 --- a/arch/cris/kernel/crisksyms.c +++ b/arch/cris/kernel/crisksyms.c | |||
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(loops_per_usec); | |||
39 | /* String functions */ | 39 | /* String functions */ |
40 | EXPORT_SYMBOL(memcmp); | 40 | EXPORT_SYMBOL(memcmp); |
41 | EXPORT_SYMBOL(memmove); | 41 | EXPORT_SYMBOL(memmove); |
42 | EXPORT_SYMBOL(strpbrk); | ||
43 | EXPORT_SYMBOL(strstr); | 42 | EXPORT_SYMBOL(strstr); |
44 | EXPORT_SYMBOL(strcpy); | 43 | EXPORT_SYMBOL(strcpy); |
45 | EXPORT_SYMBOL(strchr); | 44 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 1d21c8d34d8a..a9b59527a741 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -1170,12 +1170,6 @@ __syscall_badsys: | |||
1170 | # syscall vector table | 1170 | # syscall vector table |
1171 | # | 1171 | # |
1172 | ############################################################################### | 1172 | ############################################################################### |
1173 | #ifdef CONFIG_MMU | ||
1174 | #define __MMU(X) X | ||
1175 | #else | ||
1176 | #define __MMU(X) sys_ni_syscall | ||
1177 | #endif | ||
1178 | |||
1179 | .section .rodata | 1173 | .section .rodata |
1180 | ALIGN | 1174 | ALIGN |
1181 | .globl sys_call_table | 1175 | .globl sys_call_table |
@@ -1305,7 +1299,7 @@ sys_call_table: | |||
1305 | .long sys_newuname | 1299 | .long sys_newuname |
1306 | .long sys_ni_syscall /* old "cacheflush" */ | 1300 | .long sys_ni_syscall /* old "cacheflush" */ |
1307 | .long sys_adjtimex | 1301 | .long sys_adjtimex |
1308 | .long __MMU(sys_mprotect) /* 125 */ | 1302 | .long sys_mprotect /* 125 */ |
1309 | .long sys_sigprocmask | 1303 | .long sys_sigprocmask |
1310 | .long sys_ni_syscall /* old "create_module" */ | 1304 | .long sys_ni_syscall /* old "create_module" */ |
1311 | .long sys_init_module | 1305 | .long sys_init_module |
@@ -1324,16 +1318,16 @@ sys_call_table: | |||
1324 | .long sys_getdents | 1318 | .long sys_getdents |
1325 | .long sys_select | 1319 | .long sys_select |
1326 | .long sys_flock | 1320 | .long sys_flock |
1327 | .long __MMU(sys_msync) | 1321 | .long sys_msync |
1328 | .long sys_readv /* 145 */ | 1322 | .long sys_readv /* 145 */ |
1329 | .long sys_writev | 1323 | .long sys_writev |
1330 | .long sys_getsid | 1324 | .long sys_getsid |
1331 | .long sys_fdatasync | 1325 | .long sys_fdatasync |
1332 | .long sys_sysctl | 1326 | .long sys_sysctl |
1333 | .long __MMU(sys_mlock) /* 150 */ | 1327 | .long sys_mlock /* 150 */ |
1334 | .long __MMU(sys_munlock) | 1328 | .long sys_munlock |
1335 | .long __MMU(sys_mlockall) | 1329 | .long sys_mlockall |
1336 | .long __MMU(sys_munlockall) | 1330 | .long sys_munlockall |
1337 | .long sys_sched_setparam | 1331 | .long sys_sched_setparam |
1338 | .long sys_sched_getparam /* 155 */ | 1332 | .long sys_sched_getparam /* 155 */ |
1339 | .long sys_sched_setscheduler | 1333 | .long sys_sched_setscheduler |
@@ -1343,7 +1337,7 @@ sys_call_table: | |||
1343 | .long sys_sched_get_priority_min /* 160 */ | 1337 | .long sys_sched_get_priority_min /* 160 */ |
1344 | .long sys_sched_rr_get_interval | 1338 | .long sys_sched_rr_get_interval |
1345 | .long sys_nanosleep | 1339 | .long sys_nanosleep |
1346 | .long __MMU(sys_mremap) | 1340 | .long sys_mremap |
1347 | .long sys_setresuid16 | 1341 | .long sys_setresuid16 |
1348 | .long sys_getresuid16 /* 165 */ | 1342 | .long sys_getresuid16 /* 165 */ |
1349 | .long sys_ni_syscall /* for vm86 */ | 1343 | .long sys_ni_syscall /* for vm86 */ |
@@ -1398,8 +1392,8 @@ sys_call_table: | |||
1398 | .long sys_setfsuid /* 215 */ | 1392 | .long sys_setfsuid /* 215 */ |
1399 | .long sys_setfsgid | 1393 | .long sys_setfsgid |
1400 | .long sys_pivot_root | 1394 | .long sys_pivot_root |
1401 | .long __MMU(sys_mincore) | 1395 | .long sys_mincore |
1402 | .long __MMU(sys_madvise) | 1396 | .long sys_madvise |
1403 | .long sys_getdents64 /* 220 */ | 1397 | .long sys_getdents64 /* 220 */ |
1404 | .long sys_fcntl64 | 1398 | .long sys_fcntl64 |
1405 | .long sys_ni_syscall /* reserved for TUX */ | 1399 | .long sys_ni_syscall /* reserved for TUX */ |
@@ -1437,7 +1431,7 @@ sys_call_table: | |||
1437 | .long sys_epoll_create | 1431 | .long sys_epoll_create |
1438 | .long sys_epoll_ctl /* 255 */ | 1432 | .long sys_epoll_ctl /* 255 */ |
1439 | .long sys_epoll_wait | 1433 | .long sys_epoll_wait |
1440 | .long __MMU(sys_remap_file_pages) | 1434 | .long sys_remap_file_pages |
1441 | .long sys_set_tid_address | 1435 | .long sys_set_tid_address |
1442 | .long sys_timer_create | 1436 | .long sys_timer_create |
1443 | .long sys_timer_settime /* 260 */ | 1437 | .long sys_timer_settime /* 260 */ |
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index 07c8ffa0dd39..0f273a7aca5a 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c | |||
@@ -27,7 +27,6 @@ EXPORT_SYMBOL(__ioremap); | |||
27 | EXPORT_SYMBOL(iounmap); | 27 | EXPORT_SYMBOL(iounmap); |
28 | 28 | ||
29 | EXPORT_SYMBOL(strnlen); | 29 | EXPORT_SYMBOL(strnlen); |
30 | EXPORT_SYMBOL(strpbrk); | ||
31 | EXPORT_SYMBOL(strrchr); | 30 | EXPORT_SYMBOL(strrchr); |
32 | EXPORT_SYMBOL(strstr); | 31 | EXPORT_SYMBOL(strstr); |
33 | EXPORT_SYMBOL(strchr); | 32 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index b6cd78c972bb..f8d6dee84781 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c | |||
@@ -25,7 +25,6 @@ extern char h8300_debug_device[]; | |||
25 | /* platform dependent support */ | 25 | /* platform dependent support */ |
26 | 26 | ||
27 | EXPORT_SYMBOL(strnlen); | 27 | EXPORT_SYMBOL(strnlen); |
28 | EXPORT_SYMBOL(strpbrk); | ||
29 | EXPORT_SYMBOL(strrchr); | 28 | EXPORT_SYMBOL(strrchr); |
30 | EXPORT_SYMBOL(strstr); | 29 | EXPORT_SYMBOL(strstr); |
31 | EXPORT_SYMBOL(strchr); | 30 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f17bd1d2707e..18ec9fe6deb6 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -53,6 +53,35 @@ source "init/Kconfig" | |||
53 | 53 | ||
54 | menu "Processor type and features" | 54 | menu "Processor type and features" |
55 | 55 | ||
56 | config SMP | ||
57 | bool "Symmetric multi-processing support" | ||
58 | ---help--- | ||
59 | This enables support for systems with more than one CPU. If you have | ||
60 | a system with only one CPU, like most personal computers, say N. If | ||
61 | you have a system with more than one CPU, say Y. | ||
62 | |||
63 | If you say N here, the kernel will run on single and multiprocessor | ||
64 | machines, but will use only one CPU of a multiprocessor machine. If | ||
65 | you say Y here, the kernel will run on many, but not all, | ||
66 | singleprocessor machines. On a singleprocessor machine, the kernel | ||
67 | will run faster if you say N here. | ||
68 | |||
69 | Note that if you say Y here and choose architecture "586" or | ||
70 | "Pentium" under "Processor family", the kernel will not work on 486 | ||
71 | architectures. Similarly, multiprocessor kernels for the "PPro" | ||
72 | architecture may not work on all Pentium based boards. | ||
73 | |||
74 | People using multiprocessor machines who say Y here should also say | ||
75 | Y to "Enhanced Real Time Clock Support", below. The "Advanced Power | ||
76 | Management" code will be disabled if you say Y here. | ||
77 | |||
78 | See also the <file:Documentation/smp.txt>, | ||
79 | <file:Documentation/i386/IO-APIC.txt>, | ||
80 | <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at | ||
81 | <http://www.tldp.org/docs.html#howto>. | ||
82 | |||
83 | If you don't know what to do here, say N. | ||
84 | |||
56 | choice | 85 | choice |
57 | prompt "Subarchitecture Type" | 86 | prompt "Subarchitecture Type" |
58 | default X86_PC | 87 | default X86_PC |
@@ -178,35 +207,6 @@ config HPET_EMULATE_RTC | |||
178 | depends on HPET_TIMER && RTC=y | 207 | depends on HPET_TIMER && RTC=y |
179 | default y | 208 | default y |
180 | 209 | ||
181 | config SMP | ||
182 | bool "Symmetric multi-processing support" | ||
183 | ---help--- | ||
184 | This enables support for systems with more than one CPU. If you have | ||
185 | a system with only one CPU, like most personal computers, say N. If | ||
186 | you have a system with more than one CPU, say Y. | ||
187 | |||
188 | If you say N here, the kernel will run on single and multiprocessor | ||
189 | machines, but will use only one CPU of a multiprocessor machine. If | ||
190 | you say Y here, the kernel will run on many, but not all, | ||
191 | singleprocessor machines. On a singleprocessor machine, the kernel | ||
192 | will run faster if you say N here. | ||
193 | |||
194 | Note that if you say Y here and choose architecture "586" or | ||
195 | "Pentium" under "Processor family", the kernel will not work on 486 | ||
196 | architectures. Similarly, multiprocessor kernels for the "PPro" | ||
197 | architecture may not work on all Pentium based boards. | ||
198 | |||
199 | People using multiprocessor machines who say Y here should also say | ||
200 | Y to "Enhanced Real Time Clock Support", below. The "Advanced Power | ||
201 | Management" code will be disabled if you say Y here. | ||
202 | |||
203 | See also the <file:Documentation/smp.txt>, | ||
204 | <file:Documentation/i386/IO-APIC.txt>, | ||
205 | <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at | ||
206 | <http://www.tldp.org/docs.html#howto>. | ||
207 | |||
208 | If you don't know what to do here, say N. | ||
209 | |||
210 | config NR_CPUS | 210 | config NR_CPUS |
211 | int "Maximum number of CPUs (2-255)" | 211 | int "Maximum number of CPUs (2-255)" |
212 | range 2 255 | 212 | range 2 255 |
@@ -522,6 +522,12 @@ config NUMA | |||
522 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" | 522 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" |
523 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) | 523 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) |
524 | 524 | ||
525 | config NODES_SHIFT | ||
526 | int | ||
527 | default "4" if X86_NUMAQ | ||
528 | default "3" | ||
529 | depends on NEED_MULTIPLE_NODES | ||
530 | |||
525 | config HAVE_ARCH_BOOTMEM_NODE | 531 | config HAVE_ARCH_BOOTMEM_NODE |
526 | bool | 532 | bool |
527 | depends on NUMA | 533 | depends on NUMA |
@@ -757,15 +763,6 @@ config HOTPLUG_CPU | |||
757 | 763 | ||
758 | Say N. | 764 | Say N. |
759 | 765 | ||
760 | config DOUBLEFAULT | ||
761 | default y | ||
762 | bool "Enable doublefault exception handler" if EMBEDDED | ||
763 | help | ||
764 | This option allows trapping of rare doublefault exceptions that | ||
765 | would otherwise cause a system to silently reboot. Disabling this | ||
766 | option saves about 4k and might cause you much additional grey | ||
767 | hair. | ||
768 | |||
769 | endmenu | 766 | endmenu |
770 | 767 | ||
771 | 768 | ||
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index 79603b3471f9..eb130482ba18 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu | |||
@@ -311,5 +311,5 @@ config X86_OOSTORE | |||
311 | 311 | ||
312 | config X86_TSC | 312 | config X86_TSC |
313 | bool | 313 | bool |
314 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ | 314 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ |
315 | default y | 315 | default y |
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 0000a2674537..c9343c3a8082 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S | |||
@@ -97,6 +97,7 @@ | |||
97 | #define PARAM_VESAPM_OFF 0x30 | 97 | #define PARAM_VESAPM_OFF 0x30 |
98 | #define PARAM_LFB_PAGES 0x32 | 98 | #define PARAM_LFB_PAGES 0x32 |
99 | #define PARAM_VESA_ATTRIB 0x34 | 99 | #define PARAM_VESA_ATTRIB 0x34 |
100 | #define PARAM_CAPABILITIES 0x36 | ||
100 | 101 | ||
101 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ | 102 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ |
102 | #ifdef CONFIG_VIDEO_RETAIN | 103 | #ifdef CONFIG_VIDEO_RETAIN |
@@ -233,6 +234,10 @@ mopar_gr: | |||
233 | movw 18(%di), %ax | 234 | movw 18(%di), %ax |
234 | movl %eax, %fs:(PARAM_LFB_SIZE) | 235 | movl %eax, %fs:(PARAM_LFB_SIZE) |
235 | 236 | ||
237 | # store mode capabilities | ||
238 | movl 10(%di), %eax | ||
239 | movl %eax, %fs:(PARAM_CAPABILITIES) | ||
240 | |||
236 | # switching the DAC to 8-bit is for <= 8 bpp only | 241 | # switching the DAC to 8-bit is for <= 8 bpp only |
237 | movw %fs:(PARAM_LFB_DEPTH), %ax | 242 | movw %fs:(PARAM_LFB_DEPTH), %ax |
238 | cmpw $8, %ax | 243 | cmpw $8, %ax |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 033066176b3e..030a0007a4e0 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -168,7 +168,7 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
168 | unsigned long i; | 168 | unsigned long i; |
169 | int config_size; | 169 | int config_size; |
170 | 170 | ||
171 | if (!phys_addr || !size) | 171 | if (!phys_addr || !size || !cpu_has_apic) |
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | 173 | ||
174 | mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); | 174 | mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); |
@@ -215,7 +215,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) | |||
215 | { | 215 | { |
216 | struct acpi_table_madt *madt = NULL; | 216 | struct acpi_table_madt *madt = NULL; |
217 | 217 | ||
218 | if (!phys_addr || !size) | 218 | if (!phys_addr || !size || !cpu_has_apic) |
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | 220 | ||
221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); | 221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); |
@@ -693,6 +693,9 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
693 | { | 693 | { |
694 | int count; | 694 | int count; |
695 | 695 | ||
696 | if (!cpu_has_apic) | ||
697 | return -ENODEV; | ||
698 | |||
696 | /* | 699 | /* |
697 | * Note that the LAPIC address is obtained from the MADT (32-bit value) | 700 | * Note that the LAPIC address is obtained from the MADT (32-bit value) |
698 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). | 701 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). |
@@ -751,6 +754,9 @@ static int __init acpi_parse_madt_ioapic_entries(void) | |||
751 | return -ENODEV; | 754 | return -ENODEV; |
752 | } | 755 | } |
753 | 756 | ||
757 | if (!cpu_has_apic) | ||
758 | return -ENODEV; | ||
759 | |||
754 | /* | 760 | /* |
755 | * if "noapic" boot option, don't look for IO-APICs | 761 | * if "noapic" boot option, don't look for IO-APICs |
756 | */ | 762 | */ |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 6273bf74c203..254cee9f0b7b 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -62,6 +62,18 @@ int apic_verbosity; | |||
62 | 62 | ||
63 | static void apic_pm_activate(void); | 63 | static void apic_pm_activate(void); |
64 | 64 | ||
65 | int modern_apic(void) | ||
66 | { | ||
67 | unsigned int lvr, version; | ||
68 | /* AMD systems use old APIC versions, so check the CPU */ | ||
69 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | ||
70 | boot_cpu_data.x86 >= 0xf) | ||
71 | return 1; | ||
72 | lvr = apic_read(APIC_LVR); | ||
73 | version = GET_APIC_VERSION(lvr); | ||
74 | return version >= 0x14; | ||
75 | } | ||
76 | |||
65 | /* | 77 | /* |
66 | * 'what should we do if we get a hw irq event on an illegal vector'. | 78 | * 'what should we do if we get a hw irq event on an illegal vector'. |
67 | * each architecture has to answer this themselves. | 79 | * each architecture has to answer this themselves. |
@@ -119,10 +131,7 @@ void enable_NMI_through_LVT0 (void * dummy) | |||
119 | 131 | ||
120 | int get_physical_broadcast(void) | 132 | int get_physical_broadcast(void) |
121 | { | 133 | { |
122 | unsigned int lvr, version; | 134 | if (modern_apic()) |
123 | lvr = apic_read(APIC_LVR); | ||
124 | version = GET_APIC_VERSION(lvr); | ||
125 | if (!APIC_INTEGRATED(version) || version >= 0x14) | ||
126 | return 0xff; | 135 | return 0xff; |
127 | else | 136 | else |
128 | return 0xf; | 137 | return 0xf; |
@@ -349,9 +358,9 @@ int __init verify_local_APIC(void) | |||
349 | 358 | ||
350 | void __init sync_Arb_IDs(void) | 359 | void __init sync_Arb_IDs(void) |
351 | { | 360 | { |
352 | /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ | 361 | /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 |
353 | unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); | 362 | And not needed on AMD */ |
354 | if (ver >= 0x14) /* P4 or higher */ | 363 | if (modern_apic()) |
355 | return; | 364 | return; |
356 | /* | 365 | /* |
357 | * Wait for idle. | 366 | * Wait for idle. |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 0810f81f2a05..ff2b2154ac1b 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -212,8 +212,6 @@ static void __init init_amd(struct cpuinfo_x86 *c) | |||
212 | 212 | ||
213 | if (cpuid_eax(0x80000000) >= 0x80000008) { | 213 | if (cpuid_eax(0x80000000) >= 0x80000008) { |
214 | c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; | 214 | c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; |
215 | if (c->x86_max_cores & (c->x86_max_cores - 1)) | ||
216 | c->x86_max_cores = 1; | ||
217 | } | 215 | } |
218 | 216 | ||
219 | if (cpuid_eax(0x80000000) >= 0x80000007) { | 217 | if (cpuid_eax(0x80000000) >= 0x80000007) { |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 712a26bd4457..7c0e160a2145 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | #define PFX "powernow-k8: " | 47 | #define PFX "powernow-k8: " |
48 | #define BFX PFX "BIOS error: " | 48 | #define BFX PFX "BIOS error: " |
49 | #define VERSION "version 1.60.1" | 49 | #define VERSION "version 1.60.2" |
50 | #include "powernow-k8.h" | 50 | #include "powernow-k8.h" |
51 | 51 | ||
52 | /* serialize freq changes */ | 52 | /* serialize freq changes */ |
@@ -55,7 +55,7 @@ static DEFINE_MUTEX(fidvid_mutex); | |||
55 | static struct powernow_k8_data *powernow_data[NR_CPUS]; | 55 | static struct powernow_k8_data *powernow_data[NR_CPUS]; |
56 | 56 | ||
57 | #ifndef CONFIG_SMP | 57 | #ifndef CONFIG_SMP |
58 | static cpumask_t cpu_core_map[1] = { CPU_MASK_ALL }; | 58 | static cpumask_t cpu_core_map[1]; |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | /* Return a frequency in MHz, given an input fid */ | 61 | /* Return a frequency in MHz, given an input fid */ |
@@ -910,6 +910,9 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
910 | unsigned int newstate; | 910 | unsigned int newstate; |
911 | int ret = -EIO; | 911 | int ret = -EIO; |
912 | 912 | ||
913 | if (!data) | ||
914 | return -EINVAL; | ||
915 | |||
913 | /* only run on specific CPU from here on */ | 916 | /* only run on specific CPU from here on */ |
914 | oldmask = current->cpus_allowed; | 917 | oldmask = current->cpus_allowed; |
915 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 918 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
@@ -969,6 +972,9 @@ static int powernowk8_verify(struct cpufreq_policy *pol) | |||
969 | { | 972 | { |
970 | struct powernow_k8_data *data = powernow_data[pol->cpu]; | 973 | struct powernow_k8_data *data = powernow_data[pol->cpu]; |
971 | 974 | ||
975 | if (!data) | ||
976 | return -EINVAL; | ||
977 | |||
972 | return cpufreq_frequency_table_verify(pol, data->powernow_table); | 978 | return cpufreq_frequency_table_verify(pol, data->powernow_table); |
973 | } | 979 | } |
974 | 980 | ||
@@ -977,7 +983,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
977 | { | 983 | { |
978 | struct powernow_k8_data *data; | 984 | struct powernow_k8_data *data; |
979 | cpumask_t oldmask = CPU_MASK_ALL; | 985 | cpumask_t oldmask = CPU_MASK_ALL; |
980 | int rc, i; | 986 | int rc; |
981 | 987 | ||
982 | if (!cpu_online(pol->cpu)) | 988 | if (!cpu_online(pol->cpu)) |
983 | return -ENODEV; | 989 | return -ENODEV; |
@@ -1063,8 +1069,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1063 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1069 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1064 | data->currfid, data->currvid); | 1070 | data->currfid, data->currvid); |
1065 | 1071 | ||
1066 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) | 1072 | powernow_data[pol->cpu] = data; |
1067 | powernow_data[i] = data; | ||
1068 | 1073 | ||
1069 | return 0; | 1074 | return 0; |
1070 | 1075 | ||
@@ -1104,6 +1109,9 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1104 | if (!data) | 1109 | if (!data) |
1105 | return -EINVAL; | 1110 | return -EINVAL; |
1106 | 1111 | ||
1112 | if (!data) | ||
1113 | return -EINVAL; | ||
1114 | |||
1107 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 1115 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
1108 | if (smp_processor_id() != cpu) { | 1116 | if (smp_processor_id() != cpu) { |
1109 | printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); | 1117 | printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); |
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 055325056a74..036a9857936f 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c | |||
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(__put_user_2); | |||
19 | EXPORT_SYMBOL(__put_user_4); | 19 | EXPORT_SYMBOL(__put_user_4); |
20 | EXPORT_SYMBOL(__put_user_8); | 20 | EXPORT_SYMBOL(__put_user_8); |
21 | 21 | ||
22 | EXPORT_SYMBOL(strpbrk); | ||
23 | EXPORT_SYMBOL(strstr); | 22 | EXPORT_SYMBOL(strstr); |
24 | 23 | ||
25 | #ifdef CONFIG_SMP | 24 | #ifdef CONFIG_SMP |
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 8d8aa9d1796d..34d21e21e012 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -38,12 +38,6 @@ | |||
38 | int smp_found_config; | 38 | int smp_found_config; |
39 | unsigned int __initdata maxcpus = NR_CPUS; | 39 | unsigned int __initdata maxcpus = NR_CPUS; |
40 | 40 | ||
41 | #ifdef CONFIG_HOTPLUG_CPU | ||
42 | #define CPU_HOTPLUG_ENABLED (1) | ||
43 | #else | ||
44 | #define CPU_HOTPLUG_ENABLED (0) | ||
45 | #endif | ||
46 | |||
47 | /* | 41 | /* |
48 | * Various Linux-internal data structures created from the | 42 | * Various Linux-internal data structures created from the |
49 | * MP-table. | 43 | * MP-table. |
@@ -110,21 +104,6 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
110 | static int mpc_record; | 104 | static int mpc_record; |
111 | static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; | 105 | static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; |
112 | 106 | ||
113 | #ifdef CONFIG_X86_NUMAQ | ||
114 | static int MP_valid_apicid(int apicid, int version) | ||
115 | { | ||
116 | return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; | ||
117 | } | ||
118 | #else | ||
119 | static int MP_valid_apicid(int apicid, int version) | ||
120 | { | ||
121 | if (version >= 0x14) | ||
122 | return apicid < 0xff; | ||
123 | else | ||
124 | return apicid < 0xf; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | static void __devinit MP_processor_info (struct mpc_config_processor *m) | 107 | static void __devinit MP_processor_info (struct mpc_config_processor *m) |
129 | { | 108 | { |
130 | int ver, apicid; | 109 | int ver, apicid; |
@@ -190,12 +169,6 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) | |||
190 | 169 | ||
191 | ver = m->mpc_apicver; | 170 | ver = m->mpc_apicver; |
192 | 171 | ||
193 | if (!MP_valid_apicid(apicid, ver)) { | ||
194 | printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", | ||
195 | m->mpc_apicid, MAX_APICS); | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | /* | 172 | /* |
200 | * Validate version | 173 | * Validate version |
201 | */ | 174 | */ |
@@ -225,7 +198,14 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) | |||
225 | cpu_set(num_processors, cpu_possible_map); | 198 | cpu_set(num_processors, cpu_possible_map); |
226 | num_processors++; | 199 | num_processors++; |
227 | 200 | ||
228 | if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) { | 201 | /* |
202 | * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y | ||
203 | * but we need to work other dependencies like SMP_SUSPEND etc | ||
204 | * before this can be done without some confusion. | ||
205 | * if (CPU_HOTPLUG_ENABLED || num_processors > 8) | ||
206 | * - Ashok Raj <ashok.raj@intel.com> | ||
207 | */ | ||
208 | if (num_processors > 8) { | ||
229 | switch (boot_cpu_data.x86_vendor) { | 209 | switch (boot_cpu_data.x86_vendor) { |
230 | case X86_VENDOR_INTEL: | 210 | case X86_VENDOR_INTEL: |
231 | if (!APIC_XAPIC(ver)) { | 211 | if (!APIC_XAPIC(ver)) { |
@@ -249,6 +229,13 @@ static void __init MP_bus_info (struct mpc_config_bus *m) | |||
249 | 229 | ||
250 | mpc_oem_bus_info(m, str, translation_table[mpc_record]); | 230 | mpc_oem_bus_info(m, str, translation_table[mpc_record]); |
251 | 231 | ||
232 | if (m->mpc_busid >= MAX_MP_BUSSES) { | ||
233 | printk(KERN_WARNING "MP table busid value (%d) for bustype %s " | ||
234 | " is too large, max. supported is %d\n", | ||
235 | m->mpc_busid, str, MAX_MP_BUSSES - 1); | ||
236 | return; | ||
237 | } | ||
238 | |||
252 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { | 239 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { |
253 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; | 240 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; |
254 | } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { | 241 | } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { |
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c index 10e21a4773dd..99aab41a05b0 100644 --- a/arch/i386/kernel/reboot_fixups.c +++ b/arch/i386/kernel/reboot_fixups.c | |||
@@ -51,7 +51,5 @@ void mach_reboot_fixups(void) | |||
51 | 51 | ||
52 | cur->reboot_fixup(dev); | 52 | cur->reboot_fixup(dev); |
53 | } | 53 | } |
54 | |||
55 | printk(KERN_WARNING "No reboot fixup found for your hardware\n"); | ||
56 | } | 54 | } |
57 | 55 | ||
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index eacc3f0a2ea4..80cb3b2d0997 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -963,6 +963,36 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | |||
963 | return 0; | 963 | return 0; |
964 | } | 964 | } |
965 | 965 | ||
966 | /* | ||
967 | * This function checks if the entire range <start,end> is mapped with type. | ||
968 | * | ||
969 | * Note: this function only works correct if the e820 table is sorted and | ||
970 | * not-overlapping, which is the case | ||
971 | */ | ||
972 | int __init | ||
973 | e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | ||
974 | { | ||
975 | int i; | ||
976 | for (i = 0; i < e820.nr_map; i++) { | ||
977 | struct e820entry *ei = &e820.map[i]; | ||
978 | if (type && ei->type != type) | ||
979 | continue; | ||
980 | /* is the region (part) in overlap with the current region ?*/ | ||
981 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
982 | continue; | ||
983 | /* if the region is at the beginning of <start,end> we move | ||
984 | * start to the end of the region since it's ok until there | ||
985 | */ | ||
986 | if (ei->addr <= start) | ||
987 | start = ei->addr + ei->size; | ||
988 | /* if start is now at or beyond end, we're done, full | ||
989 | * coverage */ | ||
990 | if (start >= end) | ||
991 | return 1; /* we're done */ | ||
992 | } | ||
993 | return 0; | ||
994 | } | ||
995 | |||
966 | /* | 996 | /* |
967 | * Find the highest page frame number we have available | 997 | * Find the highest page frame number we have available |
968 | */ | 998 | */ |
@@ -1317,8 +1347,8 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
1317 | /* | 1347 | /* |
1318 | * Request address space for all standard resources | 1348 | * Request address space for all standard resources |
1319 | * | 1349 | * |
1320 | * This is called just before pcibios_assign_resources(), which is also | 1350 | * This is called just before pcibios_init(), which is also a |
1321 | * an fs_initcall, but is linked in later (in arch/i386/pci/i386.c). | 1351 | * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). |
1322 | */ | 1352 | */ |
1323 | static int __init request_standard_resources(void) | 1353 | static int __init request_standard_resources(void) |
1324 | { | 1354 | { |
@@ -1339,7 +1369,7 @@ static int __init request_standard_resources(void) | |||
1339 | return 0; | 1369 | return 0; |
1340 | } | 1370 | } |
1341 | 1371 | ||
1342 | fs_initcall(request_standard_resources); | 1372 | subsys_initcall(request_standard_resources); |
1343 | 1373 | ||
1344 | static void __init register_memory(void) | 1374 | static void __init register_memory(void) |
1345 | { | 1375 | { |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e38527994590..2d22f5761b1d 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -365,6 +365,9 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
365 | 365 | ||
366 | if (++die.lock_owner_depth < 3) { | 366 | if (++die.lock_owner_depth < 3) { |
367 | int nl = 0; | 367 | int nl = 0; |
368 | unsigned long esp; | ||
369 | unsigned short ss; | ||
370 | |||
368 | handle_BUG(regs); | 371 | handle_BUG(regs); |
369 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); | 372 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); |
370 | #ifdef CONFIG_PREEMPT | 373 | #ifdef CONFIG_PREEMPT |
@@ -387,8 +390,19 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
387 | printk("\n"); | 390 | printk("\n"); |
388 | if (notify_die(DIE_OOPS, str, regs, err, | 391 | if (notify_die(DIE_OOPS, str, regs, err, |
389 | current->thread.trap_no, SIGSEGV) != | 392 | current->thread.trap_no, SIGSEGV) != |
390 | NOTIFY_STOP) | 393 | NOTIFY_STOP) { |
391 | show_registers(regs); | 394 | show_registers(regs); |
395 | /* Executive summary in case the oops scrolled away */ | ||
396 | esp = (unsigned long) (®s->esp); | ||
397 | savesegment(ss, ss); | ||
398 | if (user_mode(regs)) { | ||
399 | esp = regs->esp; | ||
400 | ss = regs->xss & 0xffff; | ||
401 | } | ||
402 | printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip); | ||
403 | print_symbol("%s", regs->eip); | ||
404 | printk(" SS:ESP %04x:%08lx\n", ss, esp); | ||
405 | } | ||
392 | else | 406 | else |
393 | regs = NULL; | 407 | regs = NULL; |
394 | } else | 408 | } else |
diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/i386/mach-voyager/voyager_cat.c index 23967fe658d3..3039539de51e 100644 --- a/arch/i386/mach-voyager/voyager_cat.c +++ b/arch/i386/mach-voyager/voyager_cat.c | |||
@@ -106,9 +106,15 @@ voyager_module_t *voyager_cat_list; | |||
106 | 106 | ||
107 | /* the I/O port assignments for the VIC and QIC */ | 107 | /* the I/O port assignments for the VIC and QIC */ |
108 | static struct resource vic_res = { | 108 | static struct resource vic_res = { |
109 | "Voyager Interrupt Controller", 0xFC00, 0xFC6F }; | 109 | .name = "Voyager Interrupt Controller", |
110 | .start = 0xFC00, | ||
111 | .end = 0xFC6F | ||
112 | }; | ||
110 | static struct resource qic_res = { | 113 | static struct resource qic_res = { |
111 | "Quad Interrupt Controller", 0xFC70, 0xFCFF }; | 114 | .name = "Quad Interrupt Controller", |
115 | .start = 0xFC70, | ||
116 | .end = 0xFCFF | ||
117 | }; | ||
112 | 118 | ||
113 | /* This function is used to pack a data bit stream inside a message. | 119 | /* This function is used to pack a data bit stream inside a message. |
114 | * It writes num_bits of the data buffer in msg starting at start_bit. | 120 | * It writes num_bits of the data buffer in msg starting at start_bit. |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 9f66ac582a8b..ae6534ad8161 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -651,6 +651,7 @@ void __init mem_init(void) | |||
651 | * Specifically, in the case of x86, we will always add | 651 | * Specifically, in the case of x86, we will always add |
652 | * memory to the highmem for now. | 652 | * memory to the highmem for now. |
653 | */ | 653 | */ |
654 | #ifdef CONFIG_HOTPLUG_MEMORY | ||
654 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 655 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
655 | int add_memory(u64 start, u64 size) | 656 | int add_memory(u64 start, u64 size) |
656 | { | 657 | { |
@@ -667,6 +668,7 @@ int remove_memory(u64 start, u64 size) | |||
667 | return -EINVAL; | 668 | return -EINVAL; |
668 | } | 669 | } |
669 | #endif | 670 | #endif |
671 | #endif | ||
670 | 672 | ||
671 | kmem_cache_t *pgd_cache; | 673 | kmem_cache_t *pgd_cache; |
672 | kmem_cache_t *pmd_cache; | 674 | kmem_cache_t *pmd_cache; |
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c index 99012b93bd12..5d81fb510375 100644 --- a/arch/i386/pci/direct.c +++ b/arch/i386/pci/direct.c | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/dmi.h> | ||
7 | #include "pci.h" | 8 | #include "pci.h" |
8 | 9 | ||
9 | /* | 10 | /* |
@@ -18,8 +19,10 @@ int pci_conf1_read(unsigned int seg, unsigned int bus, | |||
18 | { | 19 | { |
19 | unsigned long flags; | 20 | unsigned long flags; |
20 | 21 | ||
21 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) | 22 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { |
23 | *value = -1; | ||
22 | return -EINVAL; | 24 | return -EINVAL; |
25 | } | ||
23 | 26 | ||
24 | spin_lock_irqsave(&pci_config_lock, flags); | 27 | spin_lock_irqsave(&pci_config_lock, flags); |
25 | 28 | ||
@@ -91,8 +94,10 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, | |||
91 | unsigned long flags; | 94 | unsigned long flags; |
92 | int dev, fn; | 95 | int dev, fn; |
93 | 96 | ||
94 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) | 97 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { |
98 | *value = -1; | ||
95 | return -EINVAL; | 99 | return -EINVAL; |
100 | } | ||
96 | 101 | ||
97 | dev = PCI_SLOT(devfn); | 102 | dev = PCI_SLOT(devfn); |
98 | fn = PCI_FUNC(devfn); | 103 | fn = PCI_FUNC(devfn); |
@@ -188,6 +193,10 @@ static int __init pci_sanity_check(struct pci_raw_ops *o) | |||
188 | 193 | ||
189 | if (pci_probe & PCI_NO_CHECKS) | 194 | if (pci_probe & PCI_NO_CHECKS) |
190 | return 1; | 195 | return 1; |
196 | /* Assume Type 1 works for newer systems. | ||
197 | This handles machines that don't have anything on PCI Bus 0. */ | ||
198 | if (dmi_get_year(DMI_BIOS_DATE) >= 2001) | ||
199 | return 1; | ||
191 | 200 | ||
192 | for (devfn = 0; devfn < 0x100; devfn++) { | 201 | for (devfn = 0; devfn < 0x100; devfn++) { |
193 | if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x)) | 202 | if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x)) |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 613789071f30..6b1ea0c9a570 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -12,14 +12,20 @@ | |||
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 <linux/acpi.h> |
15 | #include <asm/e820.h> | ||
15 | #include "pci.h" | 16 | #include "pci.h" |
16 | 17 | ||
18 | #define MMCONFIG_APER_SIZE (256*1024*1024) | ||
19 | |||
20 | /* Assume systems with more busses have correct MCFG */ | ||
21 | #define MAX_CHECK_BUS 16 | ||
22 | |||
17 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 23 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
18 | 24 | ||
19 | /* The base address of the last MMCONFIG device accessed */ | 25 | /* The base address of the last MMCONFIG device accessed */ |
20 | static u32 mmcfg_last_accessed_device; | 26 | static u32 mmcfg_last_accessed_device; |
21 | 27 | ||
22 | static DECLARE_BITMAP(fallback_slots, 32); | 28 | static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); |
23 | 29 | ||
24 | /* | 30 | /* |
25 | * Functions for accessing PCI configuration space with MMCONFIG accesses | 31 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
@@ -29,8 +35,8 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
29 | int cfg_num = -1; | 35 | int cfg_num = -1; |
30 | struct acpi_table_mcfg_config *cfg; | 36 | struct acpi_table_mcfg_config *cfg; |
31 | 37 | ||
32 | if (seg == 0 && bus == 0 && | 38 | if (seg == 0 && bus < MAX_CHECK_BUS && |
33 | test_bit(PCI_SLOT(devfn), fallback_slots)) | 39 | test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) |
34 | return 0; | 40 | return 0; |
35 | 41 | ||
36 | while (1) { | 42 | while (1) { |
@@ -74,8 +80,10 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
74 | unsigned long flags; | 80 | unsigned long flags; |
75 | u32 base; | 81 | u32 base; |
76 | 82 | ||
77 | if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) | 83 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) { |
84 | *value = -1; | ||
78 | return -EINVAL; | 85 | return -EINVAL; |
86 | } | ||
79 | 87 | ||
80 | base = get_base_addr(seg, bus, devfn); | 88 | base = get_base_addr(seg, bus, devfn); |
81 | if (!base) | 89 | if (!base) |
@@ -146,29 +154,34 @@ static struct pci_raw_ops pci_mmcfg = { | |||
146 | Normally this can be expressed in the MCFG by not listing them | 154 | Normally this can be expressed in the MCFG by not listing them |
147 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. | 155 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. |
148 | Instead try to discover all devices on bus 0 that are unreachable using MM | 156 | Instead try to discover all devices on bus 0 that are unreachable using MM |
149 | and fallback for them. | 157 | and fallback for them. */ |
150 | We only do this for bus 0/seg 0 */ | ||
151 | static __init void unreachable_devices(void) | 158 | static __init void unreachable_devices(void) |
152 | { | 159 | { |
153 | int i; | 160 | int i, k; |
154 | unsigned long flags; | 161 | unsigned long flags; |
155 | 162 | ||
156 | for (i = 0; i < 32; i++) { | 163 | for (k = 0; k < MAX_CHECK_BUS; k++) { |
157 | u32 val1; | 164 | for (i = 0; i < 32; i++) { |
158 | u32 addr; | 165 | u32 val1; |
159 | 166 | u32 addr; | |
160 | pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1); | 167 | |
161 | if (val1 == 0xffffffff) | 168 | pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1); |
162 | continue; | 169 | if (val1 == 0xffffffff) |
163 | 170 | continue; | |
164 | /* Locking probably not needed, but safer */ | 171 | |
165 | spin_lock_irqsave(&pci_config_lock, flags); | 172 | /* Locking probably not needed, but safer */ |
166 | addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); | 173 | spin_lock_irqsave(&pci_config_lock, flags); |
167 | if (addr != 0) | 174 | addr = get_base_addr(0, k, PCI_DEVFN(i, 0)); |
168 | pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); | 175 | if (addr != 0) |
169 | if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) | 176 | pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0)); |
170 | set_bit(i, fallback_slots); | 177 | if (addr == 0 || |
171 | spin_unlock_irqrestore(&pci_config_lock, flags); | 178 | readl((u32 __iomem *)mmcfg_virt_addr) != val1) { |
179 | set_bit(i, fallback_slots); | ||
180 | printk(KERN_NOTICE | ||
181 | "PCI: No mmconfig possible on %x:%x\n", k, i); | ||
182 | } | ||
183 | spin_unlock_irqrestore(&pci_config_lock, flags); | ||
184 | } | ||
172 | } | 185 | } |
173 | } | 186 | } |
174 | 187 | ||
@@ -183,6 +196,14 @@ void __init pci_mmcfg_init(void) | |||
183 | (pci_mmcfg_config[0].base_address == 0)) | 196 | (pci_mmcfg_config[0].base_address == 0)) |
184 | return; | 197 | return; |
185 | 198 | ||
199 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
200 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||
201 | E820_RESERVED)) { | ||
202 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||
203 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
204 | return; | ||
205 | } | ||
206 | |||
186 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); | 207 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); |
187 | raw_pci_ops = &pci_mmcfg; | 208 | raw_pci_ops = &pci_mmcfg; |
188 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 209 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index edffe25a477a..9f40eeff0b5c 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -260,15 +260,6 @@ config NR_CPUS | |||
260 | than 64 will cause the use of a CPU mask array, causing a small | 260 | than 64 will cause the use of a CPU mask array, causing a small |
261 | performance hit. | 261 | performance hit. |
262 | 262 | ||
263 | config IA64_NR_NODES | ||
264 | int "Maximum number of NODEs (256-1024)" if (IA64_SGI_SN2 || IA64_GENERIC) | ||
265 | range 256 1024 | ||
266 | depends on IA64_SGI_SN2 || IA64_GENERIC | ||
267 | default "256" | ||
268 | help | ||
269 | This option specifies the maximum number of nodes in your SSI system. | ||
270 | If in doubt, use the default. | ||
271 | |||
272 | config HOTPLUG_CPU | 263 | config HOTPLUG_CPU |
273 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | 264 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" |
274 | depends on SMP && EXPERIMENTAL | 265 | depends on SMP && EXPERIMENTAL |
@@ -352,6 +343,16 @@ config NUMA | |||
352 | Access). This option is for configuring high-end multiprocessor | 343 | Access). This option is for configuring high-end multiprocessor |
353 | server systems. If in doubt, say N. | 344 | server systems. If in doubt, say N. |
354 | 345 | ||
346 | config NODES_SHIFT | ||
347 | int "Max num nodes shift(3-10)" | ||
348 | range 3 10 | ||
349 | default "8" | ||
350 | depends on NEED_MULTIPLE_NODES | ||
351 | help | ||
352 | This option specifies the maximum number of nodes in your SSI system. | ||
353 | MAX_NUMNODES will be 2^(This value). | ||
354 | If in doubt, use the default. | ||
355 | |||
355 | # VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. | 356 | # VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. |
356 | # VIRTUAL_MEM_MAP has been retained for historical reasons. | 357 | # VIRTUAL_MEM_MAP has been retained for historical reasons. |
357 | config VIRTUAL_MEM_MAP | 358 | config VIRTUAL_MEM_MAP |
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 4a5574ff007b..fff82929d225 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c | |||
@@ -1,105 +1,104 @@ | |||
1 | /* | 1 | /* |
2 | * arch/ia64/kernel/acpi-ext.c | 2 | * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P. |
3 | * Alex Williamson <alex.williamson@hp.com> | ||
4 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
3 | * | 5 | * |
4 | * Copyright (C) 2003 Hewlett-Packard | 6 | * This program is free software; you can redistribute it and/or modify |
5 | * Copyright (C) Alex Williamson | 7 | * it under the terms of the GNU General Public License version 2 as |
6 | * Copyright (C) Bjorn Helgaas | 8 | * published by the Free Software Foundation. |
7 | * | ||
8 | * Vendor specific extensions to ACPI. | ||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/efi.h> | ||
16 | 15 | ||
17 | #include <asm/acpi-ext.h> | 16 | #include <asm/acpi-ext.h> |
18 | 17 | ||
19 | struct acpi_vendor_descriptor { | 18 | /* |
20 | u8 guid_id; | 19 | * Device CSRs that do not appear in PCI config space should be described |
21 | efi_guid_t guid; | 20 | * via ACPI. This would normally be done with Address Space Descriptors |
22 | }; | 21 | * marked as "consumer-only," but old versions of Windows and Linux ignore |
22 | * the producer/consumer flag, so HP invented a vendor-defined resource to | ||
23 | * describe the location and size of CSR space. | ||
24 | */ | ||
23 | 25 | ||
24 | struct acpi_vendor_info { | 26 | struct acpi_vendor_uuid hp_ccsr_uuid = { |
25 | struct acpi_vendor_descriptor *descriptor; | 27 | .subtype = 2, |
26 | u8 *data; | 28 | .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a, |
27 | u32 length; | 29 | 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad }, |
28 | }; | 30 | }; |
29 | 31 | ||
30 | acpi_status | 32 | static acpi_status hp_ccsr_locate(acpi_handle obj, u64 *base, u64 *length) |
31 | acpi_vendor_resource_match(struct acpi_resource *resource, void *context) | ||
32 | { | 33 | { |
33 | struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; | 34 | acpi_status status; |
34 | struct acpi_resource_vendor *vendor; | 35 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
35 | struct acpi_vendor_descriptor *descriptor; | 36 | struct acpi_resource *resource; |
36 | u32 byte_length; | 37 | struct acpi_resource_vendor_typed *vendor; |
37 | |||
38 | if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) | ||
39 | return AE_OK; | ||
40 | |||
41 | vendor = (struct acpi_resource_vendor *)&resource->data; | ||
42 | descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; | ||
43 | if (vendor->byte_length <= sizeof(*info->descriptor) || | ||
44 | descriptor->guid_id != info->descriptor->guid_id || | ||
45 | efi_guidcmp(descriptor->guid, info->descriptor->guid)) | ||
46 | return AE_OK; | ||
47 | |||
48 | byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); | ||
49 | info->data = acpi_os_allocate(byte_length); | ||
50 | if (!info->data) | ||
51 | return AE_NO_MEMORY; | ||
52 | |||
53 | memcpy(info->data, | ||
54 | vendor->byte_data + sizeof(struct acpi_vendor_descriptor), | ||
55 | byte_length); | ||
56 | info->length = byte_length; | ||
57 | return AE_CTRL_TERMINATE; | ||
58 | } | ||
59 | 38 | ||
60 | acpi_status | 39 | status = acpi_get_vendor_resource(obj, METHOD_NAME__CRS, &hp_ccsr_uuid, |
61 | acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, | 40 | &buffer); |
62 | u8 ** data, u32 * byte_length) | ||
63 | { | ||
64 | struct acpi_vendor_info info; | ||
65 | 41 | ||
66 | info.descriptor = id; | 42 | resource = buffer.pointer; |
67 | info.data = NULL; | 43 | vendor = &resource->data.vendor_typed; |
68 | 44 | ||
69 | acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, | 45 | if (ACPI_FAILURE(status) || vendor->byte_length < 16) { |
70 | &info); | 46 | status = AE_NOT_FOUND; |
71 | if (!info.data) | 47 | goto exit; |
72 | return AE_NOT_FOUND; | 48 | } |
73 | 49 | ||
74 | *data = info.data; | 50 | memcpy(base, vendor->byte_data, sizeof(*base)); |
75 | *byte_length = info.length; | 51 | memcpy(length, vendor->byte_data + 8, sizeof(*length)); |
76 | return AE_OK; | 52 | |
53 | exit: | ||
54 | acpi_os_free(buffer.pointer); | ||
55 | return status; | ||
77 | } | 56 | } |
78 | 57 | ||
79 | struct acpi_vendor_descriptor hp_ccsr_descriptor = { | 58 | struct csr_space { |
80 | .guid_id = 2, | 59 | u64 base; |
81 | .guid = | 60 | u64 length; |
82 | EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, | ||
83 | 0x37, 0x0e, 0xad) | ||
84 | }; | 61 | }; |
85 | 62 | ||
86 | acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length) | 63 | static acpi_status find_csr_space(struct acpi_resource *resource, void *data) |
87 | { | 64 | { |
65 | struct csr_space *space = data; | ||
66 | struct acpi_resource_address64 addr; | ||
88 | acpi_status status; | 67 | acpi_status status; |
89 | u8 *data; | ||
90 | u32 length; | ||
91 | 68 | ||
92 | status = | 69 | status = acpi_resource_to_address64(resource, &addr); |
93 | acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); | 70 | if (ACPI_SUCCESS(status) && |
71 | addr.resource_type == ACPI_MEMORY_RANGE && | ||
72 | addr.address_length && | ||
73 | addr.producer_consumer == ACPI_CONSUMER) { | ||
74 | space->base = addr.minimum; | ||
75 | space->length = addr.address_length; | ||
76 | return AE_CTRL_TERMINATE; | ||
77 | } | ||
78 | return AE_OK; /* keep looking */ | ||
79 | } | ||
94 | 80 | ||
95 | if (ACPI_FAILURE(status) || length != 16) | 81 | static acpi_status hp_crs_locate(acpi_handle obj, u64 *base, u64 *length) |
96 | return AE_NOT_FOUND; | 82 | { |
83 | struct csr_space space = { 0, 0 }; | ||
97 | 84 | ||
98 | memcpy(csr_base, data, sizeof(*csr_base)); | 85 | acpi_walk_resources(obj, METHOD_NAME__CRS, find_csr_space, &space); |
99 | memcpy(csr_length, data + 8, sizeof(*csr_length)); | 86 | if (!space.length) |
100 | acpi_os_free(data); | 87 | return AE_NOT_FOUND; |
101 | 88 | ||
89 | *base = space.base; | ||
90 | *length = space.length; | ||
102 | return AE_OK; | 91 | return AE_OK; |
103 | } | 92 | } |
104 | 93 | ||
94 | acpi_status hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length) | ||
95 | { | ||
96 | acpi_status status; | ||
97 | |||
98 | status = hp_ccsr_locate(obj, csr_base, csr_length); | ||
99 | if (ACPI_SUCCESS(status)) | ||
100 | return status; | ||
101 | |||
102 | return hp_crs_locate(obj, csr_base, csr_length); | ||
103 | } | ||
105 | EXPORT_SYMBOL(hp_acpi_csr_space); | 104 | EXPORT_SYMBOL(hp_acpi_csr_space); |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 750e8e7fbdc3..6e16f6b35bd3 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1606,5 +1606,8 @@ sys_call_table: | |||
1606 | data8 sys_ni_syscall // 1295 reserved for ppoll | 1606 | data8 sys_ni_syscall // 1295 reserved for ppoll |
1607 | data8 sys_unshare | 1607 | data8 sys_unshare |
1608 | data8 sys_splice | 1608 | data8 sys_splice |
1609 | data8 sys_set_robust_list | ||
1610 | data8 sys_get_robust_list | ||
1611 | data8 sys_sync_file_range // 1300 | ||
1609 | 1612 | ||
1610 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1613 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 8963171788d5..5e6fdbe78bcd 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -581,10 +581,12 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) | |||
581 | { | 581 | { |
582 | unsigned long flags; | 582 | unsigned long flags; |
583 | int cpu = smp_processor_id(); | 583 | int cpu = smp_processor_id(); |
584 | struct ia64_mca_notify_die nd = | ||
585 | { .sos = NULL, .monarch_cpu = &monarch_cpu }; | ||
584 | 586 | ||
585 | /* Mask all interrupts */ | 587 | /* Mask all interrupts */ |
586 | local_irq_save(flags); | 588 | local_irq_save(flags); |
587 | if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0) | 589 | if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, (long)&nd, 0, 0) |
588 | == NOTIFY_STOP) | 590 | == NOTIFY_STOP) |
589 | ia64_mca_spin(__FUNCTION__); | 591 | ia64_mca_spin(__FUNCTION__); |
590 | 592 | ||
@@ -594,7 +596,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) | |||
594 | */ | 596 | */ |
595 | ia64_sal_mc_rendez(); | 597 | ia64_sal_mc_rendez(); |
596 | 598 | ||
597 | if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0) | 599 | if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, (long)&nd, 0, 0) |
598 | == NOTIFY_STOP) | 600 | == NOTIFY_STOP) |
599 | ia64_mca_spin(__FUNCTION__); | 601 | ia64_mca_spin(__FUNCTION__); |
600 | 602 | ||
@@ -602,7 +604,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) | |||
602 | while (monarch_cpu != -1) | 604 | while (monarch_cpu != -1) |
603 | cpu_relax(); /* spin until monarch leaves */ | 605 | cpu_relax(); /* spin until monarch leaves */ |
604 | 606 | ||
605 | if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0) | 607 | if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, (long)&nd, 0, 0) |
606 | == NOTIFY_STOP) | 608 | == NOTIFY_STOP) |
607 | ia64_mca_spin(__FUNCTION__); | 609 | ia64_mca_spin(__FUNCTION__); |
608 | 610 | ||
@@ -1023,6 +1025,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1023 | &sos->proc_state_param; | 1025 | &sos->proc_state_param; |
1024 | int recover, cpu = smp_processor_id(); | 1026 | int recover, cpu = smp_processor_id(); |
1025 | task_t *previous_current; | 1027 | task_t *previous_current; |
1028 | struct ia64_mca_notify_die nd = | ||
1029 | { .sos = sos, .monarch_cpu = &monarch_cpu }; | ||
1026 | 1030 | ||
1027 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ | 1031 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ |
1028 | console_loglevel = 15; /* make sure printks make it to console */ | 1032 | console_loglevel = 15; /* make sure printks make it to console */ |
@@ -1031,7 +1035,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1031 | 1035 | ||
1032 | previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); | 1036 | previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); |
1033 | monarch_cpu = cpu; | 1037 | monarch_cpu = cpu; |
1034 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) | 1038 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) |
1035 | == NOTIFY_STOP) | 1039 | == NOTIFY_STOP) |
1036 | ia64_mca_spin(__FUNCTION__); | 1040 | ia64_mca_spin(__FUNCTION__); |
1037 | ia64_wait_for_slaves(cpu); | 1041 | ia64_wait_for_slaves(cpu); |
@@ -1043,7 +1047,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1043 | * spinning in SAL does not work. | 1047 | * spinning in SAL does not work. |
1044 | */ | 1048 | */ |
1045 | ia64_mca_wakeup_all(); | 1049 | ia64_mca_wakeup_all(); |
1046 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0) | 1050 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) |
1047 | == NOTIFY_STOP) | 1051 | == NOTIFY_STOP) |
1048 | ia64_mca_spin(__FUNCTION__); | 1052 | ia64_mca_spin(__FUNCTION__); |
1049 | 1053 | ||
@@ -1064,7 +1068,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1064 | ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); | 1068 | ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); |
1065 | sos->os_status = IA64_MCA_CORRECTED; | 1069 | sos->os_status = IA64_MCA_CORRECTED; |
1066 | } | 1070 | } |
1067 | if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover) | 1071 | if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover) |
1068 | == NOTIFY_STOP) | 1072 | == NOTIFY_STOP) |
1069 | ia64_mca_spin(__FUNCTION__); | 1073 | ia64_mca_spin(__FUNCTION__); |
1070 | 1074 | ||
@@ -1351,10 +1355,14 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1351 | static atomic_t monarchs; | 1355 | static atomic_t monarchs; |
1352 | task_t *previous_current; | 1356 | task_t *previous_current; |
1353 | int cpu = smp_processor_id(); | 1357 | int cpu = smp_processor_id(); |
1358 | struct ia64_mca_notify_die nd = | ||
1359 | { .sos = sos, .monarch_cpu = &monarch_cpu }; | ||
1354 | 1360 | ||
1355 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ | 1361 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ |
1356 | console_loglevel = 15; /* make sure printks make it to console */ | 1362 | console_loglevel = 15; /* make sure printks make it to console */ |
1357 | 1363 | ||
1364 | (void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0); | ||
1365 | |||
1358 | printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", | 1366 | printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", |
1359 | sos->proc_state_param, cpu, sos->monarch); | 1367 | sos->proc_state_param, cpu, sos->monarch); |
1360 | salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); | 1368 | salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); |
@@ -1390,15 +1398,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1390 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; | 1398 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; |
1391 | while (monarch_cpu == -1) | 1399 | while (monarch_cpu == -1) |
1392 | cpu_relax(); /* spin until monarch enters */ | 1400 | cpu_relax(); /* spin until monarch enters */ |
1393 | if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0) | 1401 | if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, (long)&nd, 0, 0) |
1394 | == NOTIFY_STOP) | 1402 | == NOTIFY_STOP) |
1395 | ia64_mca_spin(__FUNCTION__); | 1403 | ia64_mca_spin(__FUNCTION__); |
1396 | if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0) | 1404 | if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, (long)&nd, 0, 0) |
1397 | == NOTIFY_STOP) | 1405 | == NOTIFY_STOP) |
1398 | ia64_mca_spin(__FUNCTION__); | 1406 | ia64_mca_spin(__FUNCTION__); |
1399 | while (monarch_cpu != -1) | 1407 | while (monarch_cpu != -1) |
1400 | cpu_relax(); /* spin until monarch leaves */ | 1408 | cpu_relax(); /* spin until monarch leaves */ |
1401 | if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0) | 1409 | if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0) |
1402 | == NOTIFY_STOP) | 1410 | == NOTIFY_STOP) |
1403 | ia64_mca_spin(__FUNCTION__); | 1411 | ia64_mca_spin(__FUNCTION__); |
1404 | printk("Slave on cpu %d returning to normal service.\n", cpu); | 1412 | printk("Slave on cpu %d returning to normal service.\n", cpu); |
@@ -1409,7 +1417,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1409 | } | 1417 | } |
1410 | 1418 | ||
1411 | monarch_cpu = cpu; | 1419 | monarch_cpu = cpu; |
1412 | if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0) | 1420 | if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, (long)&nd, 0, 0) |
1413 | == NOTIFY_STOP) | 1421 | == NOTIFY_STOP) |
1414 | ia64_mca_spin(__FUNCTION__); | 1422 | ia64_mca_spin(__FUNCTION__); |
1415 | 1423 | ||
@@ -1426,10 +1434,10 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1426 | * to default_monarch_init_process() above and just print all the | 1434 | * to default_monarch_init_process() above and just print all the |
1427 | * tasks. | 1435 | * tasks. |
1428 | */ | 1436 | */ |
1429 | if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0) | 1437 | if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, (long)&nd, 0, 0) |
1430 | == NOTIFY_STOP) | 1438 | == NOTIFY_STOP) |
1431 | ia64_mca_spin(__FUNCTION__); | 1439 | ia64_mca_spin(__FUNCTION__); |
1432 | if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0) | 1440 | if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0) |
1433 | == NOTIFY_STOP) | 1441 | == NOTIFY_STOP) |
1434 | ia64_mca_spin(__FUNCTION__); | 1442 | ia64_mca_spin(__FUNCTION__); |
1435 | printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); | 1443 | printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); |
@@ -1631,6 +1639,7 @@ ia64_mca_init(void) | |||
1631 | printk(KERN_INFO "Increasing MCA rendezvous timeout from " | 1639 | printk(KERN_INFO "Increasing MCA rendezvous timeout from " |
1632 | "%ld to %ld milliseconds\n", timeout, isrv.v0); | 1640 | "%ld to %ld milliseconds\n", timeout, isrv.v0); |
1633 | timeout = isrv.v0; | 1641 | timeout = isrv.v0; |
1642 | (void) notify_die(DIE_MCA_NEW_TIMEOUT, "MCA", NULL, timeout, 0, 0); | ||
1634 | continue; | 1643 | continue; |
1635 | } | 1644 | } |
1636 | printk(KERN_ERR "Failed to register rendezvous interrupt " | 1645 | printk(KERN_ERR "Failed to register rendezvous interrupt " |
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 60a464bfd9e2..6dff024cd62b 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S | |||
@@ -827,7 +827,7 @@ ia64_state_restore: | |||
827 | ld8 r9=[temp2],16 // sal_gp | 827 | ld8 r9=[temp2],16 // sal_gp |
828 | ;; | 828 | ;; |
829 | ld8 r22=[temp1],16 // pal_min_state, virtual | 829 | ld8 r22=[temp1],16 // pal_min_state, virtual |
830 | ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT | 830 | ld8 r13=[temp2],16 // prev_IA64_KR_CURRENT |
831 | ;; | 831 | ;; |
832 | ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK | 832 | ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK |
833 | ld8 r20=[temp2],16 // prev_task | 833 | ld8 r20=[temp2],16 // prev_task |
@@ -848,7 +848,7 @@ ia64_state_restore: | |||
848 | mov cr.iim=temp3 | 848 | mov cr.iim=temp3 |
849 | mov cr.iha=temp4 | 849 | mov cr.iha=temp4 |
850 | dep r22=0,r22,62,1 // pal_min_state, physical, uncached | 850 | dep r22=0,r22,62,1 // pal_min_state, physical, uncached |
851 | mov IA64_KR(CURRENT)=r21 | 851 | mov IA64_KR(CURRENT)=r13 |
852 | ld8 r8=[temp1] // os_status | 852 | ld8 r8=[temp1] // os_status |
853 | ld8 r10=[temp2] // context | 853 | ld8 r10=[temp2] // context |
854 | 854 | ||
@@ -856,7 +856,7 @@ ia64_state_restore: | |||
856 | * avoid any dependencies on the algorithm in ia64_switch_to(), just | 856 | * avoid any dependencies on the algorithm in ia64_switch_to(), just |
857 | * purge any existing CURRENT_STACK mapping and insert the new one. | 857 | * purge any existing CURRENT_STACK mapping and insert the new one. |
858 | * | 858 | * |
859 | * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains | 859 | * r16 contains prev_IA64_KR_CURRENT_STACK, r13 contains |
860 | * prev_IA64_KR_CURRENT, these values may have been changed by the C | 860 | * prev_IA64_KR_CURRENT, these values may have been changed by the C |
861 | * code. Do not use r8, r9, r10, r22, they contain values ready for | 861 | * code. Do not use r8, r9, r10, r22, they contain values ready for |
862 | * the return to SAL. | 862 | * the return to SAL. |
@@ -873,7 +873,7 @@ ia64_state_restore: | |||
873 | ;; | 873 | ;; |
874 | srlz.d | 874 | srlz.d |
875 | 875 | ||
876 | extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT | 876 | extr.u r19=r13,61,3 // r13 = prev_IA64_KR_CURRENT |
877 | shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK | 877 | shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK |
878 | movl r21=PAGE_KERNEL // page properties | 878 | movl r21=PAGE_KERNEL // page properties |
879 | ;; | 879 | ;; |
@@ -883,7 +883,7 @@ ia64_state_restore: | |||
883 | (p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( | 883 | (p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( |
884 | ;; | 884 | ;; |
885 | mov cr.itir=r18 | 885 | mov cr.itir=r18 |
886 | mov cr.ifa=r21 | 886 | mov cr.ifa=r13 |
887 | mov r20=IA64_TR_CURRENT_STACK | 887 | mov r20=IA64_TR_CURRENT_STACK |
888 | ;; | 888 | ;; |
889 | itr.d dtr[r20]=r21 | 889 | itr.d dtr[r20]=r21 |
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index 7a2f0a798d12..3a30cfc9574f 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c | |||
@@ -947,7 +947,7 @@ void | |||
947 | percpu_modcopy (void *pcpudst, const void *src, unsigned long size) | 947 | percpu_modcopy (void *pcpudst, const void *src, unsigned long size) |
948 | { | 948 | { |
949 | unsigned int i; | 949 | unsigned int i; |
950 | for_each_cpu(i) { | 950 | for_each_possible_cpu(i) { |
951 | memcpy(pcpudst + __per_cpu_offset[i], src, size); | 951 | memcpy(pcpudst + __per_cpu_offset[i], src, size); |
952 | } | 952 | } |
953 | } | 953 | } |
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index af7eb087dca7..d98ec49570b8 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -60,6 +60,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
60 | struct siginfo si; | 60 | struct siginfo si; |
61 | unsigned long mask; | 61 | unsigned long mask; |
62 | 62 | ||
63 | /* mmap_sem is performance critical.... */ | ||
64 | prefetchw(&mm->mmap_sem); | ||
65 | |||
63 | /* | 66 | /* |
64 | * If we're in an interrupt or have no user context, we must not take the fault.. | 67 | * If we're in an interrupt or have no user context, we must not take the fault.. |
65 | */ | 68 | */ |
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index d0abddd9ffe6..8255a9be4632 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -1831,7 +1831,7 @@ xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload) | |||
1831 | { | 1831 | { |
1832 | struct xpc_partition *part = &xpc_partitions[partid]; | 1832 | struct xpc_partition *part = &xpc_partitions[partid]; |
1833 | enum xpc_retval ret = xpcUnknownReason; | 1833 | enum xpc_retval ret = xpcUnknownReason; |
1834 | struct xpc_msg *msg; | 1834 | struct xpc_msg *msg = NULL; |
1835 | 1835 | ||
1836 | 1836 | ||
1837 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | 1837 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); |
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 05c864c6c2d9..41fd490af3b4 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
@@ -285,6 +285,11 @@ config NUMA | |||
285 | depends on SMP && BROKEN | 285 | depends on SMP && BROKEN |
286 | default n | 286 | default n |
287 | 287 | ||
288 | config NODES_SHIFT | ||
289 | int | ||
290 | default "1" | ||
291 | depends on NEED_MULTIPLE_NODES | ||
292 | |||
288 | # turning this on wastes a bunch of space. | 293 | # turning this on wastes a bunch of space. |
289 | # Summit needs it only when NUMA is on | 294 | # Summit needs it only when NUMA is on |
290 | config BOOT_IOREMAP | 295 | config BOOT_IOREMAP |
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index be8b711367ec..c50330fa83b9 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c | |||
@@ -23,9 +23,6 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
23 | EXPORT_SYMBOL(dump_fpu); | 23 | EXPORT_SYMBOL(dump_fpu); |
24 | EXPORT_SYMBOL(__ioremap); | 24 | EXPORT_SYMBOL(__ioremap); |
25 | EXPORT_SYMBOL(iounmap); | 25 | EXPORT_SYMBOL(iounmap); |
26 | EXPORT_SYMBOL(enable_irq); | ||
27 | EXPORT_SYMBOL(disable_irq); | ||
28 | EXPORT_SYMBOL(disable_irq_nosync); | ||
29 | EXPORT_SYMBOL(kernel_thread); | 26 | EXPORT_SYMBOL(kernel_thread); |
30 | EXPORT_SYMBOL(__down); | 27 | EXPORT_SYMBOL(__down); |
31 | EXPORT_SYMBOL(__down_interruptible); | 28 | EXPORT_SYMBOL(__down_interruptible); |
@@ -38,13 +35,6 @@ EXPORT_SYMBOL(__udelay); | |||
38 | EXPORT_SYMBOL(__delay); | 35 | EXPORT_SYMBOL(__delay); |
39 | EXPORT_SYMBOL(__const_udelay); | 36 | EXPORT_SYMBOL(__const_udelay); |
40 | 37 | ||
41 | EXPORT_SYMBOL(__get_user_1); | ||
42 | EXPORT_SYMBOL(__get_user_2); | ||
43 | EXPORT_SYMBOL(__get_user_4); | ||
44 | |||
45 | EXPORT_SYMBOL(strpbrk); | ||
46 | EXPORT_SYMBOL(strstr); | ||
47 | |||
48 | EXPORT_SYMBOL(strncpy_from_user); | 38 | EXPORT_SYMBOL(strncpy_from_user); |
49 | EXPORT_SYMBOL(__strncpy_from_user); | 39 | EXPORT_SYMBOL(__strncpy_from_user); |
50 | EXPORT_SYMBOL(clear_user); | 40 | EXPORT_SYMBOL(clear_user); |
@@ -59,11 +49,8 @@ extern void *dcache_dummy; | |||
59 | EXPORT_SYMBOL(dcache_dummy); | 49 | EXPORT_SYMBOL(dcache_dummy); |
60 | #endif | 50 | #endif |
61 | EXPORT_SYMBOL(cpu_data); | 51 | EXPORT_SYMBOL(cpu_data); |
62 | EXPORT_SYMBOL(cpu_online_map); | ||
63 | EXPORT_SYMBOL(cpu_callout_map); | ||
64 | 52 | ||
65 | /* Global SMP stuff */ | 53 | /* Global SMP stuff */ |
66 | EXPORT_SYMBOL(synchronize_irq); | ||
67 | EXPORT_SYMBOL(smp_call_function); | 54 | EXPORT_SYMBOL(smp_call_function); |
68 | 55 | ||
69 | /* TLB flushing */ | 56 | /* TLB flushing */ |
@@ -83,27 +70,11 @@ EXPORT_SYMBOL(__lshrdi3); | |||
83 | EXPORT_SYMBOL(__muldi3); | 70 | EXPORT_SYMBOL(__muldi3); |
84 | 71 | ||
85 | /* memory and string operations */ | 72 | /* memory and string operations */ |
86 | EXPORT_SYMBOL(memchr); | ||
87 | EXPORT_SYMBOL(memcpy); | 73 | EXPORT_SYMBOL(memcpy); |
88 | /* EXPORT_SYMBOL(memcpy_fromio); // not implement yet */ | ||
89 | /* EXPORT_SYMBOL(memcpy_toio); // not implement yet */ | ||
90 | EXPORT_SYMBOL(memset); | 74 | EXPORT_SYMBOL(memset); |
91 | /* EXPORT_SYMBOL(memset_io); // not implement yet */ | ||
92 | EXPORT_SYMBOL(memmove); | ||
93 | EXPORT_SYMBOL(memcmp); | ||
94 | EXPORT_SYMBOL(memscan); | ||
95 | EXPORT_SYMBOL(copy_page); | 75 | EXPORT_SYMBOL(copy_page); |
96 | EXPORT_SYMBOL(clear_page); | 76 | EXPORT_SYMBOL(clear_page); |
97 | |||
98 | EXPORT_SYMBOL(strcat); | ||
99 | EXPORT_SYMBOL(strchr); | ||
100 | EXPORT_SYMBOL(strcmp); | ||
101 | EXPORT_SYMBOL(strcpy); | ||
102 | EXPORT_SYMBOL(strlen); | 77 | EXPORT_SYMBOL(strlen); |
103 | EXPORT_SYMBOL(strncat); | ||
104 | EXPORT_SYMBOL(strncmp); | ||
105 | EXPORT_SYMBOL(strnlen); | ||
106 | EXPORT_SYMBOL(strncpy); | ||
107 | 78 | ||
108 | EXPORT_SYMBOL(_inb); | 79 | EXPORT_SYMBOL(_inb); |
109 | EXPORT_SYMBOL(_inw); | 80 | EXPORT_SYMBOL(_inw); |
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 0d78942b4c76..3cd3c2988a48 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/kernel.h> | ||
12 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
13 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
@@ -219,8 +220,6 @@ static unsigned long __init setup_memory(void) | |||
219 | extern unsigned long setup_memory(void); | 220 | extern unsigned long setup_memory(void); |
220 | #endif /* CONFIG_DISCONTIGMEM */ | 221 | #endif /* CONFIG_DISCONTIGMEM */ |
221 | 222 | ||
222 | #define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */ | ||
223 | |||
224 | void __init setup_arch(char **cmdline_p) | 223 | void __init setup_arch(char **cmdline_p) |
225 | { | 224 | { |
226 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); | 225 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); |
@@ -269,15 +268,14 @@ void __init setup_arch(char **cmdline_p) | |||
269 | paging_init(); | 268 | paging_init(); |
270 | } | 269 | } |
271 | 270 | ||
272 | static struct cpu cpu[NR_CPUS]; | 271 | static struct cpu cpu_devices[NR_CPUS]; |
273 | 272 | ||
274 | static int __init topology_init(void) | 273 | static int __init topology_init(void) |
275 | { | 274 | { |
276 | int cpu_id; | 275 | int i; |
277 | 276 | ||
278 | for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++) | 277 | for_each_present_cpu(i) |
279 | if (cpu_possible(cpu_id)) | 278 | register_cpu(&cpu_devices[i], i, NULL); |
280 | register_cpu(&cpu[cpu_id], cpu_id, NULL); | ||
281 | 279 | ||
282 | return 0; | 280 | return 0; |
283 | } | 281 | } |
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index d7ec16e7fb25..840b4348bf0c 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c | |||
@@ -39,8 +39,10 @@ | |||
39 | * Martin J. Bligh : Added support for multi-quad systems | 39 | * Martin J. Bligh : Added support for multi-quad systems |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include <linux/module.h> | ||
42 | #include <linux/config.h> | 43 | #include <linux/config.h> |
43 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/kernel.h> | ||
44 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
45 | #include <linux/smp_lock.h> | 47 | #include <linux/smp_lock.h> |
46 | #include <linux/irq.h> | 48 | #include <linux/irq.h> |
@@ -72,11 +74,15 @@ physid_mask_t phys_cpu_present_map; | |||
72 | 74 | ||
73 | /* Bitmask of currently online CPUs */ | 75 | /* Bitmask of currently online CPUs */ |
74 | cpumask_t cpu_online_map; | 76 | cpumask_t cpu_online_map; |
77 | EXPORT_SYMBOL(cpu_online_map); | ||
75 | 78 | ||
76 | cpumask_t cpu_bootout_map; | 79 | cpumask_t cpu_bootout_map; |
77 | cpumask_t cpu_bootin_map; | 80 | cpumask_t cpu_bootin_map; |
78 | cpumask_t cpu_callout_map; | ||
79 | static cpumask_t cpu_callin_map; | 81 | static cpumask_t cpu_callin_map; |
82 | cpumask_t cpu_callout_map; | ||
83 | EXPORT_SYMBOL(cpu_callout_map); | ||
84 | cpumask_t cpu_possible_map = CPU_MASK_ALL; | ||
85 | EXPORT_SYMBOL(cpu_possible_map); | ||
80 | 86 | ||
81 | /* Per CPU bogomips and other parameters */ | 87 | /* Per CPU bogomips and other parameters */ |
82 | struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; | 88 | struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; |
@@ -110,7 +116,6 @@ static unsigned int calibration_result; | |||
110 | 116 | ||
111 | void smp_prepare_boot_cpu(void); | 117 | void smp_prepare_boot_cpu(void); |
112 | void smp_prepare_cpus(unsigned int); | 118 | void smp_prepare_cpus(unsigned int); |
113 | static void smp_tune_scheduling(void); | ||
114 | static void init_ipi_lock(void); | 119 | static void init_ipi_lock(void); |
115 | static void do_boot_cpu(int); | 120 | static void do_boot_cpu(int); |
116 | int __cpu_up(unsigned int); | 121 | int __cpu_up(unsigned int); |
@@ -177,6 +182,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
177 | } | 182 | } |
178 | for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) | 183 | for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) |
179 | physid_set(phys_id, phys_cpu_present_map); | 184 | physid_set(phys_id, phys_cpu_present_map); |
185 | #ifndef CONFIG_HOTPLUG_CPU | ||
186 | cpu_present_map = cpu_possible_map; | ||
187 | #endif | ||
180 | 188 | ||
181 | show_mp_info(nr_cpu); | 189 | show_mp_info(nr_cpu); |
182 | 190 | ||
@@ -186,7 +194,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
186 | * Setup boot CPU information | 194 | * Setup boot CPU information |
187 | */ | 195 | */ |
188 | smp_store_cpu_info(0); /* Final full version of the data */ | 196 | smp_store_cpu_info(0); /* Final full version of the data */ |
189 | smp_tune_scheduling(); | ||
190 | 197 | ||
191 | /* | 198 | /* |
192 | * If SMP should be disabled, then really disable it! | 199 | * If SMP should be disabled, then really disable it! |
@@ -230,11 +237,6 @@ smp_done: | |||
230 | Dprintk("Boot done.\n"); | 237 | Dprintk("Boot done.\n"); |
231 | } | 238 | } |
232 | 239 | ||
233 | static void __init smp_tune_scheduling(void) | ||
234 | { | ||
235 | /* Nothing to do. */ | ||
236 | } | ||
237 | |||
238 | /* | 240 | /* |
239 | * init_ipi_lock : Initialize IPI locks. | 241 | * init_ipi_lock : Initialize IPI locks. |
240 | */ | 242 | */ |
@@ -629,4 +631,3 @@ static void __init unmap_cpu_to_physid(int cpu_id, int phys_id) | |||
629 | physid_2_cpu[phys_id] = -1; | 631 | physid_2_cpu[phys_id] = -1; |
630 | cpu_2_physid[cpu_id] = -1; | 632 | cpu_2_physid[cpu_id] = -1; |
631 | } | 633 | } |
632 | |||
diff --git a/arch/m32r/lib/Makefile b/arch/m32r/lib/Makefile index e632d10c7d78..d16b4e40d1ae 100644 --- a/arch/m32r/lib/Makefile +++ b/arch/m32r/lib/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for M32R-specific library files.. | 2 | # Makefile for M32R-specific library files.. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \ | 5 | lib-y := checksum.o ashxdi3.o memset.o memcpy.o \ |
6 | putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o | 6 | delay.o strlen.o usercopy.o csum_partial_copy.o |
7 | 7 | ||
diff --git a/arch/m32r/lib/getuser.S b/arch/m32r/lib/getuser.S deleted file mode 100644 index 58a0db055c5c..000000000000 --- a/arch/m32r/lib/getuser.S +++ /dev/null | |||
@@ -1,88 +0,0 @@ | |||
1 | /* | ||
2 | * __get_user functions. | ||
3 | * | ||
4 | * (C) Copyright 2001 Hirokazu Takata | ||
5 | * | ||
6 | * These functions have a non-standard call interface | ||
7 | * to make them more efficient, especially as they | ||
8 | * return an error value in addition to the "real" | ||
9 | * return value. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | |||
14 | /* | ||
15 | * __get_user_X | ||
16 | * | ||
17 | * Inputs: r0 contains the address | ||
18 | * | ||
19 | * Outputs: r0 is error code (0 or -EFAULT) | ||
20 | * r1 contains zero-extended value | ||
21 | * | ||
22 | * These functions should not modify any other registers, | ||
23 | * as they get called from within inline assembly. | ||
24 | */ | ||
25 | |||
26 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
27 | |||
28 | .text | ||
29 | .balign 4 | ||
30 | .globl __get_user_1 | ||
31 | __get_user_1: | ||
32 | 1: ldub r1, @r0 || ldi r0, #0 | ||
33 | jmp r14 | ||
34 | |||
35 | .balign 4 | ||
36 | .globl __get_user_2 | ||
37 | __get_user_2: | ||
38 | 2: lduh r1, @r0 || ldi r0, #0 | ||
39 | jmp r14 | ||
40 | |||
41 | .balign 4 | ||
42 | .globl __get_user_4 | ||
43 | __get_user_4: | ||
44 | 3: ld r1, @r0 || ldi r0, #0 | ||
45 | jmp r14 | ||
46 | |||
47 | bad_get_user: | ||
48 | ldi r1, #0 || ldi r0, #-14 | ||
49 | jmp r14 | ||
50 | |||
51 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
52 | |||
53 | .text | ||
54 | .balign 4 | ||
55 | .globl __get_user_1 | ||
56 | __get_user_1: | ||
57 | 1: ldub r1, @r0 | ||
58 | ldi r0, #0 | ||
59 | jmp r14 | ||
60 | |||
61 | .balign 4 | ||
62 | .globl __get_user_2 | ||
63 | __get_user_2: | ||
64 | 2: lduh r1, @r0 | ||
65 | ldi r0, #0 | ||
66 | jmp r14 | ||
67 | |||
68 | .balign 4 | ||
69 | .globl __get_user_4 | ||
70 | __get_user_4: | ||
71 | 3: ld r1, @r0 | ||
72 | ldi r0, #0 | ||
73 | jmp r14 | ||
74 | |||
75 | bad_get_user: | ||
76 | ldi r1, #0 | ||
77 | ldi r0, #-14 | ||
78 | jmp r14 | ||
79 | |||
80 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | ||
81 | |||
82 | .section __ex_table,"a" | ||
83 | .long 1b,bad_get_user | ||
84 | .long 2b,bad_get_user | ||
85 | .long 3b,bad_get_user | ||
86 | .previous | ||
87 | |||
88 | .end | ||
diff --git a/arch/m32r/lib/putuser.S b/arch/m32r/lib/putuser.S deleted file mode 100644 index 218154cc3890..000000000000 --- a/arch/m32r/lib/putuser.S +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * __put_user functions. | ||
3 | * | ||
4 | * (C) Copyright 1998 Linus Torvalds | ||
5 | * (C) Copyright 2001 Hirokazu Takata | ||
6 | * | ||
7 | * These functions have a non-standard call interface | ||
8 | * to make them more efficient. | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | |||
13 | /* | ||
14 | * __put_user_X | ||
15 | * | ||
16 | * Inputs: r0 contains the address | ||
17 | * r1 contains the value | ||
18 | * | ||
19 | * Outputs: r0 is error code (0 or -EFAULT) | ||
20 | * r1 is corrupted (will contain "current_task"). | ||
21 | * | ||
22 | * These functions should not modify any other registers, | ||
23 | * as they get called from within inline assembly. | ||
24 | */ | ||
25 | |||
26 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
27 | |||
28 | .text | ||
29 | .balign 4 | ||
30 | .globl __put_user_1 | ||
31 | __put_user_1: | ||
32 | 1: stb r1, @r0 || ldi r0, #0 | ||
33 | jmp r14 | ||
34 | |||
35 | .balign 4 | ||
36 | .globl __put_user_2 | ||
37 | __put_user_2: | ||
38 | 2: sth r1, @r0 || ldi r0, #0 | ||
39 | jmp r14 | ||
40 | |||
41 | .balign 4 | ||
42 | .globl __put_user_4 | ||
43 | __put_user_4: | ||
44 | 3: st r1, @r0 || ldi r0, #0 | ||
45 | jmp r14 | ||
46 | |||
47 | bad_put_user: | ||
48 | ldi r0, #-14 || jmp r14 | ||
49 | |||
50 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
51 | |||
52 | .text | ||
53 | .balign 4 | ||
54 | .globl __put_user_1 | ||
55 | __put_user_1: | ||
56 | 1: stb r1, @r0 | ||
57 | ldi r0, #0 | ||
58 | jmp r14 | ||
59 | |||
60 | .balign 4 | ||
61 | .globl __put_user_2 | ||
62 | __put_user_2: | ||
63 | 2: sth r1, @r0 | ||
64 | ldi r0, #0 | ||
65 | jmp r14 | ||
66 | |||
67 | .balign 4 | ||
68 | .globl __put_user_4 | ||
69 | __put_user_4: | ||
70 | 3: st r1, @r0 | ||
71 | ldi r0, #0 | ||
72 | jmp r14 | ||
73 | |||
74 | bad_put_user: | ||
75 | ldi r0, #-14 | ||
76 | jmp r14 | ||
77 | |||
78 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | ||
79 | |||
80 | .section __ex_table,"a" | ||
81 | .long 1b,bad_put_user | ||
82 | .long 2b,bad_put_user | ||
83 | .long 3b,bad_put_user | ||
84 | .previous | ||
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index c3319514a85e..5b7952ea2bae 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c | |||
@@ -57,7 +57,6 @@ EXPORT_SYMBOL(dump_thread); | |||
57 | EXPORT_SYMBOL(strnlen); | 57 | EXPORT_SYMBOL(strnlen); |
58 | EXPORT_SYMBOL(strrchr); | 58 | EXPORT_SYMBOL(strrchr); |
59 | EXPORT_SYMBOL(strstr); | 59 | EXPORT_SYMBOL(strstr); |
60 | EXPORT_SYMBOL(strpbrk); | ||
61 | EXPORT_SYMBOL(enable_irq); | 60 | EXPORT_SYMBOL(enable_irq); |
62 | EXPORT_SYMBOL(disable_irq); | 61 | EXPORT_SYMBOL(disable_irq); |
63 | EXPORT_SYMBOL(kernel_thread); | 62 | EXPORT_SYMBOL(kernel_thread); |
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c index f9b4ea16c099..4320d5dcc9cb 100644 --- a/arch/m68knommu/kernel/m68k_ksyms.c +++ b/arch/m68knommu/kernel/m68k_ksyms.c | |||
@@ -26,7 +26,6 @@ EXPORT_SYMBOL(__ioremap); | |||
26 | EXPORT_SYMBOL(iounmap); | 26 | EXPORT_SYMBOL(iounmap); |
27 | EXPORT_SYMBOL(dump_fpu); | 27 | EXPORT_SYMBOL(dump_fpu); |
28 | EXPORT_SYMBOL(strnlen); | 28 | EXPORT_SYMBOL(strnlen); |
29 | EXPORT_SYMBOL(strpbrk); | ||
30 | EXPORT_SYMBOL(strrchr); | 29 | EXPORT_SYMBOL(strrchr); |
31 | EXPORT_SYMBOL(strstr); | 30 | EXPORT_SYMBOL(strstr); |
32 | EXPORT_SYMBOL(strchr); | 31 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e15709ce8866..7aec60d40420 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1590,6 +1590,11 @@ config ARCH_FLATMEM_ENABLE | |||
1590 | def_bool y | 1590 | def_bool y |
1591 | depends on !NUMA | 1591 | depends on !NUMA |
1592 | 1592 | ||
1593 | config NODES_SHIFT | ||
1594 | int | ||
1595 | default "6" | ||
1596 | depends on NEED_MULTIPLE_NODES | ||
1597 | |||
1593 | source "mm/Kconfig" | 1598 | source "mm/Kconfig" |
1594 | 1599 | ||
1595 | config SMP | 1600 | config SMP |
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 86e42c633f73..e042f9d2ba31 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(strchr); | |||
39 | EXPORT_SYMBOL(strncmp); | 39 | EXPORT_SYMBOL(strncmp); |
40 | #endif | 40 | #endif |
41 | EXPORT_SYMBOL(strlen); | 41 | EXPORT_SYMBOL(strlen); |
42 | EXPORT_SYMBOL(strpbrk); | ||
43 | EXPORT_SYMBOL(strncat); | 42 | EXPORT_SYMBOL(strncat); |
44 | EXPORT_SYMBOL(strnlen); | 43 | EXPORT_SYMBOL(strnlen); |
45 | EXPORT_SYMBOL(strrchr); | 44 | EXPORT_SYMBOL(strrchr); |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 2fdf21989dc2..19f911c5dd58 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -177,6 +177,11 @@ config ARCH_DISCONTIGMEM_DEFAULT | |||
177 | def_bool y | 177 | def_bool y |
178 | depends on ARCH_DISCONTIGMEM_ENABLE | 178 | depends on ARCH_DISCONTIGMEM_ENABLE |
179 | 179 | ||
180 | config NODES_SHIFT | ||
181 | int | ||
182 | default "3" | ||
183 | depends on NEED_MULTIPLE_NODES | ||
184 | |||
180 | source "kernel/Kconfig.preempt" | 185 | source "kernel/Kconfig.preempt" |
181 | source "kernel/Kconfig.hz" | 186 | source "kernel/Kconfig.hz" |
182 | source "mm/Kconfig" | 187 | source "mm/Kconfig" |
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 47ca5c0a323b..fc107add627c 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | EXPORT_SYMBOL(memset); | 33 | EXPORT_SYMBOL(memset); |
34 | EXPORT_SYMBOL(strpbrk); | ||
35 | 34 | ||
36 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
37 | EXPORT_SYMBOL(__xchg8); | 36 | EXPORT_SYMBOL(__xchg8); |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2cdc35ce8045..167e70e95556 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -649,6 +649,11 @@ config NUMA | |||
649 | depends on PPC64 | 649 | depends on PPC64 |
650 | default y if SMP && PPC_PSERIES | 650 | default y if SMP && PPC_PSERIES |
651 | 651 | ||
652 | config NODES_SHIFT | ||
653 | int | ||
654 | default "4" | ||
655 | depends on NEED_MULTIPLE_NODES | ||
656 | |||
652 | config ARCH_SELECT_MEMORY_MODEL | 657 | config ARCH_SELECT_MEMORY_MODEL |
653 | def_bool y | 658 | def_bool y |
654 | depends on PPC64 | 659 | depends on PPC64 |
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile index d4077e69086f..80c84d562fa4 100644 --- a/arch/ppc/boot/lib/Makefile +++ b/arch/ppc/boot/lib/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | CFLAGS_kbd.o := -Idrivers/char | 5 | CFLAGS_kbd.o := -Idrivers/char |
6 | CFLAGS_vreset.o := -I$(srctree)/arch/ppc/boot/include | 6 | CFLAGS_vreset.o := -Iarch/ppc/boot/include |
7 | 7 | ||
8 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c | 8 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c |
9 | 9 | ||
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 6c6b197898d0..7bb16fb97d4f 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -67,7 +67,6 @@ cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE) | |||
67 | endif | 67 | endif |
68 | 68 | ||
69 | CFLAGS += -mbackchain -msoft-float $(cflags-y) | 69 | CFLAGS += -mbackchain -msoft-float $(cflags-y) |
70 | CFLAGS += $(call cc-option,-finline-limit=10000) | ||
71 | CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare | 70 | CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare |
72 | AFLAGS += $(aflags-y) | 71 | AFLAGS += $(aflags-y) |
73 | 72 | ||
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index f8d0cd540a06..f4dfc10026d2 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -1,10 +1,11 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc2 | 3 | # Linux kernel version: 2.6.17-rc1 |
4 | # Wed Feb 8 10:44:39 2006 | 4 | # Mon Apr 3 14:34:15 2006 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
8 | CONFIG_GENERIC_HWEIGHT=y | ||
8 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 9 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
9 | CONFIG_S390=y | 10 | CONFIG_S390=y |
10 | 11 | ||
@@ -30,8 +31,8 @@ CONFIG_AUDIT=y | |||
30 | CONFIG_IKCONFIG=y | 31 | CONFIG_IKCONFIG=y |
31 | CONFIG_IKCONFIG_PROC=y | 32 | CONFIG_IKCONFIG_PROC=y |
32 | # CONFIG_CPUSETS is not set | 33 | # CONFIG_CPUSETS is not set |
34 | # CONFIG_RELAY is not set | ||
33 | CONFIG_INITRAMFS_SOURCE="" | 35 | CONFIG_INITRAMFS_SOURCE="" |
34 | CONFIG_UID16=y | ||
35 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 36 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
36 | # CONFIG_EMBEDDED is not set | 37 | # CONFIG_EMBEDDED is not set |
37 | CONFIG_KALLSYMS=y | 38 | CONFIG_KALLSYMS=y |
@@ -45,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
45 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
46 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
47 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
48 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
49 | CONFIG_CC_ALIGN_LABELS=0 | ||
50 | CONFIG_CC_ALIGN_LOOPS=0 | ||
51 | CONFIG_CC_ALIGN_JUMPS=0 | ||
52 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
53 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
54 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -60,7 +57,6 @@ CONFIG_BASE_SMALL=0 | |||
60 | CONFIG_MODULES=y | 57 | CONFIG_MODULES=y |
61 | CONFIG_MODULE_UNLOAD=y | 58 | CONFIG_MODULE_UNLOAD=y |
62 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 59 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
63 | CONFIG_OBSOLETE_MODPARM=y | ||
64 | CONFIG_MODVERSIONS=y | 60 | CONFIG_MODVERSIONS=y |
65 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 61 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
66 | CONFIG_KMOD=y | 62 | CONFIG_KMOD=y |
@@ -69,7 +65,7 @@ CONFIG_STOP_MACHINE=y | |||
69 | # | 65 | # |
70 | # Block layer | 66 | # Block layer |
71 | # | 67 | # |
72 | # CONFIG_LBD is not set | 68 | # CONFIG_BLK_DEV_IO_TRACE is not set |
73 | 69 | ||
74 | # | 70 | # |
75 | # IO Schedulers | 71 | # IO Schedulers |
@@ -91,17 +87,20 @@ CONFIG_DEFAULT_IOSCHED="deadline" | |||
91 | # | 87 | # |
92 | # Processor type and features | 88 | # Processor type and features |
93 | # | 89 | # |
94 | # CONFIG_64BIT is not set | 90 | CONFIG_64BIT=y |
95 | CONFIG_SMP=y | 91 | CONFIG_SMP=y |
96 | CONFIG_NR_CPUS=32 | 92 | CONFIG_NR_CPUS=32 |
97 | CONFIG_HOTPLUG_CPU=y | 93 | CONFIG_HOTPLUG_CPU=y |
98 | CONFIG_MATHEMU=y | 94 | CONFIG_DEFAULT_MIGRATION_COST=1000000 |
95 | CONFIG_COMPAT=y | ||
96 | CONFIG_SYSVIPC_COMPAT=y | ||
97 | CONFIG_BINFMT_ELF32=y | ||
99 | 98 | ||
100 | # | 99 | # |
101 | # Code generation options | 100 | # Code generation options |
102 | # | 101 | # |
103 | CONFIG_MARCH_G5=y | 102 | # CONFIG_MARCH_G5 is not set |
104 | # CONFIG_MARCH_Z900 is not set | 103 | CONFIG_MARCH_Z900=y |
105 | # CONFIG_MARCH_Z990 is not set | 104 | # CONFIG_MARCH_Z990 is not set |
106 | CONFIG_PACK_STACK=y | 105 | CONFIG_PACK_STACK=y |
107 | # CONFIG_SMALL_STACK is not set | 106 | # CONFIG_SMALL_STACK is not set |
@@ -143,7 +142,7 @@ CONFIG_VIRT_CPU_ACCOUNTING=y | |||
143 | # CONFIG_APPLDATA_BASE is not set | 142 | # CONFIG_APPLDATA_BASE is not set |
144 | CONFIG_NO_IDLE_HZ=y | 143 | CONFIG_NO_IDLE_HZ=y |
145 | CONFIG_NO_IDLE_HZ_INIT=y | 144 | CONFIG_NO_IDLE_HZ_INIT=y |
146 | # CONFIG_KEXEC is not set | 145 | CONFIG_KEXEC=y |
147 | 146 | ||
148 | # | 147 | # |
149 | # Networking | 148 | # Networking |
@@ -173,6 +172,7 @@ CONFIG_IP_FIB_HASH=y | |||
173 | # CONFIG_INET_AH is not set | 172 | # CONFIG_INET_AH is not set |
174 | # CONFIG_INET_ESP is not set | 173 | # CONFIG_INET_ESP is not set |
175 | # CONFIG_INET_IPCOMP is not set | 174 | # CONFIG_INET_IPCOMP is not set |
175 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
176 | # CONFIG_INET_TUNNEL is not set | 176 | # CONFIG_INET_TUNNEL is not set |
177 | CONFIG_INET_DIAG=y | 177 | CONFIG_INET_DIAG=y |
178 | CONFIG_INET_TCP_DIAG=y | 178 | CONFIG_INET_TCP_DIAG=y |
@@ -180,9 +180,11 @@ CONFIG_INET_TCP_DIAG=y | |||
180 | CONFIG_TCP_CONG_BIC=y | 180 | CONFIG_TCP_CONG_BIC=y |
181 | CONFIG_IPV6=y | 181 | CONFIG_IPV6=y |
182 | # CONFIG_IPV6_PRIVACY is not set | 182 | # CONFIG_IPV6_PRIVACY is not set |
183 | # CONFIG_IPV6_ROUTER_PREF is not set | ||
183 | # CONFIG_INET6_AH is not set | 184 | # CONFIG_INET6_AH is not set |
184 | # CONFIG_INET6_ESP is not set | 185 | # CONFIG_INET6_ESP is not set |
185 | # CONFIG_INET6_IPCOMP is not set | 186 | # CONFIG_INET6_IPCOMP is not set |
187 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
186 | # CONFIG_INET6_TUNNEL is not set | 188 | # CONFIG_INET6_TUNNEL is not set |
187 | # CONFIG_IPV6_TUNNEL is not set | 189 | # CONFIG_IPV6_TUNNEL is not set |
188 | # CONFIG_NETFILTER is not set | 190 | # CONFIG_NETFILTER is not set |
@@ -276,6 +278,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
276 | # CONFIG_DEBUG_DRIVER is not set | 278 | # CONFIG_DEBUG_DRIVER is not set |
277 | 279 | ||
278 | # | 280 | # |
281 | # Connector - unified userspace <-> kernelspace linker | ||
282 | # | ||
283 | # CONFIG_CONNECTOR is not set | ||
284 | |||
285 | # | ||
279 | # SCSI device support | 286 | # SCSI device support |
280 | # | 287 | # |
281 | # CONFIG_RAID_ATTRS is not set | 288 | # CONFIG_RAID_ATTRS is not set |
@@ -340,8 +347,7 @@ CONFIG_DASD_PROFILE=y | |||
340 | CONFIG_DASD_ECKD=y | 347 | CONFIG_DASD_ECKD=y |
341 | CONFIG_DASD_FBA=y | 348 | CONFIG_DASD_FBA=y |
342 | CONFIG_DASD_DIAG=y | 349 | CONFIG_DASD_DIAG=y |
343 | CONFIG_DASD_EER=m | 350 | CONFIG_DASD_EER=y |
344 | # CONFIG_DASD_CMB is not set | ||
345 | # CONFIG_ATA_OVER_ETH is not set | 351 | # CONFIG_ATA_OVER_ETH is not set |
346 | 352 | ||
347 | # | 353 | # |
@@ -354,6 +360,7 @@ CONFIG_MD_RAID0=m | |||
354 | CONFIG_MD_RAID1=m | 360 | CONFIG_MD_RAID1=m |
355 | # CONFIG_MD_RAID10 is not set | 361 | # CONFIG_MD_RAID10 is not set |
356 | CONFIG_MD_RAID5=m | 362 | CONFIG_MD_RAID5=m |
363 | # CONFIG_MD_RAID5_RESHAPE is not set | ||
357 | # CONFIG_MD_RAID6 is not set | 364 | # CONFIG_MD_RAID6 is not set |
358 | CONFIG_MD_MULTIPATH=m | 365 | CONFIG_MD_MULTIPATH=m |
359 | # CONFIG_MD_FAULTY is not set | 366 | # CONFIG_MD_FAULTY is not set |
@@ -404,6 +411,7 @@ CONFIG_S390_TAPE_BLOCK=y | |||
404 | # S/390 tape hardware support | 411 | # S/390 tape hardware support |
405 | # | 412 | # |
406 | CONFIG_S390_TAPE_34XX=m | 413 | CONFIG_S390_TAPE_34XX=m |
414 | # CONFIG_S390_TAPE_3590 is not set | ||
407 | # CONFIG_VMLOGRDR is not set | 415 | # CONFIG_VMLOGRDR is not set |
408 | # CONFIG_VMCP is not set | 416 | # CONFIG_VMCP is not set |
409 | # CONFIG_MONREADER is not set | 417 | # CONFIG_MONREADER is not set |
@@ -529,7 +537,6 @@ CONFIG_SYSFS=y | |||
529 | CONFIG_TMPFS=y | 537 | CONFIG_TMPFS=y |
530 | # CONFIG_HUGETLB_PAGE is not set | 538 | # CONFIG_HUGETLB_PAGE is not set |
531 | CONFIG_RAMFS=y | 539 | CONFIG_RAMFS=y |
532 | # CONFIG_RELAYFS_FS is not set | ||
533 | # CONFIG_CONFIGFS_FS is not set | 540 | # CONFIG_CONFIGFS_FS is not set |
534 | 541 | ||
535 | # | 542 | # |
@@ -619,14 +626,15 @@ CONFIG_LOG_BUF_SHIFT=17 | |||
619 | # CONFIG_DETECT_SOFTLOCKUP is not set | 626 | # CONFIG_DETECT_SOFTLOCKUP is not set |
620 | # CONFIG_SCHEDSTATS is not set | 627 | # CONFIG_SCHEDSTATS is not set |
621 | # CONFIG_DEBUG_SLAB is not set | 628 | # CONFIG_DEBUG_SLAB is not set |
622 | # CONFIG_DEBUG_PREEMPT is not set | 629 | CONFIG_DEBUG_PREEMPT=y |
623 | CONFIG_DEBUG_MUTEXES=y | 630 | CONFIG_DEBUG_MUTEXES=y |
624 | # CONFIG_DEBUG_SPINLOCK is not set | 631 | CONFIG_DEBUG_SPINLOCK=y |
625 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 632 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
626 | # CONFIG_DEBUG_KOBJECT is not set | 633 | # CONFIG_DEBUG_KOBJECT is not set |
627 | # CONFIG_DEBUG_INFO is not set | 634 | # CONFIG_DEBUG_INFO is not set |
628 | CONFIG_DEBUG_FS=y | 635 | CONFIG_DEBUG_FS=y |
629 | # CONFIG_DEBUG_VM is not set | 636 | # CONFIG_DEBUG_VM is not set |
637 | # CONFIG_UNWIND_INFO is not set | ||
630 | CONFIG_FORCED_INLINING=y | 638 | CONFIG_FORCED_INLINING=y |
631 | # CONFIG_RCU_TORTURE_TEST is not set | 639 | # CONFIG_RCU_TORTURE_TEST is not set |
632 | 640 | ||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 58583f459471..2bcecf422573 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -527,6 +527,11 @@ config CPU_HAS_SR_RB | |||
527 | See <file:Documentation/sh/register-banks.txt> for further | 527 | See <file:Documentation/sh/register-banks.txt> for further |
528 | information on SR.RB and register banking in the kernel in general. | 528 | information on SR.RB and register banking in the kernel in general. |
529 | 529 | ||
530 | config NODES_SHIFT | ||
531 | int | ||
532 | default "1" | ||
533 | depends on NEED_MULTIPLE_NODES | ||
534 | |||
530 | endmenu | 535 | endmenu |
531 | 536 | ||
532 | menu "Boot options" | 537 | menu "Boot options" |
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 1cf94a618be3..d5d032533a8b 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c | |||
@@ -37,7 +37,6 @@ EXPORT_SYMBOL(disable_irq_nosync); | |||
37 | EXPORT_SYMBOL(irq_desc); | 37 | EXPORT_SYMBOL(irq_desc); |
38 | EXPORT_SYMBOL(no_irq_type); | 38 | EXPORT_SYMBOL(no_irq_type); |
39 | 39 | ||
40 | EXPORT_SYMBOL(strpbrk); | ||
41 | EXPORT_SYMBOL(strstr); | 40 | EXPORT_SYMBOL(strstr); |
42 | EXPORT_SYMBOL(strlen); | 41 | EXPORT_SYMBOL(strlen); |
43 | EXPORT_SYMBOL(strnlen); | 42 | EXPORT_SYMBOL(strnlen); |
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c index de29c45f23a7..6f3a1c946339 100644 --- a/arch/sh64/kernel/sh_ksyms.c +++ b/arch/sh64/kernel/sh_ksyms.c | |||
@@ -41,7 +41,6 @@ EXPORT_SYMBOL(kernel_thread); | |||
41 | /* Networking helper routines. */ | 41 | /* Networking helper routines. */ |
42 | EXPORT_SYMBOL(csum_partial_copy); | 42 | EXPORT_SYMBOL(csum_partial_copy); |
43 | 43 | ||
44 | EXPORT_SYMBOL(strpbrk); | ||
45 | EXPORT_SYMBOL(strstr); | 44 | EXPORT_SYMBOL(strstr); |
46 | 45 | ||
47 | #ifdef CONFIG_VT | 46 | #ifdef CONFIG_VT |
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 2be812115197..a93f5da6855d 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c | |||
@@ -244,7 +244,7 @@ int setup_profiling_timer(unsigned int multiplier) | |||
244 | return -EINVAL; | 244 | return -EINVAL; |
245 | 245 | ||
246 | spin_lock_irqsave(&prof_setup_lock, flags); | 246 | spin_lock_irqsave(&prof_setup_lock, flags); |
247 | for_each_cpu(i) { | 247 | for_each_possible_cpu(i) { |
248 | load_profile_irq(i, lvl14_resolution / multiplier); | 248 | load_profile_irq(i, lvl14_resolution / multiplier); |
249 | prof_multiplier(i) = multiplier; | 249 | prof_multiplier(i) = multiplier; |
250 | } | 250 | } |
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 2c21d7907635..ec1c9687d679 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
@@ -263,7 +263,6 @@ EXPORT_SYMBOL(strcmp); | |||
263 | EXPORT_SYMBOL(strncmp); | 263 | EXPORT_SYMBOL(strncmp); |
264 | EXPORT_SYMBOL(strchr); | 264 | EXPORT_SYMBOL(strchr); |
265 | EXPORT_SYMBOL(strrchr); | 265 | EXPORT_SYMBOL(strrchr); |
266 | EXPORT_SYMBOL(strpbrk); | ||
267 | EXPORT_SYMBOL(strstr); | 266 | EXPORT_SYMBOL(strstr); |
268 | EXPORT_SYMBOL(page_kernel); | 267 | EXPORT_SYMBOL(page_kernel); |
269 | 268 | ||
diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile index f84a9a6162be..8136987977f4 100644 --- a/arch/sparc/math-emu/Makefile +++ b/arch/sparc/math-emu/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | obj-y := math.o | 5 | obj-y := math.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := -ansi | 7 | EXTRA_AFLAGS := -ansi |
8 | EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w | 8 | EXTRA_CFLAGS = -I. -Iinclude/math-emu -w |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index d1e2fc566486..648047a0bce3 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -194,6 +194,9 @@ endchoice | |||
194 | 194 | ||
195 | endmenu | 195 | endmenu |
196 | 196 | ||
197 | config ARCH_SELECT_MEMORY_MODEL | ||
198 | def_bool y | ||
199 | |||
197 | config ARCH_SPARSEMEM_ENABLE | 200 | config ARCH_SPARSEMEM_ENABLE |
198 | def_bool y | 201 | def_bool y |
199 | 202 | ||
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 30389085a359..1317380fa937 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16 | 3 | # Linux kernel version: 2.6.16 |
4 | # Fri Mar 31 01:40:57 2006 | 4 | # Sun Apr 2 19:31:04 2006 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
@@ -838,7 +838,6 @@ CONFIG_FB_TILEBLITTING=y | |||
838 | # CONFIG_FB_NVIDIA is not set | 838 | # CONFIG_FB_NVIDIA is not set |
839 | # CONFIG_FB_RIVA is not set | 839 | # CONFIG_FB_RIVA is not set |
840 | # CONFIG_FB_MATROX is not set | 840 | # CONFIG_FB_MATROX is not set |
841 | # CONFIG_FB_RADEON_OLD is not set | ||
842 | CONFIG_FB_RADEON=y | 841 | CONFIG_FB_RADEON=y |
843 | CONFIG_FB_RADEON_I2C=y | 842 | CONFIG_FB_RADEON_I2C=y |
844 | # CONFIG_FB_RADEON_DEBUG is not set | 843 | # CONFIG_FB_RADEON_DEBUG is not set |
@@ -924,6 +923,7 @@ CONFIG_SND_MTPAV=m | |||
924 | # PCI devices | 923 | # PCI devices |
925 | # | 924 | # |
926 | # CONFIG_SND_AD1889 is not set | 925 | # CONFIG_SND_AD1889 is not set |
926 | # CONFIG_SND_ALS300 is not set | ||
927 | CONFIG_SND_ALI5451=m | 927 | CONFIG_SND_ALI5451=m |
928 | # CONFIG_SND_ATIIXP is not set | 928 | # CONFIG_SND_ATIIXP is not set |
929 | # CONFIG_SND_ATIIXP_MODEM is not set | 929 | # CONFIG_SND_ATIIXP_MODEM is not set |
@@ -955,6 +955,7 @@ CONFIG_SND_ALI5451=m | |||
955 | # CONFIG_SND_MIXART is not set | 955 | # CONFIG_SND_MIXART is not set |
956 | # CONFIG_SND_NM256 is not set | 956 | # CONFIG_SND_NM256 is not set |
957 | # CONFIG_SND_PCXHR is not set | 957 | # CONFIG_SND_PCXHR is not set |
958 | # CONFIG_SND_RIPTIDE is not set | ||
958 | # CONFIG_SND_RME32 is not set | 959 | # CONFIG_SND_RME32 is not set |
959 | # CONFIG_SND_RME96 is not set | 960 | # CONFIG_SND_RME96 is not set |
960 | # CONFIG_SND_RME9652 is not set | 961 | # CONFIG_SND_RME9652 is not set |
@@ -1109,6 +1110,11 @@ CONFIG_USB_HIDDEV=y | |||
1109 | # CONFIG_MMC is not set | 1110 | # CONFIG_MMC is not set |
1110 | 1111 | ||
1111 | # | 1112 | # |
1113 | # LED devices | ||
1114 | # | ||
1115 | # CONFIG_NEW_LEDS is not set | ||
1116 | |||
1117 | # | ||
1112 | # InfiniBand support | 1118 | # InfiniBand support |
1113 | # | 1119 | # |
1114 | # CONFIG_INFINIBAND is not set | 1120 | # CONFIG_INFINIBAND is not set |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 9372d4f376d5..9e94db2573a2 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -1092,7 +1092,7 @@ void sun4v_pci_init(int node, char *model_name) | |||
1092 | } | 1092 | } |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | for_each_cpu(i) { | 1095 | for_each_possible_cpu(i) { |
1096 | unsigned long page = get_zeroed_page(GFP_ATOMIC); | 1096 | unsigned long page = get_zeroed_page(GFP_ATOMIC); |
1097 | 1097 | ||
1098 | if (!page) | 1098 | if (!page) |
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index eb93e9c52846..49e6dedd027d 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
@@ -244,6 +244,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
244 | } | 244 | } |
245 | 245 | ||
246 | switch(request) { | 246 | switch(request) { |
247 | case PTRACE_PEEKUSR: | ||
248 | if (addr != 0) | ||
249 | pt_error_return(regs, EIO); | ||
250 | else | ||
251 | pt_succ_return(regs, 0); | ||
252 | goto out_tsk; | ||
253 | |||
247 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | 254 | case PTRACE_PEEKTEXT: /* read word at location addr. */ |
248 | case PTRACE_PEEKDATA: { | 255 | case PTRACE_PEEKDATA: { |
249 | unsigned long tmp64; | 256 | unsigned long tmp64; |
@@ -602,6 +609,22 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
602 | 609 | ||
603 | /* PTRACE_DUMPCORE unsupported... */ | 610 | /* PTRACE_DUMPCORE unsupported... */ |
604 | 611 | ||
612 | case PTRACE_GETEVENTMSG: { | ||
613 | int err; | ||
614 | |||
615 | if (test_thread_flag(TIF_32BIT)) | ||
616 | err = put_user(child->ptrace_message, | ||
617 | (unsigned int __user *) data); | ||
618 | else | ||
619 | err = put_user(child->ptrace_message, | ||
620 | (unsigned long __user *) data); | ||
621 | if (err) | ||
622 | pt_error_return(regs, -err); | ||
623 | else | ||
624 | pt_succ_return(regs, 0); | ||
625 | break; | ||
626 | } | ||
627 | |||
605 | default: { | 628 | default: { |
606 | int err = ptrace_request(child, request, addr, data); | 629 | int err = ptrace_request(child, request, addr, data); |
607 | if (err) | 630 | if (err) |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 7d0e67c1ce50..005167f82419 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -535,7 +535,7 @@ static int __init topology_init(void) | |||
535 | while (!cpu_find_by_instance(ncpus_probed, NULL, NULL)) | 535 | while (!cpu_find_by_instance(ncpus_probed, NULL, NULL)) |
536 | ncpus_probed++; | 536 | ncpus_probed++; |
537 | 537 | ||
538 | for_each_cpu(i) { | 538 | for_each_possible_cpu(i) { |
539 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | 539 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); |
540 | if (p) { | 540 | if (p) { |
541 | register_cpu(p, i, NULL); | 541 | register_cpu(p, i, NULL); |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 8175a6968c6b..90eaca3ec9a6 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -745,12 +745,21 @@ struct call_data_struct { | |||
745 | int wait; | 745 | int wait; |
746 | }; | 746 | }; |
747 | 747 | ||
748 | static DEFINE_SPINLOCK(call_lock); | 748 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); |
749 | static struct call_data_struct *call_data; | 749 | static struct call_data_struct *call_data; |
750 | 750 | ||
751 | extern unsigned long xcall_call_function; | 751 | extern unsigned long xcall_call_function; |
752 | 752 | ||
753 | /* | 753 | /** |
754 | * smp_call_function(): Run a function on all other CPUs. | ||
755 | * @func: The function to run. This must be fast and non-blocking. | ||
756 | * @info: An arbitrary pointer to pass to the function. | ||
757 | * @nonatomic: currently unused. | ||
758 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | ||
759 | * | ||
760 | * Returns 0 on success, else a negative status code. Does not return until | ||
761 | * remote CPUs are nearly ready to execute <<func>> or are or have executed. | ||
762 | * | ||
754 | * You must not call this function with disabled interrupts or from a | 763 | * You must not call this function with disabled interrupts or from a |
755 | * hardware interrupt handler or from a bottom half handler. | 764 | * hardware interrupt handler or from a bottom half handler. |
756 | */ | 765 | */ |
@@ -759,7 +768,6 @@ static int smp_call_function_mask(void (*func)(void *info), void *info, | |||
759 | { | 768 | { |
760 | struct call_data_struct data; | 769 | struct call_data_struct data; |
761 | int cpus; | 770 | int cpus; |
762 | long timeout; | ||
763 | 771 | ||
764 | /* Can deadlock when called with interrupts disabled */ | 772 | /* Can deadlock when called with interrupts disabled */ |
765 | WARN_ON(irqs_disabled()); | 773 | WARN_ON(irqs_disabled()); |
@@ -777,31 +785,18 @@ static int smp_call_function_mask(void (*func)(void *info), void *info, | |||
777 | goto out_unlock; | 785 | goto out_unlock; |
778 | 786 | ||
779 | call_data = &data; | 787 | call_data = &data; |
788 | mb(); | ||
780 | 789 | ||
781 | smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask); | 790 | smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask); |
782 | 791 | ||
783 | /* | 792 | /* Wait for response */ |
784 | * Wait for other cpus to complete function or at | 793 | while (atomic_read(&data.finished) != cpus) |
785 | * least snap the call data. | 794 | cpu_relax(); |
786 | */ | ||
787 | timeout = 1000000; | ||
788 | while (atomic_read(&data.finished) != cpus) { | ||
789 | if (--timeout <= 0) | ||
790 | goto out_timeout; | ||
791 | barrier(); | ||
792 | udelay(1); | ||
793 | } | ||
794 | 795 | ||
795 | out_unlock: | 796 | out_unlock: |
796 | spin_unlock(&call_lock); | 797 | spin_unlock(&call_lock); |
797 | 798 | ||
798 | return 0; | 799 | return 0; |
799 | |||
800 | out_timeout: | ||
801 | spin_unlock(&call_lock); | ||
802 | printk("XCALL: Remote cpus not responding, ncpus=%d finished=%d\n", | ||
803 | cpus, atomic_read(&data.finished)); | ||
804 | return 0; | ||
805 | } | 800 | } |
806 | 801 | ||
807 | int smp_call_function(void (*func)(void *info), void *info, | 802 | int smp_call_function(void (*func)(void *info), void *info, |
@@ -1285,7 +1280,7 @@ int setup_profiling_timer(unsigned int multiplier) | |||
1285 | return -EINVAL; | 1280 | return -EINVAL; |
1286 | 1281 | ||
1287 | spin_lock_irqsave(&prof_setup_lock, flags); | 1282 | spin_lock_irqsave(&prof_setup_lock, flags); |
1288 | for_each_cpu(i) | 1283 | for_each_possible_cpu(i) |
1289 | prof_multiplier(i) = multiplier; | 1284 | prof_multiplier(i) = multiplier; |
1290 | current_tick_offset = (timer_tick_offset / multiplier); | 1285 | current_tick_offset = (timer_tick_offset / multiplier); |
1291 | spin_unlock_irqrestore(&prof_setup_lock, flags); | 1286 | spin_unlock_irqrestore(&prof_setup_lock, flags); |
@@ -1313,12 +1308,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
1313 | } | 1308 | } |
1314 | } | 1309 | } |
1315 | 1310 | ||
1316 | for_each_cpu(i) { | 1311 | for_each_possible_cpu(i) { |
1317 | if (tlb_type == hypervisor) { | 1312 | if (tlb_type == hypervisor) { |
1318 | int j; | 1313 | int j; |
1319 | 1314 | ||
1320 | /* XXX get this mapping from machine description */ | 1315 | /* XXX get this mapping from machine description */ |
1321 | for_each_cpu(j) { | 1316 | for_each_possible_cpu(j) { |
1322 | if ((j >> 2) == (i >> 2)) | 1317 | if ((j >> 2) == (i >> 2)) |
1323 | cpu_set(j, cpu_sibling_map[i]); | 1318 | cpu_set(j, cpu_sibling_map[i]); |
1324 | } | 1319 | } |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index f5e8db1de76b..62d8a99271ea 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -276,7 +276,6 @@ EXPORT_SYMBOL(__prom_getsibling); | |||
276 | EXPORT_SYMBOL(strlen); | 276 | EXPORT_SYMBOL(strlen); |
277 | EXPORT_SYMBOL(__strlen_user); | 277 | EXPORT_SYMBOL(__strlen_user); |
278 | EXPORT_SYMBOL(__strnlen_user); | 278 | EXPORT_SYMBOL(__strnlen_user); |
279 | EXPORT_SYMBOL(strpbrk); | ||
280 | 279 | ||
281 | #ifdef CONFIG_SOLARIS_EMUL_MODULE | 280 | #ifdef CONFIG_SOLARIS_EMUL_MODULE |
282 | EXPORT_SYMBOL(linux_sparc_syscall); | 281 | EXPORT_SYMBOL(linux_sparc_syscall); |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index ff090bb9734b..2793a5d82380 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -1130,9 +1130,9 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in | |||
1130 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), | 1130 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), |
1131 | afsr, afar, | 1131 | afsr, afar, |
1132 | (afsr & CHAFSR_TL1) ? 1 : 0); | 1132 | (afsr & CHAFSR_TL1) ? 1 : 0); |
1133 | printk("%s" "ERROR(%d): TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", | 1133 | printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n", |
1134 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), | 1134 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), |
1135 | regs->tpc, regs->tnpc, regs->tstate); | 1135 | regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate); |
1136 | printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", | 1136 | printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", |
1137 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), | 1137 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), |
1138 | (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, | 1138 | (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, |
diff --git a/arch/um/Makefile b/arch/um/Makefile index 24790bed2054..a508e7a02891 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
@@ -159,6 +159,7 @@ archclean: | |||
159 | $(SYMLINK_HEADERS): | 159 | $(SYMLINK_HEADERS): |
160 | @echo ' SYMLINK $@' | 160 | @echo ' SYMLINK $@' |
161 | ifneq ($(KBUILD_SRC),) | 161 | ifneq ($(KBUILD_SRC),) |
162 | $(Q)mkdir -p $(objtree)/include/asm-um | ||
162 | $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ | 163 | $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ |
163 | else | 164 | else |
164 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ | 165 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ |
@@ -168,7 +169,7 @@ endif | |||
168 | include/asm-um/arch: | 169 | include/asm-um/arch: |
169 | @echo ' SYMLINK $@' | 170 | @echo ' SYMLINK $@' |
170 | ifneq ($(KBUILD_SRC),) | 171 | ifneq ($(KBUILD_SRC),) |
171 | $(Q)mkdir -p include/asm-um | 172 | $(Q)mkdir -p $(objtree)/include/asm-um |
172 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch | 173 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch |
173 | else | 174 | else |
174 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch | 175 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch |
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h index 04e3958266e0..dc36b222100b 100644 --- a/arch/um/drivers/cow.h +++ b/arch/um/drivers/cow.h | |||
@@ -46,7 +46,7 @@ extern int file_reader(__u64 offset, char *buf, int len, void *arg); | |||
46 | extern int read_cow_header(int (*reader)(__u64, char *, int, void *), | 46 | extern int read_cow_header(int (*reader)(__u64, char *, int, void *), |
47 | void *arg, __u32 *version_out, | 47 | void *arg, __u32 *version_out, |
48 | char **backing_file_out, time_t *mtime_out, | 48 | char **backing_file_out, time_t *mtime_out, |
49 | __u64 *size_out, int *sectorsize_out, | 49 | unsigned long long *size_out, int *sectorsize_out, |
50 | __u32 *align_out, int *bitmap_offset_out); | 50 | __u32 *align_out, int *bitmap_offset_out); |
51 | 51 | ||
52 | extern int write_cow_header(char *cow_file, int fd, char *backing_file, | 52 | extern int write_cow_header(char *cow_file, int fd, char *backing_file, |
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 94de4ead4f7a..7a5b4afde692 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h | |||
@@ -28,7 +28,7 @@ static inline int cow_seek_file(int fd, __u64 offset) | |||
28 | return(os_seek_file(fd, offset)); | 28 | return(os_seek_file(fd, offset)); |
29 | } | 29 | } |
30 | 30 | ||
31 | static inline int cow_file_size(char *file, __u64 *size_out) | 31 | static inline int cow_file_size(char *file, unsigned long long *size_out) |
32 | { | 32 | { |
33 | return(os_file_size(file, size_out)); | 33 | return(os_file_size(file, size_out)); |
34 | } | 34 | } |
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 61951b721268..0ec4052db9c5 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c | |||
@@ -17,30 +17,34 @@ | |||
17 | 17 | ||
18 | #define PATH_LEN_V1 256 | 18 | #define PATH_LEN_V1 256 |
19 | 19 | ||
20 | typedef __u32 time32_t; | ||
21 | |||
20 | struct cow_header_v1 { | 22 | struct cow_header_v1 { |
21 | int magic; | 23 | __s32 magic; |
22 | int version; | 24 | __s32 version; |
23 | char backing_file[PATH_LEN_V1]; | 25 | char backing_file[PATH_LEN_V1]; |
24 | time_t mtime; | 26 | time32_t mtime; |
25 | __u64 size; | 27 | __u64 size; |
26 | int sectorsize; | 28 | __s32 sectorsize; |
27 | }; | 29 | } __attribute__((packed)); |
28 | 30 | ||
29 | #define PATH_LEN_V2 MAXPATHLEN | 31 | /* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in |
32 | * case other systems have different values for MAXPATHLEN. | ||
33 | * | ||
34 | * The same must hold for V2 - we want file format compatibility, not anything | ||
35 | * else. | ||
36 | */ | ||
37 | #define PATH_LEN_V3 4096 | ||
38 | #define PATH_LEN_V2 PATH_LEN_V3 | ||
30 | 39 | ||
31 | struct cow_header_v2 { | 40 | struct cow_header_v2 { |
32 | __u32 magic; | 41 | __u32 magic; |
33 | __u32 version; | 42 | __u32 version; |
34 | char backing_file[PATH_LEN_V2]; | 43 | char backing_file[PATH_LEN_V2]; |
35 | time_t mtime; | 44 | time32_t mtime; |
36 | __u64 size; | 45 | __u64 size; |
37 | int sectorsize; | 46 | __s32 sectorsize; |
38 | }; | 47 | } __attribute__((packed)); |
39 | |||
40 | /* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in | ||
41 | * case other systems have different values for MAXPATHLEN | ||
42 | */ | ||
43 | #define PATH_LEN_V3 4096 | ||
44 | 48 | ||
45 | /* Changes from V2 - | 49 | /* Changes from V2 - |
46 | * PATH_LEN_V3 as described above | 50 | * PATH_LEN_V3 as described above |
@@ -66,6 +70,15 @@ struct cow_header_v2 { | |||
66 | * Fixed (finally!) the rounding bug | 70 | * Fixed (finally!) the rounding bug |
67 | */ | 71 | */ |
68 | 72 | ||
73 | /* Until Dec2005, __attribute__((packed)) was left out from the below | ||
74 | * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to | ||
75 | * align size to 8-byte alignment. This shifted all fields above (no padding | ||
76 | * was present on 32-bit, no other padding was added). | ||
77 | * | ||
78 | * However, this _can be detected_: it means that cow_format (always 0 until | ||
79 | * now) is shifted onto the first 4 bytes of backing_file, where it is otherwise | ||
80 | * impossible to find 4 zeros. -bb */ | ||
81 | |||
69 | struct cow_header_v3 { | 82 | struct cow_header_v3 { |
70 | __u32 magic; | 83 | __u32 magic; |
71 | __u32 version; | 84 | __u32 version; |
@@ -75,6 +88,18 @@ struct cow_header_v3 { | |||
75 | __u32 alignment; | 88 | __u32 alignment; |
76 | __u32 cow_format; | 89 | __u32 cow_format; |
77 | char backing_file[PATH_LEN_V3]; | 90 | char backing_file[PATH_LEN_V3]; |
91 | } __attribute__((packed)); | ||
92 | |||
93 | /* This is the broken layout used by some 64-bit binaries. */ | ||
94 | struct cow_header_v3_broken { | ||
95 | __u32 magic; | ||
96 | __u32 version; | ||
97 | __s64 mtime; | ||
98 | __u64 size; | ||
99 | __u32 sectorsize; | ||
100 | __u32 alignment; | ||
101 | __u32 cow_format; | ||
102 | char backing_file[PATH_LEN_V3]; | ||
78 | }; | 103 | }; |
79 | 104 | ||
80 | /* COW format definitions - for now, we have only the usual COW bitmap */ | 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ |
@@ -84,6 +109,7 @@ union cow_header { | |||
84 | struct cow_header_v1 v1; | 109 | struct cow_header_v1 v1; |
85 | struct cow_header_v2 v2; | 110 | struct cow_header_v2 v2; |
86 | struct cow_header_v3 v3; | 111 | struct cow_header_v3 v3; |
112 | struct cow_header_v3_broken v3_b; | ||
87 | }; | 113 | }; |
88 | 114 | ||
89 | #define COW_MAGIC 0x4f4f4f4d /* MOOO */ | 115 | #define COW_MAGIC 0x4f4f4f4d /* MOOO */ |
@@ -184,8 +210,9 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, | |||
184 | 210 | ||
185 | err = -EINVAL; | 211 | err = -EINVAL; |
186 | if(strlen(backing_file) > sizeof(header->backing_file) - 1){ | 212 | if(strlen(backing_file) > sizeof(header->backing_file) - 1){ |
213 | /* Below, %zd is for a size_t value */ | ||
187 | cow_printf("Backing file name \"%s\" is too long - names are " | 214 | cow_printf("Backing file name \"%s\" is too long - names are " |
188 | "limited to %d characters\n", backing_file, | 215 | "limited to %zd characters\n", backing_file, |
189 | sizeof(header->backing_file) - 1); | 216 | sizeof(header->backing_file) - 1); |
190 | goto out_free; | 217 | goto out_free; |
191 | } | 218 | } |
@@ -300,7 +327,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, | |||
300 | *align_out = *sectorsize_out; | 327 | *align_out = *sectorsize_out; |
301 | file = header->v2.backing_file; | 328 | file = header->v2.backing_file; |
302 | } | 329 | } |
303 | else if(version == 3){ | 330 | /* This is very subtle - see above at union cow_header definition */ |
331 | else if(version == 3 && (*((int*)header->v3.backing_file) != 0)){ | ||
304 | if(n < sizeof(header->v3)){ | 332 | if(n < sizeof(header->v3)){ |
305 | cow_printf("read_cow_header - failed to read V3 " | 333 | cow_printf("read_cow_header - failed to read V3 " |
306 | "header\n"); | 334 | "header\n"); |
@@ -310,9 +338,43 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, | |||
310 | *size_out = ntohll(header->v3.size); | 338 | *size_out = ntohll(header->v3.size); |
311 | *sectorsize_out = ntohl(header->v3.sectorsize); | 339 | *sectorsize_out = ntohl(header->v3.sectorsize); |
312 | *align_out = ntohl(header->v3.alignment); | 340 | *align_out = ntohl(header->v3.alignment); |
341 | if (*align_out == 0) { | ||
342 | cow_printf("read_cow_header - invalid COW header, " | ||
343 | "align == 0\n"); | ||
344 | } | ||
313 | *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); | 345 | *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); |
314 | file = header->v3.backing_file; | 346 | file = header->v3.backing_file; |
315 | } | 347 | } |
348 | else if(version == 3){ | ||
349 | cow_printf("read_cow_header - broken V3 file with" | ||
350 | " 64-bit layout - recovering content.\n"); | ||
351 | |||
352 | if(n < sizeof(header->v3_b)){ | ||
353 | cow_printf("read_cow_header - failed to read V3 " | ||
354 | "header\n"); | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | /* this was used until Dec2005 - 64bits are needed to represent | ||
359 | * 2038+. I.e. we can safely do this truncating cast. | ||
360 | * | ||
361 | * Additionally, we must use ntohl() instead of ntohll(), since | ||
362 | * the program used to use the former (tested - I got mtime | ||
363 | * mismatch "0 vs whatever"). | ||
364 | * | ||
365 | * Ever heard about bug-to-bug-compatibility ? ;-) */ | ||
366 | *mtime_out = (time32_t) ntohl(header->v3_b.mtime); | ||
367 | |||
368 | *size_out = ntohll(header->v3_b.size); | ||
369 | *sectorsize_out = ntohl(header->v3_b.sectorsize); | ||
370 | *align_out = ntohl(header->v3_b.alignment); | ||
371 | if (*align_out == 0) { | ||
372 | cow_printf("read_cow_header - invalid COW header, " | ||
373 | "align == 0\n"); | ||
374 | } | ||
375 | *bitmap_offset_out = ROUND_UP(sizeof(header->v3_b), *align_out); | ||
376 | file = header->v3_b.backing_file; | ||
377 | } | ||
316 | else { | 378 | else { |
317 | cow_printf("read_cow_header - invalid COW version\n"); | 379 | cow_printf("read_cow_header - invalid COW version\n"); |
318 | goto out; | 380 | goto out; |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 28e3760e8b98..6d7173fc55a3 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -62,7 +62,7 @@ static void mc_work_proc(void *unused) | |||
62 | unsigned long flags; | 62 | unsigned long flags; |
63 | 63 | ||
64 | while(!list_empty(&mc_requests)){ | 64 | while(!list_empty(&mc_requests)){ |
65 | local_save_flags(flags); | 65 | local_irq_save(flags); |
66 | req = list_entry(mc_requests.next, struct mconsole_entry, | 66 | req = list_entry(mc_requests.next, struct mconsole_entry, |
67 | list); | 67 | list); |
68 | list_del(&req->list); | 68 | list_del(&req->list); |
@@ -87,7 +87,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id, | |||
87 | if(req.cmd->context == MCONSOLE_INTR) | 87 | if(req.cmd->context == MCONSOLE_INTR) |
88 | (*req.cmd->handler)(&req); | 88 | (*req.cmd->handler)(&req); |
89 | else { | 89 | else { |
90 | new = kmalloc(sizeof(*new), GFP_ATOMIC); | 90 | new = kmalloc(sizeof(*new), GFP_NOWAIT); |
91 | if(new == NULL) | 91 | if(new == NULL) |
92 | mconsole_reply(&req, "Out of memory", 1, 0); | 92 | mconsole_reply(&req, "Out of memory", 1, 0); |
93 | else { | 93 | else { |
@@ -415,7 +415,6 @@ static int mem_config(char *str) | |||
415 | 415 | ||
416 | unplugged = page_address(page); | 416 | unplugged = page_address(page); |
417 | if(unplug_index == UNPLUGGED_PER_PAGE){ | 417 | if(unplug_index == UNPLUGGED_PER_PAGE){ |
418 | INIT_LIST_HEAD(&unplugged->list); | ||
419 | list_add(&unplugged->list, &unplugged_pages); | 418 | list_add(&unplugged->list, &unplugged_pages); |
420 | unplug_index = 0; | 419 | unplug_index = 0; |
421 | } | 420 | } |
@@ -616,7 +615,7 @@ static void console_write(struct console *console, const char *string, | |||
616 | return; | 615 | return; |
617 | 616 | ||
618 | while(1){ | 617 | while(1){ |
619 | n = min((size_t)len, ARRAY_SIZE(console_buf) - console_index); | 618 | n = min((size_t) len, ARRAY_SIZE(console_buf) - console_index); |
620 | strncpy(&console_buf[console_index], string, n); | 619 | strncpy(&console_buf[console_index], string, n); |
621 | console_index += n; | 620 | console_index += n; |
622 | string += n; | 621 | string += n; |
@@ -655,7 +654,6 @@ static void with_console(struct mc_request *req, void (*proc)(void *), | |||
655 | struct mconsole_entry entry; | 654 | struct mconsole_entry entry; |
656 | unsigned long flags; | 655 | unsigned long flags; |
657 | 656 | ||
658 | INIT_LIST_HEAD(&entry.list); | ||
659 | entry.request = *req; | 657 | entry.request = *req; |
660 | list_add(&entry.list, &clients); | 658 | list_add(&entry.list, &clients); |
661 | spin_lock_irqsave(&console_lock, flags); | 659 | spin_lock_irqsave(&console_lock, flags); |
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 0e2f06187ea7..0a7786e00cfb 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -182,7 +182,9 @@ static int change_tramp(char **argv, char *output, int output_len) | |||
182 | pe_data.stdout = fds[1]; | 182 | pe_data.stdout = fds[1]; |
183 | pid = run_helper(change_pre_exec, &pe_data, argv, NULL); | 183 | pid = run_helper(change_pre_exec, &pe_data, argv, NULL); |
184 | 184 | ||
185 | read_output(fds[0], output, output_len); | 185 | if (pid > 0) /* Avoid hang as we won't get data in failure case. */ |
186 | read_output(fds[0], output, output_len); | ||
187 | |||
186 | os_close_file(fds[0]); | 188 | os_close_file(fds[0]); |
187 | os_close_file(fds[1]); | 189 | os_close_file(fds[1]); |
188 | 190 | ||
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index b94c66114bc8..33c5f6e625e8 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c | |||
@@ -104,7 +104,7 @@ static void slirp_close(int fd, void *data) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | if(err == 0) { | 106 | if(err == 0) { |
107 | printk("slirp_close: process %d has not exited\n"); | 107 | printk("slirp_close: process %d has not exited\n", pri->pid); |
108 | return; | 108 | return; |
109 | } | 109 | } |
110 | 110 | ||
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 42557130a408..efa3d33c0be6 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -117,10 +117,6 @@ extern struct task_struct *get_task(int pid, int require); | |||
117 | extern void machine_halt(void); | 117 | extern void machine_halt(void); |
118 | extern int is_syscall(unsigned long addr); | 118 | extern int is_syscall(unsigned long addr); |
119 | 119 | ||
120 | extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to); | ||
121 | |||
122 | extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to); | ||
123 | |||
124 | extern void free_irq(unsigned int, void *); | 120 | extern void free_irq(unsigned int, void *); |
125 | extern int cpu(void); | 121 | extern int cpu(void); |
126 | 122 | ||
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h index 808521980186..acb8356e1f98 100644 --- a/arch/um/include/tt/tt.h +++ b/arch/um/include/tt/tt.h | |||
@@ -19,7 +19,8 @@ extern int fork_tramp(void *sig_stack); | |||
19 | extern int do_proc_op(void *t, int proc_id); | 19 | extern int do_proc_op(void *t, int proc_id); |
20 | extern int tracer(int (*init_proc)(void *), void *sp); | 20 | extern int tracer(int (*init_proc)(void *), void *sp); |
21 | extern void attach_process(int pid); | 21 | extern void attach_process(int pid); |
22 | extern void tracer_panic(char *format, ...); | 22 | extern void tracer_panic(char *format, ...) |
23 | __attribute__ ((format (printf, 1, 2))); | ||
23 | extern void set_init_pid(int pid); | 24 | extern void set_init_pid(int pid); |
24 | extern int set_user_mode(void *task); | 25 | extern int set_user_mode(void *task); |
25 | extern void set_tracing(void *t, int tracing); | 26 | extern void set_tracing(void *t, int tracing); |
diff --git a/arch/um/include/user.h b/arch/um/include/user.h index 91b0ac4ad88c..39f8c8801076 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h | |||
@@ -6,8 +6,10 @@ | |||
6 | #ifndef __USER_H__ | 6 | #ifndef __USER_H__ |
7 | #define __USER_H__ | 7 | #define __USER_H__ |
8 | 8 | ||
9 | extern void panic(const char *fmt, ...); | 9 | extern void panic(const char *fmt, ...) |
10 | extern int printk(const char *fmt, ...); | 10 | __attribute__ ((format (printf, 1, 2))); |
11 | extern int printk(const char *fmt, ...) | ||
12 | __attribute__ ((format (printf, 1, 2))); | ||
11 | extern void schedule(void); | 13 | extern void schedule(void); |
12 | extern void *um_kmalloc(int size); | 14 | extern void *um_kmalloc(int size); |
13 | extern void *um_kmalloc_atomic(int size); | 15 | extern void *um_kmalloc_atomic(int size); |
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index fe0c29b5144d..802d7842514d 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h | |||
@@ -55,7 +55,8 @@ extern int get_pty(void); | |||
55 | extern void *um_kmalloc(int size); | 55 | extern void *um_kmalloc(int size); |
56 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 56 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
57 | extern void do_exec(int old_pid, int new_pid); | 57 | extern void do_exec(int old_pid, int new_pid); |
58 | extern void tracer_panic(char *msg, ...); | 58 | extern void tracer_panic(char *msg, ...) |
59 | __attribute__ ((format (printf, 1, 2))); | ||
59 | extern int detach(int pid, int sig); | 60 | extern int detach(int pid, int sig); |
60 | extern int attach(int pid); | 61 | extern int attach(int pid); |
61 | extern void kill_child_dead(int pid); | 62 | extern void kill_child_dead(int pid); |
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7713e7a6f476..432cf0b97a13 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c | |||
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(um_virt_to_phys); | |||
39 | EXPORT_SYMBOL(mode_tt); | 39 | EXPORT_SYMBOL(mode_tt); |
40 | EXPORT_SYMBOL(handle_page_fault); | 40 | EXPORT_SYMBOL(handle_page_fault); |
41 | EXPORT_SYMBOL(find_iomem); | 41 | EXPORT_SYMBOL(find_iomem); |
42 | EXPORT_SYMBOL(end_iomem); | ||
43 | 42 | ||
44 | #ifdef CONFIG_MODE_TT | 43 | #ifdef CONFIG_MODE_TT |
45 | EXPORT_SYMBOL(strncpy_from_user_tt); | 44 | EXPORT_SYMBOL(strncpy_from_user_tt); |
@@ -89,12 +88,10 @@ EXPORT_SYMBOL(dump_thread); | |||
89 | EXPORT_SYMBOL(do_gettimeofday); | 88 | EXPORT_SYMBOL(do_gettimeofday); |
90 | EXPORT_SYMBOL(do_settimeofday); | 89 | EXPORT_SYMBOL(do_settimeofday); |
91 | 90 | ||
92 | /* This is here because UML expands open to sys_open, not to a system | 91 | /* This is here because UML expands lseek to sys_lseek, not to a system |
93 | * call instruction. | 92 | * call instruction. |
94 | */ | 93 | */ |
95 | EXPORT_SYMBOL(sys_open); | ||
96 | EXPORT_SYMBOL(sys_lseek); | 94 | EXPORT_SYMBOL(sys_lseek); |
97 | EXPORT_SYMBOL(sys_read); | ||
98 | EXPORT_SYMBOL(sys_wait4); | 95 | EXPORT_SYMBOL(sys_wait4); |
99 | 96 | ||
100 | #ifdef CONFIG_SMP | 97 | #ifdef CONFIG_SMP |
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 901b85e8a1c6..8f49507e64ef 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c | |||
@@ -40,7 +40,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, | |||
40 | int fd) | 40 | int fd) |
41 | { | 41 | { |
42 | struct addr_change change; | 42 | struct addr_change change; |
43 | void *output; | 43 | char *output; |
44 | int n; | 44 | int n; |
45 | 45 | ||
46 | change.what = op; | 46 | change.what = op; |
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 6490a4ff40ac..6987d1d247a2 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
@@ -43,7 +43,7 @@ static int helper_child(void *arg) | |||
43 | (*data->pre_exec)(data->pre_data); | 43 | (*data->pre_exec)(data->pre_data); |
44 | execvp(argv[0], argv); | 44 | execvp(argv[0], argv); |
45 | errval = errno; | 45 | errval = errno; |
46 | printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); | 46 | printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); |
47 | os_write_file(data->fd, &errval, sizeof(errval)); | 47 | os_write_file(data->fd, &errval, sizeof(errval)); |
48 | kill(os_getpid(), SIGKILL); | 48 | kill(os_getpid(), SIGKILL); |
49 | return(0); | 49 | return(0); |
@@ -92,15 +92,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
92 | close(fds[1]); | 92 | close(fds[1]); |
93 | fds[1] = -1; | 93 | fds[1] = -1; |
94 | 94 | ||
95 | /*Read the errno value from the child.*/ | 95 | /* Read the errno value from the child, if the exec failed, or get 0 if |
96 | * the exec succeeded because the pipe fd was set as close-on-exec. */ | ||
96 | n = os_read_file(fds[0], &ret, sizeof(ret)); | 97 | n = os_read_file(fds[0], &ret, sizeof(ret)); |
97 | if(n < 0){ | 98 | if (n < 0) { |
98 | printk("run_helper : read on pipe failed, ret = %d\n", -n); | 99 | printk("run_helper : read on pipe failed, ret = %d\n", -n); |
99 | ret = n; | 100 | ret = n; |
100 | kill(pid, SIGKILL); | 101 | kill(pid, SIGKILL); |
101 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 102 | CATCH_EINTR(waitpid(pid, NULL, 0)); |
102 | } | 103 | } else if(n != 0){ |
103 | else if(n != 0){ | ||
104 | CATCH_EINTR(n = waitpid(pid, NULL, 0)); | 104 | CATCH_EINTR(n = waitpid(pid, NULL, 0)); |
105 | ret = -errno; | 105 | ret = -errno; |
106 | } else { | 106 | } else { |
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 6ab372da9657..71bb90a7606d 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
@@ -53,33 +53,36 @@ static void __init find_tempdir(void) | |||
53 | */ | 53 | */ |
54 | int make_tempfile(const char *template, char **out_tempname, int do_unlink) | 54 | int make_tempfile(const char *template, char **out_tempname, int do_unlink) |
55 | { | 55 | { |
56 | char tempname[MAXPATHLEN]; | 56 | char *tempname; |
57 | int fd; | 57 | int fd; |
58 | 58 | ||
59 | tempname = malloc(MAXPATHLEN); | ||
60 | |||
59 | find_tempdir(); | 61 | find_tempdir(); |
60 | if (*template != '/') | 62 | if (template[0] != '/') |
61 | strcpy(tempname, tempdir); | 63 | strcpy(tempname, tempdir); |
62 | else | 64 | else |
63 | *tempname = 0; | 65 | tempname[0] = '\0'; |
64 | strcat(tempname, template); | 66 | strcat(tempname, template); |
65 | fd = mkstemp(tempname); | 67 | fd = mkstemp(tempname); |
66 | if(fd < 0){ | 68 | if(fd < 0){ |
67 | fprintf(stderr, "open - cannot create %s: %s\n", tempname, | 69 | fprintf(stderr, "open - cannot create %s: %s\n", tempname, |
68 | strerror(errno)); | 70 | strerror(errno)); |
69 | return -1; | 71 | goto out; |
70 | } | 72 | } |
71 | if(do_unlink && (unlink(tempname) < 0)){ | 73 | if(do_unlink && (unlink(tempname) < 0)){ |
72 | perror("unlink"); | 74 | perror("unlink"); |
73 | return -1; | 75 | goto out; |
74 | } | 76 | } |
75 | if(out_tempname){ | 77 | if(out_tempname){ |
76 | *out_tempname = strdup(tempname); | 78 | *out_tempname = tempname; |
77 | if(*out_tempname == NULL){ | 79 | } else { |
78 | perror("strdup"); | 80 | free(tempname); |
79 | return -1; | ||
80 | } | ||
81 | } | 81 | } |
82 | return(fd); | 82 | return(fd); |
83 | out: | ||
84 | free(tempname); | ||
85 | return -1; | ||
83 | } | 86 | } |
84 | 87 | ||
85 | #define TEMPNAME_TEMPLATE "vm_file-XXXXXX" | 88 | #define TEMPNAME_TEMPLATE "vm_file-XXXXXX" |
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 9ba942947146..00e9388e947a 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -304,8 +304,8 @@ out_clear_poll: | |||
304 | .size = 0, | 304 | .size = 0, |
305 | .used = 0 }); | 305 | .used = 0 }); |
306 | out_free: | 306 | out_free: |
307 | kfree(p); | ||
308 | sigio_unlock(); | 307 | sigio_unlock(); |
308 | kfree(p); | ||
309 | out_close2: | 309 | out_close2: |
310 | close(l_sigio_private[0]); | 310 | close(l_sigio_private[0]); |
311 | close(l_sigio_private[1]); | 311 | close(l_sigio_private[1]); |
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index fbb080c2fc26..b3c11cfa995a 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c | |||
@@ -82,8 +82,8 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | |||
82 | if (offset) { | 82 | if (offset) { |
83 | data = (unsigned long *)(mm_idp->stack + | 83 | data = (unsigned long *)(mm_idp->stack + |
84 | offset - UML_CONFIG_STUB_DATA); | 84 | offset - UML_CONFIG_STUB_DATA); |
85 | printk("do_syscall_stub : ret = %d, offset = %d, " | 85 | printk("do_syscall_stub : ret = %ld, offset = %ld, " |
86 | "data = 0x%x\n", ret, offset, data); | 86 | "data = %p\n", ret, offset, data); |
87 | syscall = (unsigned long *)((unsigned long)data + data[0]); | 87 | syscall = (unsigned long *)((unsigned long)data + data[0]); |
88 | printk("do_syscall_stub: syscall %ld failed, return value = " | 88 | printk("do_syscall_stub: syscall %ld failed, return value = " |
89 | "0x%lx, expected return value = 0x%lx\n", | 89 | "0x%lx, expected return value = 0x%lx\n", |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index bbf34cb91ce1..045ae0037456 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -265,7 +265,7 @@ void userspace(union uml_pt_regs *regs) | |||
265 | if(err) | 265 | if(err) |
266 | panic("userspace - could not resume userspace process, " | 266 | panic("userspace - could not resume userspace process, " |
267 | "pid=%d, ptrace operation = %d, errno = %d\n", | 267 | "pid=%d, ptrace operation = %d, errno = %d\n", |
268 | op, errno); | 268 | pid, op, errno); |
269 | 269 | ||
270 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); | 270 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); |
271 | if(err < 0) | 271 | if(err < 0) |
@@ -369,7 +369,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
369 | */ | 369 | */ |
370 | wait_stub_done(pid, -1, "copy_context_skas0"); | 370 | wait_stub_done(pid, -1, "copy_context_skas0"); |
371 | if (child_data->err != UML_CONFIG_STUB_DATA) | 371 | if (child_data->err != UML_CONFIG_STUB_DATA) |
372 | panic("copy_context_skas0 - stub-child reports error %d\n", | 372 | panic("copy_context_skas0 - stub-child reports error %ld\n", |
373 | child_data->err); | 373 | child_data->err); |
374 | 374 | ||
375 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, | 375 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, |
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index ba21f0e04a2f..120abbe4e3ce 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <errno.h> | ||
1 | #include <linux/unistd.h> | 2 | #include <linux/unistd.h> |
2 | #include "sysdep/tls.h" | 3 | #include "sysdep/tls.h" |
3 | #include "user_util.h" | 4 | #include "user_util.h" |
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 198e59163288..34bfc1bb9e38 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c | |||
@@ -120,7 +120,8 @@ static int not_dead_yet(char *dir) | |||
120 | 120 | ||
121 | dead = 0; | 121 | dead = 0; |
122 | fd = open(file, O_RDONLY); | 122 | fd = open(file, O_RDONLY); |
123 | if(fd < 0){ | 123 | if(fd < 0) { |
124 | fd = -errno; | ||
124 | if(fd != -ENOENT){ | 125 | if(fd != -ENOENT){ |
125 | printk("not_dead_yet : couldn't open pid file '%s', " | 126 | printk("not_dead_yet : couldn't open pid file '%s', " |
126 | "err = %d\n", file, -fd); | 127 | "err = %d\n", file, -fd); |
@@ -130,9 +131,13 @@ static int not_dead_yet(char *dir) | |||
130 | 131 | ||
131 | err = 0; | 132 | err = 0; |
132 | n = read(fd, pid, sizeof(pid)); | 133 | n = read(fd, pid, sizeof(pid)); |
133 | if(n <= 0){ | 134 | if(n < 0){ |
135 | printk("not_dead_yet : couldn't read pid file '%s', " | ||
136 | "err = %d\n", file, errno); | ||
137 | goto out_close; | ||
138 | } else if(n == 0){ | ||
134 | printk("not_dead_yet : couldn't read pid file '%s', " | 139 | printk("not_dead_yet : couldn't read pid file '%s', " |
135 | "err = %d\n", file, -n); | 140 | "0-byte read\n", file); |
136 | goto out_close; | 141 | goto out_close; |
137 | } | 142 | } |
138 | 143 | ||
@@ -155,9 +160,9 @@ static int not_dead_yet(char *dir) | |||
155 | 160 | ||
156 | return err; | 161 | return err; |
157 | 162 | ||
158 | out_close: | 163 | out_close: |
159 | close(fd); | 164 | close(fd); |
160 | out: | 165 | out: |
161 | return 0; | 166 | return 0; |
162 | } | 167 | } |
163 | 168 | ||
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 8da6ab31152a..2598158e1f53 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c | |||
@@ -18,14 +18,19 @@ extern void *memmove(void *, const void *, size_t); | |||
18 | extern void *memset(void *, int, size_t); | 18 | extern void *memset(void *, int, size_t); |
19 | extern int printf(const char *, ...); | 19 | extern int printf(const char *, ...); |
20 | 20 | ||
21 | /* If they're not defined, the export is included in lib/string.c.*/ | ||
22 | #ifdef __HAVE_ARCH_STRLEN | ||
21 | EXPORT_SYMBOL(strlen); | 23 | EXPORT_SYMBOL(strlen); |
24 | #endif | ||
25 | #ifdef __HAVE_ARCH_STRSTR | ||
26 | EXPORT_SYMBOL(strstr); | ||
27 | #endif | ||
28 | |||
22 | EXPORT_SYMBOL(memcpy); | 29 | EXPORT_SYMBOL(memcpy); |
23 | EXPORT_SYMBOL(memmove); | 30 | EXPORT_SYMBOL(memmove); |
24 | EXPORT_SYMBOL(memset); | 31 | EXPORT_SYMBOL(memset); |
25 | EXPORT_SYMBOL(printf); | 32 | EXPORT_SYMBOL(printf); |
26 | 33 | ||
27 | EXPORT_SYMBOL(strstr); | ||
28 | |||
29 | /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. | 34 | /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. |
30 | * However, the modules will use the CRC defined *here*, no matter if it is | 35 | * However, the modules will use the CRC defined *here*, no matter if it is |
31 | * good; so the versions of these symbols will always match | 36 | * good; so the versions of these symbols will always match |
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index b696b451774c..5e7a9c310aa5 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
@@ -9,10 +9,8 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | |||
9 | 9 | ||
10 | $(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \ | 10 | $(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \ |
11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) | 11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) |
12 | $(USER_OBJS): cmd_checksrc = | 12 | $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ |
13 | $(USER_OBJS): quiet_cmd_checksrc = | 13 | -Dunix -D__unix__ -D__$(SUBARCH)__ |
14 | $(USER_OBJS): cmd_force_checksrc = | ||
15 | $(USER_OBJS): quiet_cmd_force_checksrc = | ||
16 | 14 | ||
17 | 15 | ||
18 | # The stubs and unmap.o can't try to call mcount or update basic block data | 16 | # The stubs and unmap.o can't try to call mcount or update basic block data |
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c index db524ab3f743..2a1eac1859ce 100644 --- a/arch/um/sys-i386/ksyms.c +++ b/arch/um/sys-i386/ksyms.c | |||
@@ -15,7 +15,3 @@ EXPORT_SYMBOL(__up_wakeup); | |||
15 | 15 | ||
16 | /* Networking helper routines. */ | 16 | /* Networking helper routines. */ |
17 | EXPORT_SYMBOL(csum_partial); | 17 | EXPORT_SYMBOL(csum_partial); |
18 | |||
19 | /* delay core functions */ | ||
20 | EXPORT_SYMBOL(__const_udelay); | ||
21 | EXPORT_SYMBOL(__udelay); | ||
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 9f3bd8ed78f5..40aa88531446 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c | |||
@@ -57,7 +57,7 @@ static void write_debugregs(int pid, unsigned long *regs) | |||
57 | if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], | 57 | if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], |
58 | regs[i]) < 0) | 58 | regs[i]) < 0) |
59 | printk("write_debugregs - ptrace failed on " | 59 | printk("write_debugregs - ptrace failed on " |
60 | "register %d, value = 0x%x, errno = %d\n", i, | 60 | "register %d, value = 0x%lx, errno = %d\n", i, |
61 | regs[i], errno); | 61 | regs[i], errno); |
62 | } | 62 | } |
63 | } | 63 | } |
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index f5d0e1c37ea2..618fd8594643 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -147,7 +147,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, | |||
147 | * delivery. The sp passed in is the original, and this needs | 147 | * delivery. The sp passed in is the original, and this needs |
148 | * to be restored, so we stick it in separately. | 148 | * to be restored, so we stick it in separately. |
149 | */ | 149 | */ |
150 | err |= copy_to_user(&SC_SP(to), sp, sizeof(sp)); | 150 | err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp)); |
151 | 151 | ||
152 | if(from_fp != NULL){ | 152 | if(from_fp != NULL){ |
153 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); | 153 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); |
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c index a3188e861cc7..71b9796258ef 100644 --- a/arch/um/sys-i386/tls.c +++ b/arch/um/sys-i386/tls.c | |||
@@ -378,7 +378,7 @@ static int __init __setup_host_supports_tls(void) { | |||
378 | } else | 378 | } else |
379 | printk(KERN_ERR " Host TLS support NOT detected! " | 379 | printk(KERN_ERR " Host TLS support NOT detected! " |
380 | "TLS support inside UML will not work\n"); | 380 | "TLS support inside UML will not work\n"); |
381 | return 1; | 381 | return 0; |
382 | } | 382 | } |
383 | 383 | ||
384 | __initcall(__setup_host_supports_tls); | 384 | __initcall(__setup_host_supports_tls); |
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index e75c4e1838b0..a4c46a8af008 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c | |||
@@ -137,7 +137,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, | |||
137 | * delivery. The sp passed in is the original, and this needs | 137 | * delivery. The sp passed in is the original, and this needs |
138 | * to be restored, so we stick it in separately. | 138 | * to be restored, so we stick it in separately. |
139 | */ | 139 | */ |
140 | err |= copy_to_user(&SC_SP(to), sp, sizeof(sp)); | 140 | err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp)); |
141 | 141 | ||
142 | if(from_fp != NULL){ | 142 | if(from_fp != NULL){ |
143 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); | 143 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); |
diff --git a/arch/v850/kernel/v850_ksyms.c b/arch/v850/kernel/v850_ksyms.c index 8ffc29c1c89d..6bcfcfe88384 100644 --- a/arch/v850/kernel/v850_ksyms.c +++ b/arch/v850/kernel/v850_ksyms.c | |||
@@ -43,7 +43,6 @@ EXPORT_SYMBOL (strncmp); | |||
43 | EXPORT_SYMBOL (strchr); | 43 | EXPORT_SYMBOL (strchr); |
44 | EXPORT_SYMBOL (strlen); | 44 | EXPORT_SYMBOL (strlen); |
45 | EXPORT_SYMBOL (strnlen); | 45 | EXPORT_SYMBOL (strnlen); |
46 | EXPORT_SYMBOL (strpbrk); | ||
47 | EXPORT_SYMBOL (strrchr); | 46 | EXPORT_SYMBOL (strrchr); |
48 | EXPORT_SYMBOL (strstr); | 47 | EXPORT_SYMBOL (strstr); |
49 | EXPORT_SYMBOL (memset); | 48 | EXPORT_SYMBOL (memset); |
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 4310b4a311a5..408d44a59756 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -136,6 +136,11 @@ config X86_L1_CACHE_SHIFT | |||
136 | default "7" if GENERIC_CPU || MPSC | 136 | default "7" if GENERIC_CPU || MPSC |
137 | default "6" if MK8 | 137 | default "6" if MK8 |
138 | 138 | ||
139 | config X86_INTERNODE_CACHE_BYTES | ||
140 | int | ||
141 | default "4096" if X86_VSMP | ||
142 | default X86_L1_CACHE_BYTES if !X86_VSMP | ||
143 | |||
139 | config X86_TSC | 144 | config X86_TSC |
140 | bool | 145 | bool |
141 | default y | 146 | default y |
@@ -283,6 +288,11 @@ config K8_NUMA | |||
283 | Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA | 288 | Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA |
284 | instead, which also takes priority if both are compiled in. | 289 | instead, which also takes priority if both are compiled in. |
285 | 290 | ||
291 | config NODES_SHIFT | ||
292 | int | ||
293 | default "6" | ||
294 | depends on NEED_MULTIPLE_NODES | ||
295 | |||
286 | # Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig. | 296 | # Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig. |
287 | 297 | ||
288 | config X86_64_ACPI_NUMA | 298 | config X86_64_ACPI_NUMA |
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 585fd4a559c8..e573e2ab5510 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile | |||
@@ -24,37 +24,37 @@ | |||
24 | LDFLAGS := -m elf_x86_64 | 24 | LDFLAGS := -m elf_x86_64 |
25 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 25 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
26 | LDFLAGS_vmlinux := | 26 | LDFLAGS_vmlinux := |
27 | |||
28 | CHECKFLAGS += -D__x86_64__ -m64 | 27 | CHECKFLAGS += -D__x86_64__ -m64 |
29 | 28 | ||
29 | cflags-y := | ||
30 | cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) | 30 | cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) |
31 | cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) | 31 | cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) |
32 | cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) | 32 | cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) |
33 | CFLAGS += $(cflags-y) | ||
34 | 33 | ||
35 | CFLAGS += -m64 | 34 | cflags-y += -m64 |
36 | CFLAGS += -mno-red-zone | 35 | cflags-y += -mno-red-zone |
37 | CFLAGS += -mcmodel=kernel | 36 | cflags-y += -mcmodel=kernel |
38 | CFLAGS += -pipe | 37 | cflags-y += -pipe |
39 | cflags-$(CONFIG_REORDER) += -ffunction-sections | 38 | cflags-$(CONFIG_REORDER) += -ffunction-sections |
40 | # this makes reading assembly source easier, but produces worse code | 39 | # this makes reading assembly source easier, but produces worse code |
41 | # actually it makes the kernel smaller too. | 40 | # actually it makes the kernel smaller too. |
42 | CFLAGS += -fno-reorder-blocks | 41 | cflags-y += -fno-reorder-blocks |
43 | CFLAGS += -Wno-sign-compare | 42 | cflags-y += -Wno-sign-compare |
44 | ifneq ($(CONFIG_UNWIND_INFO),y) | 43 | ifneq ($(CONFIG_UNWIND_INFO),y) |
45 | CFLAGS += -fno-asynchronous-unwind-tables | 44 | cflags-y += -fno-asynchronous-unwind-tables |
46 | endif | 45 | endif |
47 | ifneq ($(CONFIG_DEBUG_INFO),y) | 46 | ifneq ($(CONFIG_DEBUG_INFO),y) |
48 | # -fweb shrinks the kernel a bit, but the difference is very small | 47 | # -fweb shrinks the kernel a bit, but the difference is very small |
49 | # it also messes up debugging, so don't use it for now. | 48 | # it also messes up debugging, so don't use it for now. |
50 | #CFLAGS += $(call cc-option,-fweb) | 49 | #cflags-y += $(call cc-option,-fweb) |
51 | endif | 50 | endif |
52 | # -funit-at-a-time shrinks the kernel .text considerably | 51 | # -funit-at-a-time shrinks the kernel .text considerably |
53 | # unfortunately it makes reading oopses harder. | 52 | # unfortunately it makes reading oopses harder. |
54 | CFLAGS += $(call cc-option,-funit-at-a-time) | 53 | cflags-y += $(call cc-option,-funit-at-a-time) |
55 | # prevent gcc from generating any FP code by mistake | 54 | # prevent gcc from generating any FP code by mistake |
56 | CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) | 55 | cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) |
57 | 56 | ||
57 | CFLAGS += $(cflags-y) | ||
58 | AFLAGS += -m64 | 58 | AFLAGS += -m64 |
59 | 59 | ||
60 | head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o | 60 | head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o |
diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S index 0587477c99f2..32327bb37aff 100644 --- a/arch/x86_64/boot/video.S +++ b/arch/x86_64/boot/video.S | |||
@@ -97,6 +97,7 @@ | |||
97 | #define PARAM_VESAPM_OFF 0x30 | 97 | #define PARAM_VESAPM_OFF 0x30 |
98 | #define PARAM_LFB_PAGES 0x32 | 98 | #define PARAM_LFB_PAGES 0x32 |
99 | #define PARAM_VESA_ATTRIB 0x34 | 99 | #define PARAM_VESA_ATTRIB 0x34 |
100 | #define PARAM_CAPABILITIES 0x36 | ||
100 | 101 | ||
101 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ | 102 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ |
102 | #ifdef CONFIG_VIDEO_RETAIN | 103 | #ifdef CONFIG_VIDEO_RETAIN |
@@ -233,6 +234,10 @@ mopar_gr: | |||
233 | movw 18(%di), %ax | 234 | movw 18(%di), %ax |
234 | movl %eax, %fs:(PARAM_LFB_SIZE) | 235 | movl %eax, %fs:(PARAM_LFB_SIZE) |
235 | 236 | ||
237 | # store mode capabilities | ||
238 | movl 10(%di), %eax | ||
239 | movl %eax, %fs:(PARAM_CAPABILITIES) | ||
240 | |||
236 | # switching the DAC to 8-bit is for <= 8 bpp only | 241 | # switching the DAC to 8-bit is for <= 8 bpp only |
237 | movw %fs:(PARAM_LFB_DEPTH), %ax | 242 | movw %fs:(PARAM_LFB_DEPTH), %ax |
238 | cmpw $8, %ax | 243 | cmpw $8, %ax |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 566ecc97ee5a..3c45ec22b3fe 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-git9 | 3 | # Linux kernel version: 2.6.17-rc1 |
4 | # Sat Mar 25 15:18:40 2006 | 4 | # Mon Apr 3 16:11:14 2006 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -9,6 +9,7 @@ CONFIG_X86=y | |||
9 | CONFIG_SEMAPHORE_SLEEPERS=y | 9 | CONFIG_SEMAPHORE_SLEEPERS=y |
10 | CONFIG_MMU=y | 10 | CONFIG_MMU=y |
11 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 11 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
12 | CONFIG_GENERIC_HWEIGHT=y | ||
12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 13 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
13 | CONFIG_X86_CMPXCHG=y | 14 | CONFIG_X86_CMPXCHG=y |
14 | CONFIG_EARLY_PRINTK=y | 15 | CONFIG_EARLY_PRINTK=y |
@@ -55,10 +56,6 @@ CONFIG_BASE_FULL=y | |||
55 | CONFIG_FUTEX=y | 56 | CONFIG_FUTEX=y |
56 | CONFIG_EPOLL=y | 57 | CONFIG_EPOLL=y |
57 | CONFIG_SHMEM=y | 58 | CONFIG_SHMEM=y |
58 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
59 | CONFIG_CC_ALIGN_LABELS=0 | ||
60 | CONFIG_CC_ALIGN_LOOPS=0 | ||
61 | CONFIG_CC_ALIGN_JUMPS=0 | ||
62 | CONFIG_SLAB=y | 59 | CONFIG_SLAB=y |
63 | # CONFIG_TINY_SHMEM is not set | 60 | # CONFIG_TINY_SHMEM is not set |
64 | CONFIG_BASE_SMALL=0 | 61 | CONFIG_BASE_SMALL=0 |
@@ -70,7 +67,6 @@ CONFIG_BASE_SMALL=0 | |||
70 | CONFIG_MODULES=y | 67 | CONFIG_MODULES=y |
71 | CONFIG_MODULE_UNLOAD=y | 68 | CONFIG_MODULE_UNLOAD=y |
72 | CONFIG_MODULE_FORCE_UNLOAD=y | 69 | CONFIG_MODULE_FORCE_UNLOAD=y |
73 | CONFIG_OBSOLETE_MODPARM=y | ||
74 | # CONFIG_MODVERSIONS is not set | 70 | # CONFIG_MODVERSIONS is not set |
75 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 71 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
76 | # CONFIG_KMOD is not set | 72 | # CONFIG_KMOD is not set |
@@ -81,6 +77,7 @@ CONFIG_STOP_MACHINE=y | |||
81 | # | 77 | # |
82 | CONFIG_LBD=y | 78 | CONFIG_LBD=y |
83 | # CONFIG_BLK_DEV_IO_TRACE is not set | 79 | # CONFIG_BLK_DEV_IO_TRACE is not set |
80 | # CONFIG_LSF is not set | ||
84 | 81 | ||
85 | # | 82 | # |
86 | # IO Schedulers | 83 | # IO Schedulers |
@@ -105,6 +102,7 @@ CONFIG_X86_PC=y | |||
105 | CONFIG_GENERIC_CPU=y | 102 | CONFIG_GENERIC_CPU=y |
106 | CONFIG_X86_L1_CACHE_BYTES=128 | 103 | CONFIG_X86_L1_CACHE_BYTES=128 |
107 | CONFIG_X86_L1_CACHE_SHIFT=7 | 104 | CONFIG_X86_L1_CACHE_SHIFT=7 |
105 | CONFIG_X86_INTERNODE_CACHE_BYTES=128 | ||
108 | CONFIG_X86_TSC=y | 106 | CONFIG_X86_TSC=y |
109 | CONFIG_X86_GOOD_APIC=y | 107 | CONFIG_X86_GOOD_APIC=y |
110 | # CONFIG_MICROCODE is not set | 108 | # CONFIG_MICROCODE is not set |
@@ -116,6 +114,7 @@ CONFIG_X86_LOCAL_APIC=y | |||
116 | CONFIG_MTRR=y | 114 | CONFIG_MTRR=y |
117 | CONFIG_SMP=y | 115 | CONFIG_SMP=y |
118 | CONFIG_SCHED_SMT=y | 116 | CONFIG_SCHED_SMT=y |
117 | CONFIG_SCHED_MC=y | ||
119 | # CONFIG_PREEMPT_NONE is not set | 118 | # CONFIG_PREEMPT_NONE is not set |
120 | CONFIG_PREEMPT_VOLUNTARY=y | 119 | CONFIG_PREEMPT_VOLUNTARY=y |
121 | # CONFIG_PREEMPT is not set | 120 | # CONFIG_PREEMPT is not set |
@@ -138,6 +137,7 @@ CONFIG_NEED_MULTIPLE_NODES=y | |||
138 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 137 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
139 | CONFIG_MIGRATION=y | 138 | CONFIG_MIGRATION=y |
140 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | 139 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y |
140 | CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y | ||
141 | CONFIG_NR_CPUS=32 | 141 | CONFIG_NR_CPUS=32 |
142 | CONFIG_HOTPLUG_CPU=y | 142 | CONFIG_HOTPLUG_CPU=y |
143 | CONFIG_HPET_TIMER=y | 143 | CONFIG_HPET_TIMER=y |
@@ -289,6 +289,7 @@ CONFIG_IP_PNP_DHCP=y | |||
289 | # CONFIG_INET_AH is not set | 289 | # CONFIG_INET_AH is not set |
290 | # CONFIG_INET_ESP is not set | 290 | # CONFIG_INET_ESP is not set |
291 | # CONFIG_INET_IPCOMP is not set | 291 | # CONFIG_INET_IPCOMP is not set |
292 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
292 | # CONFIG_INET_TUNNEL is not set | 293 | # CONFIG_INET_TUNNEL is not set |
293 | CONFIG_INET_DIAG=y | 294 | CONFIG_INET_DIAG=y |
294 | CONFIG_INET_TCP_DIAG=y | 295 | CONFIG_INET_TCP_DIAG=y |
@@ -300,6 +301,7 @@ CONFIG_IPV6=y | |||
300 | # CONFIG_INET6_AH is not set | 301 | # CONFIG_INET6_AH is not set |
301 | # CONFIG_INET6_ESP is not set | 302 | # CONFIG_INET6_ESP is not set |
302 | # CONFIG_INET6_IPCOMP is not set | 303 | # CONFIG_INET6_IPCOMP is not set |
304 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
303 | # CONFIG_INET6_TUNNEL is not set | 305 | # CONFIG_INET6_TUNNEL is not set |
304 | # CONFIG_IPV6_TUNNEL is not set | 306 | # CONFIG_IPV6_TUNNEL is not set |
305 | # CONFIG_NETFILTER is not set | 307 | # CONFIG_NETFILTER is not set |
@@ -704,7 +706,6 @@ CONFIG_S2IO=m | |||
704 | # Wireless LAN (non-hamradio) | 706 | # Wireless LAN (non-hamradio) |
705 | # | 707 | # |
706 | # CONFIG_NET_RADIO is not set | 708 | # CONFIG_NET_RADIO is not set |
707 | # CONFIG_NET_WIRELESS_RTNETLINK is not set | ||
708 | 709 | ||
709 | # | 710 | # |
710 | # Wan interfaces | 711 | # Wan interfaces |
@@ -791,7 +792,7 @@ CONFIG_HW_CONSOLE=y | |||
791 | # | 792 | # |
792 | CONFIG_SERIAL_8250=y | 793 | CONFIG_SERIAL_8250=y |
793 | CONFIG_SERIAL_8250_CONSOLE=y | 794 | CONFIG_SERIAL_8250_CONSOLE=y |
794 | # CONFIG_SERIAL_8250_ACPI is not set | 795 | CONFIG_SERIAL_8250_PCI=y |
795 | CONFIG_SERIAL_8250_NR_UARTS=4 | 796 | CONFIG_SERIAL_8250_NR_UARTS=4 |
796 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 797 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
797 | # CONFIG_SERIAL_8250_EXTENDED is not set | 798 | # CONFIG_SERIAL_8250_EXTENDED is not set |
@@ -921,6 +922,7 @@ CONFIG_HWMON=y | |||
921 | # Digital Video Broadcasting Devices | 922 | # Digital Video Broadcasting Devices |
922 | # | 923 | # |
923 | # CONFIG_DVB is not set | 924 | # CONFIG_DVB is not set |
925 | # CONFIG_USB_DABUSB is not set | ||
924 | 926 | ||
925 | # | 927 | # |
926 | # Graphics support | 928 | # Graphics support |
@@ -932,6 +934,8 @@ CONFIG_VIDEO_SELECT=y | |||
932 | # Console display driver support | 934 | # Console display driver support |
933 | # | 935 | # |
934 | CONFIG_VGA_CONSOLE=y | 936 | CONFIG_VGA_CONSOLE=y |
937 | CONFIG_VGACON_SOFT_SCROLLBACK=y | ||
938 | CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256 | ||
935 | CONFIG_DUMMY_CONSOLE=y | 939 | CONFIG_DUMMY_CONSOLE=y |
936 | 940 | ||
937 | # | 941 | # |
@@ -1058,15 +1062,6 @@ CONFIG_USB_HIDINPUT=y | |||
1058 | # CONFIG_USB_MICROTEK is not set | 1062 | # CONFIG_USB_MICROTEK is not set |
1059 | 1063 | ||
1060 | # | 1064 | # |
1061 | # USB Multimedia devices | ||
1062 | # | ||
1063 | # CONFIG_USB_DABUSB is not set | ||
1064 | |||
1065 | # | ||
1066 | # Video4Linux support is needed for USB Multimedia device support | ||
1067 | # | ||
1068 | |||
1069 | # | ||
1070 | # USB Network Adapters | 1065 | # USB Network Adapters |
1071 | # | 1066 | # |
1072 | # CONFIG_USB_CATC is not set | 1067 | # CONFIG_USB_CATC is not set |
@@ -1118,9 +1113,15 @@ CONFIG_USB_MON=y | |||
1118 | # CONFIG_MMC is not set | 1113 | # CONFIG_MMC is not set |
1119 | 1114 | ||
1120 | # | 1115 | # |
1116 | # LED devices | ||
1117 | # | ||
1118 | # CONFIG_NEW_LEDS is not set | ||
1119 | |||
1120 | # | ||
1121 | # InfiniBand support | 1121 | # InfiniBand support |
1122 | # | 1122 | # |
1123 | # CONFIG_INFINIBAND is not set | 1123 | # CONFIG_INFINIBAND is not set |
1124 | # CONFIG_IPATH_CORE is not set | ||
1124 | 1125 | ||
1125 | # | 1126 | # |
1126 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | 1127 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) |
@@ -1128,6 +1129,11 @@ CONFIG_USB_MON=y | |||
1128 | # CONFIG_EDAC is not set | 1129 | # CONFIG_EDAC is not set |
1129 | 1130 | ||
1130 | # | 1131 | # |
1132 | # Real Time Clock | ||
1133 | # | ||
1134 | # CONFIG_RTC_CLASS is not set | ||
1135 | |||
1136 | # | ||
1131 | # Firmware Drivers | 1137 | # Firmware Drivers |
1132 | # | 1138 | # |
1133 | # CONFIG_EDD is not set | 1139 | # CONFIG_EDD is not set |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 35b2faccdc6c..5a9802676689 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <asm/vsyscall32.h> | 15 | #include <asm/vsyscall32.h> |
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | 17 | ||
18 | #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) | ||
19 | |||
18 | .macro IA32_ARG_FIXUP noebp=0 | 20 | .macro IA32_ARG_FIXUP noebp=0 |
19 | movl %edi,%r8d | 21 | movl %edi,%r8d |
20 | .if \noebp | 22 | .if \noebp |
@@ -109,8 +111,8 @@ ENTRY(ia32_sysenter_target) | |||
109 | CFI_REMEMBER_STATE | 111 | CFI_REMEMBER_STATE |
110 | jnz sysenter_tracesys | 112 | jnz sysenter_tracesys |
111 | sysenter_do_call: | 113 | sysenter_do_call: |
112 | cmpl $(IA32_NR_syscalls),%eax | 114 | cmpl $(IA32_NR_syscalls-1),%eax |
113 | jae ia32_badsys | 115 | ja ia32_badsys |
114 | IA32_ARG_FIXUP 1 | 116 | IA32_ARG_FIXUP 1 |
115 | call *ia32_sys_call_table(,%rax,8) | 117 | call *ia32_sys_call_table(,%rax,8) |
116 | movq %rax,RAX-ARGOFFSET(%rsp) | 118 | movq %rax,RAX-ARGOFFSET(%rsp) |
@@ -210,8 +212,8 @@ ENTRY(ia32_cstar_target) | |||
210 | CFI_REMEMBER_STATE | 212 | CFI_REMEMBER_STATE |
211 | jnz cstar_tracesys | 213 | jnz cstar_tracesys |
212 | cstar_do_call: | 214 | cstar_do_call: |
213 | cmpl $IA32_NR_syscalls,%eax | 215 | cmpl $IA32_NR_syscalls-1,%eax |
214 | jae ia32_badsys | 216 | ja ia32_badsys |
215 | IA32_ARG_FIXUP 1 | 217 | IA32_ARG_FIXUP 1 |
216 | call *ia32_sys_call_table(,%rax,8) | 218 | call *ia32_sys_call_table(,%rax,8) |
217 | movq %rax,RAX-ARGOFFSET(%rsp) | 219 | movq %rax,RAX-ARGOFFSET(%rsp) |
@@ -296,8 +298,8 @@ ENTRY(ia32_syscall) | |||
296 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) | 298 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) |
297 | jnz ia32_tracesys | 299 | jnz ia32_tracesys |
298 | ia32_do_syscall: | 300 | ia32_do_syscall: |
299 | cmpl $(IA32_NR_syscalls),%eax | 301 | cmpl $(IA32_NR_syscalls-1),%eax |
300 | jae ia32_badsys | 302 | ja ia32_badsys |
301 | IA32_ARG_FIXUP | 303 | IA32_ARG_FIXUP |
302 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative | 304 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative |
303 | ia32_sysret: | 305 | ia32_sysret: |
@@ -685,12 +687,11 @@ ia32_sys_call_table: | |||
685 | .quad sys_readlinkat /* 305 */ | 687 | .quad sys_readlinkat /* 305 */ |
686 | .quad sys_fchmodat | 688 | .quad sys_fchmodat |
687 | .quad sys_faccessat | 689 | .quad sys_faccessat |
688 | .quad sys_ni_syscall /* pselect6 for now */ | 690 | .quad quiet_ni_syscall /* pselect6 for now */ |
689 | .quad sys_ni_syscall /* ppoll for now */ | 691 | .quad quiet_ni_syscall /* ppoll for now */ |
690 | .quad sys_unshare /* 310 */ | 692 | .quad sys_unshare /* 310 */ |
691 | .quad compat_sys_set_robust_list | 693 | .quad compat_sys_set_robust_list |
692 | .quad compat_sys_get_robust_list | 694 | .quad compat_sys_get_robust_list |
695 | .quad sys_splice | ||
696 | .quad sys_sync_file_range | ||
693 | ia32_syscall_end: | 697 | ia32_syscall_end: |
694 | .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 | ||
695 | .quad ni_syscall | ||
696 | .endr | ||
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index fffd6b0a2fab..70b9d21ed675 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c | |||
@@ -80,7 +80,7 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) | |||
80 | printk("Aperture from %s beyond 4GB. Ignoring.\n",name); | 80 | printk("Aperture from %s beyond 4GB. Ignoring.\n",name); |
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { | 83 | if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { |
84 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); | 84 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); |
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 293cd71a266a..62776c07cff1 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -80,7 +80,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) | 83 | /* |
84 | * This function checks if any part of the range <start,end> is mapped | ||
85 | * with type. | ||
86 | */ | ||
87 | int __meminit | ||
88 | e820_any_mapped(unsigned long start, unsigned long end, unsigned type) | ||
84 | { | 89 | { |
85 | int i; | 90 | int i; |
86 | for (i = 0; i < e820.nr_map; i++) { | 91 | for (i = 0; i < e820.nr_map; i++) { |
@@ -94,6 +99,35 @@ int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) | |||
94 | return 0; | 99 | return 0; |
95 | } | 100 | } |
96 | 101 | ||
102 | /* | ||
103 | * This function checks if the entire range <start,end> is mapped with type. | ||
104 | * | ||
105 | * Note: this function only works correct if the e820 table is sorted and | ||
106 | * not-overlapping, which is the case | ||
107 | */ | ||
108 | int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | ||
109 | { | ||
110 | int i; | ||
111 | for (i = 0; i < e820.nr_map; i++) { | ||
112 | struct e820entry *ei = &e820.map[i]; | ||
113 | if (type && ei->type != type) | ||
114 | continue; | ||
115 | /* is the region (part) in overlap with the current region ?*/ | ||
116 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
117 | continue; | ||
118 | |||
119 | /* if the region is at the beginning of <start,end> we move | ||
120 | * start to the end of the region since it's ok until there | ||
121 | */ | ||
122 | if (ei->addr <= start) | ||
123 | start = ei->addr + ei->size; | ||
124 | /* if start is now at or beyond end, we're done, full coverage */ | ||
125 | if (start >= end) | ||
126 | return 1; /* we're done */ | ||
127 | } | ||
128 | return 0; | ||
129 | } | ||
130 | |||
97 | /* | 131 | /* |
98 | * Find a free area in a specific range. | 132 | * Find a free area in a specific range. |
99 | */ | 133 | */ |
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 8538bfea30e6..c946e4fe67a7 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -180,6 +180,10 @@ rff_trace: | |||
180 | * | 180 | * |
181 | * XXX if we had a free scratch register we could save the RSP into the stack frame | 181 | * XXX if we had a free scratch register we could save the RSP into the stack frame |
182 | * and report it properly in ps. Unfortunately we haven't. | 182 | * and report it properly in ps. Unfortunately we haven't. |
183 | * | ||
184 | * When user can change the frames always force IRET. That is because | ||
185 | * it deals with uncanonical addresses better. SYSRET has trouble | ||
186 | * with them due to bugs in both AMD and Intel CPUs. | ||
183 | */ | 187 | */ |
184 | 188 | ||
185 | ENTRY(system_call) | 189 | ENTRY(system_call) |
@@ -254,7 +258,10 @@ sysret_signal: | |||
254 | xorl %esi,%esi # oldset -> arg2 | 258 | xorl %esi,%esi # oldset -> arg2 |
255 | call ptregscall_common | 259 | call ptregscall_common |
256 | 1: movl $_TIF_NEED_RESCHED,%edi | 260 | 1: movl $_TIF_NEED_RESCHED,%edi |
257 | jmp sysret_check | 261 | /* Use IRET because user could have changed frame. This |
262 | works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ | ||
263 | cli | ||
264 | jmp int_with_check | ||
258 | 265 | ||
259 | badsys: | 266 | badsys: |
260 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) | 267 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) |
@@ -280,7 +287,8 @@ tracesys: | |||
280 | call syscall_trace_leave | 287 | call syscall_trace_leave |
281 | RESTORE_TOP_OF_STACK %rbx | 288 | RESTORE_TOP_OF_STACK %rbx |
282 | RESTORE_REST | 289 | RESTORE_REST |
283 | jmp ret_from_sys_call | 290 | /* Use IRET because user could have changed frame */ |
291 | jmp int_ret_from_sys_call | ||
284 | CFI_ENDPROC | 292 | CFI_ENDPROC |
285 | 293 | ||
286 | /* | 294 | /* |
@@ -408,25 +416,9 @@ ENTRY(stub_execve) | |||
408 | CFI_ADJUST_CFA_OFFSET -8 | 416 | CFI_ADJUST_CFA_OFFSET -8 |
409 | CFI_REGISTER rip, r11 | 417 | CFI_REGISTER rip, r11 |
410 | SAVE_REST | 418 | SAVE_REST |
411 | movq %r11, %r15 | ||
412 | CFI_REGISTER rip, r15 | ||
413 | FIXUP_TOP_OF_STACK %r11 | 419 | FIXUP_TOP_OF_STACK %r11 |
414 | call sys_execve | 420 | call sys_execve |
415 | GET_THREAD_INFO(%rcx) | ||
416 | bt $TIF_IA32,threadinfo_flags(%rcx) | ||
417 | CFI_REMEMBER_STATE | ||
418 | jc exec_32bit | ||
419 | RESTORE_TOP_OF_STACK %r11 | 421 | RESTORE_TOP_OF_STACK %r11 |
420 | movq %r15, %r11 | ||
421 | CFI_REGISTER rip, r11 | ||
422 | RESTORE_REST | ||
423 | pushq %r11 | ||
424 | CFI_ADJUST_CFA_OFFSET 8 | ||
425 | CFI_REL_OFFSET rip, 0 | ||
426 | ret | ||
427 | |||
428 | exec_32bit: | ||
429 | CFI_RESTORE_STATE | ||
430 | movq %rax,RAX(%rsp) | 422 | movq %rax,RAX(%rsp) |
431 | RESTORE_REST | 423 | RESTORE_REST |
432 | jmp int_ret_from_sys_call | 424 | jmp int_ret_from_sys_call |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 10b3e348fc99..6f0790e8b6d3 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #define MISC_MCELOG_MINOR 227 | 29 | #define MISC_MCELOG_MINOR 227 |
30 | #define NR_BANKS 6 | 30 | #define NR_BANKS 6 |
31 | 31 | ||
32 | atomic_t mce_entry; | ||
33 | |||
32 | static int mce_dont_init; | 34 | static int mce_dont_init; |
33 | 35 | ||
34 | /* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic, | 36 | /* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic, |
@@ -172,10 +174,12 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
172 | int i; | 174 | int i; |
173 | int panicm_found = 0; | 175 | int panicm_found = 0; |
174 | 176 | ||
177 | atomic_inc(&mce_entry); | ||
178 | |||
175 | if (regs) | 179 | if (regs) |
176 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); | 180 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); |
177 | if (!banks) | 181 | if (!banks) |
178 | return; | 182 | goto out2; |
179 | 183 | ||
180 | memset(&m, 0, sizeof(struct mce)); | 184 | memset(&m, 0, sizeof(struct mce)); |
181 | m.cpu = safe_smp_processor_id(); | 185 | m.cpu = safe_smp_processor_id(); |
@@ -266,6 +270,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
266 | out: | 270 | out: |
267 | /* Last thing done in the machine check exception to clear state. */ | 271 | /* Last thing done in the machine check exception to clear state. */ |
268 | wrmsrl(MSR_IA32_MCG_STATUS, 0); | 272 | wrmsrl(MSR_IA32_MCG_STATUS, 0); |
273 | out2: | ||
274 | atomic_dec(&mce_entry); | ||
269 | } | 275 | } |
270 | 276 | ||
271 | /* | 277 | /* |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index d9e4067faf05..4e6357fe0ec3 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/proto.h> | 34 | #include <asm/proto.h> |
35 | #include <asm/kdebug.h> | 35 | #include <asm/kdebug.h> |
36 | #include <asm/local.h> | 36 | #include <asm/local.h> |
37 | #include <asm/mce.h> | ||
37 | 38 | ||
38 | /* | 39 | /* |
39 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: | 40 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: |
@@ -480,6 +481,12 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | |||
480 | __get_cpu_var(nmi_touch) = 0; | 481 | __get_cpu_var(nmi_touch) = 0; |
481 | touched = 1; | 482 | touched = 1; |
482 | } | 483 | } |
484 | #ifdef CONFIG_X86_MCE | ||
485 | /* Could check oops_in_progress here too, but it's safer | ||
486 | not too */ | ||
487 | if (atomic_read(&mce_entry) > 0) | ||
488 | touched = 1; | ||
489 | #endif | ||
483 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { | 490 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { |
484 | /* | 491 | /* |
485 | * Ayiee, looks like this CPU is stuck ... | 492 | * Ayiee, looks like this CPU is stuck ... |
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 03c9eeedb0f3..af035ede70cd 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c | |||
@@ -48,9 +48,11 @@ dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order) | |||
48 | { | 48 | { |
49 | struct page *page; | 49 | struct page *page; |
50 | int node; | 50 | int node; |
51 | #ifdef CONFIG_PCI | ||
51 | if (dev->bus == &pci_bus_type) | 52 | if (dev->bus == &pci_bus_type) |
52 | node = pcibus_to_node(to_pci_dev(dev)->bus); | 53 | node = pcibus_to_node(to_pci_dev(dev)->bus); |
53 | else | 54 | else |
55 | #endif | ||
54 | node = numa_node_id(); | 56 | node = numa_node_id(); |
55 | page = alloc_pages_node(node, gfp, order); | 57 | page = alloc_pages_node(node, gfp, order); |
56 | return page ? page_address(page) : NULL; | 58 | return page ? page_address(page) : NULL; |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 70dd8e5c6889..1c44b53cb15b 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -781,10 +781,16 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
781 | } | 781 | } |
782 | case ARCH_GET_GS: { | 782 | case ARCH_GET_GS: { |
783 | unsigned long base; | 783 | unsigned long base; |
784 | unsigned gsindex; | ||
784 | if (task->thread.gsindex == GS_TLS_SEL) | 785 | if (task->thread.gsindex == GS_TLS_SEL) |
785 | base = read_32bit_tls(task, GS_TLS); | 786 | base = read_32bit_tls(task, GS_TLS); |
786 | else if (doit) | 787 | else if (doit) { |
787 | rdmsrl(MSR_KERNEL_GS_BASE, base); | 788 | asm("movl %%gs,%0" : "=r" (gsindex)); |
789 | if (gsindex) | ||
790 | rdmsrl(MSR_KERNEL_GS_BASE, base); | ||
791 | else | ||
792 | base = task->thread.gs; | ||
793 | } | ||
788 | else | 794 | else |
789 | base = task->thread.gs; | 795 | base = task->thread.gs; |
790 | ret = put_user(base, (unsigned long __user *)addr); | 796 | ret = put_user(base, (unsigned long __user *)addr); |
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index d44b2c1e63a6..da8e7903d817 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
@@ -274,11 +274,6 @@ static int putreg(struct task_struct *child, | |||
274 | return -EIO; | 274 | return -EIO; |
275 | value &= 0xffff; | 275 | value &= 0xffff; |
276 | break; | 276 | break; |
277 | case offsetof(struct user_regs_struct, rip): | ||
278 | /* Check if the new RIP address is canonical */ | ||
279 | if (value >= TASK_SIZE_OF(child)) | ||
280 | return -EIO; | ||
281 | break; | ||
282 | } | 277 | } |
283 | put_stack_long(child, regno - sizeof(struct pt_regs), value); | 278 | put_stack_long(child, regno - sizeof(struct pt_regs), value); |
284 | return 0; | 279 | return 0; |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 0856ad444f90..c50b06765a80 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -353,8 +353,10 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
353 | if (fullarg(from, "enable_timer_pin_1")) | 353 | if (fullarg(from, "enable_timer_pin_1")) |
354 | disable_timer_pin_1 = -1; | 354 | disable_timer_pin_1 = -1; |
355 | 355 | ||
356 | if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) | 356 | if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) { |
357 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); | ||
357 | disable_apic = 1; | 358 | disable_apic = 1; |
359 | } | ||
358 | 360 | ||
359 | if (fullarg(from, "noapic")) | 361 | if (fullarg(from, "noapic")) |
360 | skip_ioapic_setup = 1; | 362 | skip_ioapic_setup = 1; |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index ef8bc46dc140..7392570f975d 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -726,7 +726,7 @@ static __init int late_hpet_init(void) | |||
726 | unsigned int ntimer; | 726 | unsigned int ntimer; |
727 | 727 | ||
728 | if (!vxtime.hpet_address) | 728 | if (!vxtime.hpet_address) |
729 | return -1; | 729 | return 0; |
730 | 730 | ||
731 | memset(&hd, 0, sizeof (hd)); | 731 | memset(&hd, 0, sizeof (hd)); |
732 | 732 | ||
@@ -917,6 +917,8 @@ void __init time_init(void) | |||
917 | vxtime.hpet_address = 0; | 917 | vxtime.hpet_address = 0; |
918 | 918 | ||
919 | if (hpet_use_timer) { | 919 | if (hpet_use_timer) { |
920 | /* set tick_nsec to use the proper rate for HPET */ | ||
921 | tick_nsec = TICK_NSEC_HPET; | ||
920 | cpu_khz = hpet_calibrate_tsc(); | 922 | cpu_khz = hpet_calibrate_tsc(); |
921 | timename = "HPET"; | 923 | timename = "HPET"; |
922 | #ifdef CONFIG_X86_PM_TIMER | 924 | #ifdef CONFIG_X86_PM_TIMER |
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 39ff0708f803..b81f473c4a19 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S | |||
@@ -65,7 +65,7 @@ SECTIONS | |||
65 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { | 65 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
66 | *(.data.cacheline_aligned) | 66 | *(.data.cacheline_aligned) |
67 | } | 67 | } |
68 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 68 | . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES); |
69 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { | 69 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { |
70 | *(.data.read_mostly) | 70 | *(.data.read_mostly) |
71 | } | 71 | } |
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index d78f46056bda..1def21c9f7cd 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c | |||
@@ -112,7 +112,6 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback); | |||
112 | #undef memcpy | 112 | #undef memcpy |
113 | #undef memset | 113 | #undef memset |
114 | #undef memmove | 114 | #undef memmove |
115 | #undef strlen | ||
116 | 115 | ||
117 | extern void * memset(void *,int,__kernel_size_t); | 116 | extern void * memset(void *,int,__kernel_size_t); |
118 | extern size_t strlen(const char *); | 117 | extern size_t strlen(const char *); |
@@ -121,8 +120,6 @@ extern void * memcpy(void *,const void *,__kernel_size_t); | |||
121 | extern void * __memcpy(void *,const void *,__kernel_size_t); | 120 | extern void * __memcpy(void *,const void *,__kernel_size_t); |
122 | 121 | ||
123 | EXPORT_SYMBOL(memset); | 122 | EXPORT_SYMBOL(memset); |
124 | EXPORT_SYMBOL(strlen); | ||
125 | EXPORT_SYMBOL(strpbrk); | ||
126 | EXPORT_SYMBOL(memmove); | 123 | EXPORT_SYMBOL(memmove); |
127 | EXPORT_SYMBOL(memcpy); | 124 | EXPORT_SYMBOL(memcpy); |
128 | EXPORT_SYMBOL(__memcpy); | 125 | EXPORT_SYMBOL(__memcpy); |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index e5f7f1c34462..4ba34e95d835 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -305,7 +305,7 @@ static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned | |||
305 | if (paddr >= end) | 305 | if (paddr >= end) |
306 | break; | 306 | break; |
307 | 307 | ||
308 | if (!after_bootmem && !e820_mapped(paddr, paddr+PUD_SIZE, 0)) { | 308 | if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) { |
309 | set_pud(pud, __pud(0)); | 309 | set_pud(pud, __pud(0)); |
310 | continue; | 310 | continue; |
311 | } | 311 | } |
@@ -507,9 +507,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
507 | 507 | ||
508 | /* | 508 | /* |
509 | * Memory hotplug specific functions | 509 | * Memory hotplug specific functions |
510 | * These are only for non-NUMA machines right now. | ||
511 | */ | 510 | */ |
512 | #ifdef CONFIG_MEMORY_HOTPLUG | 511 | #if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) |
513 | 512 | ||
514 | void online_page(struct page *page) | 513 | void online_page(struct page *page) |
515 | { | 514 | { |
@@ -520,6 +519,38 @@ void online_page(struct page *page) | |||
520 | num_physpages++; | 519 | num_physpages++; |
521 | } | 520 | } |
522 | 521 | ||
522 | #ifndef CONFIG_MEMORY_HOTPLUG | ||
523 | /* | ||
524 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | ||
525 | * just online the pages. | ||
526 | */ | ||
527 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | ||
528 | { | ||
529 | int err = -EIO; | ||
530 | unsigned long pfn; | ||
531 | unsigned long total = 0, mem = 0; | ||
532 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
533 | if (pfn_valid(pfn)) { | ||
534 | online_page(pfn_to_page(pfn)); | ||
535 | err = 0; | ||
536 | mem++; | ||
537 | } | ||
538 | total++; | ||
539 | } | ||
540 | if (!err) { | ||
541 | z->spanned_pages += total; | ||
542 | z->present_pages += mem; | ||
543 | z->zone_pgdat->node_spanned_pages += total; | ||
544 | z->zone_pgdat->node_present_pages += mem; | ||
545 | } | ||
546 | return err; | ||
547 | } | ||
548 | #endif | ||
549 | |||
550 | /* | ||
551 | * Memory is added always to NORMAL zone. This means you will never get | ||
552 | * additional DMA/DMA32 memory. | ||
553 | */ | ||
523 | int add_memory(u64 start, u64 size) | 554 | int add_memory(u64 start, u64 size) |
524 | { | 555 | { |
525 | struct pglist_data *pgdat = NODE_DATA(0); | 556 | struct pglist_data *pgdat = NODE_DATA(0); |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 4be82d6e2b48..cc02573a3271 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -100,11 +100,30 @@ int early_pfn_to_nid(unsigned long pfn) | |||
100 | } | 100 | } |
101 | #endif | 101 | #endif |
102 | 102 | ||
103 | static void * __init | ||
104 | early_node_mem(int nodeid, unsigned long start, unsigned long end, | ||
105 | unsigned long size) | ||
106 | { | ||
107 | unsigned long mem = find_e820_area(start, end, size); | ||
108 | void *ptr; | ||
109 | if (mem != -1L) | ||
110 | return __va(mem); | ||
111 | ptr = __alloc_bootmem_nopanic(size, | ||
112 | SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)); | ||
113 | if (ptr == 0) { | ||
114 | printk(KERN_ERR "Cannot find %lu bytes in node %d\n", | ||
115 | size, nodeid); | ||
116 | return NULL; | ||
117 | } | ||
118 | return ptr; | ||
119 | } | ||
120 | |||
103 | /* Initialize bootmem allocator for a node */ | 121 | /* Initialize bootmem allocator for a node */ |
104 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) | 122 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) |
105 | { | 123 | { |
106 | unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; | 124 | unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; |
107 | unsigned long nodedata_phys; | 125 | unsigned long nodedata_phys; |
126 | void *bootmap; | ||
108 | const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); | 127 | const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); |
109 | 128 | ||
110 | start = round_up(start, ZONE_ALIGN); | 129 | start = round_up(start, ZONE_ALIGN); |
@@ -114,13 +133,11 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
114 | start_pfn = start >> PAGE_SHIFT; | 133 | start_pfn = start >> PAGE_SHIFT; |
115 | end_pfn = end >> PAGE_SHIFT; | 134 | end_pfn = end >> PAGE_SHIFT; |
116 | 135 | ||
117 | nodedata_phys = find_e820_area(start, end, pgdat_size); | 136 | node_data[nodeid] = early_node_mem(nodeid, start, end, pgdat_size); |
118 | if (nodedata_phys == -1L) | 137 | if (node_data[nodeid] == NULL) |
119 | panic("Cannot find memory pgdat in node %d\n", nodeid); | 138 | return; |
120 | 139 | nodedata_phys = __pa(node_data[nodeid]); | |
121 | Dprintk("nodedata_phys %lx\n", nodedata_phys); | ||
122 | 140 | ||
123 | node_data[nodeid] = phys_to_virt(nodedata_phys); | ||
124 | memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); | 141 | memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); |
125 | NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; | 142 | NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; |
126 | NODE_DATA(nodeid)->node_start_pfn = start_pfn; | 143 | NODE_DATA(nodeid)->node_start_pfn = start_pfn; |
@@ -129,9 +146,15 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
129 | /* Find a place for the bootmem map */ | 146 | /* Find a place for the bootmem map */ |
130 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | 147 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); |
131 | bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); | 148 | bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); |
132 | bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<<PAGE_SHIFT); | 149 | bootmap = early_node_mem(nodeid, bootmap_start, end, |
133 | if (bootmap_start == -1L) | 150 | bootmap_pages<<PAGE_SHIFT); |
134 | panic("Not enough continuous space for bootmap on node %d", nodeid); | 151 | if (bootmap == NULL) { |
152 | if (nodedata_phys < start || nodedata_phys >= end) | ||
153 | free_bootmem((unsigned long)node_data[nodeid],pgdat_size); | ||
154 | node_data[nodeid] = NULL; | ||
155 | return; | ||
156 | } | ||
157 | bootmap_start = __pa(bootmap); | ||
135 | Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); | 158 | Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); |
136 | 159 | ||
137 | bootmap_size = init_bootmem_node(NODE_DATA(nodeid), | 160 | bootmap_size = init_bootmem_node(NODE_DATA(nodeid), |
@@ -142,6 +165,9 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
142 | 165 | ||
143 | reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); | 166 | reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); |
144 | reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT); | 167 | reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT); |
168 | #ifdef CONFIG_ACPI_NUMA | ||
169 | srat_reserve_add_area(nodeid); | ||
170 | #endif | ||
145 | node_set_online(nodeid); | 171 | node_set_online(nodeid); |
146 | } | 172 | } |
147 | 173 | ||
@@ -335,6 +361,8 @@ __init int numa_setup(char *opt) | |||
335 | #ifdef CONFIG_ACPI_NUMA | 361 | #ifdef CONFIG_ACPI_NUMA |
336 | if (!strncmp(opt,"noacpi",6)) | 362 | if (!strncmp(opt,"noacpi",6)) |
337 | acpi_numa = -1; | 363 | acpi_numa = -1; |
364 | if (!strncmp(opt,"hotadd=", 7)) | ||
365 | hotadd_percent = simple_strtoul(opt+7, NULL, 10); | ||
338 | #endif | 366 | #endif |
339 | return 1; | 367 | return 1; |
340 | } | 368 | } |
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 2eb879590dc4..15ae9fcd65a7 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c | |||
@@ -15,15 +15,26 @@ | |||
15 | #include <linux/bitmap.h> | 15 | #include <linux/bitmap.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/topology.h> | 17 | #include <linux/topology.h> |
18 | #include <linux/bootmem.h> | ||
19 | #include <linux/mm.h> | ||
18 | #include <asm/proto.h> | 20 | #include <asm/proto.h> |
19 | #include <asm/numa.h> | 21 | #include <asm/numa.h> |
20 | #include <asm/e820.h> | 22 | #include <asm/e820.h> |
21 | 23 | ||
24 | #if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ | ||
25 | defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \ | ||
26 | && !defined(CONFIG_MEMORY_HOTPLUG) | ||
27 | #define RESERVE_HOTADD 1 | ||
28 | #endif | ||
29 | |||
22 | static struct acpi_table_slit *acpi_slit; | 30 | static struct acpi_table_slit *acpi_slit; |
23 | 31 | ||
24 | static nodemask_t nodes_parsed __initdata; | 32 | static nodemask_t nodes_parsed __initdata; |
25 | static nodemask_t nodes_found __initdata; | 33 | static nodemask_t nodes_found __initdata; |
26 | static struct bootnode nodes[MAX_NUMNODES] __initdata; | 34 | static struct bootnode nodes[MAX_NUMNODES] __initdata; |
35 | static struct bootnode nodes_add[MAX_NUMNODES] __initdata; | ||
36 | static int found_add_area __initdata; | ||
37 | int hotadd_percent __initdata = 10; | ||
27 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; | 38 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; |
28 | 39 | ||
29 | /* Too small nodes confuse the VM badly. Usually they result | 40 | /* Too small nodes confuse the VM badly. Usually they result |
@@ -71,6 +82,10 @@ static __init int conflicting_nodes(unsigned long start, unsigned long end) | |||
71 | static __init void cutoff_node(int i, unsigned long start, unsigned long end) | 82 | static __init void cutoff_node(int i, unsigned long start, unsigned long end) |
72 | { | 83 | { |
73 | struct bootnode *nd = &nodes[i]; | 84 | struct bootnode *nd = &nodes[i]; |
85 | |||
86 | if (found_add_area) | ||
87 | return; | ||
88 | |||
74 | if (nd->start < start) { | 89 | if (nd->start < start) { |
75 | nd->start = start; | 90 | nd->start = start; |
76 | if (nd->end < nd->start) | 91 | if (nd->end < nd->start) |
@@ -90,6 +105,8 @@ static __init void bad_srat(void) | |||
90 | acpi_numa = -1; | 105 | acpi_numa = -1; |
91 | for (i = 0; i < MAX_LOCAL_APIC; i++) | 106 | for (i = 0; i < MAX_LOCAL_APIC; i++) |
92 | apicid_to_node[i] = NUMA_NO_NODE; | 107 | apicid_to_node[i] = NUMA_NO_NODE; |
108 | for (i = 0; i < MAX_NUMNODES; i++) | ||
109 | nodes_add[i].start = nodes[i].end = 0; | ||
93 | } | 110 | } |
94 | 111 | ||
95 | static __init inline int srat_disabled(void) | 112 | static __init inline int srat_disabled(void) |
@@ -155,11 +172,114 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) | |||
155 | pxm, pa->apic_id, node); | 172 | pxm, pa->apic_id, node); |
156 | } | 173 | } |
157 | 174 | ||
175 | #ifdef RESERVE_HOTADD | ||
176 | /* | ||
177 | * Protect against too large hotadd areas that would fill up memory. | ||
178 | */ | ||
179 | static int hotadd_enough_memory(struct bootnode *nd) | ||
180 | { | ||
181 | static unsigned long allocated; | ||
182 | static unsigned long last_area_end; | ||
183 | unsigned long pages = (nd->end - nd->start) >> PAGE_SHIFT; | ||
184 | long mem = pages * sizeof(struct page); | ||
185 | unsigned long addr; | ||
186 | unsigned long allowed; | ||
187 | unsigned long oldpages = pages; | ||
188 | |||
189 | if (mem < 0) | ||
190 | return 0; | ||
191 | allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE; | ||
192 | allowed = (allowed / 100) * hotadd_percent; | ||
193 | if (allocated + mem > allowed) { | ||
194 | /* Give them at least part of their hotadd memory upto hotadd_percent | ||
195 | It would be better to spread the limit out | ||
196 | over multiple hotplug areas, but that is too complicated | ||
197 | right now */ | ||
198 | if (allocated >= allowed) | ||
199 | return 0; | ||
200 | pages = (allowed - allocated + mem) / sizeof(struct page); | ||
201 | mem = pages * sizeof(struct page); | ||
202 | nd->end = nd->start + pages*PAGE_SIZE; | ||
203 | } | ||
204 | /* Not completely fool proof, but a good sanity check */ | ||
205 | addr = find_e820_area(last_area_end, end_pfn<<PAGE_SHIFT, mem); | ||
206 | if (addr == -1UL) | ||
207 | return 0; | ||
208 | if (pages != oldpages) | ||
209 | printk(KERN_NOTICE "SRAT: Hotadd area limited to %lu bytes\n", | ||
210 | pages << PAGE_SHIFT); | ||
211 | last_area_end = addr + mem; | ||
212 | allocated += mem; | ||
213 | return 1; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * It is fine to add this area to the nodes data it will be used later | ||
218 | * This code supports one contigious hot add area per node. | ||
219 | */ | ||
220 | static int reserve_hotadd(int node, unsigned long start, unsigned long end) | ||
221 | { | ||
222 | unsigned long s_pfn = start >> PAGE_SHIFT; | ||
223 | unsigned long e_pfn = end >> PAGE_SHIFT; | ||
224 | int changed = 0; | ||
225 | struct bootnode *nd = &nodes_add[node]; | ||
226 | |||
227 | /* I had some trouble with strange memory hotadd regions breaking | ||
228 | the boot. Be very strict here and reject anything unexpected. | ||
229 | If you want working memory hotadd write correct SRATs. | ||
230 | |||
231 | The node size check is a basic sanity check to guard against | ||
232 | mistakes */ | ||
233 | if ((signed long)(end - start) < NODE_MIN_SIZE) { | ||
234 | printk(KERN_ERR "SRAT: Hotplug area too small\n"); | ||
235 | return -1; | ||
236 | } | ||
237 | |||
238 | /* This check might be a bit too strict, but I'm keeping it for now. */ | ||
239 | if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) { | ||
240 | printk(KERN_ERR "SRAT: Hotplug area has existing memory\n"); | ||
241 | return -1; | ||
242 | } | ||
243 | |||
244 | if (!hotadd_enough_memory(&nodes_add[node])) { | ||
245 | printk(KERN_ERR "SRAT: Hotplug area too large\n"); | ||
246 | return -1; | ||
247 | } | ||
248 | |||
249 | /* Looks good */ | ||
250 | |||
251 | found_add_area = 1; | ||
252 | if (nd->start == nd->end) { | ||
253 | nd->start = start; | ||
254 | nd->end = end; | ||
255 | changed = 1; | ||
256 | } else { | ||
257 | if (nd->start == end) { | ||
258 | nd->start = start; | ||
259 | changed = 1; | ||
260 | } | ||
261 | if (nd->end == start) { | ||
262 | nd->end = end; | ||
263 | changed = 1; | ||
264 | } | ||
265 | if (!changed) | ||
266 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); | ||
267 | } | ||
268 | |||
269 | if ((nd->end >> PAGE_SHIFT) > end_pfn) | ||
270 | end_pfn = nd->end >> PAGE_SHIFT; | ||
271 | |||
272 | if (changed) | ||
273 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end); | ||
274 | return 0; | ||
275 | } | ||
276 | #endif | ||
277 | |||
158 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 278 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
159 | void __init | 279 | void __init |
160 | acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | 280 | acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) |
161 | { | 281 | { |
162 | struct bootnode *nd; | 282 | struct bootnode *nd, oldnode; |
163 | unsigned long start, end; | 283 | unsigned long start, end; |
164 | int node, pxm; | 284 | int node, pxm; |
165 | int i; | 285 | int i; |
@@ -172,6 +292,8 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
172 | } | 292 | } |
173 | if (ma->flags.enabled == 0) | 293 | if (ma->flags.enabled == 0) |
174 | return; | 294 | return; |
295 | if (ma->flags.hot_pluggable && hotadd_percent == 0) | ||
296 | return; | ||
175 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | 297 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); |
176 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | 298 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); |
177 | pxm = ma->proximity_domain; | 299 | pxm = ma->proximity_domain; |
@@ -181,10 +303,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
181 | bad_srat(); | 303 | bad_srat(); |
182 | return; | 304 | return; |
183 | } | 305 | } |
184 | /* It is fine to add this area to the nodes data it will be used later*/ | ||
185 | if (ma->flags.hot_pluggable == 1) | ||
186 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", | ||
187 | start, end); | ||
188 | i = conflicting_nodes(start, end); | 306 | i = conflicting_nodes(start, end); |
189 | if (i == node) { | 307 | if (i == node) { |
190 | printk(KERN_WARNING | 308 | printk(KERN_WARNING |
@@ -199,6 +317,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
199 | return; | 317 | return; |
200 | } | 318 | } |
201 | nd = &nodes[node]; | 319 | nd = &nodes[node]; |
320 | oldnode = *nd; | ||
202 | if (!node_test_and_set(node, nodes_parsed)) { | 321 | if (!node_test_and_set(node, nodes_parsed)) { |
203 | nd->start = start; | 322 | nd->start = start; |
204 | nd->end = end; | 323 | nd->end = end; |
@@ -208,8 +327,19 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
208 | if (nd->end < end) | 327 | if (nd->end < end) |
209 | nd->end = end; | 328 | nd->end = end; |
210 | } | 329 | } |
330 | |||
211 | printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, | 331 | printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, |
212 | nd->start, nd->end); | 332 | nd->start, nd->end); |
333 | |||
334 | #ifdef RESERVE_HOTADD | ||
335 | if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) { | ||
336 | /* Ignore hotadd region. Undo damage */ | ||
337 | printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); | ||
338 | *nd = oldnode; | ||
339 | if ((nd->start | nd->end) == 0) | ||
340 | node_clear(node, nodes_parsed); | ||
341 | } | ||
342 | #endif | ||
213 | } | 343 | } |
214 | 344 | ||
215 | /* Sanity check to catch more bad SRATs (they are amazingly common). | 345 | /* Sanity check to catch more bad SRATs (they are amazingly common). |
@@ -225,6 +355,9 @@ static int nodes_cover_memory(void) | |||
225 | unsigned long e = nodes[i].end >> PAGE_SHIFT; | 355 | unsigned long e = nodes[i].end >> PAGE_SHIFT; |
226 | pxmram += e - s; | 356 | pxmram += e - s; |
227 | pxmram -= e820_hole_size(s, e); | 357 | pxmram -= e820_hole_size(s, e); |
358 | pxmram -= nodes_add[i].end - nodes_add[i].start; | ||
359 | if ((long)pxmram < 0) | ||
360 | pxmram = 0; | ||
228 | } | 361 | } |
229 | 362 | ||
230 | e820ram = end_pfn - e820_hole_size(0, end_pfn); | 363 | e820ram = end_pfn - e820_hole_size(0, end_pfn); |
@@ -258,7 +391,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
258 | 391 | ||
259 | /* First clean up the node list */ | 392 | /* First clean up the node list */ |
260 | for (i = 0; i < MAX_NUMNODES; i++) { | 393 | for (i = 0; i < MAX_NUMNODES; i++) { |
261 | cutoff_node(i, start, end); | 394 | cutoff_node(i, start, end); |
262 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) | 395 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) |
263 | unparse_node(i); | 396 | unparse_node(i); |
264 | } | 397 | } |
@@ -282,6 +415,12 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
282 | /* Finally register nodes */ | 415 | /* Finally register nodes */ |
283 | for_each_node_mask(i, nodes_parsed) | 416 | for_each_node_mask(i, nodes_parsed) |
284 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 417 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); |
418 | /* Try again in case setup_node_bootmem missed one due | ||
419 | to missing bootmem */ | ||
420 | for_each_node_mask(i, nodes_parsed) | ||
421 | if (!node_online(i)) | ||
422 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | ||
423 | |||
285 | for (i = 0; i < NR_CPUS; i++) { | 424 | for (i = 0; i < NR_CPUS; i++) { |
286 | if (cpu_to_node[i] == NUMA_NO_NODE) | 425 | if (cpu_to_node[i] == NUMA_NO_NODE) |
287 | continue; | 426 | continue; |
@@ -303,6 +442,25 @@ static int node_to_pxm(int n) | |||
303 | return 0; | 442 | return 0; |
304 | } | 443 | } |
305 | 444 | ||
445 | void __init srat_reserve_add_area(int nodeid) | ||
446 | { | ||
447 | if (found_add_area && nodes_add[nodeid].end) { | ||
448 | u64 total_mb; | ||
449 | |||
450 | printk(KERN_INFO "SRAT: Reserving hot-add memory space " | ||
451 | "for node %d at %Lx-%Lx\n", | ||
452 | nodeid, nodes_add[nodeid].start, nodes_add[nodeid].end); | ||
453 | total_mb = (nodes_add[nodeid].end - nodes_add[nodeid].start) | ||
454 | >> PAGE_SHIFT; | ||
455 | total_mb *= sizeof(struct page); | ||
456 | total_mb >>= 20; | ||
457 | printk(KERN_INFO "SRAT: This will cost you %Lu MB of " | ||
458 | "pre-allocated memory.\n", (unsigned long long)total_mb); | ||
459 | reserve_bootmem_node(NODE_DATA(nodeid), nodes_add[nodeid].start, | ||
460 | nodes_add[nodeid].end - nodes_add[nodeid].start); | ||
461 | } | ||
462 | } | ||
463 | |||
306 | int __node_distance(int a, int b) | 464 | int __node_distance(int a, int b) |
307 | { | 465 | { |
308 | int index; | 466 | int index; |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index e616500207e4..a2060e4d5de6 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -9,11 +9,16 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
12 | #include <asm/e820.h> | ||
13 | |||
12 | #include "pci.h" | 14 | #include "pci.h" |
13 | 15 | ||
14 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 16 | #define MMCONFIG_APER_SIZE (256*1024*1024) |
17 | /* Verify the first 16 busses. We assume that systems with more busses | ||
18 | get MCFG right. */ | ||
19 | #define MAX_CHECK_BUS 16 | ||
15 | 20 | ||
16 | static DECLARE_BITMAP(fallback_slots, 32); | 21 | static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS); |
17 | 22 | ||
18 | /* Static virtual mapping of the MMCONFIG aperture */ | 23 | /* Static virtual mapping of the MMCONFIG aperture */ |
19 | struct mmcfg_virt { | 24 | struct mmcfg_virt { |
@@ -55,7 +60,8 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) | |||
55 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 60 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
56 | { | 61 | { |
57 | char __iomem *addr; | 62 | char __iomem *addr; |
58 | if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), fallback_slots)) | 63 | if (seg == 0 && bus < MAX_CHECK_BUS && |
64 | test_bit(32*bus + PCI_SLOT(devfn), fallback_slots)) | ||
59 | return NULL; | 65 | return NULL; |
60 | addr = get_virt(seg, bus); | 66 | addr = get_virt(seg, bus); |
61 | if (!addr) | 67 | if (!addr) |
@@ -69,8 +75,10 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
69 | char __iomem *addr; | 75 | char __iomem *addr; |
70 | 76 | ||
71 | /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ | 77 | /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ |
72 | if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) | 78 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) { |
79 | *value = -1; | ||
73 | return -EINVAL; | 80 | return -EINVAL; |
81 | } | ||
74 | 82 | ||
75 | addr = pci_dev_base(seg, bus, devfn); | 83 | addr = pci_dev_base(seg, bus, devfn); |
76 | if (!addr) | 84 | if (!addr) |
@@ -129,21 +137,26 @@ static struct pci_raw_ops pci_mmcfg = { | |||
129 | Normally this can be expressed in the MCFG by not listing them | 137 | Normally this can be expressed in the MCFG by not listing them |
130 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. | 138 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. |
131 | Instead try to discover all devices on bus 0 that are unreachable using MM | 139 | Instead try to discover all devices on bus 0 that are unreachable using MM |
132 | and fallback for them. | 140 | and fallback for them. */ |
133 | We only do this for bus 0/seg 0 */ | ||
134 | static __init void unreachable_devices(void) | 141 | static __init void unreachable_devices(void) |
135 | { | 142 | { |
136 | int i; | 143 | int i, k; |
137 | for (i = 0; i < 32; i++) { | 144 | /* Use the max bus number from ACPI here? */ |
138 | u32 val1; | 145 | for (k = 0; k < MAX_CHECK_BUS; k++) { |
139 | char __iomem *addr; | 146 | for (i = 0; i < 32; i++) { |
140 | 147 | u32 val1; | |
141 | pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1); | 148 | char __iomem *addr; |
142 | if (val1 == 0xffffffff) | 149 | |
143 | continue; | 150 | pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1); |
144 | addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0)); | 151 | if (val1 == 0xffffffff) |
145 | if (addr == NULL|| readl(addr) != val1) { | 152 | continue; |
146 | set_bit(i, fallback_slots); | 153 | addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); |
154 | if (addr == NULL|| readl(addr) != val1) { | ||
155 | set_bit(i + 32*k, fallback_slots); | ||
156 | printk(KERN_NOTICE | ||
157 | "PCI: No mmconfig possible on device %x:%x\n", | ||
158 | k, i); | ||
159 | } | ||
147 | } | 160 | } |
148 | } | 161 | } |
149 | } | 162 | } |
@@ -161,6 +174,14 @@ void __init pci_mmcfg_init(void) | |||
161 | (pci_mmcfg_config[0].base_address == 0)) | 174 | (pci_mmcfg_config[0].base_address == 0)) |
162 | return; | 175 | return; |
163 | 176 | ||
177 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
178 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||
179 | E820_RESERVED)) { | ||
180 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||
181 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
182 | return; | ||
183 | } | ||
184 | |||
164 | /* RED-PEN i386 doesn't do _nocache right now */ | 185 | /* RED-PEN i386 doesn't do _nocache right now */ |
165 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); | 186 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); |
166 | if (pci_mmcfg_virt == NULL) { | 187 | if (pci_mmcfg_virt == NULL) { |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 152b9370789b..a15b6e3e72c8 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -48,7 +48,6 @@ EXPORT_SYMBOL(memchr); | |||
48 | EXPORT_SYMBOL(strcat); | 48 | EXPORT_SYMBOL(strcat); |
49 | EXPORT_SYMBOL(strchr); | 49 | EXPORT_SYMBOL(strchr); |
50 | EXPORT_SYMBOL(strlen); | 50 | EXPORT_SYMBOL(strlen); |
51 | EXPORT_SYMBOL(strpbrk); | ||
52 | EXPORT_SYMBOL(strncat); | 51 | EXPORT_SYMBOL(strncat); |
53 | EXPORT_SYMBOL(strnlen); | 52 | EXPORT_SYMBOL(strnlen); |
54 | EXPORT_SYMBOL(strrchr); | 53 | EXPORT_SYMBOL(strrchr); |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 5cb96300eb0f..c24652d31bf9 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -329,7 +329,7 @@ config ACPI_CONTAINER | |||
329 | config ACPI_HOTPLUG_MEMORY | 329 | config ACPI_HOTPLUG_MEMORY |
330 | tristate "Memory Hotplug" | 330 | tristate "Memory Hotplug" |
331 | depends on ACPI | 331 | depends on ACPI |
332 | depends on MEMORY_HOTPLUG | 332 | depends on MEMORY_HOTPLUG || X86_64 |
333 | default n | 333 | default n |
334 | help | 334 | help |
335 | This driver adds supports for ACPI Memory Hotplug. This driver | 335 | This driver adds supports for ACPI Memory Hotplug. This driver |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 16c513aa4d48..c80c3aeed004 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -106,7 +106,7 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf) | |||
106 | other_node = 0; | 106 | other_node = 0; |
107 | for (i = 0; i < MAX_NR_ZONES; i++) { | 107 | for (i = 0; i < MAX_NR_ZONES; i++) { |
108 | struct zone *z = &pg->node_zones[i]; | 108 | struct zone *z = &pg->node_zones[i]; |
109 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 109 | for_each_online_cpu(cpu) { |
110 | struct per_cpu_pageset *ps = zone_pcp(z,cpu); | 110 | struct per_cpu_pageset *ps = zone_pcp(z,cpu); |
111 | numa_hit += ps->numa_hit; | 111 | numa_hit += ps->numa_hit; |
112 | numa_miss += ps->numa_miss; | 112 | numa_miss += ps->numa_miss; |
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c index ce4a1ce59d6a..ec004897b634 100644 --- a/drivers/cdrom/aztcd.c +++ b/drivers/cdrom/aztcd.c | |||
@@ -1763,7 +1763,7 @@ static int __init aztcd_init(void) | |||
1763 | release_region(azt_port, 4); | 1763 | release_region(azt_port, 4); |
1764 | } | 1764 | } |
1765 | } | 1765 | } |
1766 | if ((azt_port_auto[i] == 0) || (i == 16)) { | 1766 | if ((i == 16) || (azt_port_auto[i] == 0)) { |
1767 | printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n"); | 1767 | printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n"); |
1768 | return -EIO; | 1768 | return -EIO; |
1769 | } | 1769 | } |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 889cad07774e..402296670d3a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -805,10 +805,6 @@ config S3C2410_RTC | |||
805 | Samsung S3C2410. This can provide periodic interrupt rates | 805 | Samsung S3C2410. This can provide periodic interrupt rates |
806 | from 1Hz to 64Hz for user programs, and wakeup from Alarm. | 806 | from 1Hz to 64Hz for user programs, and wakeup from Alarm. |
807 | 807 | ||
808 | config RTC_VR41XX | ||
809 | tristate "NEC VR4100 series Real Time Clock Support" | ||
810 | depends on CPU_VR41XX | ||
811 | |||
812 | config COBALT_LCD | 808 | config COBALT_LCD |
813 | bool "Support for Cobalt LCD" | 809 | bool "Support for Cobalt LCD" |
814 | depends on MIPS_COBALT | 810 | depends on MIPS_COBALT |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index a73cb4956928..f5b01c6d498e 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -67,7 +67,6 @@ obj-$(CONFIG_SGI_DS1286) += ds1286.o | |||
67 | obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o | 67 | obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o |
68 | obj-$(CONFIG_DS1302) += ds1302.o | 68 | obj-$(CONFIG_DS1302) += ds1302.o |
69 | obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o | 69 | obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o |
70 | obj-$(CONFIG_RTC_VR41XX) += vr41xx_rtc.o | ||
71 | ifeq ($(CONFIG_GENERIC_NVRAM),y) | 70 | ifeq ($(CONFIG_GENERIC_NVRAM),y) |
72 | obj-$(CONFIG_NVRAM) += generic_nvram.o | 71 | obj-$(CONFIG_NVRAM) += generic_nvram.o |
73 | else | 72 | else |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 927a5bbe112c..a370e7a0bad5 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -142,7 +142,7 @@ static int ac_register_board(unsigned long physloc, void __iomem *loc, | |||
142 | if (!boardno) | 142 | if (!boardno) |
143 | boardno = readb(loc + NUMCARD_OWNER_TO_PC); | 143 | boardno = readb(loc + NUMCARD_OWNER_TO_PC); |
144 | 144 | ||
145 | if (!boardno && boardno > MAX_BOARD) { | 145 | if (!boardno || boardno > MAX_BOARD) { |
146 | printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n", | 146 | printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n", |
147 | boardno, physloc, MAX_BOARD); | 147 | boardno, physloc, MAX_BOARD); |
148 | return 0; | 148 | return 0; |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index a229915ce1b2..87dcaa237f07 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -490,7 +490,7 @@ for (i = 0; i < 10; i++) \ | |||
490 | release_region(dtlk_portlist[i], DTLK_IO_EXTENT); | 490 | release_region(dtlk_portlist[i], DTLK_IO_EXTENT); |
491 | } | 491 | } |
492 | 492 | ||
493 | printk(KERN_INFO "\nDoubleTalk PC - not found\n"); | 493 | printk(KERN_INFO "DoubleTalk PC - not found\n"); |
494 | return -ENODEV; | 494 | return -ENODEV; |
495 | } | 495 | } |
496 | 496 | ||
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 0ded046d5aa8..9f2f8fdec69a 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -941,6 +941,7 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) | |||
941 | list_del(&msg->link); | 941 | list_del(&msg->link); |
942 | list_add_tail(&msg->link, &msgs); | 942 | list_add_tail(&msg->link, &msgs); |
943 | } | 943 | } |
944 | intf->waiting_events_count = 0; | ||
944 | } | 945 | } |
945 | 946 | ||
946 | /* Hold the events lock while doing this to preserve order. */ | 947 | /* Hold the events lock while doing this to preserve order. */ |
@@ -2916,6 +2917,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
2916 | 2917 | ||
2917 | copy_event_into_recv_msg(recv_msg, msg); | 2918 | copy_event_into_recv_msg(recv_msg, msg); |
2918 | list_add_tail(&(recv_msg->link), &(intf->waiting_events)); | 2919 | list_add_tail(&(recv_msg->link), &(intf->waiting_events)); |
2920 | intf->waiting_events_count++; | ||
2919 | } else { | 2921 | } else { |
2920 | /* There's too many things in the queue, discard this | 2922 | /* There's too many things in the queue, discard this |
2921 | message. */ | 2923 | message. */ |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 86be04b241e1..58f3512c52e1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1584,7 +1584,6 @@ u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dpo | |||
1584 | 1584 | ||
1585 | return twothirdsMD4Transform(daddr, hash); | 1585 | return twothirdsMD4Transform(daddr, hash); |
1586 | } | 1586 | } |
1587 | EXPORT_SYMBOL(secure_ipv6_port_ephemeral); | ||
1588 | #endif | 1587 | #endif |
1589 | 1588 | ||
1590 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | 1589 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 2546637a55c0..f58ad7f68267 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
@@ -327,7 +327,7 @@ static ssize_t store_received_ref_clk3a(struct device *d, | |||
327 | return strnlen(buf, count); | 327 | return strnlen(buf, count); |
328 | } | 328 | } |
329 | 329 | ||
330 | static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, | 330 | static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL, |
331 | store_received_ref_clk3a); | 331 | store_received_ref_clk3a); |
332 | 332 | ||
333 | 333 | ||
@@ -349,7 +349,7 @@ static ssize_t store_received_ref_clk3b(struct device *d, | |||
349 | return strnlen(buf, count); | 349 | return strnlen(buf, count); |
350 | } | 350 | } |
351 | 351 | ||
352 | static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, | 352 | static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL, |
353 | store_received_ref_clk3b); | 353 | store_received_ref_clk3b); |
354 | 354 | ||
355 | 355 | ||
@@ -371,7 +371,7 @@ static ssize_t store_enable_clk3b_output(struct device *d, | |||
371 | return strnlen(buf, count); | 371 | return strnlen(buf, count); |
372 | } | 372 | } |
373 | 373 | ||
374 | static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, | 374 | static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL, |
375 | store_enable_clk3b_output); | 375 | store_enable_clk3b_output); |
376 | 376 | ||
377 | static ssize_t store_enable_clk3a_output(struct device *d, | 377 | static ssize_t store_enable_clk3a_output(struct device *d, |
@@ -392,7 +392,7 @@ static ssize_t store_enable_clk3a_output(struct device *d, | |||
392 | return strnlen(buf, count); | 392 | return strnlen(buf, count); |
393 | } | 393 | } |
394 | 394 | ||
395 | static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, | 395 | static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL, |
396 | store_enable_clk3a_output); | 396 | store_enable_clk3a_output); |
397 | 397 | ||
398 | static ssize_t store_enable_clkb1_output(struct device *d, | 398 | static ssize_t store_enable_clkb1_output(struct device *d, |
@@ -413,7 +413,7 @@ static ssize_t store_enable_clkb1_output(struct device *d, | |||
413 | return strnlen(buf, count); | 413 | return strnlen(buf, count); |
414 | } | 414 | } |
415 | 415 | ||
416 | static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, | 416 | static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL, |
417 | store_enable_clkb1_output); | 417 | store_enable_clkb1_output); |
418 | 418 | ||
419 | 419 | ||
@@ -435,7 +435,7 @@ static ssize_t store_enable_clka1_output(struct device *d, | |||
435 | return strnlen(buf, count); | 435 | return strnlen(buf, count); |
436 | } | 436 | } |
437 | 437 | ||
438 | static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, | 438 | static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL, |
439 | store_enable_clka1_output); | 439 | store_enable_clka1_output); |
440 | 440 | ||
441 | static ssize_t store_enable_clkb0_output(struct device *d, | 441 | static ssize_t store_enable_clkb0_output(struct device *d, |
@@ -456,7 +456,7 @@ static ssize_t store_enable_clkb0_output(struct device *d, | |||
456 | return strnlen(buf, count); | 456 | return strnlen(buf, count); |
457 | } | 457 | } |
458 | 458 | ||
459 | static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, | 459 | static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL, |
460 | store_enable_clkb0_output); | 460 | store_enable_clkb0_output); |
461 | 461 | ||
462 | static ssize_t store_enable_clka0_output(struct device *d, | 462 | static ssize_t store_enable_clka0_output(struct device *d, |
@@ -477,7 +477,7 @@ static ssize_t store_enable_clka0_output(struct device *d, | |||
477 | return strnlen(buf, count); | 477 | return strnlen(buf, count); |
478 | } | 478 | } |
479 | 479 | ||
480 | static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, | 480 | static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL, |
481 | store_enable_clka0_output); | 481 | store_enable_clka0_output); |
482 | 482 | ||
483 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, | 483 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, |
@@ -519,7 +519,7 @@ static ssize_t store_select_amcb2_transmit_clock(struct device *d, | |||
519 | return strnlen(buf, count); | 519 | return strnlen(buf, count); |
520 | } | 520 | } |
521 | 521 | ||
522 | static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, | 522 | static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL, |
523 | store_select_amcb2_transmit_clock); | 523 | store_select_amcb2_transmit_clock); |
524 | 524 | ||
525 | static ssize_t store_select_amcb1_transmit_clock(struct device *d, | 525 | static ssize_t store_select_amcb1_transmit_clock(struct device *d, |
@@ -560,7 +560,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, | |||
560 | return strnlen(buf, count); | 560 | return strnlen(buf, count); |
561 | } | 561 | } |
562 | 562 | ||
563 | static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, | 563 | static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL, |
564 | store_select_amcb1_transmit_clock); | 564 | store_select_amcb1_transmit_clock); |
565 | 565 | ||
566 | static ssize_t store_select_redundant_clock(struct device *d, | 566 | static ssize_t store_select_redundant_clock(struct device *d, |
@@ -581,7 +581,7 @@ static ssize_t store_select_redundant_clock(struct device *d, | |||
581 | return strnlen(buf, count); | 581 | return strnlen(buf, count); |
582 | } | 582 | } |
583 | 583 | ||
584 | static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, | 584 | static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL, |
585 | store_select_redundant_clock); | 585 | store_select_redundant_clock); |
586 | 586 | ||
587 | static ssize_t store_select_ref_frequency(struct device *d, | 587 | static ssize_t store_select_ref_frequency(struct device *d, |
@@ -602,7 +602,7 @@ static ssize_t store_select_ref_frequency(struct device *d, | |||
602 | return strnlen(buf, count); | 602 | return strnlen(buf, count); |
603 | } | 603 | } |
604 | 604 | ||
605 | static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, | 605 | static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL, |
606 | store_select_ref_frequency); | 606 | store_select_ref_frequency); |
607 | 607 | ||
608 | static ssize_t store_filter_select(struct device *d, | 608 | static ssize_t store_filter_select(struct device *d, |
@@ -623,7 +623,7 @@ static ssize_t store_filter_select(struct device *d, | |||
623 | return strnlen(buf, count); | 623 | return strnlen(buf, count); |
624 | } | 624 | } |
625 | 625 | ||
626 | static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); | 626 | static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select); |
627 | 627 | ||
628 | static ssize_t store_hardware_switching_mode(struct device *d, | 628 | static ssize_t store_hardware_switching_mode(struct device *d, |
629 | struct device_attribute *attr, const char *buf, size_t count) | 629 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -643,7 +643,7 @@ static ssize_t store_hardware_switching_mode(struct device *d, | |||
643 | return strnlen(buf, count); | 643 | return strnlen(buf, count); |
644 | } | 644 | } |
645 | 645 | ||
646 | static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, | 646 | static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL, |
647 | store_hardware_switching_mode); | 647 | store_hardware_switching_mode); |
648 | 648 | ||
649 | static ssize_t store_hardware_switching(struct device *d, | 649 | static ssize_t store_hardware_switching(struct device *d, |
@@ -664,7 +664,7 @@ static ssize_t store_hardware_switching(struct device *d, | |||
664 | return strnlen(buf, count); | 664 | return strnlen(buf, count); |
665 | } | 665 | } |
666 | 666 | ||
667 | static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, | 667 | static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL, |
668 | store_hardware_switching); | 668 | store_hardware_switching); |
669 | 669 | ||
670 | static ssize_t store_refalign (struct device *d, | 670 | static ssize_t store_refalign (struct device *d, |
@@ -684,7 +684,7 @@ static ssize_t store_refalign (struct device *d, | |||
684 | return strnlen(buf, count); | 684 | return strnlen(buf, count); |
685 | } | 685 | } |
686 | 686 | ||
687 | static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); | 687 | static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign); |
688 | 688 | ||
689 | static ssize_t store_mode_select (struct device *d, | 689 | static ssize_t store_mode_select (struct device *d, |
690 | struct device_attribute *attr, const char *buf, size_t count) | 690 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -704,7 +704,7 @@ static ssize_t store_mode_select (struct device *d, | |||
704 | return strnlen(buf, count); | 704 | return strnlen(buf, count); |
705 | } | 705 | } |
706 | 706 | ||
707 | static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); | 707 | static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select); |
708 | 708 | ||
709 | static ssize_t store_reset (struct device *d, | 709 | static ssize_t store_reset (struct device *d, |
710 | struct device_attribute *attr, const char *buf, size_t count) | 710 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -724,7 +724,7 @@ static ssize_t store_reset (struct device *d, | |||
724 | return strnlen(buf, count); | 724 | return strnlen(buf, count); |
725 | } | 725 | } |
726 | 726 | ||
727 | static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); | 727 | static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); |
728 | 728 | ||
729 | static struct attribute *tlclk_sysfs_entries[] = { | 729 | static struct attribute *tlclk_sysfs_entries[] = { |
730 | &dev_attr_current_ref.attr, | 730 | &dev_attr_current_ref.attr, |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 98b126c2ded8..f70a47eadb52 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -351,10 +351,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
351 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 351 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
352 | return size; | 352 | return size; |
353 | } | 353 | } |
354 | |||
355 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 354 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
356 | 355 | ||
357 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size) | 356 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, |
357 | size_t size) | ||
358 | { | 358 | { |
359 | int copied = 0; | 359 | int copied = 0; |
360 | do { | 360 | do { |
@@ -368,17 +368,16 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s | |||
368 | tb->used += space; | 368 | tb->used += space; |
369 | copied += space; | 369 | copied += space; |
370 | chars += space; | 370 | chars += space; |
371 | /* printk("Flip insert %d.\n", space); */ | ||
372 | } | 371 | } |
373 | /* There is a small chance that we need to split the data over | 372 | /* There is a small chance that we need to split the data over |
374 | several buffers. If this is the case we must loop */ | 373 | several buffers. If this is the case we must loop */ |
375 | while (unlikely(size > copied)); | 374 | while (unlikely(size > copied)); |
376 | return copied; | 375 | return copied; |
377 | } | 376 | } |
378 | |||
379 | EXPORT_SYMBOL(tty_insert_flip_string); | 377 | EXPORT_SYMBOL(tty_insert_flip_string); |
380 | 378 | ||
381 | int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) | 379 | int tty_insert_flip_string_flags(struct tty_struct *tty, |
380 | const unsigned char *chars, const char *flags, size_t size) | ||
382 | { | 381 | { |
383 | int copied = 0; | 382 | int copied = 0; |
384 | do { | 383 | do { |
@@ -399,9 +398,20 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *ch | |||
399 | while (unlikely(size > copied)); | 398 | while (unlikely(size > copied)); |
400 | return copied; | 399 | return copied; |
401 | } | 400 | } |
402 | |||
403 | EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); | 401 | EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); |
404 | 402 | ||
403 | void tty_schedule_flip(struct tty_struct *tty) | ||
404 | { | ||
405 | unsigned long flags; | ||
406 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
407 | if (tty->buf.tail != NULL) { | ||
408 | tty->buf.tail->active = 0; | ||
409 | tty->buf.tail->commit = tty->buf.tail->used; | ||
410 | } | ||
411 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
412 | schedule_delayed_work(&tty->buf.work, 1); | ||
413 | } | ||
414 | EXPORT_SYMBOL(tty_schedule_flip); | ||
405 | 415 | ||
406 | /* | 416 | /* |
407 | * Prepare a block of space in the buffer for data. Returns the length | 417 | * Prepare a block of space in the buffer for data. Returns the length |
@@ -1730,7 +1740,7 @@ static void release_dev(struct file * filp) | |||
1730 | { | 1740 | { |
1731 | struct tty_struct *tty, *o_tty; | 1741 | struct tty_struct *tty, *o_tty; |
1732 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1742 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1733 | int devpts_master, devpts; | 1743 | int devpts; |
1734 | int idx; | 1744 | int idx; |
1735 | char buf[64]; | 1745 | char buf[64]; |
1736 | unsigned long flags; | 1746 | unsigned long flags; |
@@ -1747,7 +1757,6 @@ static void release_dev(struct file * filp) | |||
1747 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1757 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1748 | tty->driver->subtype == PTY_TYPE_MASTER); | 1758 | tty->driver->subtype == PTY_TYPE_MASTER); |
1749 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1759 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1750 | devpts_master = pty_master && devpts; | ||
1751 | o_tty = tty->link; | 1760 | o_tty = tty->link; |
1752 | 1761 | ||
1753 | #ifdef TTY_PARANOIA_CHECK | 1762 | #ifdef TTY_PARANOIA_CHECK |
@@ -2185,6 +2194,7 @@ static int ptmx_open(struct inode * inode, struct file * filp) | |||
2185 | return 0; | 2194 | return 0; |
2186 | out1: | 2195 | out1: |
2187 | release_dev(filp); | 2196 | release_dev(filp); |
2197 | return retval; | ||
2188 | out: | 2198 | out: |
2189 | down(&allocated_ptys_lock); | 2199 | down(&allocated_ptys_lock); |
2190 | idr_remove(&allocated_ptys, index); | 2200 | idr_remove(&allocated_ptys, index); |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 23a9e1ea8e32..1659f6c41458 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -509,12 +509,22 @@ static int hdaps_dmi_match_invert(struct dmi_system_id *id) | |||
509 | } \ | 509 | } \ |
510 | } | 510 | } |
511 | 511 | ||
512 | #define HDAPS_DMI_MATCH_LENOVO(model) { \ | ||
513 | .ident = "Lenovo " model, \ | ||
514 | .callback = hdaps_dmi_match_invert, \ | ||
515 | .matches = { \ | ||
516 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), \ | ||
517 | DMI_MATCH(DMI_PRODUCT_VERSION, model) \ | ||
518 | } \ | ||
519 | } | ||
520 | |||
512 | static int __init hdaps_init(void) | 521 | static int __init hdaps_init(void) |
513 | { | 522 | { |
514 | int ret; | 523 | int ret; |
515 | 524 | ||
516 | /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ | 525 | /* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ |
517 | struct dmi_system_id hdaps_whitelist[] = { | 526 | struct dmi_system_id hdaps_whitelist[] = { |
527 | HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), | ||
518 | HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), | 528 | HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), |
519 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), | 529 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), |
520 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), | 530 | HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), |
@@ -524,15 +534,17 @@ static int __init hdaps_init(void) | |||
524 | HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), | 534 | HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), |
525 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), | 535 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"), |
526 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), | 536 | HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), |
537 | HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"), | ||
527 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), | 538 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), |
528 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), | 539 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"), |
529 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), | 540 | HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), |
541 | HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"), | ||
530 | { .ident = NULL } | 542 | { .ident = NULL } |
531 | }; | 543 | }; |
532 | 544 | ||
533 | if (!dmi_check_system(hdaps_whitelist)) { | 545 | if (!dmi_check_system(hdaps_whitelist)) { |
534 | printk(KERN_WARNING "hdaps: supported laptop not found!\n"); | 546 | printk(KERN_WARNING "hdaps: supported laptop not found!\n"); |
535 | ret = -ENXIO; | 547 | ret = -ENODEV; |
536 | goto out; | 548 | goto out; |
537 | } | 549 | } |
538 | 550 | ||
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig index 53c4fb62ed85..5b203fe21dcd 100644 --- a/drivers/isdn/gigaset/Kconfig +++ b/drivers/isdn/gigaset/Kconfig | |||
@@ -3,8 +3,8 @@ menu "Siemens Gigaset" | |||
3 | 3 | ||
4 | config ISDN_DRV_GIGASET | 4 | config ISDN_DRV_GIGASET |
5 | tristate "Siemens Gigaset support (isdn)" | 5 | tristate "Siemens Gigaset support (isdn)" |
6 | depends on ISDN_I4L && m | 6 | depends on ISDN_I4L |
7 | # depends on ISDN_I4L && MODULES | 7 | select CRC_CCITT |
8 | help | 8 | help |
9 | Say m here if you have a Gigaset or Sinus isdn device. | 9 | Say m here if you have a Gigaset or Sinus isdn device. |
10 | 10 | ||
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c index 171f8b703d61..ce3cd77094b3 100644 --- a/drivers/isdn/gigaset/asyncdata.c +++ b/drivers/isdn/gigaset/asyncdata.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>, | 4 | * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Stefan Eilers <Eilers.Stefan@epost.de>. | 6 | * Stefan Eilers. |
7 | * | 7 | * |
8 | * ===================================================================== | 8 | * ===================================================================== |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
@@ -11,10 +11,6 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: asyncdata.c,v 1.2.2.7 2005/11/13 23:05:18 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
@@ -45,7 +41,7 @@ static inline int muststuff(unsigned char c) | |||
45 | * number of processed bytes | 41 | * number of processed bytes |
46 | */ | 42 | */ |
47 | static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | 43 | static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, |
48 | struct inbuf_t *inbuf) | 44 | struct inbuf_t *inbuf) |
49 | { | 45 | { |
50 | struct cardstate *cs = inbuf->cs; | 46 | struct cardstate *cs = inbuf->cs; |
51 | unsigned cbytes = cs->cbytes; | 47 | unsigned cbytes = cs->cbytes; |
@@ -55,10 +51,11 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | |||
55 | for (;;) { | 51 | for (;;) { |
56 | cs->respdata[cbytes] = c; | 52 | cs->respdata[cbytes] = c; |
57 | if (c == 10 || c == 13) { | 53 | if (c == 10 || c == 13) { |
58 | dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", | 54 | gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", |
59 | __func__, cbytes); | 55 | __func__, cbytes); |
60 | cs->cbytes = cbytes; | 56 | cs->cbytes = cbytes; |
61 | gigaset_handle_modem_response(cs); /* can change cs->dle */ | 57 | gigaset_handle_modem_response(cs); /* can change |
58 | cs->dle */ | ||
62 | cbytes = 0; | 59 | cbytes = 0; |
63 | 60 | ||
64 | if (cs->dle && | 61 | if (cs->dle && |
@@ -71,7 +68,7 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | |||
71 | if (cbytes < MAX_RESP_SIZE - 1) | 68 | if (cbytes < MAX_RESP_SIZE - 1) |
72 | cbytes++; | 69 | cbytes++; |
73 | else | 70 | else |
74 | warn("response too large"); | 71 | dev_warn(cs->dev, "response too large\n"); |
75 | } | 72 | } |
76 | 73 | ||
77 | if (!numbytes) | 74 | if (!numbytes) |
@@ -96,11 +93,12 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, | |||
96 | * number of processed bytes | 93 | * number of processed bytes |
97 | */ | 94 | */ |
98 | static inline int lock_loop(unsigned char *src, int numbytes, | 95 | static inline int lock_loop(unsigned char *src, int numbytes, |
99 | struct inbuf_t *inbuf) | 96 | struct inbuf_t *inbuf) |
100 | { | 97 | { |
101 | struct cardstate *cs = inbuf->cs; | 98 | struct cardstate *cs = inbuf->cs; |
102 | 99 | ||
103 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src, 0); | 100 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", |
101 | numbytes, src); | ||
104 | gigaset_if_receive(cs, src, numbytes); | 102 | gigaset_if_receive(cs, src, numbytes); |
105 | 103 | ||
106 | return numbytes; | 104 | return numbytes; |
@@ -115,24 +113,18 @@ static inline int lock_loop(unsigned char *src, int numbytes, | |||
115 | * numbytes (all bytes processed) on error --FIXME | 113 | * numbytes (all bytes processed) on error --FIXME |
116 | */ | 114 | */ |
117 | static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, | 115 | static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, |
118 | struct inbuf_t *inbuf) | 116 | struct inbuf_t *inbuf) |
119 | { | 117 | { |
120 | struct cardstate *cs = inbuf->cs; | 118 | struct cardstate *cs = inbuf->cs; |
121 | struct bc_state *bcs = inbuf->bcs; | 119 | struct bc_state *bcs = inbuf->bcs; |
122 | int inputstate; | 120 | int inputstate = bcs->inputstate; |
123 | __u16 fcs; | 121 | __u16 fcs = bcs->fcs; |
124 | struct sk_buff *skb; | 122 | struct sk_buff *skb = bcs->skb; |
125 | unsigned char error; | 123 | unsigned char error; |
126 | struct sk_buff *compskb; | 124 | struct sk_buff *compskb; |
127 | int startbytes = numbytes; | 125 | int startbytes = numbytes; |
128 | int l; | 126 | int l; |
129 | 127 | ||
130 | IFNULLRETVAL(bcs, numbytes); | ||
131 | inputstate = bcs->inputstate; | ||
132 | fcs = bcs->fcs; | ||
133 | skb = bcs->skb; | ||
134 | IFNULLRETVAL(skb, numbytes); | ||
135 | |||
136 | if (unlikely(inputstate & INS_byte_stuff)) { | 128 | if (unlikely(inputstate & INS_byte_stuff)) { |
137 | inputstate &= ~INS_byte_stuff; | 129 | inputstate &= ~INS_byte_stuff; |
138 | goto byte_stuff; | 130 | goto byte_stuff; |
@@ -156,39 +148,37 @@ byte_stuff: | |||
156 | c ^= PPP_TRANS; | 148 | c ^= PPP_TRANS; |
157 | #ifdef CONFIG_GIGASET_DEBUG | 149 | #ifdef CONFIG_GIGASET_DEBUG |
158 | if (unlikely(!muststuff(c))) | 150 | if (unlikely(!muststuff(c))) |
159 | dbg(DEBUG_HDLC, | 151 | gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c); |
160 | "byte stuffed: 0x%02x", c); | ||
161 | #endif | 152 | #endif |
162 | } else if (unlikely(c == PPP_FLAG)) { | 153 | } else if (unlikely(c == PPP_FLAG)) { |
163 | if (unlikely(inputstate & INS_skip_frame)) { | 154 | if (unlikely(inputstate & INS_skip_frame)) { |
164 | if (!(inputstate & INS_have_data)) { /* 7E 7E */ | 155 | if (!(inputstate & INS_have_data)) { /* 7E 7E */ |
165 | //dbg(DEBUG_HDLC, "(7e)7e------------------------"); | ||
166 | #ifdef CONFIG_GIGASET_DEBUG | 156 | #ifdef CONFIG_GIGASET_DEBUG |
167 | ++bcs->emptycount; | 157 | ++bcs->emptycount; |
168 | #endif | 158 | #endif |
169 | } else | 159 | } else |
170 | dbg(DEBUG_HDLC, | 160 | gig_dbg(DEBUG_HDLC, |
171 | "7e----------------------------"); | 161 | "7e----------------------------"); |
172 | 162 | ||
173 | /* end of frame */ | 163 | /* end of frame */ |
174 | error = 1; | 164 | error = 1; |
175 | gigaset_rcv_error(NULL, cs, bcs); | 165 | gigaset_rcv_error(NULL, cs, bcs); |
176 | } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ | 166 | } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ |
177 | //dbg(DEBUG_HDLC, "(7e)7e------------------------"); | ||
178 | #ifdef CONFIG_GIGASET_DEBUG | 167 | #ifdef CONFIG_GIGASET_DEBUG |
179 | ++bcs->emptycount; | 168 | ++bcs->emptycount; |
180 | #endif | 169 | #endif |
181 | break; | 170 | break; |
182 | } else { | 171 | } else { |
183 | dbg(DEBUG_HDLC, | 172 | gig_dbg(DEBUG_HDLC, |
184 | "7e----------------------------"); | 173 | "7e----------------------------"); |
185 | 174 | ||
186 | /* end of frame */ | 175 | /* end of frame */ |
187 | error = 0; | 176 | error = 0; |
188 | 177 | ||
189 | if (unlikely(fcs != PPP_GOODFCS)) { | 178 | if (unlikely(fcs != PPP_GOODFCS)) { |
190 | err("Packet checksum at %lu failed, " | 179 | dev_err(cs->dev, |
191 | "packet is corrupted (%u bytes)!", | 180 | "Packet checksum at %lu failed, " |
181 | "packet is corrupted (%u bytes)!\n", | ||
192 | bcs->rcvbytes, skb->len); | 182 | bcs->rcvbytes, skb->len); |
193 | compskb = NULL; | 183 | compskb = NULL; |
194 | gigaset_rcv_error(compskb, cs, bcs); | 184 | gigaset_rcv_error(compskb, cs, bcs); |
@@ -202,9 +192,11 @@ byte_stuff: | |||
202 | skb = NULL; | 192 | skb = NULL; |
203 | inputstate |= INS_skip_frame; | 193 | inputstate |= INS_skip_frame; |
204 | if (l == 1) { | 194 | if (l == 1) { |
205 | err("invalid packet size (1)!"); | 195 | dev_err(cs->dev, |
196 | "invalid packet size (1)!\n"); | ||
206 | error = 1; | 197 | error = 1; |
207 | gigaset_rcv_error(NULL, cs, bcs); | 198 | gigaset_rcv_error(NULL, |
199 | cs, bcs); | ||
208 | } | 200 | } |
209 | } | 201 | } |
210 | if (likely(!(error || | 202 | if (likely(!(error || |
@@ -227,7 +219,8 @@ byte_stuff: | |||
227 | } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { | 219 | } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { |
228 | skb_reserve(skb, HW_HDR_LEN); | 220 | skb_reserve(skb, HW_HDR_LEN); |
229 | } else { | 221 | } else { |
230 | warn("could not allocate new skb"); | 222 | dev_warn(cs->dev, |
223 | "could not allocate new skb\n"); | ||
231 | inputstate |= INS_skip_frame; | 224 | inputstate |= INS_skip_frame; |
232 | } | 225 | } |
233 | 226 | ||
@@ -235,7 +228,7 @@ byte_stuff: | |||
235 | #ifdef CONFIG_GIGASET_DEBUG | 228 | #ifdef CONFIG_GIGASET_DEBUG |
236 | } else if (unlikely(muststuff(c))) { | 229 | } else if (unlikely(muststuff(c))) { |
237 | /* Should not happen. Possible after ZDLE=1<CR><LF>. */ | 230 | /* Should not happen. Possible after ZDLE=1<CR><LF>. */ |
238 | dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); | 231 | gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); |
239 | #endif | 232 | #endif |
240 | } | 233 | } |
241 | 234 | ||
@@ -243,8 +236,8 @@ byte_stuff: | |||
243 | 236 | ||
244 | #ifdef CONFIG_GIGASET_DEBUG | 237 | #ifdef CONFIG_GIGASET_DEBUG |
245 | if (unlikely(!(inputstate & INS_have_data))) { | 238 | if (unlikely(!(inputstate & INS_have_data))) { |
246 | dbg(DEBUG_HDLC, | 239 | gig_dbg(DEBUG_HDLC, "7e (%d x) ================", |
247 | "7e (%d x) ================", bcs->emptycount); | 240 | bcs->emptycount); |
248 | bcs->emptycount = 0; | 241 | bcs->emptycount = 0; |
249 | } | 242 | } |
250 | #endif | 243 | #endif |
@@ -253,14 +246,13 @@ byte_stuff: | |||
253 | 246 | ||
254 | if (likely(!(inputstate & INS_skip_frame))) { | 247 | if (likely(!(inputstate & INS_skip_frame))) { |
255 | if (unlikely(skb->len == SBUFSIZE)) { | 248 | if (unlikely(skb->len == SBUFSIZE)) { |
256 | warn("received packet too long"); | 249 | dev_warn(cs->dev, "received packet too long\n"); |
257 | dev_kfree_skb_any(skb); | 250 | dev_kfree_skb_any(skb); |
258 | skb = NULL; | 251 | skb = NULL; |
259 | inputstate |= INS_skip_frame; | 252 | inputstate |= INS_skip_frame; |
260 | break; | 253 | break; |
261 | } | 254 | } |
262 | *gigaset_skb_put_quick(skb, 1) = c; | 255 | *__skb_put(skb, 1) = c; |
263 | /* *__skb_put (skb, 1) = c; */ | ||
264 | fcs = crc_ccitt_byte(fcs, c); | 256 | fcs = crc_ccitt_byte(fcs, c); |
265 | } | 257 | } |
266 | 258 | ||
@@ -289,19 +281,14 @@ byte_stuff: | |||
289 | * numbytes (all bytes processed) on error --FIXME | 281 | * numbytes (all bytes processed) on error --FIXME |
290 | */ | 282 | */ |
291 | static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | 283 | static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, |
292 | struct inbuf_t *inbuf) | 284 | struct inbuf_t *inbuf) |
293 | { | 285 | { |
294 | struct cardstate *cs = inbuf->cs; | 286 | struct cardstate *cs = inbuf->cs; |
295 | struct bc_state *bcs = inbuf->bcs; | 287 | struct bc_state *bcs = inbuf->bcs; |
296 | int inputstate; | 288 | int inputstate = bcs->inputstate; |
297 | struct sk_buff *skb; | 289 | struct sk_buff *skb = bcs->skb; |
298 | int startbytes = numbytes; | 290 | int startbytes = numbytes; |
299 | 291 | ||
300 | IFNULLRETVAL(bcs, numbytes); | ||
301 | inputstate = bcs->inputstate; | ||
302 | skb = bcs->skb; | ||
303 | IFNULLRETVAL(skb, numbytes); | ||
304 | |||
305 | for (;;) { | 292 | for (;;) { |
306 | /* add character */ | 293 | /* add character */ |
307 | inputstate |= INS_have_data; | 294 | inputstate |= INS_have_data; |
@@ -309,13 +296,13 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | |||
309 | if (likely(!(inputstate & INS_skip_frame))) { | 296 | if (likely(!(inputstate & INS_skip_frame))) { |
310 | if (unlikely(skb->len == SBUFSIZE)) { | 297 | if (unlikely(skb->len == SBUFSIZE)) { |
311 | //FIXME just pass skb up and allocate a new one | 298 | //FIXME just pass skb up and allocate a new one |
312 | warn("received packet too long"); | 299 | dev_warn(cs->dev, "received packet too long\n"); |
313 | dev_kfree_skb_any(skb); | 300 | dev_kfree_skb_any(skb); |
314 | skb = NULL; | 301 | skb = NULL; |
315 | inputstate |= INS_skip_frame; | 302 | inputstate |= INS_skip_frame; |
316 | break; | 303 | break; |
317 | } | 304 | } |
318 | *gigaset_skb_put_quick(skb, 1) = gigaset_invtab[c]; | 305 | *__skb_put(skb, 1) = gigaset_invtab[c]; |
319 | } | 306 | } |
320 | 307 | ||
321 | if (unlikely(!numbytes)) | 308 | if (unlikely(!numbytes)) |
@@ -343,7 +330,7 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | |||
343 | != NULL)) { | 330 | != NULL)) { |
344 | skb_reserve(skb, HW_HDR_LEN); | 331 | skb_reserve(skb, HW_HDR_LEN); |
345 | } else { | 332 | } else { |
346 | warn("could not allocate new skb"); | 333 | dev_warn(cs->dev, "could not allocate new skb\n"); |
347 | inputstate |= INS_skip_frame; | 334 | inputstate |= INS_skip_frame; |
348 | } | 335 | } |
349 | } | 336 | } |
@@ -364,13 +351,13 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
364 | 351 | ||
365 | head = atomic_read(&inbuf->head); | 352 | head = atomic_read(&inbuf->head); |
366 | tail = atomic_read(&inbuf->tail); | 353 | tail = atomic_read(&inbuf->tail); |
367 | dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 354 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
368 | 355 | ||
369 | if (head != tail) { | 356 | if (head != tail) { |
370 | cs = inbuf->cs; | 357 | cs = inbuf->cs; |
371 | src = inbuf->data + head; | 358 | src = inbuf->data + head; |
372 | numbytes = (head > tail ? RBUFSIZE : tail) - head; | 359 | numbytes = (head > tail ? RBUFSIZE : tail) - head; |
373 | dbg(DEBUG_INTR, "processing %u bytes", numbytes); | 360 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); |
374 | 361 | ||
375 | while (numbytes) { | 362 | while (numbytes) { |
376 | if (atomic_read(&cs->mstate) == MS_LOCKED) { | 363 | if (atomic_read(&cs->mstate) == MS_LOCKED) { |
@@ -392,8 +379,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
392 | 379 | ||
393 | if (!(inbuf->inputstate & INS_DLE_char)) { | 380 | if (!(inbuf->inputstate & INS_DLE_char)) { |
394 | 381 | ||
395 | /* FIXME Einfach je nach Modus Funktionszeiger in cs setzen [hier+hdlc_loop]? */ | 382 | /* FIXME use function pointers? */ |
396 | /* FIXME Spart folgendes "if" und ermoeglicht andere Protokolle */ | ||
397 | if (inbuf->inputstate & INS_command) | 383 | if (inbuf->inputstate & INS_command) |
398 | procbytes = cmd_loop(c, src, numbytes, inbuf); | 384 | procbytes = cmd_loop(c, src, numbytes, inbuf); |
399 | else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) | 385 | else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) |
@@ -403,13 +389,14 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
403 | 389 | ||
404 | src += procbytes; | 390 | src += procbytes; |
405 | numbytes -= procbytes; | 391 | numbytes -= procbytes; |
406 | } else { /* DLE-char */ | 392 | } else { /* DLE char */ |
407 | inbuf->inputstate &= ~INS_DLE_char; | 393 | inbuf->inputstate &= ~INS_DLE_char; |
408 | switch (c) { | 394 | switch (c) { |
409 | case 'X': /*begin of command*/ | 395 | case 'X': /*begin of command*/ |
410 | #ifdef CONFIG_GIGASET_DEBUG | 396 | #ifdef CONFIG_GIGASET_DEBUG |
411 | if (inbuf->inputstate & INS_command) | 397 | if (inbuf->inputstate & INS_command) |
412 | err("received <DLE> 'X' in command mode"); | 398 | dev_err(cs->dev, |
399 | "received <DLE> 'X' in command mode\n"); | ||
413 | #endif | 400 | #endif |
414 | inbuf->inputstate |= | 401 | inbuf->inputstate |= |
415 | INS_command | INS_DLE_command; | 402 | INS_command | INS_DLE_command; |
@@ -417,7 +404,8 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
417 | case '.': /*end of command*/ | 404 | case '.': /*end of command*/ |
418 | #ifdef CONFIG_GIGASET_DEBUG | 405 | #ifdef CONFIG_GIGASET_DEBUG |
419 | if (!(inbuf->inputstate & INS_command)) | 406 | if (!(inbuf->inputstate & INS_command)) |
420 | err("received <DLE> '.' in hdlc mode"); | 407 | dev_err(cs->dev, |
408 | "received <DLE> '.' in hdlc mode\n"); | ||
421 | #endif | 409 | #endif |
422 | inbuf->inputstate &= cs->dle ? | 410 | inbuf->inputstate &= cs->dle ? |
423 | ~(INS_DLE_command|INS_command) | 411 | ~(INS_DLE_command|INS_command) |
@@ -425,7 +413,9 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
425 | break; | 413 | break; |
426 | //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */ | 414 | //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */ |
427 | default: | 415 | default: |
428 | err("received 0x10 0x%02x!", (int) c); | 416 | dev_err(cs->dev, |
417 | "received 0x10 0x%02x!\n", | ||
418 | (int) c); | ||
429 | /* FIXME: reset driver?? */ | 419 | /* FIXME: reset driver?? */ |
430 | } | 420 | } |
431 | } | 421 | } |
@@ -444,7 +434,7 @@ nextbyte: | |||
444 | } | 434 | } |
445 | } | 435 | } |
446 | 436 | ||
447 | dbg(DEBUG_INTR, "setting head to %u", head); | 437 | gig_dbg(DEBUG_INTR, "setting head to %u", head); |
448 | atomic_set(&inbuf->head, head); | 438 | atomic_set(&inbuf->head, head); |
449 | } | 439 | } |
450 | } | 440 | } |
@@ -479,14 +469,13 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | |||
479 | stuf_cnt++; | 469 | stuf_cnt++; |
480 | fcs = crc_ccitt_byte(fcs, *cp++); | 470 | fcs = crc_ccitt_byte(fcs, *cp++); |
481 | } | 471 | } |
482 | fcs ^= 0xffff; /* complement */ | 472 | fcs ^= 0xffff; /* complement */ |
483 | 473 | ||
484 | /* size of new buffer: original size + number of stuffing bytes | 474 | /* size of new buffer: original size + number of stuffing bytes |
485 | * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes | 475 | * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes |
486 | */ | 476 | */ |
487 | hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); | 477 | hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); |
488 | if (!hdlc_skb) { | 478 | if (!hdlc_skb) { |
489 | err("unable to allocate memory for HDLC encoding!"); | ||
490 | dev_kfree_skb(skb); | 479 | dev_kfree_skb(skb); |
491 | return NULL; | 480 | return NULL; |
492 | } | 481 | } |
@@ -508,7 +497,7 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | |||
508 | } | 497 | } |
509 | 498 | ||
510 | /* Finally add FCS (byte stuffed) and flag sequence */ | 499 | /* Finally add FCS (byte stuffed) and flag sequence */ |
511 | c = (fcs & 0x00ff); /* least significant byte first */ | 500 | c = (fcs & 0x00ff); /* least significant byte first */ |
512 | if (muststuff(c)) { | 501 | if (muststuff(c)) { |
513 | *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; | 502 | *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; |
514 | c ^= PPP_TRANS; | 503 | c ^= PPP_TRANS; |
@@ -546,7 +535,6 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | |||
546 | /* worst case: every byte must be stuffed */ | 535 | /* worst case: every byte must be stuffed */ |
547 | iraw_skb = dev_alloc_skb(2*skb->len + tail + head); | 536 | iraw_skb = dev_alloc_skb(2*skb->len + tail + head); |
548 | if (!iraw_skb) { | 537 | if (!iraw_skb) { |
549 | err("unable to allocate memory for HDLC encoding!"); | ||
550 | dev_kfree_skb(skb); | 538 | dev_kfree_skb(skb); |
551 | return NULL; | 539 | return NULL; |
552 | } | 540 | } |
@@ -577,21 +565,23 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | |||
577 | */ | 565 | */ |
578 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) | 566 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) |
579 | { | 567 | { |
580 | unsigned len; | 568 | unsigned len = skb->len; |
581 | 569 | unsigned long flags; | |
582 | IFNULLRETVAL(bcs, -EFAULT); | ||
583 | IFNULLRETVAL(skb, -EFAULT); | ||
584 | len = skb->len; | ||
585 | 570 | ||
586 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) | 571 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) |
587 | skb = HDLC_Encode(skb, HW_HDR_LEN, 0); | 572 | skb = HDLC_Encode(skb, HW_HDR_LEN, 0); |
588 | else | 573 | else |
589 | skb = iraw_encode(skb, HW_HDR_LEN, 0); | 574 | skb = iraw_encode(skb, HW_HDR_LEN, 0); |
590 | if (!skb) | 575 | if (!skb) { |
576 | err("unable to allocate memory for encoding!\n"); | ||
591 | return -ENOMEM; | 577 | return -ENOMEM; |
578 | } | ||
592 | 579 | ||
593 | skb_queue_tail(&bcs->squeue, skb); | 580 | skb_queue_tail(&bcs->squeue, skb); |
594 | tasklet_schedule(&bcs->cs->write_tasklet); | 581 | spin_lock_irqsave(&bcs->cs->lock, flags); |
582 | if (bcs->cs->connected) | ||
583 | tasklet_schedule(&bcs->cs->write_tasklet); | ||
584 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
595 | 585 | ||
596 | return len; /* ok so far */ | 586 | return len; /* ok so far */ |
597 | } | 587 | } |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 31f0f07832bc..f86ed6af3aa2 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Hansjoerg Lipp <hjlipp@web.de>, | 4 | * Copyright (c) 2001 by Hansjoerg Lipp <hjlipp@web.de>, |
5 | * Tilman Schmidt <tilman@imap.cc>, | 5 | * Tilman Schmidt <tilman@imap.cc>, |
6 | * Stefan Eilers <Eilers.Stefan@epost.de>. | 6 | * Stefan Eilers. |
7 | * | 7 | * |
8 | * Based on usb-gigaset.c. | 8 | * Based on usb-gigaset.c. |
9 | * | 9 | * |
@@ -13,10 +13,6 @@ | |||
13 | * published by the Free Software Foundation; either version 2 of | 13 | * published by the Free Software Foundation; either version 2 of |
14 | * the License, or (at your option) any later version. | 14 | * the License, or (at your option) any later version. |
15 | * ===================================================================== | 15 | * ===================================================================== |
16 | * ToDo: ... | ||
17 | * ===================================================================== | ||
18 | * Version: $Id: bas-gigaset.c,v 1.52.4.19 2006/02/04 18:28:16 hjlipp Exp $ | ||
19 | * ===================================================================== | ||
20 | */ | 16 | */ |
21 | 17 | ||
22 | #include "gigaset.h" | 18 | #include "gigaset.h" |
@@ -30,7 +26,7 @@ | |||
30 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
31 | 27 | ||
32 | /* Version Information */ | 28 | /* Version Information */ |
33 | #define DRIVER_AUTHOR "Tilman Schmidt <tilman@imap.cc>, Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers <Eilers.Stefan@epost.de>" | 29 | #define DRIVER_AUTHOR "Tilman Schmidt <tilman@imap.cc>, Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers" |
34 | #define DRIVER_DESC "USB Driver for Gigaset 307x" | 30 | #define DRIVER_DESC "USB Driver for Gigaset 307x" |
35 | 31 | ||
36 | 32 | ||
@@ -70,9 +66,6 @@ static struct usb_device_id gigaset_table [] = { | |||
70 | 66 | ||
71 | MODULE_DEVICE_TABLE(usb, gigaset_table); | 67 | MODULE_DEVICE_TABLE(usb, gigaset_table); |
72 | 68 | ||
73 | /* Get a minor range for your devices from the usb maintainer */ | ||
74 | #define USB_SKEL_MINOR_BASE 200 | ||
75 | |||
76 | /*======================= local function prototypes =============================*/ | 69 | /*======================= local function prototypes =============================*/ |
77 | 70 | ||
78 | /* This function is called if a new device is connected to the USB port. It | 71 | /* This function is called if a new device is connected to the USB port. It |
@@ -88,25 +81,25 @@ static void gigaset_disconnect(struct usb_interface *interface); | |||
88 | /*==============================================================================*/ | 81 | /*==============================================================================*/ |
89 | 82 | ||
90 | struct bas_cardstate { | 83 | struct bas_cardstate { |
91 | struct usb_device *udev; /* USB device pointer */ | 84 | struct usb_device *udev; /* USB device pointer */ |
92 | struct usb_interface *interface; /* interface for this device */ | 85 | struct usb_interface *interface; /* interface for this device */ |
93 | unsigned char minor; /* starting minor number */ | 86 | unsigned char minor; /* starting minor number */ |
94 | 87 | ||
95 | struct urb *urb_ctrl; /* control pipe default URB */ | 88 | struct urb *urb_ctrl; /* control pipe default URB */ |
96 | struct usb_ctrlrequest dr_ctrl; | 89 | struct usb_ctrlrequest dr_ctrl; |
97 | struct timer_list timer_ctrl; /* control request timeout */ | 90 | struct timer_list timer_ctrl; /* control request timeout */ |
98 | 91 | ||
99 | struct timer_list timer_atrdy; /* AT command ready timeout */ | 92 | struct timer_list timer_atrdy; /* AT command ready timeout */ |
100 | struct urb *urb_cmd_out; /* for sending AT commands */ | 93 | struct urb *urb_cmd_out; /* for sending AT commands */ |
101 | struct usb_ctrlrequest dr_cmd_out; | 94 | struct usb_ctrlrequest dr_cmd_out; |
102 | int retry_cmd_out; | 95 | int retry_cmd_out; |
103 | 96 | ||
104 | struct urb *urb_cmd_in; /* for receiving AT replies */ | 97 | struct urb *urb_cmd_in; /* for receiving AT replies */ |
105 | struct usb_ctrlrequest dr_cmd_in; | 98 | struct usb_ctrlrequest dr_cmd_in; |
106 | struct timer_list timer_cmd_in; /* receive request timeout */ | 99 | struct timer_list timer_cmd_in; /* receive request timeout */ |
107 | unsigned char *rcvbuf; /* AT reply receive buffer */ | 100 | unsigned char *rcvbuf; /* AT reply receive buffer */ |
108 | 101 | ||
109 | struct urb *urb_int_in; /* URB for interrupt pipe */ | 102 | struct urb *urb_int_in; /* URB for interrupt pipe */ |
110 | unsigned char int_in_buf[3]; | 103 | unsigned char int_in_buf[3]; |
111 | 104 | ||
112 | spinlock_t lock; /* locks all following */ | 105 | spinlock_t lock; /* locks all following */ |
@@ -208,53 +201,54 @@ static inline char *usb_pipetype_str(int pipe) | |||
208 | * write content of URB to syslog for debugging | 201 | * write content of URB to syslog for debugging |
209 | */ | 202 | */ |
210 | static inline void dump_urb(enum debuglevel level, const char *tag, | 203 | static inline void dump_urb(enum debuglevel level, const char *tag, |
211 | struct urb *urb) | 204 | struct urb *urb) |
212 | { | 205 | { |
213 | #ifdef CONFIG_GIGASET_DEBUG | 206 | #ifdef CONFIG_GIGASET_DEBUG |
214 | int i; | 207 | int i; |
215 | IFNULLRET(tag); | 208 | gig_dbg(level, "%s urb(0x%08lx)->{", tag, (unsigned long) urb); |
216 | dbg(level, "%s urb(0x%08lx)->{", tag, (unsigned long) urb); | ||
217 | if (urb) { | 209 | if (urb) { |
218 | dbg(level, | 210 | gig_dbg(level, |
219 | " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " | 211 | " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " |
220 | "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,", | 212 | "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,", |
221 | (unsigned long) urb->dev, | 213 | (unsigned long) urb->dev, |
222 | usb_pipetype_str(urb->pipe), | 214 | usb_pipetype_str(urb->pipe), |
223 | usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), | 215 | usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), |
224 | usb_pipein(urb->pipe) ? "in" : "out", | 216 | usb_pipein(urb->pipe) ? "in" : "out", |
225 | urb->status, (unsigned long) urb->hcpriv, | 217 | urb->status, (unsigned long) urb->hcpriv, |
226 | urb->transfer_flags); | 218 | urb->transfer_flags); |
227 | dbg(level, | 219 | gig_dbg(level, |
228 | " transfer_buffer=0x%08lx[%d], actual_length=%d, " | 220 | " transfer_buffer=0x%08lx[%d], actual_length=%d, " |
229 | "bandwidth=%d, setup_packet=0x%08lx,", | 221 | "bandwidth=%d, setup_packet=0x%08lx,", |
230 | (unsigned long) urb->transfer_buffer, | 222 | (unsigned long) urb->transfer_buffer, |
231 | urb->transfer_buffer_length, urb->actual_length, | 223 | urb->transfer_buffer_length, urb->actual_length, |
232 | urb->bandwidth, (unsigned long) urb->setup_packet); | 224 | urb->bandwidth, (unsigned long) urb->setup_packet); |
233 | dbg(level, | 225 | gig_dbg(level, |
234 | " start_frame=%d, number_of_packets=%d, interval=%d, " | 226 | " start_frame=%d, number_of_packets=%d, interval=%d, " |
235 | "error_count=%d,", | 227 | "error_count=%d,", |
236 | urb->start_frame, urb->number_of_packets, urb->interval, | 228 | urb->start_frame, urb->number_of_packets, urb->interval, |
237 | urb->error_count); | 229 | urb->error_count); |
238 | dbg(level, | 230 | gig_dbg(level, |
239 | " context=0x%08lx, complete=0x%08lx, iso_frame_desc[]={", | 231 | " context=0x%08lx, complete=0x%08lx, " |
240 | (unsigned long) urb->context, | 232 | "iso_frame_desc[]={", |
241 | (unsigned long) urb->complete); | 233 | (unsigned long) urb->context, |
234 | (unsigned long) urb->complete); | ||
242 | for (i = 0; i < urb->number_of_packets; i++) { | 235 | for (i = 0; i < urb->number_of_packets; i++) { |
243 | struct usb_iso_packet_descriptor *pifd = &urb->iso_frame_desc[i]; | 236 | struct usb_iso_packet_descriptor *pifd |
244 | dbg(level, | 237 | = &urb->iso_frame_desc[i]; |
245 | " {offset=%u, length=%u, actual_length=%u, " | 238 | gig_dbg(level, |
246 | "status=%u}", | 239 | " {offset=%u, length=%u, actual_length=%u, " |
247 | pifd->offset, pifd->length, pifd->actual_length, | 240 | "status=%u}", |
248 | pifd->status); | 241 | pifd->offset, pifd->length, pifd->actual_length, |
242 | pifd->status); | ||
249 | } | 243 | } |
250 | } | 244 | } |
251 | dbg(level, "}}"); | 245 | gig_dbg(level, "}}"); |
252 | #endif | 246 | #endif |
253 | } | 247 | } |
254 | 248 | ||
255 | /* read/set modem control bits etc. (m10x only) */ | 249 | /* read/set modem control bits etc. (m10x only) */ |
256 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 250 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
257 | unsigned new_state) | 251 | unsigned new_state) |
258 | { | 252 | { |
259 | return -EINVAL; | 253 | return -EINVAL; |
260 | } | 254 | } |
@@ -280,8 +274,8 @@ static inline void error_hangup(struct bc_state *bcs) | |||
280 | { | 274 | { |
281 | struct cardstate *cs = bcs->cs; | 275 | struct cardstate *cs = bcs->cs; |
282 | 276 | ||
283 | dbg(DEBUG_ANY, | 277 | gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", |
284 | "%s: scheduling HUP for channel %d", __func__, bcs->channel); | 278 | __func__, bcs->channel); |
285 | 279 | ||
286 | if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { | 280 | if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { |
287 | //FIXME what should we do? | 281 | //FIXME what should we do? |
@@ -301,22 +295,19 @@ static inline void error_hangup(struct bc_state *bcs) | |||
301 | static inline void error_reset(struct cardstate *cs) | 295 | static inline void error_reset(struct cardstate *cs) |
302 | { | 296 | { |
303 | //FIXME try to recover without bothering the user | 297 | //FIXME try to recover without bothering the user |
304 | err("unrecoverable error - please disconnect the Gigaset base to reset"); | 298 | dev_err(cs->dev, |
299 | "unrecoverable error - please disconnect Gigaset base to reset\n"); | ||
305 | } | 300 | } |
306 | 301 | ||
307 | /* check_pending | 302 | /* check_pending |
308 | * check for completion of pending control request | 303 | * check for completion of pending control request |
309 | * parameter: | 304 | * parameter: |
310 | * urb USB request block of completed request | 305 | * ucs hardware specific controller state structure |
311 | * urb->context = hardware specific controller state structure | ||
312 | */ | 306 | */ |
313 | static void check_pending(struct bas_cardstate *ucs) | 307 | static void check_pending(struct bas_cardstate *ucs) |
314 | { | 308 | { |
315 | unsigned long flags; | 309 | unsigned long flags; |
316 | 310 | ||
317 | IFNULLRET(ucs); | ||
318 | IFNULLRET(cardstate); | ||
319 | |||
320 | spin_lock_irqsave(&ucs->lock, flags); | 311 | spin_lock_irqsave(&ucs->lock, flags); |
321 | switch (ucs->pending) { | 312 | switch (ucs->pending) { |
322 | case 0: | 313 | case 0: |
@@ -336,8 +327,6 @@ static void check_pending(struct bas_cardstate *ucs) | |||
336 | case HD_CLOSE_ATCHANNEL: | 327 | case HD_CLOSE_ATCHANNEL: |
337 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) | 328 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) |
338 | ucs->pending = 0; | 329 | ucs->pending = 0; |
339 | //wake_up_interruptible(cs->initwait); | ||
340 | //FIXME need own wait queue? | ||
341 | break; | 330 | break; |
342 | case HD_CLOSE_B1CHANNEL: | 331 | case HD_CLOSE_B1CHANNEL: |
343 | if (!(atomic_read(&ucs->basstate) & BS_B1OPEN)) | 332 | if (!(atomic_read(&ucs->basstate) & BS_B1OPEN)) |
@@ -354,7 +343,9 @@ static void check_pending(struct bas_cardstate *ucs) | |||
354 | * are handled separately and should never end up here | 343 | * are handled separately and should never end up here |
355 | */ | 344 | */ |
356 | default: | 345 | default: |
357 | warn("unknown pending request 0x%02x cleared", ucs->pending); | 346 | dev_warn(&ucs->interface->dev, |
347 | "unknown pending request 0x%02x cleared\n", | ||
348 | ucs->pending); | ||
358 | ucs->pending = 0; | 349 | ucs->pending = 0; |
359 | } | 350 | } |
360 | 351 | ||
@@ -372,27 +363,23 @@ static void check_pending(struct bas_cardstate *ucs) | |||
372 | static void cmd_in_timeout(unsigned long data) | 363 | static void cmd_in_timeout(unsigned long data) |
373 | { | 364 | { |
374 | struct cardstate *cs = (struct cardstate *) data; | 365 | struct cardstate *cs = (struct cardstate *) data; |
375 | struct bas_cardstate *ucs; | 366 | struct bas_cardstate *ucs = cs->hw.bas; |
376 | unsigned long flags; | 367 | unsigned long flags; |
377 | 368 | ||
378 | IFNULLRET(cs); | ||
379 | ucs = cs->hw.bas; | ||
380 | IFNULLRET(ucs); | ||
381 | |||
382 | spin_lock_irqsave(&cs->lock, flags); | 369 | spin_lock_irqsave(&cs->lock, flags); |
383 | if (!atomic_read(&cs->connected)) { | 370 | if (unlikely(!cs->connected)) { |
384 | dbg(DEBUG_USBREQ, "%s: disconnected", __func__); | 371 | gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__); |
385 | spin_unlock_irqrestore(&cs->lock, flags); | 372 | spin_unlock_irqrestore(&cs->lock, flags); |
386 | return; | 373 | return; |
387 | } | 374 | } |
388 | if (!ucs->rcvbuf_size) { | 375 | if (!ucs->rcvbuf_size) { |
389 | dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); | 376 | gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); |
390 | spin_unlock_irqrestore(&cs->lock, flags); | 377 | spin_unlock_irqrestore(&cs->lock, flags); |
391 | return; | 378 | return; |
392 | } | 379 | } |
393 | spin_unlock_irqrestore(&cs->lock, flags); | 380 | spin_unlock_irqrestore(&cs->lock, flags); |
394 | 381 | ||
395 | err("timeout reading AT response"); | 382 | dev_err(cs->dev, "timeout reading AT response\n"); |
396 | error_reset(cs); //FIXME retry? | 383 | error_reset(cs); //FIXME retry? |
397 | } | 384 | } |
398 | 385 | ||
@@ -412,18 +399,15 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs); | |||
412 | */ | 399 | */ |
413 | static int atread_submit(struct cardstate *cs, int timeout) | 400 | static int atread_submit(struct cardstate *cs, int timeout) |
414 | { | 401 | { |
415 | struct bas_cardstate *ucs; | 402 | struct bas_cardstate *ucs = cs->hw.bas; |
416 | int ret; | 403 | int ret; |
417 | 404 | ||
418 | IFNULLRETVAL(cs, -EINVAL); | 405 | gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", |
419 | ucs = cs->hw.bas; | 406 | ucs->rcvbuf_size); |
420 | IFNULLRETVAL(ucs, -EINVAL); | ||
421 | IFNULLRETVAL(ucs->urb_cmd_in, -EINVAL); | ||
422 | |||
423 | dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", ucs->rcvbuf_size); | ||
424 | 407 | ||
425 | if (ucs->urb_cmd_in->status == -EINPROGRESS) { | 408 | if (ucs->urb_cmd_in->status == -EINPROGRESS) { |
426 | err("could not submit HD_READ_ATMESSAGE: URB busy"); | 409 | dev_err(cs->dev, |
410 | "could not submit HD_READ_ATMESSAGE: URB busy\n"); | ||
427 | return -EBUSY; | 411 | return -EBUSY; |
428 | } | 412 | } |
429 | 413 | ||
@@ -433,19 +417,19 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
433 | ucs->dr_cmd_in.wIndex = 0; | 417 | ucs->dr_cmd_in.wIndex = 0; |
434 | ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); | 418 | ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); |
435 | usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, | 419 | usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, |
436 | usb_rcvctrlpipe(ucs->udev, 0), | 420 | usb_rcvctrlpipe(ucs->udev, 0), |
437 | (unsigned char*) & ucs->dr_cmd_in, | 421 | (unsigned char*) & ucs->dr_cmd_in, |
438 | ucs->rcvbuf, ucs->rcvbuf_size, | 422 | ucs->rcvbuf, ucs->rcvbuf_size, |
439 | read_ctrl_callback, cs->inbuf); | 423 | read_ctrl_callback, cs->inbuf); |
440 | 424 | ||
441 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { | 425 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { |
442 | err("could not submit HD_READ_ATMESSAGE: %s", | 426 | dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", |
443 | get_usb_statmsg(ret)); | 427 | get_usb_statmsg(ret)); |
444 | return ret; | 428 | return ret; |
445 | } | 429 | } |
446 | 430 | ||
447 | if (timeout > 0) { | 431 | if (timeout > 0) { |
448 | dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); | 432 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); |
449 | ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; | 433 | ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; |
450 | ucs->timer_cmd_in.data = (unsigned long) cs; | 434 | ucs->timer_cmd_in.data = (unsigned long) cs; |
451 | ucs->timer_cmd_in.function = cmd_in_timeout; | 435 | ucs->timer_cmd_in.function = cmd_in_timeout; |
@@ -483,25 +467,14 @@ inline static void update_basstate(struct bas_cardstate *ucs, | |||
483 | */ | 467 | */ |
484 | static void read_int_callback(struct urb *urb, struct pt_regs *regs) | 468 | static void read_int_callback(struct urb *urb, struct pt_regs *regs) |
485 | { | 469 | { |
486 | struct cardstate *cs; | 470 | struct cardstate *cs = urb->context; |
487 | struct bas_cardstate *ucs; | 471 | struct bas_cardstate *ucs = cs->hw.bas; |
488 | struct bc_state *bcs; | 472 | struct bc_state *bcs; |
489 | unsigned long flags; | 473 | unsigned long flags; |
490 | int status; | 474 | int status; |
491 | unsigned l; | 475 | unsigned l; |
492 | int channel; | 476 | int channel; |
493 | 477 | ||
494 | IFNULLRET(urb); | ||
495 | cs = (struct cardstate *) urb->context; | ||
496 | IFNULLRET(cs); | ||
497 | ucs = cs->hw.bas; | ||
498 | IFNULLRET(ucs); | ||
499 | |||
500 | if (unlikely(!atomic_read(&cs->connected))) { | ||
501 | warn("%s: disconnected", __func__); | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | switch (urb->status) { | 478 | switch (urb->status) { |
506 | case 0: /* success */ | 479 | case 0: /* success */ |
507 | break; | 480 | break; |
@@ -509,11 +482,12 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
509 | case -ECONNRESET: /* canceled (async) */ | 482 | case -ECONNRESET: /* canceled (async) */ |
510 | case -EINPROGRESS: /* pending */ | 483 | case -EINPROGRESS: /* pending */ |
511 | /* ignore silently */ | 484 | /* ignore silently */ |
512 | dbg(DEBUG_USBREQ, | 485 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
513 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 486 | __func__, get_usb_statmsg(urb->status)); |
514 | return; | 487 | return; |
515 | default: /* severe trouble */ | 488 | default: /* severe trouble */ |
516 | warn("interrupt read: %s", get_usb_statmsg(urb->status)); | 489 | dev_warn(cs->dev, "interrupt read: %s\n", |
490 | get_usb_statmsg(urb->status)); | ||
517 | //FIXME corrective action? resubmission always ok? | 491 | //FIXME corrective action? resubmission always ok? |
518 | goto resubmit; | 492 | goto resubmit; |
519 | } | 493 | } |
@@ -521,10 +495,9 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
521 | l = (unsigned) ucs->int_in_buf[1] + | 495 | l = (unsigned) ucs->int_in_buf[1] + |
522 | (((unsigned) ucs->int_in_buf[2]) << 8); | 496 | (((unsigned) ucs->int_in_buf[2]) << 8); |
523 | 497 | ||
524 | dbg(DEBUG_USBREQ, | 498 | gig_dbg(DEBUG_USBREQ, "<-------%d: 0x%02x (%u [0x%02x 0x%02x])", |
525 | "<-------%d: 0x%02x (%u [0x%02x 0x%02x])", urb->actual_length, | 499 | urb->actual_length, (int)ucs->int_in_buf[0], l, |
526 | (int)ucs->int_in_buf[0], l, | 500 | (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]); |
527 | (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]); | ||
528 | 501 | ||
529 | channel = 0; | 502 | channel = 0; |
530 | 503 | ||
@@ -570,28 +543,30 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
570 | case HD_B1_FLOW_CONTROL: | 543 | case HD_B1_FLOW_CONTROL: |
571 | bcs = cs->bcs + channel; | 544 | bcs = cs->bcs + channel; |
572 | atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES, | 545 | atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES, |
573 | &bcs->hw.bas->corrbytes); | 546 | &bcs->hw.bas->corrbytes); |
574 | dbg(DEBUG_ISO, | 547 | gig_dbg(DEBUG_ISO, |
575 | "Flow control (channel %d, sub %d): 0x%02x => %d", | 548 | "Flow control (channel %d, sub %d): 0x%02x => %d", |
576 | channel, bcs->hw.bas->numsub, l, | 549 | channel, bcs->hw.bas->numsub, l, |
577 | atomic_read(&bcs->hw.bas->corrbytes)); | 550 | atomic_read(&bcs->hw.bas->corrbytes)); |
578 | break; | 551 | break; |
579 | 552 | ||
580 | case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */ | 553 | case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */ |
581 | if (!l) { | 554 | if (!l) { |
582 | warn("HD_RECEIVEATDATA_ACK with length 0 ignored"); | 555 | dev_warn(cs->dev, |
556 | "HD_RECEIVEATDATA_ACK with length 0 ignored\n"); | ||
583 | break; | 557 | break; |
584 | } | 558 | } |
585 | spin_lock_irqsave(&cs->lock, flags); | 559 | spin_lock_irqsave(&cs->lock, flags); |
586 | if (ucs->rcvbuf_size) { | 560 | if (ucs->rcvbuf_size) { |
587 | spin_unlock_irqrestore(&cs->lock, flags); | 561 | spin_unlock_irqrestore(&cs->lock, flags); |
588 | err("receive AT data overrun, %d bytes lost", l); | 562 | dev_err(cs->dev, |
563 | "receive AT data overrun, %d bytes lost\n", l); | ||
589 | error_reset(cs); //FIXME reschedule | 564 | error_reset(cs); //FIXME reschedule |
590 | break; | 565 | break; |
591 | } | 566 | } |
592 | if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { | 567 | if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { |
593 | spin_unlock_irqrestore(&cs->lock, flags); | 568 | spin_unlock_irqrestore(&cs->lock, flags); |
594 | err("%s: out of memory, %d bytes lost", __func__, l); | 569 | dev_err(cs->dev, "out of memory, %d bytes lost\n", l); |
595 | error_reset(cs); //FIXME reschedule | 570 | error_reset(cs); //FIXME reschedule |
596 | break; | 571 | break; |
597 | } | 572 | } |
@@ -607,25 +582,28 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
607 | break; | 582 | break; |
608 | 583 | ||
609 | case HD_RESET_INTERRUPT_PIPE_ACK: | 584 | case HD_RESET_INTERRUPT_PIPE_ACK: |
610 | dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); | 585 | gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); |
611 | break; | 586 | break; |
612 | 587 | ||
613 | case HD_SUSPEND_END: | 588 | case HD_SUSPEND_END: |
614 | dbg(DEBUG_USBREQ, "HD_SUSPEND_END"); | 589 | gig_dbg(DEBUG_USBREQ, "HD_SUSPEND_END"); |
615 | break; | 590 | break; |
616 | 591 | ||
617 | default: | 592 | default: |
618 | warn("unknown Gigaset signal 0x%02x (%u) ignored", | 593 | dev_warn(cs->dev, |
619 | (int) ucs->int_in_buf[0], l); | 594 | "unknown Gigaset signal 0x%02x (%u) ignored\n", |
595 | (int) ucs->int_in_buf[0], l); | ||
620 | } | 596 | } |
621 | 597 | ||
622 | check_pending(ucs); | 598 | check_pending(ucs); |
623 | 599 | ||
624 | resubmit: | 600 | resubmit: |
625 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 601 | spin_lock_irqsave(&cs->lock, flags); |
602 | status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
603 | spin_unlock_irqrestore(&cs->lock, flags); | ||
626 | if (unlikely(status)) { | 604 | if (unlikely(status)) { |
627 | err("could not resubmit interrupt URB: %s", | 605 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", |
628 | get_usb_statmsg(status)); | 606 | get_usb_statmsg(status)); |
629 | error_reset(cs); | 607 | error_reset(cs); |
630 | } | 608 | } |
631 | } | 609 | } |
@@ -639,30 +617,22 @@ resubmit: | |||
639 | */ | 617 | */ |
640 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | 618 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) |
641 | { | 619 | { |
642 | struct cardstate *cs; | 620 | struct inbuf_t *inbuf = urb->context; |
643 | struct bas_cardstate *ucs; | 621 | struct cardstate *cs = inbuf->cs; |
622 | struct bas_cardstate *ucs = cs->hw.bas; | ||
623 | int have_data = 0; | ||
644 | unsigned numbytes; | 624 | unsigned numbytes; |
645 | unsigned long flags; | 625 | unsigned long flags; |
646 | struct inbuf_t *inbuf; | ||
647 | int have_data = 0; | ||
648 | |||
649 | IFNULLRET(urb); | ||
650 | inbuf = (struct inbuf_t *) urb->context; | ||
651 | IFNULLRET(inbuf); | ||
652 | cs = inbuf->cs; | ||
653 | IFNULLRET(cs); | ||
654 | ucs = cs->hw.bas; | ||
655 | IFNULLRET(ucs); | ||
656 | 626 | ||
657 | spin_lock_irqsave(&cs->lock, flags); | 627 | spin_lock_irqsave(&cs->lock, flags); |
658 | if (!atomic_read(&cs->connected)) { | 628 | if (unlikely(!cs->connected)) { |
659 | warn("%s: disconnected", __func__); | 629 | warn("%s: disconnected", __func__); |
660 | spin_unlock_irqrestore(&cs->lock, flags); | 630 | spin_unlock_irqrestore(&cs->lock, flags); |
661 | return; | 631 | return; |
662 | } | 632 | } |
663 | 633 | ||
664 | if (!ucs->rcvbuf_size) { | 634 | if (!ucs->rcvbuf_size) { |
665 | warn("%s: no receive in progress", __func__); | 635 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); |
666 | spin_unlock_irqrestore(&cs->lock, flags); | 636 | spin_unlock_irqrestore(&cs->lock, flags); |
667 | return; | 637 | return; |
668 | } | 638 | } |
@@ -673,12 +643,14 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
673 | case 0: /* normal completion */ | 643 | case 0: /* normal completion */ |
674 | numbytes = urb->actual_length; | 644 | numbytes = urb->actual_length; |
675 | if (unlikely(numbytes == 0)) { | 645 | if (unlikely(numbytes == 0)) { |
676 | warn("control read: empty block received"); | 646 | dev_warn(cs->dev, |
647 | "control read: empty block received\n"); | ||
677 | goto retry; | 648 | goto retry; |
678 | } | 649 | } |
679 | if (unlikely(numbytes != ucs->rcvbuf_size)) { | 650 | if (unlikely(numbytes != ucs->rcvbuf_size)) { |
680 | warn("control read: received %d chars, expected %d", | 651 | dev_warn(cs->dev, |
681 | numbytes, ucs->rcvbuf_size); | 652 | "control read: received %d chars, expected %d\n", |
653 | numbytes, ucs->rcvbuf_size); | ||
682 | if (numbytes > ucs->rcvbuf_size) | 654 | if (numbytes > ucs->rcvbuf_size) |
683 | numbytes = ucs->rcvbuf_size; | 655 | numbytes = ucs->rcvbuf_size; |
684 | } | 656 | } |
@@ -698,23 +670,26 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
698 | case -ECONNRESET: /* canceled (async) */ | 670 | case -ECONNRESET: /* canceled (async) */ |
699 | case -EINPROGRESS: /* pending */ | 671 | case -EINPROGRESS: /* pending */ |
700 | /* no action necessary */ | 672 | /* no action necessary */ |
701 | dbg(DEBUG_USBREQ, | 673 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
702 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 674 | __func__, get_usb_statmsg(urb->status)); |
703 | break; | 675 | break; |
704 | 676 | ||
705 | default: /* severe trouble */ | 677 | default: /* severe trouble */ |
706 | warn("control read: %s", get_usb_statmsg(urb->status)); | 678 | dev_warn(cs->dev, "control read: %s\n", |
679 | get_usb_statmsg(urb->status)); | ||
707 | retry: | 680 | retry: |
708 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | 681 | if (ucs->retry_cmd_in++ < BAS_RETRY) { |
709 | notice("control read: retry %d", ucs->retry_cmd_in); | 682 | dev_notice(cs->dev, "control read: retry %d\n", |
683 | ucs->retry_cmd_in); | ||
710 | if (atread_submit(cs, BAS_TIMEOUT) >= 0) { | 684 | if (atread_submit(cs, BAS_TIMEOUT) >= 0) { |
711 | /* resubmitted - bypass regular exit block */ | 685 | /* resubmitted - bypass regular exit block */ |
712 | spin_unlock_irqrestore(&cs->lock, flags); | 686 | spin_unlock_irqrestore(&cs->lock, flags); |
713 | return; | 687 | return; |
714 | } | 688 | } |
715 | } else { | 689 | } else { |
716 | err("control read: giving up after %d tries", | 690 | dev_err(cs->dev, |
717 | ucs->retry_cmd_in); | 691 | "control read: giving up after %d tries\n", |
692 | ucs->retry_cmd_in); | ||
718 | } | 693 | } |
719 | error_reset(cs); | 694 | error_reset(cs); |
720 | } | 695 | } |
@@ -724,7 +699,7 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
724 | ucs->rcvbuf_size = 0; | 699 | ucs->rcvbuf_size = 0; |
725 | spin_unlock_irqrestore(&cs->lock, flags); | 700 | spin_unlock_irqrestore(&cs->lock, flags); |
726 | if (have_data) { | 701 | if (have_data) { |
727 | dbg(DEBUG_INTR, "%s-->BH", __func__); | 702 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
728 | gigaset_schedule_event(cs); | 703 | gigaset_schedule_event(cs); |
729 | } | 704 | } |
730 | } | 705 | } |
@@ -743,21 +718,16 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
743 | unsigned long flags; | 718 | unsigned long flags; |
744 | int i, rc; | 719 | int i, rc; |
745 | 720 | ||
746 | IFNULLRET(urb); | ||
747 | IFNULLRET(urb->context); | ||
748 | IFNULLRET(cardstate); | ||
749 | |||
750 | /* status codes not worth bothering the tasklet with */ | 721 | /* status codes not worth bothering the tasklet with */ |
751 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || | 722 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || |
752 | urb->status == -EINPROGRESS)) { | 723 | urb->status == -EINPROGRESS)) { |
753 | dbg(DEBUG_ISO, | 724 | gig_dbg(DEBUG_ISO, "%s: %s", |
754 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 725 | __func__, get_usb_statmsg(urb->status)); |
755 | return; | 726 | return; |
756 | } | 727 | } |
757 | 728 | ||
758 | bcs = (struct bc_state *) urb->context; | 729 | bcs = urb->context; |
759 | ubc = bcs->hw.bas; | 730 | ubc = bcs->hw.bas; |
760 | IFNULLRET(ubc); | ||
761 | 731 | ||
762 | spin_lock_irqsave(&ubc->isoinlock, flags); | 732 | spin_lock_irqsave(&ubc->isoinlock, flags); |
763 | if (likely(ubc->isoindone == NULL)) { | 733 | if (likely(ubc->isoindone == NULL)) { |
@@ -777,14 +747,17 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
777 | urb->iso_frame_desc[i].actual_length = 0; | 747 | urb->iso_frame_desc[i].actual_length = 0; |
778 | } | 748 | } |
779 | if (likely(atomic_read(&ubc->running))) { | 749 | if (likely(atomic_read(&ubc->running))) { |
780 | urb->dev = bcs->cs->hw.bas->udev; /* clobbered by USB subsystem */ | 750 | /* urb->dev is clobbered by USB subsystem */ |
751 | urb->dev = bcs->cs->hw.bas->udev; | ||
781 | urb->transfer_flags = URB_ISO_ASAP; | 752 | urb->transfer_flags = URB_ISO_ASAP; |
782 | urb->number_of_packets = BAS_NUMFRAMES; | 753 | urb->number_of_packets = BAS_NUMFRAMES; |
783 | dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", __func__); | 754 | gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", |
755 | __func__); | ||
784 | rc = usb_submit_urb(urb, SLAB_ATOMIC); | 756 | rc = usb_submit_urb(urb, SLAB_ATOMIC); |
785 | if (unlikely(rc != 0)) { | 757 | if (unlikely(rc != 0)) { |
786 | err("could not resubmit isochronous read URB: %s", | 758 | dev_err(bcs->cs->dev, |
787 | get_usb_statmsg(rc)); | 759 | "could not resubmit isochronous read " |
760 | "URB: %s\n", get_usb_statmsg(rc)); | ||
788 | dump_urb(DEBUG_ISO, "isoc read", urb); | 761 | dump_urb(DEBUG_ISO, "isoc read", urb); |
789 | error_hangup(bcs); | 762 | error_hangup(bcs); |
790 | } | 763 | } |
@@ -806,23 +779,17 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
806 | struct bas_bc_state *ubc; | 779 | struct bas_bc_state *ubc; |
807 | unsigned long flags; | 780 | unsigned long flags; |
808 | 781 | ||
809 | IFNULLRET(urb); | ||
810 | IFNULLRET(urb->context); | ||
811 | IFNULLRET(cardstate); | ||
812 | |||
813 | /* status codes not worth bothering the tasklet with */ | 782 | /* status codes not worth bothering the tasklet with */ |
814 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || | 783 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || |
815 | urb->status == -EINPROGRESS)) { | 784 | urb->status == -EINPROGRESS)) { |
816 | dbg(DEBUG_ISO, | 785 | gig_dbg(DEBUG_ISO, "%s: %s", |
817 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 786 | __func__, get_usb_statmsg(urb->status)); |
818 | return; | 787 | return; |
819 | } | 788 | } |
820 | 789 | ||
821 | /* pass URB context to tasklet */ | 790 | /* pass URB context to tasklet */ |
822 | ucx = (struct isow_urbctx_t *) urb->context; | 791 | ucx = urb->context; |
823 | IFNULLRET(ucx->bcs); | ||
824 | ubc = ucx->bcs->hw.bas; | 792 | ubc = ucx->bcs->hw.bas; |
825 | IFNULLRET(ubc); | ||
826 | 793 | ||
827 | spin_lock_irqsave(&ubc->isooutlock, flags); | 794 | spin_lock_irqsave(&ubc->isooutlock, flags); |
828 | ubc->isooutovfl = ubc->isooutdone; | 795 | ubc->isooutovfl = ubc->isooutdone; |
@@ -841,15 +808,11 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
841 | */ | 808 | */ |
842 | static int starturbs(struct bc_state *bcs) | 809 | static int starturbs(struct bc_state *bcs) |
843 | { | 810 | { |
811 | struct bas_bc_state *ubc = bcs->hw.bas; | ||
844 | struct urb *urb; | 812 | struct urb *urb; |
845 | struct bas_bc_state *ubc; | ||
846 | int j, k; | 813 | int j, k; |
847 | int rc; | 814 | int rc; |
848 | 815 | ||
849 | IFNULLRETVAL(bcs, -EFAULT); | ||
850 | ubc = bcs->hw.bas; | ||
851 | IFNULLRETVAL(ubc, -EFAULT); | ||
852 | |||
853 | /* initialize L2 reception */ | 816 | /* initialize L2 reception */ |
854 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) | 817 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) |
855 | bcs->inputstate |= INS_flag_hunt; | 818 | bcs->inputstate |= INS_flag_hunt; |
@@ -859,7 +822,7 @@ static int starturbs(struct bc_state *bcs) | |||
859 | for (k = 0; k < BAS_INURBS; k++) { | 822 | for (k = 0; k < BAS_INURBS; k++) { |
860 | urb = ubc->isoinurbs[k]; | 823 | urb = ubc->isoinurbs[k]; |
861 | if (!urb) { | 824 | if (!urb) { |
862 | err("isoinurbs[%d]==NULL", k); | 825 | dev_err(bcs->cs->dev, "isoinurbs[%d]==NULL\n", k); |
863 | rc = -EFAULT; | 826 | rc = -EFAULT; |
864 | goto error; | 827 | goto error; |
865 | } | 828 | } |
@@ -882,8 +845,9 @@ static int starturbs(struct bc_state *bcs) | |||
882 | 845 | ||
883 | dump_urb(DEBUG_ISO, "Initial isoc read", urb); | 846 | dump_urb(DEBUG_ISO, "Initial isoc read", urb); |
884 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 847 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { |
885 | err("could not submit isochronous read URB %d: %s", | 848 | dev_err(bcs->cs->dev, |
886 | k, get_usb_statmsg(rc)); | 849 | "could not submit isochronous read URB %d: %s\n", |
850 | k, get_usb_statmsg(rc)); | ||
887 | goto error; | 851 | goto error; |
888 | } | 852 | } |
889 | } | 853 | } |
@@ -895,7 +859,7 @@ static int starturbs(struct bc_state *bcs) | |||
895 | for (k = 0; k < BAS_OUTURBS; ++k) { | 859 | for (k = 0; k < BAS_OUTURBS; ++k) { |
896 | urb = ubc->isoouturbs[k].urb; | 860 | urb = ubc->isoouturbs[k].urb; |
897 | if (!urb) { | 861 | if (!urb) { |
898 | err("isoouturbs[%d].urb==NULL", k); | 862 | dev_err(bcs->cs->dev, "isoouturbs[%d].urb==NULL\n", k); |
899 | rc = -EFAULT; | 863 | rc = -EFAULT; |
900 | goto error; | 864 | goto error; |
901 | } | 865 | } |
@@ -922,8 +886,9 @@ static int starturbs(struct bc_state *bcs) | |||
922 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); | 886 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); |
923 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); | 887 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); |
924 | if (rc != 0) { | 888 | if (rc != 0) { |
925 | err("could not submit isochronous write URB %d: %s", | 889 | dev_err(bcs->cs->dev, |
926 | k, get_usb_statmsg(rc)); | 890 | "could not submit isochronous write URB %d: %s\n", |
891 | k, get_usb_statmsg(rc)); | ||
927 | goto error; | 892 | goto error; |
928 | } | 893 | } |
929 | } | 894 | } |
@@ -946,20 +911,20 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
946 | { | 911 | { |
947 | int k, rc; | 912 | int k, rc; |
948 | 913 | ||
949 | IFNULLRET(ubc); | ||
950 | |||
951 | atomic_set(&ubc->running, 0); | 914 | atomic_set(&ubc->running, 0); |
952 | 915 | ||
953 | for (k = 0; k < BAS_INURBS; ++k) { | 916 | for (k = 0; k < BAS_INURBS; ++k) { |
954 | rc = usb_unlink_urb(ubc->isoinurbs[k]); | 917 | rc = usb_unlink_urb(ubc->isoinurbs[k]); |
955 | dbg(DEBUG_ISO, "%s: isoc input URB %d unlinked, result = %d", | 918 | gig_dbg(DEBUG_ISO, |
956 | __func__, k, rc); | 919 | "%s: isoc input URB %d unlinked, result = %d", |
920 | __func__, k, rc); | ||
957 | } | 921 | } |
958 | 922 | ||
959 | for (k = 0; k < BAS_OUTURBS; ++k) { | 923 | for (k = 0; k < BAS_OUTURBS; ++k) { |
960 | rc = usb_unlink_urb(ubc->isoouturbs[k].urb); | 924 | rc = usb_unlink_urb(ubc->isoouturbs[k].urb); |
961 | dbg(DEBUG_ISO, "%s: isoc output URB %d unlinked, result = %d", | 925 | gig_dbg(DEBUG_ISO, |
962 | __func__, k, rc); | 926 | "%s: isoc output URB %d unlinked, result = %d", |
927 | __func__, k, rc); | ||
963 | } | 928 | } |
964 | } | 929 | } |
965 | 930 | ||
@@ -977,19 +942,14 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
977 | */ | 942 | */ |
978 | static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | 943 | static int submit_iso_write_urb(struct isow_urbctx_t *ucx) |
979 | { | 944 | { |
980 | struct urb *urb; | 945 | struct urb *urb = ucx->urb; |
981 | struct bas_bc_state *ubc; | 946 | struct bas_bc_state *ubc = ucx->bcs->hw.bas; |
982 | struct usb_iso_packet_descriptor *ifd; | 947 | struct usb_iso_packet_descriptor *ifd; |
983 | int corrbytes, nframe, rc; | 948 | int corrbytes, nframe, rc; |
949 | unsigned long flags; | ||
984 | 950 | ||
985 | IFNULLRETVAL(ucx, -EFAULT); | 951 | /* urb->dev is clobbered by USB subsystem */ |
986 | urb = ucx->urb; | 952 | urb->dev = ucx->bcs->cs->hw.bas->udev; |
987 | IFNULLRETVAL(urb, -EFAULT); | ||
988 | IFNULLRETVAL(ucx->bcs, -EFAULT); | ||
989 | ubc = ucx->bcs->hw.bas; | ||
990 | IFNULLRETVAL(ubc, -EFAULT); | ||
991 | |||
992 | urb->dev = ucx->bcs->cs->hw.bas->udev; /* clobbered by USB subsystem */ | ||
993 | urb->transfer_flags = URB_ISO_ASAP; | 953 | urb->transfer_flags = URB_ISO_ASAP; |
994 | urb->transfer_buffer = ubc->isooutbuf->data; | 954 | urb->transfer_buffer = ubc->isooutbuf->data; |
995 | urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); | 955 | urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); |
@@ -1000,7 +960,8 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1000 | /* compute frame length according to flow control */ | 960 | /* compute frame length according to flow control */ |
1001 | ifd->length = BAS_NORMFRAME; | 961 | ifd->length = BAS_NORMFRAME; |
1002 | if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { | 962 | if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { |
1003 | dbg(DEBUG_ISO, "%s: corrbytes=%d", __func__, corrbytes); | 963 | gig_dbg(DEBUG_ISO, "%s: corrbytes=%d", |
964 | __func__, corrbytes); | ||
1004 | if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) | 965 | if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) |
1005 | corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME; | 966 | corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME; |
1006 | else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME) | 967 | else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME) |
@@ -1008,18 +969,21 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1008 | ifd->length += corrbytes; | 969 | ifd->length += corrbytes; |
1009 | atomic_add(-corrbytes, &ubc->corrbytes); | 970 | atomic_add(-corrbytes, &ubc->corrbytes); |
1010 | } | 971 | } |
1011 | //dbg(DEBUG_ISO, "%s: frame %d length=%d", __func__, nframe, ifd->length); | ||
1012 | 972 | ||
1013 | /* retrieve block of data to send */ | 973 | /* retrieve block of data to send */ |
1014 | ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, ifd->length); | 974 | ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, |
975 | ifd->length); | ||
1015 | if (ifd->offset < 0) { | 976 | if (ifd->offset < 0) { |
1016 | if (ifd->offset == -EBUSY) { | 977 | if (ifd->offset == -EBUSY) { |
1017 | dbg(DEBUG_ISO, "%s: buffer busy at frame %d", | 978 | gig_dbg(DEBUG_ISO, |
1018 | __func__, nframe); | 979 | "%s: buffer busy at frame %d", |
1019 | /* tasklet will be restarted from gigaset_send_skb() */ | 980 | __func__, nframe); |
981 | /* tasklet will be restarted from | ||
982 | gigaset_send_skb() */ | ||
1020 | } else { | 983 | } else { |
1021 | err("%s: buffer error %d at frame %d", | 984 | dev_err(ucx->bcs->cs->dev, |
1022 | __func__, ifd->offset, nframe); | 985 | "%s: buffer error %d at frame %d\n", |
986 | __func__, ifd->offset, nframe); | ||
1023 | return ifd->offset; | 987 | return ifd->offset; |
1024 | } | 988 | } |
1025 | break; | 989 | break; |
@@ -1029,9 +993,14 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1029 | ifd->actual_length = 0; | 993 | ifd->actual_length = 0; |
1030 | } | 994 | } |
1031 | if ((urb->number_of_packets = nframe) > 0) { | 995 | if ((urb->number_of_packets = nframe) > 0) { |
1032 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 996 | spin_lock_irqsave(&ucx->bcs->cs->lock, flags); |
1033 | err("could not submit isochronous write URB: %s", | 997 | rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; |
1034 | get_usb_statmsg(rc)); | 998 | spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags); |
999 | |||
1000 | if (rc) { | ||
1001 | dev_err(ucx->bcs->cs->dev, | ||
1002 | "could not submit isochronous write URB: %s\n", | ||
1003 | get_usb_statmsg(rc)); | ||
1035 | dump_urb(DEBUG_ISO, "isoc write", urb); | 1004 | dump_urb(DEBUG_ISO, "isoc write", urb); |
1036 | return rc; | 1005 | return rc; |
1037 | } | 1006 | } |
@@ -1048,9 +1017,9 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1048 | */ | 1017 | */ |
1049 | static void write_iso_tasklet(unsigned long data) | 1018 | static void write_iso_tasklet(unsigned long data) |
1050 | { | 1019 | { |
1051 | struct bc_state *bcs; | 1020 | struct bc_state *bcs = (struct bc_state *) data; |
1052 | struct bas_bc_state *ubc; | 1021 | struct bas_bc_state *ubc = bcs->hw.bas; |
1053 | struct cardstate *cs; | 1022 | struct cardstate *cs = bcs->cs; |
1054 | struct isow_urbctx_t *done, *next, *ovfl; | 1023 | struct isow_urbctx_t *done, *next, *ovfl; |
1055 | struct urb *urb; | 1024 | struct urb *urb; |
1056 | struct usb_iso_packet_descriptor *ifd; | 1025 | struct usb_iso_packet_descriptor *ifd; |
@@ -1060,22 +1029,10 @@ static void write_iso_tasklet(unsigned long data) | |||
1060 | struct sk_buff *skb; | 1029 | struct sk_buff *skb; |
1061 | int len; | 1030 | int len; |
1062 | 1031 | ||
1063 | bcs = (struct bc_state *) data; | ||
1064 | IFNULLRET(bcs); | ||
1065 | ubc = bcs->hw.bas; | ||
1066 | IFNULLRET(ubc); | ||
1067 | cs = bcs->cs; | ||
1068 | IFNULLRET(cs); | ||
1069 | |||
1070 | /* loop while completed URBs arrive in time */ | 1032 | /* loop while completed URBs arrive in time */ |
1071 | for (;;) { | 1033 | for (;;) { |
1072 | if (unlikely(!atomic_read(&cs->connected))) { | ||
1073 | warn("%s: disconnected", __func__); | ||
1074 | return; | ||
1075 | } | ||
1076 | |||
1077 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1034 | if (unlikely(!(atomic_read(&ubc->running)))) { |
1078 | dbg(DEBUG_ISO, "%s: not running", __func__); | 1035 | gig_dbg(DEBUG_ISO, "%s: not running", __func__); |
1079 | return; | 1036 | return; |
1080 | } | 1037 | } |
1081 | 1038 | ||
@@ -1087,7 +1044,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1087 | ubc->isooutovfl = NULL; | 1044 | ubc->isooutovfl = NULL; |
1088 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1045 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1089 | if (ovfl) { | 1046 | if (ovfl) { |
1090 | err("isochronous write buffer underrun - buy a faster machine :-)"); | 1047 | dev_err(cs->dev, "isochronous write buffer underrun\n"); |
1091 | error_hangup(bcs); | 1048 | error_hangup(bcs); |
1092 | break; | 1049 | break; |
1093 | } | 1050 | } |
@@ -1110,7 +1067,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1110 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1067 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1111 | if (next) { | 1068 | if (next) { |
1112 | /* couldn't put it back */ | 1069 | /* couldn't put it back */ |
1113 | err("losing isochronous write URB"); | 1070 | dev_err(cs->dev, |
1071 | "losing isochronous write URB\n"); | ||
1114 | error_hangup(bcs); | 1072 | error_hangup(bcs); |
1115 | } | 1073 | } |
1116 | } | 1074 | } |
@@ -1123,22 +1081,25 @@ static void write_iso_tasklet(unsigned long data) | |||
1123 | break; | 1081 | break; |
1124 | case -EXDEV: /* inspect individual frames */ | 1082 | case -EXDEV: /* inspect individual frames */ |
1125 | /* assumptions (for lack of documentation): | 1083 | /* assumptions (for lack of documentation): |
1126 | * - actual_length bytes of the frame in error are successfully sent | 1084 | * - actual_length bytes of the frame in error are |
1085 | * successfully sent | ||
1127 | * - all following frames are not sent at all | 1086 | * - all following frames are not sent at all |
1128 | */ | 1087 | */ |
1129 | dbg(DEBUG_ISO, "%s: URB partially completed", __func__); | 1088 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", |
1089 | __func__); | ||
1130 | offset = done->limit; /* just in case */ | 1090 | offset = done->limit; /* just in case */ |
1131 | for (i = 0; i < BAS_NUMFRAMES; i++) { | 1091 | for (i = 0; i < BAS_NUMFRAMES; i++) { |
1132 | ifd = &urb->iso_frame_desc[i]; | 1092 | ifd = &urb->iso_frame_desc[i]; |
1133 | if (ifd->status || | 1093 | if (ifd->status || |
1134 | ifd->actual_length != ifd->length) { | 1094 | ifd->actual_length != ifd->length) { |
1135 | warn("isochronous write: frame %d: %s, " | 1095 | dev_warn(cs->dev, |
1136 | "only %d of %d bytes sent", | 1096 | "isochronous write: frame %d: %s, " |
1097 | "only %d of %d bytes sent\n", | ||
1137 | i, get_usb_statmsg(ifd->status), | 1098 | i, get_usb_statmsg(ifd->status), |
1138 | ifd->actual_length, ifd->length); | 1099 | ifd->actual_length, ifd->length); |
1139 | offset = (ifd->offset + | 1100 | offset = (ifd->offset + |
1140 | ifd->actual_length) | 1101 | ifd->actual_length) |
1141 | % BAS_OUTBUFSIZE; | 1102 | % BAS_OUTBUFSIZE; |
1142 | break; | 1103 | break; |
1143 | } | 1104 | } |
1144 | } | 1105 | } |
@@ -1148,25 +1109,26 @@ static void write_iso_tasklet(unsigned long data) | |||
1148 | ifd = &urb->iso_frame_desc[i]; | 1109 | ifd = &urb->iso_frame_desc[i]; |
1149 | if (ifd->status != -EINPROGRESS | 1110 | if (ifd->status != -EINPROGRESS |
1150 | || ifd->actual_length != 0) { | 1111 | || ifd->actual_length != 0) { |
1151 | warn("isochronous write: frame %d: %s, " | 1112 | dev_warn(cs->dev, |
1152 | "%d of %d bytes sent", | 1113 | "isochronous write: frame %d: %s, " |
1114 | "%d of %d bytes sent\n", | ||
1153 | i, get_usb_statmsg(ifd->status), | 1115 | i, get_usb_statmsg(ifd->status), |
1154 | ifd->actual_length, ifd->length); | 1116 | ifd->actual_length, ifd->length); |
1155 | offset = (ifd->offset + | 1117 | offset = (ifd->offset + |
1156 | ifd->actual_length) | 1118 | ifd->actual_length) |
1157 | % BAS_OUTBUFSIZE; | 1119 | % BAS_OUTBUFSIZE; |
1158 | break; | 1120 | break; |
1159 | } | 1121 | } |
1160 | } | 1122 | } |
1161 | #endif | 1123 | #endif |
1162 | break; | 1124 | break; |
1163 | case -EPIPE: //FIXME is this the code for "underrun"? | 1125 | case -EPIPE: //FIXME is this the code for "underrun"? |
1164 | err("isochronous write stalled"); | 1126 | dev_err(cs->dev, "isochronous write stalled\n"); |
1165 | error_hangup(bcs); | 1127 | error_hangup(bcs); |
1166 | break; | 1128 | break; |
1167 | default: /* severe trouble */ | 1129 | default: /* severe trouble */ |
1168 | warn("isochronous write: %s", | 1130 | dev_warn(cs->dev, "isochronous write: %s\n", |
1169 | get_usb_statmsg(urb->status)); | 1131 | get_usb_statmsg(urb->status)); |
1170 | } | 1132 | } |
1171 | 1133 | ||
1172 | /* mark the write buffer area covered by this URB as free */ | 1134 | /* mark the write buffer area covered by this URB as free */ |
@@ -1194,8 +1156,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1194 | if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) { | 1156 | if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) { |
1195 | /* insufficient buffer space, push back onto queue */ | 1157 | /* insufficient buffer space, push back onto queue */ |
1196 | skb_queue_head(&bcs->squeue, skb); | 1158 | skb_queue_head(&bcs->squeue, skb); |
1197 | dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d", | 1159 | gig_dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d", |
1198 | __func__, skb_queue_len(&bcs->squeue)); | 1160 | __func__, skb_queue_len(&bcs->squeue)); |
1199 | break; | 1161 | break; |
1200 | } | 1162 | } |
1201 | skb_pull(skb, len); | 1163 | skb_pull(skb, len); |
@@ -1215,28 +1177,16 @@ static void write_iso_tasklet(unsigned long data) | |||
1215 | */ | 1177 | */ |
1216 | static void read_iso_tasklet(unsigned long data) | 1178 | static void read_iso_tasklet(unsigned long data) |
1217 | { | 1179 | { |
1218 | struct bc_state *bcs; | 1180 | struct bc_state *bcs = (struct bc_state *) data; |
1219 | struct bas_bc_state *ubc; | 1181 | struct bas_bc_state *ubc = bcs->hw.bas; |
1220 | struct cardstate *cs; | 1182 | struct cardstate *cs = bcs->cs; |
1221 | struct urb *urb; | 1183 | struct urb *urb; |
1222 | char *rcvbuf; | 1184 | char *rcvbuf; |
1223 | unsigned long flags; | 1185 | unsigned long flags; |
1224 | int totleft, numbytes, offset, frame, rc; | 1186 | int totleft, numbytes, offset, frame, rc; |
1225 | 1187 | ||
1226 | bcs = (struct bc_state *) data; | ||
1227 | IFNULLRET(bcs); | ||
1228 | ubc = bcs->hw.bas; | ||
1229 | IFNULLRET(ubc); | ||
1230 | cs = bcs->cs; | ||
1231 | IFNULLRET(cs); | ||
1232 | |||
1233 | /* loop while more completed URBs arrive in the meantime */ | 1188 | /* loop while more completed URBs arrive in the meantime */ |
1234 | for (;;) { | 1189 | for (;;) { |
1235 | if (!atomic_read(&cs->connected)) { | ||
1236 | warn("%s: disconnected", __func__); | ||
1237 | return; | ||
1238 | } | ||
1239 | |||
1240 | /* retrieve URB */ | 1190 | /* retrieve URB */ |
1241 | spin_lock_irqsave(&ubc->isoinlock, flags); | 1191 | spin_lock_irqsave(&ubc->isoinlock, flags); |
1242 | if (!(urb = ubc->isoindone)) { | 1192 | if (!(urb = ubc->isoindone)) { |
@@ -1245,38 +1195,45 @@ static void read_iso_tasklet(unsigned long data) | |||
1245 | } | 1195 | } |
1246 | ubc->isoindone = NULL; | 1196 | ubc->isoindone = NULL; |
1247 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { | 1197 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { |
1248 | warn("isochronous read overrun, dropped URB with status: %s, %d bytes lost", | 1198 | dev_warn(cs->dev, |
1249 | get_usb_statmsg(ubc->loststatus), ubc->isoinlost); | 1199 | "isochronous read overrun, " |
1200 | "dropped URB with status: %s, %d bytes lost\n", | ||
1201 | get_usb_statmsg(ubc->loststatus), | ||
1202 | ubc->isoinlost); | ||
1250 | ubc->loststatus = -EINPROGRESS; | 1203 | ubc->loststatus = -EINPROGRESS; |
1251 | } | 1204 | } |
1252 | spin_unlock_irqrestore(&ubc->isoinlock, flags); | 1205 | spin_unlock_irqrestore(&ubc->isoinlock, flags); |
1253 | 1206 | ||
1254 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1207 | if (unlikely(!(atomic_read(&ubc->running)))) { |
1255 | dbg(DEBUG_ISO, "%s: channel not running, dropped URB with status: %s", | 1208 | gig_dbg(DEBUG_ISO, |
1256 | __func__, get_usb_statmsg(urb->status)); | 1209 | "%s: channel not running, " |
1210 | "dropped URB with status: %s", | ||
1211 | __func__, get_usb_statmsg(urb->status)); | ||
1257 | return; | 1212 | return; |
1258 | } | 1213 | } |
1259 | 1214 | ||
1260 | switch (urb->status) { | 1215 | switch (urb->status) { |
1261 | case 0: /* normal completion */ | 1216 | case 0: /* normal completion */ |
1262 | break; | 1217 | break; |
1263 | case -EXDEV: /* inspect individual frames (we do that anyway) */ | 1218 | case -EXDEV: /* inspect individual frames |
1264 | dbg(DEBUG_ISO, "%s: URB partially completed", __func__); | 1219 | (we do that anyway) */ |
1220 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", | ||
1221 | __func__); | ||
1265 | break; | 1222 | break; |
1266 | case -ENOENT: | 1223 | case -ENOENT: |
1267 | case -ECONNRESET: | 1224 | case -ECONNRESET: |
1268 | dbg(DEBUG_ISO, "%s: URB canceled", __func__); | 1225 | gig_dbg(DEBUG_ISO, "%s: URB canceled", __func__); |
1269 | continue; /* -> skip */ | 1226 | continue; /* -> skip */ |
1270 | case -EINPROGRESS: /* huh? */ | 1227 | case -EINPROGRESS: /* huh? */ |
1271 | dbg(DEBUG_ISO, "%s: URB still pending", __func__); | 1228 | gig_dbg(DEBUG_ISO, "%s: URB still pending", __func__); |
1272 | continue; /* -> skip */ | 1229 | continue; /* -> skip */ |
1273 | case -EPIPE: | 1230 | case -EPIPE: |
1274 | err("isochronous read stalled"); | 1231 | dev_err(cs->dev, "isochronous read stalled\n"); |
1275 | error_hangup(bcs); | 1232 | error_hangup(bcs); |
1276 | continue; /* -> skip */ | 1233 | continue; /* -> skip */ |
1277 | default: /* severe trouble */ | 1234 | default: /* severe trouble */ |
1278 | warn("isochronous read: %s", | 1235 | dev_warn(cs->dev, "isochronous read: %s\n", |
1279 | get_usb_statmsg(urb->status)); | 1236 | get_usb_statmsg(urb->status)); |
1280 | goto error; | 1237 | goto error; |
1281 | } | 1238 | } |
1282 | 1239 | ||
@@ -1284,33 +1241,44 @@ static void read_iso_tasklet(unsigned long data) | |||
1284 | totleft = urb->actual_length; | 1241 | totleft = urb->actual_length; |
1285 | for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { | 1242 | for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { |
1286 | if (unlikely(urb->iso_frame_desc[frame].status)) { | 1243 | if (unlikely(urb->iso_frame_desc[frame].status)) { |
1287 | warn("isochronous read: frame %d: %s", | 1244 | dev_warn(cs->dev, |
1288 | frame, get_usb_statmsg(urb->iso_frame_desc[frame].status)); | 1245 | "isochronous read: frame %d: %s\n", |
1246 | frame, | ||
1247 | get_usb_statmsg( | ||
1248 | urb->iso_frame_desc[frame].status)); | ||
1289 | break; | 1249 | break; |
1290 | } | 1250 | } |
1291 | numbytes = urb->iso_frame_desc[frame].actual_length; | 1251 | numbytes = urb->iso_frame_desc[frame].actual_length; |
1292 | if (unlikely(numbytes > BAS_MAXFRAME)) { | 1252 | if (unlikely(numbytes > BAS_MAXFRAME)) { |
1293 | warn("isochronous read: frame %d: numbytes (%d) > BAS_MAXFRAME", | 1253 | dev_warn(cs->dev, |
1294 | frame, numbytes); | 1254 | "isochronous read: frame %d: " |
1255 | "numbytes (%d) > BAS_MAXFRAME\n", | ||
1256 | frame, numbytes); | ||
1295 | break; | 1257 | break; |
1296 | } | 1258 | } |
1297 | if (unlikely(numbytes > totleft)) { | 1259 | if (unlikely(numbytes > totleft)) { |
1298 | warn("isochronous read: frame %d: numbytes (%d) > totleft (%d)", | 1260 | dev_warn(cs->dev, |
1299 | frame, numbytes, totleft); | 1261 | "isochronous read: frame %d: " |
1262 | "numbytes (%d) > totleft (%d)\n", | ||
1263 | frame, numbytes, totleft); | ||
1300 | break; | 1264 | break; |
1301 | } | 1265 | } |
1302 | offset = urb->iso_frame_desc[frame].offset; | 1266 | offset = urb->iso_frame_desc[frame].offset; |
1303 | if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { | 1267 | if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { |
1304 | warn("isochronous read: frame %d: offset (%d) + numbytes (%d) > BAS_INBUFSIZE", | 1268 | dev_warn(cs->dev, |
1305 | frame, offset, numbytes); | 1269 | "isochronous read: frame %d: " |
1270 | "offset (%d) + numbytes (%d) " | ||
1271 | "> BAS_INBUFSIZE\n", | ||
1272 | frame, offset, numbytes); | ||
1306 | break; | 1273 | break; |
1307 | } | 1274 | } |
1308 | gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); | 1275 | gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); |
1309 | totleft -= numbytes; | 1276 | totleft -= numbytes; |
1310 | } | 1277 | } |
1311 | if (unlikely(totleft > 0)) | 1278 | if (unlikely(totleft > 0)) |
1312 | warn("isochronous read: %d data bytes missing", | 1279 | dev_warn(cs->dev, |
1313 | totleft); | 1280 | "isochronous read: %d data bytes missing\n", |
1281 | totleft); | ||
1314 | 1282 | ||
1315 | error: | 1283 | error: |
1316 | /* URB processed, resubmit */ | 1284 | /* URB processed, resubmit */ |
@@ -1318,12 +1286,17 @@ static void read_iso_tasklet(unsigned long data) | |||
1318 | urb->iso_frame_desc[frame].status = 0; | 1286 | urb->iso_frame_desc[frame].status = 0; |
1319 | urb->iso_frame_desc[frame].actual_length = 0; | 1287 | urb->iso_frame_desc[frame].actual_length = 0; |
1320 | } | 1288 | } |
1321 | urb->dev = bcs->cs->hw.bas->udev; /* clobbered by USB subsystem */ | 1289 | /* urb->dev is clobbered by USB subsystem */ |
1290 | urb->dev = bcs->cs->hw.bas->udev; | ||
1322 | urb->transfer_flags = URB_ISO_ASAP; | 1291 | urb->transfer_flags = URB_ISO_ASAP; |
1323 | urb->number_of_packets = BAS_NUMFRAMES; | 1292 | urb->number_of_packets = BAS_NUMFRAMES; |
1324 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 1293 | spin_lock_irqsave(&cs->lock, flags); |
1325 | err("could not resubmit isochronous read URB: %s", | 1294 | rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; |
1326 | get_usb_statmsg(rc)); | 1295 | spin_unlock_irqrestore(&cs->lock, flags); |
1296 | if (rc) { | ||
1297 | dev_err(cs->dev, | ||
1298 | "could not resubmit isochronous read URB: %s\n", | ||
1299 | get_usb_statmsg(rc)); | ||
1327 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); | 1300 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); |
1328 | error_hangup(bcs); | 1301 | error_hangup(bcs); |
1329 | } | 1302 | } |
@@ -1341,15 +1314,10 @@ static void read_iso_tasklet(unsigned long data) | |||
1341 | static void req_timeout(unsigned long data) | 1314 | static void req_timeout(unsigned long data) |
1342 | { | 1315 | { |
1343 | struct bc_state *bcs = (struct bc_state *) data; | 1316 | struct bc_state *bcs = (struct bc_state *) data; |
1344 | struct bas_cardstate *ucs; | 1317 | struct bas_cardstate *ucs = bcs->cs->hw.bas; |
1345 | int pending; | 1318 | int pending; |
1346 | unsigned long flags; | 1319 | unsigned long flags; |
1347 | 1320 | ||
1348 | IFNULLRET(bcs); | ||
1349 | IFNULLRET(bcs->cs); | ||
1350 | ucs = bcs->cs->hw.bas; | ||
1351 | IFNULLRET(ucs); | ||
1352 | |||
1353 | check_pending(ucs); | 1321 | check_pending(ucs); |
1354 | 1322 | ||
1355 | spin_lock_irqsave(&ucs->lock, flags); | 1323 | spin_lock_irqsave(&ucs->lock, flags); |
@@ -1359,33 +1327,34 @@ static void req_timeout(unsigned long data) | |||
1359 | 1327 | ||
1360 | switch (pending) { | 1328 | switch (pending) { |
1361 | case 0: /* no pending request */ | 1329 | case 0: /* no pending request */ |
1362 | dbg(DEBUG_USBREQ, "%s: no request pending", __func__); | 1330 | gig_dbg(DEBUG_USBREQ, "%s: no request pending", __func__); |
1363 | break; | 1331 | break; |
1364 | 1332 | ||
1365 | case HD_OPEN_ATCHANNEL: | 1333 | case HD_OPEN_ATCHANNEL: |
1366 | err("timeout opening AT channel"); | 1334 | dev_err(bcs->cs->dev, "timeout opening AT channel\n"); |
1367 | error_reset(bcs->cs); | 1335 | error_reset(bcs->cs); |
1368 | break; | 1336 | break; |
1369 | 1337 | ||
1370 | case HD_OPEN_B2CHANNEL: | 1338 | case HD_OPEN_B2CHANNEL: |
1371 | case HD_OPEN_B1CHANNEL: | 1339 | case HD_OPEN_B1CHANNEL: |
1372 | err("timeout opening channel %d", bcs->channel + 1); | 1340 | dev_err(bcs->cs->dev, "timeout opening channel %d\n", |
1341 | bcs->channel + 1); | ||
1373 | error_hangup(bcs); | 1342 | error_hangup(bcs); |
1374 | break; | 1343 | break; |
1375 | 1344 | ||
1376 | case HD_CLOSE_ATCHANNEL: | 1345 | case HD_CLOSE_ATCHANNEL: |
1377 | err("timeout closing AT channel"); | 1346 | dev_err(bcs->cs->dev, "timeout closing AT channel\n"); |
1378 | //wake_up_interruptible(cs->initwait); | ||
1379 | //FIXME need own wait queue? | ||
1380 | break; | 1347 | break; |
1381 | 1348 | ||
1382 | case HD_CLOSE_B2CHANNEL: | 1349 | case HD_CLOSE_B2CHANNEL: |
1383 | case HD_CLOSE_B1CHANNEL: | 1350 | case HD_CLOSE_B1CHANNEL: |
1384 | err("timeout closing channel %d", bcs->channel + 1); | 1351 | dev_err(bcs->cs->dev, "timeout closing channel %d\n", |
1352 | bcs->channel + 1); | ||
1385 | break; | 1353 | break; |
1386 | 1354 | ||
1387 | default: | 1355 | default: |
1388 | warn("request 0x%02x timed out, clearing", pending); | 1356 | dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", |
1357 | pending); | ||
1389 | } | 1358 | } |
1390 | } | 1359 | } |
1391 | 1360 | ||
@@ -1398,18 +1367,14 @@ static void req_timeout(unsigned long data) | |||
1398 | */ | 1367 | */ |
1399 | static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) | 1368 | static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) |
1400 | { | 1369 | { |
1401 | struct bas_cardstate *ucs; | 1370 | struct bas_cardstate *ucs = urb->context; |
1402 | unsigned long flags; | 1371 | unsigned long flags; |
1403 | 1372 | ||
1404 | IFNULLRET(urb); | ||
1405 | IFNULLRET(urb->context); | ||
1406 | IFNULLRET(cardstate); | ||
1407 | |||
1408 | ucs = (struct bas_cardstate *) urb->context; | ||
1409 | spin_lock_irqsave(&ucs->lock, flags); | 1373 | spin_lock_irqsave(&ucs->lock, flags); |
1410 | if (urb->status && ucs->pending) { | 1374 | if (urb->status && ucs->pending) { |
1411 | err("control request 0x%02x failed: %s", | 1375 | dev_err(&ucs->interface->dev, |
1412 | ucs->pending, get_usb_statmsg(urb->status)); | 1376 | "control request 0x%02x failed: %s\n", |
1377 | ucs->pending, get_usb_statmsg(urb->status)); | ||
1413 | del_timer(&ucs->timer_ctrl); | 1378 | del_timer(&ucs->timer_ctrl); |
1414 | ucs->pending = 0; | 1379 | ucs->pending = 0; |
1415 | } | 1380 | } |
@@ -1438,28 +1403,25 @@ static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
1438 | */ | 1403 | */ |
1439 | static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | 1404 | static int req_submit(struct bc_state *bcs, int req, int val, int timeout) |
1440 | { | 1405 | { |
1441 | struct bas_cardstate *ucs; | 1406 | struct bas_cardstate *ucs = bcs->cs->hw.bas; |
1442 | int ret; | 1407 | int ret; |
1443 | unsigned long flags; | 1408 | unsigned long flags; |
1444 | 1409 | ||
1445 | IFNULLRETVAL(bcs, -EINVAL); | 1410 | gig_dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val); |
1446 | IFNULLRETVAL(bcs->cs, -EINVAL); | ||
1447 | ucs = bcs->cs->hw.bas; | ||
1448 | IFNULLRETVAL(ucs, -EINVAL); | ||
1449 | IFNULLRETVAL(ucs->urb_ctrl, -EINVAL); | ||
1450 | |||
1451 | dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val); | ||
1452 | 1411 | ||
1453 | spin_lock_irqsave(&ucs->lock, flags); | 1412 | spin_lock_irqsave(&ucs->lock, flags); |
1454 | if (ucs->pending) { | 1413 | if (ucs->pending) { |
1455 | spin_unlock_irqrestore(&ucs->lock, flags); | 1414 | spin_unlock_irqrestore(&ucs->lock, flags); |
1456 | err("submission of request 0x%02x failed: request 0x%02x still pending", | 1415 | dev_err(bcs->cs->dev, |
1457 | req, ucs->pending); | 1416 | "submission of request 0x%02x failed: " |
1417 | "request 0x%02x still pending\n", | ||
1418 | req, ucs->pending); | ||
1458 | return -EBUSY; | 1419 | return -EBUSY; |
1459 | } | 1420 | } |
1460 | if (ucs->urb_ctrl->status == -EINPROGRESS) { | 1421 | if (ucs->urb_ctrl->status == -EINPROGRESS) { |
1461 | spin_unlock_irqrestore(&ucs->lock, flags); | 1422 | spin_unlock_irqrestore(&ucs->lock, flags); |
1462 | err("could not submit request 0x%02x: URB busy", req); | 1423 | dev_err(bcs->cs->dev, |
1424 | "could not submit request 0x%02x: URB busy\n", req); | ||
1463 | return -EBUSY; | 1425 | return -EBUSY; |
1464 | } | 1426 | } |
1465 | 1427 | ||
@@ -1469,19 +1431,19 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1469 | ucs->dr_ctrl.wIndex = 0; | 1431 | ucs->dr_ctrl.wIndex = 0; |
1470 | ucs->dr_ctrl.wLength = 0; | 1432 | ucs->dr_ctrl.wLength = 0; |
1471 | usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, | 1433 | usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, |
1472 | usb_sndctrlpipe(ucs->udev, 0), | 1434 | usb_sndctrlpipe(ucs->udev, 0), |
1473 | (unsigned char*) &ucs->dr_ctrl, NULL, 0, | 1435 | (unsigned char*) &ucs->dr_ctrl, NULL, 0, |
1474 | write_ctrl_callback, ucs); | 1436 | write_ctrl_callback, ucs); |
1475 | if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { | 1437 | if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { |
1476 | err("could not submit request 0x%02x: %s", | 1438 | dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", |
1477 | req, get_usb_statmsg(ret)); | 1439 | req, get_usb_statmsg(ret)); |
1478 | spin_unlock_irqrestore(&ucs->lock, flags); | 1440 | spin_unlock_irqrestore(&ucs->lock, flags); |
1479 | return ret; | 1441 | return ret; |
1480 | } | 1442 | } |
1481 | ucs->pending = req; | 1443 | ucs->pending = req; |
1482 | 1444 | ||
1483 | if (timeout > 0) { | 1445 | if (timeout > 0) { |
1484 | dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); | 1446 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); |
1485 | ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; | 1447 | ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; |
1486 | ucs->timer_ctrl.data = (unsigned long) bcs; | 1448 | ucs->timer_ctrl.data = (unsigned long) bcs; |
1487 | ucs->timer_ctrl.function = req_timeout; | 1449 | ucs->timer_ctrl.function = req_timeout; |
@@ -1504,19 +1466,18 @@ static int gigaset_init_bchannel(struct bc_state *bcs) | |||
1504 | { | 1466 | { |
1505 | int req, ret; | 1467 | int req, ret; |
1506 | 1468 | ||
1507 | IFNULLRETVAL(bcs, -EINVAL); | ||
1508 | |||
1509 | if ((ret = starturbs(bcs)) < 0) { | 1469 | if ((ret = starturbs(bcs)) < 0) { |
1510 | err("could not start isochronous I/O for channel %d", | 1470 | dev_err(bcs->cs->dev, |
1511 | bcs->channel + 1); | 1471 | "could not start isochronous I/O for channel %d\n", |
1472 | bcs->channel + 1); | ||
1512 | error_hangup(bcs); | 1473 | error_hangup(bcs); |
1513 | return ret; | 1474 | return ret; |
1514 | } | 1475 | } |
1515 | 1476 | ||
1516 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; | 1477 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; |
1517 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { | 1478 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { |
1518 | err("could not open channel %d: %s", | 1479 | dev_err(bcs->cs->dev, "could not open channel %d: %s\n", |
1519 | bcs->channel + 1, get_usb_statmsg(ret)); | 1480 | bcs->channel + 1, get_usb_statmsg(ret)); |
1520 | stopurbs(bcs->hw.bas); | 1481 | stopurbs(bcs->hw.bas); |
1521 | error_hangup(bcs); | 1482 | error_hangup(bcs); |
1522 | } | 1483 | } |
@@ -1537,8 +1498,6 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1537 | { | 1498 | { |
1538 | int req, ret; | 1499 | int req, ret; |
1539 | 1500 | ||
1540 | IFNULLRETVAL(bcs, -EINVAL); | ||
1541 | |||
1542 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & | 1501 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & |
1543 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { | 1502 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { |
1544 | /* channel not running: just signal common.c */ | 1503 | /* channel not running: just signal common.c */ |
@@ -1548,8 +1507,9 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1548 | 1507 | ||
1549 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; | 1508 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; |
1550 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) | 1509 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) |
1551 | err("could not submit HD_CLOSE_BxCHANNEL request: %s", | 1510 | dev_err(bcs->cs->dev, |
1552 | get_usb_statmsg(ret)); | 1511 | "could not submit HD_CLOSE_BxCHANNEL request: %s\n", |
1512 | get_usb_statmsg(ret)); | ||
1553 | return ret; | 1513 | return ret; |
1554 | } | 1514 | } |
1555 | 1515 | ||
@@ -1564,17 +1524,13 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1564 | */ | 1524 | */ |
1565 | static void complete_cb(struct cardstate *cs) | 1525 | static void complete_cb(struct cardstate *cs) |
1566 | { | 1526 | { |
1567 | struct cmdbuf_t *cb; | 1527 | struct cmdbuf_t *cb = cs->cmdbuf; |
1568 | |||
1569 | IFNULLRET(cs); | ||
1570 | cb = cs->cmdbuf; | ||
1571 | IFNULLRET(cb); | ||
1572 | 1528 | ||
1573 | /* unqueue completed buffer */ | 1529 | /* unqueue completed buffer */ |
1574 | cs->cmdbytes -= cs->curlen; | 1530 | cs->cmdbytes -= cs->curlen; |
1575 | dbg(DEBUG_TRANSCMD | DEBUG_LOCKCMD, | 1531 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, |
1576 | "write_command: sent %u bytes, %u left", | 1532 | "write_command: sent %u bytes, %u left", |
1577 | cs->curlen, cs->cmdbytes); | 1533 | cs->curlen, cs->cmdbytes); |
1578 | if ((cs->cmdbuf = cb->next) != NULL) { | 1534 | if ((cs->cmdbuf = cb->next) != NULL) { |
1579 | cs->cmdbuf->prev = NULL; | 1535 | cs->cmdbuf->prev = NULL; |
1580 | cs->curlen = cs->cmdbuf->len; | 1536 | cs->curlen = cs->cmdbuf->len; |
@@ -1600,15 +1556,9 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len); | |||
1600 | */ | 1556 | */ |
1601 | static void write_command_callback(struct urb *urb, struct pt_regs *regs) | 1557 | static void write_command_callback(struct urb *urb, struct pt_regs *regs) |
1602 | { | 1558 | { |
1603 | struct cardstate *cs; | 1559 | struct cardstate *cs = urb->context; |
1560 | struct bas_cardstate *ucs = cs->hw.bas; | ||
1604 | unsigned long flags; | 1561 | unsigned long flags; |
1605 | struct bas_cardstate *ucs; | ||
1606 | |||
1607 | IFNULLRET(urb); | ||
1608 | cs = (struct cardstate *) urb->context; | ||
1609 | IFNULLRET(cs); | ||
1610 | ucs = cs->hw.bas; | ||
1611 | IFNULLRET(ucs); | ||
1612 | 1562 | ||
1613 | /* check status */ | 1563 | /* check status */ |
1614 | switch (urb->status) { | 1564 | switch (urb->status) { |
@@ -1618,22 +1568,27 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs) | |||
1618 | case -ECONNRESET: /* canceled (async) */ | 1568 | case -ECONNRESET: /* canceled (async) */ |
1619 | case -EINPROGRESS: /* pending */ | 1569 | case -EINPROGRESS: /* pending */ |
1620 | /* ignore silently */ | 1570 | /* ignore silently */ |
1621 | dbg(DEBUG_USBREQ, | 1571 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
1622 | "%s: %s", __func__, get_usb_statmsg(urb->status)); | 1572 | __func__, get_usb_statmsg(urb->status)); |
1623 | return; | 1573 | return; |
1624 | default: /* any failure */ | 1574 | default: /* any failure */ |
1625 | if (++ucs->retry_cmd_out > BAS_RETRY) { | 1575 | if (++ucs->retry_cmd_out > BAS_RETRY) { |
1626 | warn("command write: %s, giving up after %d retries", | 1576 | dev_warn(cs->dev, |
1627 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); | 1577 | "command write: %s, " |
1578 | "giving up after %d retries\n", | ||
1579 | get_usb_statmsg(urb->status), | ||
1580 | ucs->retry_cmd_out); | ||
1628 | break; | 1581 | break; |
1629 | } | 1582 | } |
1630 | if (cs->cmdbuf == NULL) { | 1583 | if (cs->cmdbuf == NULL) { |
1631 | warn("command write: %s, cannot retry - cmdbuf gone", | 1584 | dev_warn(cs->dev, |
1632 | get_usb_statmsg(urb->status)); | 1585 | "command write: %s, " |
1586 | "cannot retry - cmdbuf gone\n", | ||
1587 | get_usb_statmsg(urb->status)); | ||
1633 | break; | 1588 | break; |
1634 | } | 1589 | } |
1635 | notice("command write: %s, retry %d", | 1590 | dev_notice(cs->dev, "command write: %s, retry %d\n", |
1636 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); | 1591 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); |
1637 | if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) | 1592 | if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) |
1638 | /* resubmitted - bypass regular exit block */ | 1593 | /* resubmitted - bypass regular exit block */ |
1639 | return; | 1594 | return; |
@@ -1655,13 +1610,9 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs) | |||
1655 | static void atrdy_timeout(unsigned long data) | 1610 | static void atrdy_timeout(unsigned long data) |
1656 | { | 1611 | { |
1657 | struct cardstate *cs = (struct cardstate *) data; | 1612 | struct cardstate *cs = (struct cardstate *) data; |
1658 | struct bas_cardstate *ucs; | 1613 | struct bas_cardstate *ucs = cs->hw.bas; |
1659 | |||
1660 | IFNULLRET(cs); | ||
1661 | ucs = cs->hw.bas; | ||
1662 | IFNULLRET(ucs); | ||
1663 | 1614 | ||
1664 | warn("timeout waiting for HD_READY_SEND_ATDATA"); | 1615 | dev_warn(cs->dev, "timeout waiting for HD_READY_SEND_ATDATA\n"); |
1665 | 1616 | ||
1666 | /* fake the missing signal - what else can I do? */ | 1617 | /* fake the missing signal - what else can I do? */ |
1667 | update_basstate(ucs, BS_ATREADY, BS_ATTIMER); | 1618 | update_basstate(ucs, BS_ATREADY, BS_ATTIMER); |
@@ -1682,18 +1633,15 @@ static void atrdy_timeout(unsigned long data) | |||
1682 | */ | 1633 | */ |
1683 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | 1634 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) |
1684 | { | 1635 | { |
1685 | struct bas_cardstate *ucs; | 1636 | struct bas_cardstate *ucs = cs->hw.bas; |
1637 | unsigned long flags; | ||
1686 | int ret; | 1638 | int ret; |
1687 | 1639 | ||
1688 | IFNULLRETVAL(cs, -EFAULT); | 1640 | gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); |
1689 | ucs = cs->hw.bas; | ||
1690 | IFNULLRETVAL(ucs, -EFAULT); | ||
1691 | IFNULLRETVAL(ucs->urb_cmd_out, -EFAULT); | ||
1692 | |||
1693 | dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); | ||
1694 | 1641 | ||
1695 | if (ucs->urb_cmd_out->status == -EINPROGRESS) { | 1642 | if (ucs->urb_cmd_out->status == -EINPROGRESS) { |
1696 | err("could not submit HD_WRITE_ATMESSAGE: URB busy"); | 1643 | dev_err(cs->dev, |
1644 | "could not submit HD_WRITE_ATMESSAGE: URB busy\n"); | ||
1697 | return -EBUSY; | 1645 | return -EBUSY; |
1698 | } | 1646 | } |
1699 | 1647 | ||
@@ -1707,9 +1655,13 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1707 | (unsigned char*) &ucs->dr_cmd_out, buf, len, | 1655 | (unsigned char*) &ucs->dr_cmd_out, buf, len, |
1708 | write_command_callback, cs); | 1656 | write_command_callback, cs); |
1709 | 1657 | ||
1710 | if ((ret = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC)) != 0) { | 1658 | spin_lock_irqsave(&cs->lock, flags); |
1711 | err("could not submit HD_WRITE_ATMESSAGE: %s", | 1659 | ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV; |
1712 | get_usb_statmsg(ret)); | 1660 | spin_unlock_irqrestore(&cs->lock, flags); |
1661 | |||
1662 | if (ret) { | ||
1663 | dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", | ||
1664 | get_usb_statmsg(ret)); | ||
1713 | return ret; | 1665 | return ret; |
1714 | } | 1666 | } |
1715 | 1667 | ||
@@ -1718,8 +1670,8 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1718 | 1670 | ||
1719 | /* start timeout if necessary */ | 1671 | /* start timeout if necessary */ |
1720 | if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) { | 1672 | if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) { |
1721 | dbg(DEBUG_OUTPUT, | 1673 | gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", |
1722 | "setting ATREADY timeout of %d/10 secs", ATRDY_TIMEOUT); | 1674 | ATRDY_TIMEOUT); |
1723 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; | 1675 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; |
1724 | ucs->timer_atrdy.data = (unsigned long) cs; | 1676 | ucs->timer_atrdy.data = (unsigned long) cs; |
1725 | ucs->timer_atrdy.function = atrdy_timeout; | 1677 | ucs->timer_atrdy.function = atrdy_timeout; |
@@ -1740,21 +1692,17 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1740 | static int start_cbsend(struct cardstate *cs) | 1692 | static int start_cbsend(struct cardstate *cs) |
1741 | { | 1693 | { |
1742 | struct cmdbuf_t *cb; | 1694 | struct cmdbuf_t *cb; |
1743 | struct bas_cardstate *ucs; | 1695 | struct bas_cardstate *ucs = cs->hw.bas; |
1744 | unsigned long flags; | 1696 | unsigned long flags; |
1745 | int rc; | 1697 | int rc; |
1746 | int retval = 0; | 1698 | int retval = 0; |
1747 | 1699 | ||
1748 | IFNULLRETVAL(cs, -EFAULT); | ||
1749 | ucs = cs->hw.bas; | ||
1750 | IFNULLRETVAL(ucs, -EFAULT); | ||
1751 | |||
1752 | /* check if AT channel is open */ | 1700 | /* check if AT channel is open */ |
1753 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) { | 1701 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) { |
1754 | dbg(DEBUG_TRANSCMD | DEBUG_LOCKCMD, "AT channel not open"); | 1702 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); |
1755 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); | 1703 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); |
1756 | if (rc < 0) { | 1704 | if (rc < 0) { |
1757 | err("could not open AT channel"); | 1705 | dev_err(cs->dev, "could not open AT channel\n"); |
1758 | /* flush command queue */ | 1706 | /* flush command queue */ |
1759 | spin_lock_irqsave(&cs->cmdlock, flags); | 1707 | spin_lock_irqsave(&cs->cmdlock, flags); |
1760 | while (cs->cmdbuf != NULL) | 1708 | while (cs->cmdbuf != NULL) |
@@ -1792,27 +1740,23 @@ static int start_cbsend(struct cardstate *cs) | |||
1792 | * cs controller state structure | 1740 | * cs controller state structure |
1793 | * buf command string to send | 1741 | * buf command string to send |
1794 | * len number of bytes to send (max. IF_WRITEBUF) | 1742 | * len number of bytes to send (max. IF_WRITEBUF) |
1795 | * wake_tasklet tasklet to run when transmission is completed (NULL if none) | 1743 | * wake_tasklet tasklet to run when transmission is completed |
1744 | * (NULL if none) | ||
1796 | * return value: | 1745 | * return value: |
1797 | * number of bytes queued on success | 1746 | * number of bytes queued on success |
1798 | * error code < 0 on error | 1747 | * error code < 0 on error |
1799 | */ | 1748 | */ |
1800 | static int gigaset_write_cmd(struct cardstate *cs, | 1749 | static int gigaset_write_cmd(struct cardstate *cs, |
1801 | const unsigned char *buf, int len, | 1750 | const unsigned char *buf, int len, |
1802 | struct tasklet_struct *wake_tasklet) | 1751 | struct tasklet_struct *wake_tasklet) |
1803 | { | 1752 | { |
1804 | struct cmdbuf_t *cb; | 1753 | struct cmdbuf_t *cb; |
1805 | unsigned long flags; | 1754 | unsigned long flags; |
1806 | int status; | 1755 | int status; |
1807 | 1756 | ||
1808 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 1757 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? |
1809 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 1758 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
1810 | "CMD Transmit", len, buf, 0); | 1759 | "CMD Transmit", len, buf); |
1811 | |||
1812 | if (!atomic_read(&cs->connected)) { | ||
1813 | err("%s: not connected", __func__); | ||
1814 | return -ENODEV; | ||
1815 | } | ||
1816 | 1760 | ||
1817 | if (len <= 0) | 1761 | if (len <= 0) |
1818 | return 0; /* nothing to do */ | 1762 | return 0; /* nothing to do */ |
@@ -1820,7 +1764,7 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1820 | if (len > IF_WRITEBUF) | 1764 | if (len > IF_WRITEBUF) |
1821 | len = IF_WRITEBUF; | 1765 | len = IF_WRITEBUF; |
1822 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { | 1766 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { |
1823 | err("%s: out of memory", __func__); | 1767 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
1824 | return -ENOMEM; | 1768 | return -ENOMEM; |
1825 | } | 1769 | } |
1826 | 1770 | ||
@@ -1849,7 +1793,8 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1849 | 1793 | ||
1850 | /* gigaset_write_room | 1794 | /* gigaset_write_room |
1851 | * tty_driver.write_room interface routine | 1795 | * tty_driver.write_room interface routine |
1852 | * return number of characters the driver will accept to be written via gigaset_write_cmd | 1796 | * return number of characters the driver will accept to be written via |
1797 | * gigaset_write_cmd | ||
1853 | * parameter: | 1798 | * parameter: |
1854 | * controller state structure | 1799 | * controller state structure |
1855 | * return value: | 1800 | * return value: |
@@ -1947,7 +1892,7 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
1947 | return 0; | 1892 | return 0; |
1948 | } | 1893 | } |
1949 | tasklet_init(&ubc->sent_tasklet, | 1894 | tasklet_init(&ubc->sent_tasklet, |
1950 | &write_iso_tasklet, (unsigned long) bcs); | 1895 | &write_iso_tasklet, (unsigned long) bcs); |
1951 | 1896 | ||
1952 | spin_lock_init(&ubc->isoinlock); | 1897 | spin_lock_init(&ubc->isoinlock); |
1953 | for (i = 0; i < BAS_INURBS; ++i) | 1898 | for (i = 0; i < BAS_INURBS; ++i) |
@@ -1968,7 +1913,7 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
1968 | ubc->shared0s = 0; | 1913 | ubc->shared0s = 0; |
1969 | ubc->stolen0s = 0; | 1914 | ubc->stolen0s = 0; |
1970 | tasklet_init(&ubc->rcvd_tasklet, | 1915 | tasklet_init(&ubc->rcvd_tasklet, |
1971 | &read_iso_tasklet, (unsigned long) bcs); | 1916 | &read_iso_tasklet, (unsigned long) bcs); |
1972 | return 1; | 1917 | return 1; |
1973 | } | 1918 | } |
1974 | 1919 | ||
@@ -2027,57 +1972,56 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
2027 | */ | 1972 | */ |
2028 | static void freeurbs(struct cardstate *cs) | 1973 | static void freeurbs(struct cardstate *cs) |
2029 | { | 1974 | { |
2030 | struct bas_cardstate *ucs; | 1975 | struct bas_cardstate *ucs = cs->hw.bas; |
2031 | struct bas_bc_state *ubc; | 1976 | struct bas_bc_state *ubc; |
2032 | int i, j; | 1977 | int i, j; |
2033 | 1978 | ||
2034 | IFNULLRET(cs); | ||
2035 | ucs = cs->hw.bas; | ||
2036 | IFNULLRET(ucs); | ||
2037 | |||
2038 | for (j = 0; j < 2; ++j) { | 1979 | for (j = 0; j < 2; ++j) { |
2039 | ubc = cs->bcs[j].hw.bas; | 1980 | ubc = cs->bcs[j].hw.bas; |
2040 | IFNULLCONT(ubc); | ||
2041 | for (i = 0; i < BAS_OUTURBS; ++i) | 1981 | for (i = 0; i < BAS_OUTURBS; ++i) |
2042 | if (ubc->isoouturbs[i].urb) { | 1982 | if (ubc->isoouturbs[i].urb) { |
2043 | usb_kill_urb(ubc->isoouturbs[i].urb); | 1983 | usb_kill_urb(ubc->isoouturbs[i].urb); |
2044 | dbg(DEBUG_INIT, | 1984 | gig_dbg(DEBUG_INIT, |
2045 | "%s: isoc output URB %d/%d unlinked", | 1985 | "%s: isoc output URB %d/%d unlinked", |
2046 | __func__, j, i); | 1986 | __func__, j, i); |
2047 | usb_free_urb(ubc->isoouturbs[i].urb); | 1987 | usb_free_urb(ubc->isoouturbs[i].urb); |
2048 | ubc->isoouturbs[i].urb = NULL; | 1988 | ubc->isoouturbs[i].urb = NULL; |
2049 | } | 1989 | } |
2050 | for (i = 0; i < BAS_INURBS; ++i) | 1990 | for (i = 0; i < BAS_INURBS; ++i) |
2051 | if (ubc->isoinurbs[i]) { | 1991 | if (ubc->isoinurbs[i]) { |
2052 | usb_kill_urb(ubc->isoinurbs[i]); | 1992 | usb_kill_urb(ubc->isoinurbs[i]); |
2053 | dbg(DEBUG_INIT, | 1993 | gig_dbg(DEBUG_INIT, |
2054 | "%s: isoc input URB %d/%d unlinked", | 1994 | "%s: isoc input URB %d/%d unlinked", |
2055 | __func__, j, i); | 1995 | __func__, j, i); |
2056 | usb_free_urb(ubc->isoinurbs[i]); | 1996 | usb_free_urb(ubc->isoinurbs[i]); |
2057 | ubc->isoinurbs[i] = NULL; | 1997 | ubc->isoinurbs[i] = NULL; |
2058 | } | 1998 | } |
2059 | } | 1999 | } |
2060 | if (ucs->urb_int_in) { | 2000 | if (ucs->urb_int_in) { |
2061 | usb_kill_urb(ucs->urb_int_in); | 2001 | usb_kill_urb(ucs->urb_int_in); |
2062 | dbg(DEBUG_INIT, "%s: interrupt input URB unlinked", __func__); | 2002 | gig_dbg(DEBUG_INIT, "%s: interrupt input URB unlinked", |
2003 | __func__); | ||
2063 | usb_free_urb(ucs->urb_int_in); | 2004 | usb_free_urb(ucs->urb_int_in); |
2064 | ucs->urb_int_in = NULL; | 2005 | ucs->urb_int_in = NULL; |
2065 | } | 2006 | } |
2066 | if (ucs->urb_cmd_out) { | 2007 | if (ucs->urb_cmd_out) { |
2067 | usb_kill_urb(ucs->urb_cmd_out); | 2008 | usb_kill_urb(ucs->urb_cmd_out); |
2068 | dbg(DEBUG_INIT, "%s: command output URB unlinked", __func__); | 2009 | gig_dbg(DEBUG_INIT, "%s: command output URB unlinked", |
2010 | __func__); | ||
2069 | usb_free_urb(ucs->urb_cmd_out); | 2011 | usb_free_urb(ucs->urb_cmd_out); |
2070 | ucs->urb_cmd_out = NULL; | 2012 | ucs->urb_cmd_out = NULL; |
2071 | } | 2013 | } |
2072 | if (ucs->urb_cmd_in) { | 2014 | if (ucs->urb_cmd_in) { |
2073 | usb_kill_urb(ucs->urb_cmd_in); | 2015 | usb_kill_urb(ucs->urb_cmd_in); |
2074 | dbg(DEBUG_INIT, "%s: command input URB unlinked", __func__); | 2016 | gig_dbg(DEBUG_INIT, "%s: command input URB unlinked", |
2017 | __func__); | ||
2075 | usb_free_urb(ucs->urb_cmd_in); | 2018 | usb_free_urb(ucs->urb_cmd_in); |
2076 | ucs->urb_cmd_in = NULL; | 2019 | ucs->urb_cmd_in = NULL; |
2077 | } | 2020 | } |
2078 | if (ucs->urb_ctrl) { | 2021 | if (ucs->urb_ctrl) { |
2079 | usb_kill_urb(ucs->urb_ctrl); | 2022 | usb_kill_urb(ucs->urb_ctrl); |
2080 | dbg(DEBUG_INIT, "%s: control output URB unlinked", __func__); | 2023 | gig_dbg(DEBUG_INIT, "%s: control output URB unlinked", |
2024 | __func__); | ||
2081 | usb_free_urb(ucs->urb_ctrl); | 2025 | usb_free_urb(ucs->urb_ctrl); |
2082 | ucs->urb_ctrl = NULL; | 2026 | ucs->urb_ctrl = NULL; |
2083 | } | 2027 | } |
@@ -2099,12 +2043,10 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2099 | int i, j; | 2043 | int i, j; |
2100 | int ret; | 2044 | int ret; |
2101 | 2045 | ||
2102 | IFNULLRETVAL(udev, -ENODEV); | 2046 | gig_dbg(DEBUG_ANY, |
2103 | 2047 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | |
2104 | dbg(DEBUG_ANY, | 2048 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2105 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | 2049 | le16_to_cpu(udev->descriptor.idProduct)); |
2106 | __func__, le16_to_cpu(udev->descriptor.idVendor), | ||
2107 | le16_to_cpu(udev->descriptor.idProduct)); | ||
2108 | 2050 | ||
2109 | /* See if the device offered us matches what we can accept */ | 2051 | /* See if the device offered us matches what we can accept */ |
2110 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_GIGA_VENDOR_ID) || | 2052 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_GIGA_VENDOR_ID) || |
@@ -2112,20 +2054,21 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2112 | le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID && | 2054 | le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID && |
2113 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID && | 2055 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID && |
2114 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) { | 2056 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) { |
2115 | dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__); | 2057 | gig_dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__); |
2116 | return -ENODEV; | 2058 | return -ENODEV; |
2117 | } | 2059 | } |
2118 | 2060 | ||
2119 | /* set required alternate setting */ | 2061 | /* set required alternate setting */ |
2120 | hostif = interface->cur_altsetting; | 2062 | hostif = interface->cur_altsetting; |
2121 | if (hostif->desc.bAlternateSetting != 3) { | 2063 | if (hostif->desc.bAlternateSetting != 3) { |
2122 | dbg(DEBUG_ANY, | 2064 | gig_dbg(DEBUG_ANY, |
2123 | "%s: wrong alternate setting %d - trying to switch", | 2065 | "%s: wrong alternate setting %d - trying to switch", |
2124 | __func__, hostif->desc.bAlternateSetting); | 2066 | __func__, hostif->desc.bAlternateSetting); |
2125 | if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) { | 2067 | if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) { |
2126 | warn("usb_set_interface failed, device %d interface %d altsetting %d", | 2068 | dev_warn(&udev->dev, "usb_set_interface failed, " |
2127 | udev->devnum, hostif->desc.bInterfaceNumber, | 2069 | "device %d interface %d altsetting %d\n", |
2128 | hostif->desc.bAlternateSetting); | 2070 | udev->devnum, hostif->desc.bInterfaceNumber, |
2071 | hostif->desc.bAlternateSetting); | ||
2129 | return -ENODEV; | 2072 | return -ENODEV; |
2130 | } | 2073 | } |
2131 | hostif = interface->cur_altsetting; | 2074 | hostif = interface->cur_altsetting; |
@@ -2134,23 +2077,28 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2134 | /* Reject application specific interfaces | 2077 | /* Reject application specific interfaces |
2135 | */ | 2078 | */ |
2136 | if (hostif->desc.bInterfaceClass != 255) { | 2079 | if (hostif->desc.bInterfaceClass != 255) { |
2137 | warn("%s: bInterfaceClass == %d", | 2080 | dev_warn(&udev->dev, "%s: bInterfaceClass == %d\n", |
2138 | __func__, hostif->desc.bInterfaceClass); | 2081 | __func__, hostif->desc.bInterfaceClass); |
2139 | return -ENODEV; | 2082 | return -ENODEV; |
2140 | } | 2083 | } |
2141 | 2084 | ||
2142 | info("%s: Device matched (Vendor: 0x%x, Product: 0x%x)", | 2085 | dev_info(&udev->dev, |
2143 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 2086 | "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", |
2144 | le16_to_cpu(udev->descriptor.idProduct)); | 2087 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2088 | le16_to_cpu(udev->descriptor.idProduct)); | ||
2145 | 2089 | ||
2146 | cs = gigaset_getunassignedcs(driver); | 2090 | cs = gigaset_getunassignedcs(driver); |
2147 | if (!cs) { | 2091 | if (!cs) { |
2148 | err("%s: no free cardstate", __func__); | 2092 | dev_err(&udev->dev, "no free cardstate\n"); |
2149 | return -ENODEV; | 2093 | return -ENODEV; |
2150 | } | 2094 | } |
2151 | ucs = cs->hw.bas; | 2095 | ucs = cs->hw.bas; |
2096 | |||
2097 | /* save off device structure ptrs for later use */ | ||
2098 | usb_get_dev(udev); | ||
2152 | ucs->udev = udev; | 2099 | ucs->udev = udev; |
2153 | ucs->interface = interface; | 2100 | ucs->interface = interface; |
2101 | cs->dev = &interface->dev; | ||
2154 | 2102 | ||
2155 | /* allocate URBs: | 2103 | /* allocate URBs: |
2156 | * - one for the interrupt pipe | 2104 | * - one for the interrupt pipe |
@@ -2159,22 +2107,22 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2159 | */ | 2107 | */ |
2160 | ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL); | 2108 | ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL); |
2161 | if (!ucs->urb_int_in) { | 2109 | if (!ucs->urb_int_in) { |
2162 | err("No free urbs available"); | 2110 | dev_err(cs->dev, "no free urbs available\n"); |
2163 | goto error; | 2111 | goto error; |
2164 | } | 2112 | } |
2165 | ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL); | 2113 | ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL); |
2166 | if (!ucs->urb_cmd_in) { | 2114 | if (!ucs->urb_cmd_in) { |
2167 | err("No free urbs available"); | 2115 | dev_err(cs->dev, "no free urbs available\n"); |
2168 | goto error; | 2116 | goto error; |
2169 | } | 2117 | } |
2170 | ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL); | 2118 | ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL); |
2171 | if (!ucs->urb_cmd_out) { | 2119 | if (!ucs->urb_cmd_out) { |
2172 | err("No free urbs available"); | 2120 | dev_err(cs->dev, "no free urbs available\n"); |
2173 | goto error; | 2121 | goto error; |
2174 | } | 2122 | } |
2175 | ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL); | 2123 | ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL); |
2176 | if (!ucs->urb_ctrl) { | 2124 | if (!ucs->urb_ctrl) { |
2177 | err("No free urbs available"); | 2125 | dev_err(cs->dev, "no free urbs available\n"); |
2178 | goto error; | 2126 | goto error; |
2179 | } | 2127 | } |
2180 | 2128 | ||
@@ -2184,7 +2132,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2184 | ubc->isoouturbs[i].urb = | 2132 | ubc->isoouturbs[i].urb = |
2185 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); | 2133 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); |
2186 | if (!ubc->isoouturbs[i].urb) { | 2134 | if (!ubc->isoouturbs[i].urb) { |
2187 | err("No free urbs available"); | 2135 | dev_err(cs->dev, "no free urbs available\n"); |
2188 | goto error; | 2136 | goto error; |
2189 | } | 2137 | } |
2190 | } | 2138 | } |
@@ -2192,7 +2140,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2192 | ubc->isoinurbs[i] = | 2140 | ubc->isoinurbs[i] = |
2193 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); | 2141 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); |
2194 | if (!ubc->isoinurbs[i]) { | 2142 | if (!ubc->isoinurbs[i]) { |
2195 | err("No free urbs available"); | 2143 | dev_err(cs->dev, "no free urbs available\n"); |
2196 | goto error; | 2144 | goto error; |
2197 | } | 2145 | } |
2198 | } | 2146 | } |
@@ -2204,13 +2152,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2204 | /* Fill the interrupt urb and send it to the core */ | 2152 | /* Fill the interrupt urb and send it to the core */ |
2205 | endpoint = &hostif->endpoint[0].desc; | 2153 | endpoint = &hostif->endpoint[0].desc; |
2206 | usb_fill_int_urb(ucs->urb_int_in, udev, | 2154 | usb_fill_int_urb(ucs->urb_int_in, udev, |
2207 | usb_rcvintpipe(udev, | 2155 | usb_rcvintpipe(udev, |
2208 | (endpoint->bEndpointAddress) & 0x0f), | 2156 | (endpoint->bEndpointAddress) & 0x0f), |
2209 | ucs->int_in_buf, 3, read_int_callback, cs, | 2157 | ucs->int_in_buf, 3, read_int_callback, cs, |
2210 | endpoint->bInterval); | 2158 | endpoint->bInterval); |
2211 | ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL); | 2159 | ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL); |
2212 | if (ret) { | 2160 | if (ret) { |
2213 | err("could not submit interrupt URB: %s", get_usb_statmsg(ret)); | 2161 | dev_err(cs->dev, "could not submit interrupt URB: %s\n", |
2162 | get_usb_statmsg(ret)); | ||
2214 | goto error; | 2163 | goto error; |
2215 | } | 2164 | } |
2216 | 2165 | ||
@@ -2221,18 +2170,18 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2221 | /* tell common part that the device is ready */ | 2170 | /* tell common part that the device is ready */ |
2222 | if (startmode == SM_LOCKED) | 2171 | if (startmode == SM_LOCKED) |
2223 | atomic_set(&cs->mstate, MS_LOCKED); | 2172 | atomic_set(&cs->mstate, MS_LOCKED); |
2224 | if (!gigaset_start(cs)) | ||
2225 | goto error; | ||
2226 | 2173 | ||
2227 | /* save address of controller structure */ | 2174 | /* save address of controller structure */ |
2228 | usb_set_intfdata(interface, cs); | 2175 | usb_set_intfdata(interface, cs); |
2229 | 2176 | ||
2230 | /* set up device sysfs */ | 2177 | if (!gigaset_start(cs)) |
2231 | gigaset_init_dev_sysfs(interface); | 2178 | goto error; |
2179 | |||
2232 | return 0; | 2180 | return 0; |
2233 | 2181 | ||
2234 | error: | 2182 | error: |
2235 | freeurbs(cs); | 2183 | freeurbs(cs); |
2184 | usb_set_intfdata(interface, NULL); | ||
2236 | gigaset_unassign(cs); | 2185 | gigaset_unassign(cs); |
2237 | return -ENODEV; | 2186 | return -ENODEV; |
2238 | } | 2187 | } |
@@ -2245,23 +2194,22 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
2245 | struct cardstate *cs; | 2194 | struct cardstate *cs; |
2246 | struct bas_cardstate *ucs; | 2195 | struct bas_cardstate *ucs; |
2247 | 2196 | ||
2248 | /* clear device sysfs */ | ||
2249 | gigaset_free_dev_sysfs(interface); | ||
2250 | |||
2251 | cs = usb_get_intfdata(interface); | 2197 | cs = usb_get_intfdata(interface); |
2252 | usb_set_intfdata(interface, NULL); | ||
2253 | 2198 | ||
2254 | IFNULLRET(cs); | ||
2255 | ucs = cs->hw.bas; | 2199 | ucs = cs->hw.bas; |
2256 | IFNULLRET(ucs); | ||
2257 | 2200 | ||
2258 | info("disconnecting GigaSet base"); | 2201 | dev_info(cs->dev, "disconnecting Gigaset base\n"); |
2259 | gigaset_stop(cs); | 2202 | gigaset_stop(cs); |
2260 | freeurbs(cs); | 2203 | freeurbs(cs); |
2204 | usb_set_intfdata(interface, NULL); | ||
2261 | kfree(ucs->rcvbuf); | 2205 | kfree(ucs->rcvbuf); |
2262 | ucs->rcvbuf = NULL; | 2206 | ucs->rcvbuf = NULL; |
2263 | ucs->rcvbuf_size = 0; | 2207 | ucs->rcvbuf_size = 0; |
2264 | atomic_set(&ucs->basstate, 0); | 2208 | atomic_set(&ucs->basstate, 0); |
2209 | usb_put_dev(ucs->udev); | ||
2210 | ucs->interface = NULL; | ||
2211 | ucs->udev = NULL; | ||
2212 | cs->dev = NULL; | ||
2265 | gigaset_unassign(cs); | 2213 | gigaset_unassign(cs); |
2266 | } | 2214 | } |
2267 | 2215 | ||
@@ -2293,13 +2241,14 @@ static int __init bas_gigaset_init(void) | |||
2293 | 2241 | ||
2294 | /* allocate memory for our driver state and intialize it */ | 2242 | /* allocate memory for our driver state and intialize it */ |
2295 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 2243 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
2296 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 2244 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
2297 | GIGASET_DEVFSNAME, &gigops, | 2245 | GIGASET_DEVFSNAME, &gigops, |
2298 | THIS_MODULE)) == NULL) | 2246 | THIS_MODULE)) == NULL) |
2299 | goto error; | 2247 | goto error; |
2300 | 2248 | ||
2301 | /* allocate memory for our device state and intialize it */ | 2249 | /* allocate memory for our device state and intialize it */ |
2302 | cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode, GIGASET_MODULENAME); | 2250 | cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode, |
2251 | GIGASET_MODULENAME); | ||
2303 | if (!cardstate) | 2252 | if (!cardstate) |
2304 | goto error; | 2253 | goto error; |
2305 | 2254 | ||
@@ -2329,19 +2278,18 @@ error: if (cardstate) | |||
2329 | static void __exit bas_gigaset_exit(void) | 2278 | static void __exit bas_gigaset_exit(void) |
2330 | { | 2279 | { |
2331 | gigaset_blockdriver(driver); /* => probe will fail | 2280 | gigaset_blockdriver(driver); /* => probe will fail |
2332 | * => no gigaset_start any more | 2281 | * => no gigaset_start any more |
2333 | */ | 2282 | */ |
2334 | 2283 | ||
2335 | gigaset_shutdown(cardstate); | 2284 | gigaset_shutdown(cardstate); |
2336 | /* from now on, no isdn callback should be possible */ | 2285 | /* from now on, no isdn callback should be possible */ |
2337 | 2286 | ||
2338 | if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) { | 2287 | if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) { |
2339 | dbg(DEBUG_ANY, "closing AT channel"); | 2288 | gig_dbg(DEBUG_ANY, "closing AT channel"); |
2340 | if (req_submit(cardstate->bcs, | 2289 | if (req_submit(cardstate->bcs, |
2341 | HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) { | 2290 | HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) { |
2342 | /* successfully submitted - wait for completion */ | 2291 | /* successfully submitted */ |
2343 | //wait_event_interruptible(cs->initwait, !cs->hw.bas->pending); | 2292 | //FIXME wait for completion? |
2344 | //FIXME need own wait queue? wakeup? | ||
2345 | } | 2293 | } |
2346 | } | 2294 | } |
2347 | 2295 | ||
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 64371995c1a9..749b3da1236e 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,10 +11,6 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: common.c,v 1.104.4.22 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
@@ -23,7 +19,7 @@ | |||
23 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
24 | 20 | ||
25 | /* Version Information */ | 21 | /* Version Information */ |
26 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers <Eilers.Stefan@epost.de>" | 22 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers" |
27 | #define DRIVER_DESC "Driver for Gigaset 307x" | 23 | #define DRIVER_DESC "Driver for Gigaset 307x" |
28 | 24 | ||
29 | /* Module parameters */ | 25 | /* Module parameters */ |
@@ -32,21 +28,10 @@ EXPORT_SYMBOL_GPL(gigaset_debuglevel); | |||
32 | module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR); | 28 | module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR); |
33 | MODULE_PARM_DESC(debug, "debug level"); | 29 | MODULE_PARM_DESC(debug, "debug level"); |
34 | 30 | ||
35 | /*====================================================================== | 31 | /* driver state flags */ |
36 | Prototypes of internal functions | 32 | #define VALID_MINOR 0x01 |
37 | */ | 33 | #define VALID_ID 0x02 |
38 | 34 | #define ASSIGNED 0x04 | |
39 | //static void gigaset_process_response(int resp_code, int parameter, | ||
40 | // struct at_state_t *at_state, | ||
41 | // unsigned char ** pstring); | ||
42 | static struct cardstate *alloc_cs(struct gigaset_driver *drv); | ||
43 | static void free_cs(struct cardstate *cs); | ||
44 | static void make_valid(struct cardstate *cs, unsigned mask); | ||
45 | static void make_invalid(struct cardstate *cs, unsigned mask); | ||
46 | |||
47 | #define VALID_MINOR 0x01 | ||
48 | #define VALID_ID 0x02 | ||
49 | #define ASSIGNED 0x04 | ||
50 | 35 | ||
51 | /* bitwise byte inversion table */ | 36 | /* bitwise byte inversion table */ |
52 | __u8 gigaset_invtab[256] = { | 37 | __u8 gigaset_invtab[256] = { |
@@ -86,42 +71,40 @@ __u8 gigaset_invtab[256] = { | |||
86 | EXPORT_SYMBOL_GPL(gigaset_invtab); | 71 | EXPORT_SYMBOL_GPL(gigaset_invtab); |
87 | 72 | ||
88 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | 73 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, |
89 | size_t len, const unsigned char *buf, int from_user) | 74 | size_t len, const unsigned char *buf) |
90 | { | 75 | { |
91 | unsigned char outbuf[80]; | 76 | unsigned char outbuf[80]; |
92 | unsigned char inbuf[80 - 1]; | 77 | unsigned char c; |
93 | size_t numin; | ||
94 | const unsigned char *in; | ||
95 | size_t space = sizeof outbuf - 1; | 78 | size_t space = sizeof outbuf - 1; |
96 | unsigned char *out = outbuf; | 79 | unsigned char *out = outbuf; |
80 | size_t numin = len; | ||
97 | 81 | ||
98 | if (!from_user) { | 82 | while (numin--) { |
99 | in = buf; | 83 | c = *buf++; |
100 | numin = len; | 84 | if (c == '~' || c == '^' || c == '\\') { |
101 | } else { | 85 | if (!space--) |
102 | numin = len < sizeof inbuf ? len : sizeof inbuf; | 86 | break; |
103 | in = inbuf; | 87 | *out++ = '\\'; |
104 | if (copy_from_user(inbuf, (const unsigned char __user *) buf, numin)) { | ||
105 | strncpy(inbuf, "<FAULT>", sizeof inbuf); | ||
106 | numin = sizeof "<FAULT>" - 1; | ||
107 | } | 88 | } |
108 | } | 89 | if (c & 0x80) { |
109 | 90 | if (!space--) | |
110 | for (; numin && space; --numin, ++in) { | 91 | break; |
111 | --space; | 92 | *out++ = '~'; |
112 | if (*in >= 32) | 93 | c ^= 0x80; |
113 | *out++ = *in; | 94 | } |
114 | else { | 95 | if (c < 0x20 || c == 0x7f) { |
96 | if (!space--) | ||
97 | break; | ||
115 | *out++ = '^'; | 98 | *out++ = '^'; |
116 | if (space) { | 99 | c ^= 0x40; |
117 | *out++ = '@' + *in; | ||
118 | --space; | ||
119 | } | ||
120 | } | 100 | } |
101 | if (!space--) | ||
102 | break; | ||
103 | *out++ = c; | ||
121 | } | 104 | } |
122 | *out = 0; | 105 | *out = 0; |
123 | 106 | ||
124 | dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf); | 107 | gig_dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf); |
125 | } | 108 | } |
126 | EXPORT_SYMBOL_GPL(gigaset_dbg_buffer); | 109 | EXPORT_SYMBOL_GPL(gigaset_dbg_buffer); |
127 | 110 | ||
@@ -146,11 +129,6 @@ int gigaset_enterconfigmode(struct cardstate *cs) | |||
146 | { | 129 | { |
147 | int i, r; | 130 | int i, r; |
148 | 131 | ||
149 | if (!atomic_read(&cs->connected)) { | ||
150 | err("not connected!"); | ||
151 | return -1; | ||
152 | } | ||
153 | |||
154 | cs->control_state = TIOCM_RTS; //FIXME | 132 | cs->control_state = TIOCM_RTS; //FIXME |
155 | 133 | ||
156 | r = setflags(cs, TIOCM_DTR, 200); | 134 | r = setflags(cs, TIOCM_DTR, 200); |
@@ -174,7 +152,7 @@ int gigaset_enterconfigmode(struct cardstate *cs) | |||
174 | return 0; | 152 | return 0; |
175 | 153 | ||
176 | error: | 154 | error: |
177 | err("error %d on setuartbits!\n", -r); | 155 | dev_err(cs->dev, "error %d on setuartbits\n", -r); |
178 | cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value? | 156 | cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value? |
179 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR); | 157 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR); |
180 | 158 | ||
@@ -187,13 +165,13 @@ static int test_timeout(struct at_state_t *at_state) | |||
187 | return 0; | 165 | return 0; |
188 | 166 | ||
189 | if (--at_state->timer_expires) { | 167 | if (--at_state->timer_expires) { |
190 | dbg(DEBUG_MCMD, "decreased timer of %p to %lu", | 168 | gig_dbg(DEBUG_MCMD, "decreased timer of %p to %lu", |
191 | at_state, at_state->timer_expires); | 169 | at_state, at_state->timer_expires); |
192 | return 0; | 170 | return 0; |
193 | } | 171 | } |
194 | 172 | ||
195 | if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, | 173 | if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, |
196 | atomic_read(&at_state->timer_index), NULL)) { | 174 | at_state->timer_index, NULL)) { |
197 | //FIXME what should we do? | 175 | //FIXME what should we do? |
198 | } | 176 | } |
199 | 177 | ||
@@ -221,10 +199,10 @@ static void timer_tick(unsigned long data) | |||
221 | if (test_timeout(at_state)) | 199 | if (test_timeout(at_state)) |
222 | timeout = 1; | 200 | timeout = 1; |
223 | 201 | ||
224 | if (atomic_read(&cs->running)) { | 202 | if (cs->running) { |
225 | mod_timer(&cs->timer, jiffies + GIG_TICK); | 203 | mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK)); |
226 | if (timeout) { | 204 | if (timeout) { |
227 | dbg(DEBUG_CMD, "scheduling timeout"); | 205 | gig_dbg(DEBUG_CMD, "scheduling timeout"); |
228 | tasklet_schedule(&cs->event_tasklet); | 206 | tasklet_schedule(&cs->event_tasklet); |
229 | } | 207 | } |
230 | } | 208 | } |
@@ -238,13 +216,14 @@ int gigaset_get_channel(struct bc_state *bcs) | |||
238 | 216 | ||
239 | spin_lock_irqsave(&bcs->cs->lock, flags); | 217 | spin_lock_irqsave(&bcs->cs->lock, flags); |
240 | if (bcs->use_count) { | 218 | if (bcs->use_count) { |
241 | dbg(DEBUG_ANY, "could not allocate channel %d", bcs->channel); | 219 | gig_dbg(DEBUG_ANY, "could not allocate channel %d", |
220 | bcs->channel); | ||
242 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 221 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
243 | return 0; | 222 | return 0; |
244 | } | 223 | } |
245 | ++bcs->use_count; | 224 | ++bcs->use_count; |
246 | bcs->busy = 1; | 225 | bcs->busy = 1; |
247 | dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); | 226 | gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); |
248 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 227 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
249 | return 1; | 228 | return 1; |
250 | } | 229 | } |
@@ -255,13 +234,13 @@ void gigaset_free_channel(struct bc_state *bcs) | |||
255 | 234 | ||
256 | spin_lock_irqsave(&bcs->cs->lock, flags); | 235 | spin_lock_irqsave(&bcs->cs->lock, flags); |
257 | if (!bcs->busy) { | 236 | if (!bcs->busy) { |
258 | dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); | 237 | gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); |
259 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 238 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
260 | return; | 239 | return; |
261 | } | 240 | } |
262 | --bcs->use_count; | 241 | --bcs->use_count; |
263 | bcs->busy = 0; | 242 | bcs->busy = 0; |
264 | dbg(DEBUG_ANY, "freed channel %d", bcs->channel); | 243 | gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); |
265 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 244 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
266 | } | 245 | } |
267 | 246 | ||
@@ -274,14 +253,14 @@ int gigaset_get_channels(struct cardstate *cs) | |||
274 | for (i = 0; i < cs->channels; ++i) | 253 | for (i = 0; i < cs->channels; ++i) |
275 | if (cs->bcs[i].use_count) { | 254 | if (cs->bcs[i].use_count) { |
276 | spin_unlock_irqrestore(&cs->lock, flags); | 255 | spin_unlock_irqrestore(&cs->lock, flags); |
277 | dbg(DEBUG_ANY, "could not allocated all channels"); | 256 | gig_dbg(DEBUG_ANY, "could not allocate all channels"); |
278 | return 0; | 257 | return 0; |
279 | } | 258 | } |
280 | for (i = 0; i < cs->channels; ++i) | 259 | for (i = 0; i < cs->channels; ++i) |
281 | ++cs->bcs[i].use_count; | 260 | ++cs->bcs[i].use_count; |
282 | spin_unlock_irqrestore(&cs->lock, flags); | 261 | spin_unlock_irqrestore(&cs->lock, flags); |
283 | 262 | ||
284 | dbg(DEBUG_ANY, "allocated all channels"); | 263 | gig_dbg(DEBUG_ANY, "allocated all channels"); |
285 | 264 | ||
286 | return 1; | 265 | return 1; |
287 | } | 266 | } |
@@ -291,7 +270,7 @@ void gigaset_free_channels(struct cardstate *cs) | |||
291 | unsigned long flags; | 270 | unsigned long flags; |
292 | int i; | 271 | int i; |
293 | 272 | ||
294 | dbg(DEBUG_ANY, "unblocking all channels"); | 273 | gig_dbg(DEBUG_ANY, "unblocking all channels"); |
295 | spin_lock_irqsave(&cs->lock, flags); | 274 | spin_lock_irqsave(&cs->lock, flags); |
296 | for (i = 0; i < cs->channels; ++i) | 275 | for (i = 0; i < cs->channels; ++i) |
297 | --cs->bcs[i].use_count; | 276 | --cs->bcs[i].use_count; |
@@ -303,7 +282,7 @@ void gigaset_block_channels(struct cardstate *cs) | |||
303 | unsigned long flags; | 282 | unsigned long flags; |
304 | int i; | 283 | int i; |
305 | 284 | ||
306 | dbg(DEBUG_ANY, "blocking all channels"); | 285 | gig_dbg(DEBUG_ANY, "blocking all channels"); |
307 | spin_lock_irqsave(&cs->lock, flags); | 286 | spin_lock_irqsave(&cs->lock, flags); |
308 | for (i = 0; i < cs->channels; ++i) | 287 | for (i = 0; i < cs->channels; ++i) |
309 | ++cs->bcs[i].use_count; | 288 | ++cs->bcs[i].use_count; |
@@ -314,25 +293,27 @@ static void clear_events(struct cardstate *cs) | |||
314 | { | 293 | { |
315 | struct event_t *ev; | 294 | struct event_t *ev; |
316 | unsigned head, tail; | 295 | unsigned head, tail; |
296 | unsigned long flags; | ||
317 | 297 | ||
318 | /* no locking needed (no reader/writer allowed) */ | 298 | spin_lock_irqsave(&cs->ev_lock, flags); |
319 | 299 | ||
320 | head = atomic_read(&cs->ev_head); | 300 | head = cs->ev_head; |
321 | tail = atomic_read(&cs->ev_tail); | 301 | tail = cs->ev_tail; |
322 | 302 | ||
323 | while (tail != head) { | 303 | while (tail != head) { |
324 | ev = cs->events + head; | 304 | ev = cs->events + head; |
325 | kfree(ev->ptr); | 305 | kfree(ev->ptr); |
326 | |||
327 | head = (head + 1) % MAX_EVENTS; | 306 | head = (head + 1) % MAX_EVENTS; |
328 | } | 307 | } |
329 | 308 | ||
330 | atomic_set(&cs->ev_head, tail); | 309 | cs->ev_head = tail; |
310 | |||
311 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
331 | } | 312 | } |
332 | 313 | ||
333 | struct event_t *gigaset_add_event(struct cardstate *cs, | 314 | struct event_t *gigaset_add_event(struct cardstate *cs, |
334 | struct at_state_t *at_state, int type, | 315 | struct at_state_t *at_state, int type, |
335 | void *ptr, int parameter, void *arg) | 316 | void *ptr, int parameter, void *arg) |
336 | { | 317 | { |
337 | unsigned long flags; | 318 | unsigned long flags; |
338 | unsigned next, tail; | 319 | unsigned next, tail; |
@@ -340,9 +321,9 @@ struct event_t *gigaset_add_event(struct cardstate *cs, | |||
340 | 321 | ||
341 | spin_lock_irqsave(&cs->ev_lock, flags); | 322 | spin_lock_irqsave(&cs->ev_lock, flags); |
342 | 323 | ||
343 | tail = atomic_read(&cs->ev_tail); | 324 | tail = cs->ev_tail; |
344 | next = (tail + 1) % MAX_EVENTS; | 325 | next = (tail + 1) % MAX_EVENTS; |
345 | if (unlikely(next == atomic_read(&cs->ev_head))) | 326 | if (unlikely(next == cs->ev_head)) |
346 | err("event queue full"); | 327 | err("event queue full"); |
347 | else { | 328 | else { |
348 | event = cs->events + tail; | 329 | event = cs->events + tail; |
@@ -352,7 +333,7 @@ struct event_t *gigaset_add_event(struct cardstate *cs, | |||
352 | event->ptr = ptr; | 333 | event->ptr = ptr; |
353 | event->arg = arg; | 334 | event->arg = arg; |
354 | event->parameter = parameter; | 335 | event->parameter = parameter; |
355 | atomic_set(&cs->ev_tail, next); | 336 | cs->ev_tail = next; |
356 | } | 337 | } |
357 | 338 | ||
358 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 339 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
@@ -391,14 +372,14 @@ static void gigaset_freebcs(struct bc_state *bcs) | |||
391 | { | 372 | { |
392 | int i; | 373 | int i; |
393 | 374 | ||
394 | dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel); | 375 | gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel); |
395 | if (!bcs->cs->ops->freebcshw(bcs)) { | 376 | if (!bcs->cs->ops->freebcshw(bcs)) { |
396 | dbg(DEBUG_INIT, "failed"); | 377 | gig_dbg(DEBUG_INIT, "failed"); |
397 | } | 378 | } |
398 | 379 | ||
399 | dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); | 380 | gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); |
400 | clear_at_state(&bcs->at_state); | 381 | clear_at_state(&bcs->at_state); |
401 | dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); | 382 | gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); |
402 | 383 | ||
403 | if (bcs->skb) | 384 | if (bcs->skb) |
404 | dev_kfree_skb(bcs->skb); | 385 | dev_kfree_skb(bcs->skb); |
@@ -408,6 +389,52 @@ static void gigaset_freebcs(struct bc_state *bcs) | |||
408 | } | 389 | } |
409 | } | 390 | } |
410 | 391 | ||
392 | static struct cardstate *alloc_cs(struct gigaset_driver *drv) | ||
393 | { | ||
394 | unsigned long flags; | ||
395 | unsigned i; | ||
396 | static struct cardstate *ret = NULL; | ||
397 | |||
398 | spin_lock_irqsave(&drv->lock, flags); | ||
399 | for (i = 0; i < drv->minors; ++i) { | ||
400 | if (!(drv->flags[i] & VALID_MINOR)) { | ||
401 | drv->flags[i] = VALID_MINOR; | ||
402 | ret = drv->cs + i; | ||
403 | } | ||
404 | if (ret) | ||
405 | break; | ||
406 | } | ||
407 | spin_unlock_irqrestore(&drv->lock, flags); | ||
408 | return ret; | ||
409 | } | ||
410 | |||
411 | static void free_cs(struct cardstate *cs) | ||
412 | { | ||
413 | unsigned long flags; | ||
414 | struct gigaset_driver *drv = cs->driver; | ||
415 | spin_lock_irqsave(&drv->lock, flags); | ||
416 | drv->flags[cs->minor_index] = 0; | ||
417 | spin_unlock_irqrestore(&drv->lock, flags); | ||
418 | } | ||
419 | |||
420 | static void make_valid(struct cardstate *cs, unsigned mask) | ||
421 | { | ||
422 | unsigned long flags; | ||
423 | struct gigaset_driver *drv = cs->driver; | ||
424 | spin_lock_irqsave(&drv->lock, flags); | ||
425 | drv->flags[cs->minor_index] |= mask; | ||
426 | spin_unlock_irqrestore(&drv->lock, flags); | ||
427 | } | ||
428 | |||
429 | static void make_invalid(struct cardstate *cs, unsigned mask) | ||
430 | { | ||
431 | unsigned long flags; | ||
432 | struct gigaset_driver *drv = cs->driver; | ||
433 | spin_lock_irqsave(&drv->lock, flags); | ||
434 | drv->flags[cs->minor_index] &= ~mask; | ||
435 | spin_unlock_irqrestore(&drv->lock, flags); | ||
436 | } | ||
437 | |||
411 | void gigaset_freecs(struct cardstate *cs) | 438 | void gigaset_freecs(struct cardstate *cs) |
412 | { | 439 | { |
413 | int i; | 440 | int i; |
@@ -416,7 +443,7 @@ void gigaset_freecs(struct cardstate *cs) | |||
416 | if (!cs) | 443 | if (!cs) |
417 | return; | 444 | return; |
418 | 445 | ||
419 | down(&cs->sem); | 446 | mutex_lock(&cs->mutex); |
420 | 447 | ||
421 | if (!cs->bcs) | 448 | if (!cs->bcs) |
422 | goto f_cs; | 449 | goto f_cs; |
@@ -424,8 +451,9 @@ void gigaset_freecs(struct cardstate *cs) | |||
424 | goto f_bcs; | 451 | goto f_bcs; |
425 | 452 | ||
426 | spin_lock_irqsave(&cs->lock, flags); | 453 | spin_lock_irqsave(&cs->lock, flags); |
427 | atomic_set(&cs->running, 0); | 454 | cs->running = 0; |
428 | spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are not rescheduled below */ | 455 | spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are |
456 | not rescheduled below */ | ||
429 | 457 | ||
430 | tasklet_kill(&cs->event_tasklet); | 458 | tasklet_kill(&cs->event_tasklet); |
431 | del_timer_sync(&cs->timer); | 459 | del_timer_sync(&cs->timer); |
@@ -434,7 +462,7 @@ void gigaset_freecs(struct cardstate *cs) | |||
434 | default: | 462 | default: |
435 | gigaset_if_free(cs); | 463 | gigaset_if_free(cs); |
436 | 464 | ||
437 | dbg(DEBUG_INIT, "clearing hw"); | 465 | gig_dbg(DEBUG_INIT, "clearing hw"); |
438 | cs->ops->freecshw(cs); | 466 | cs->ops->freecshw(cs); |
439 | 467 | ||
440 | //FIXME cmdbuf | 468 | //FIXME cmdbuf |
@@ -443,36 +471,36 @@ void gigaset_freecs(struct cardstate *cs) | |||
443 | case 2: /* error in initcshw */ | 471 | case 2: /* error in initcshw */ |
444 | /* Deregister from LL */ | 472 | /* Deregister from LL */ |
445 | make_invalid(cs, VALID_ID); | 473 | make_invalid(cs, VALID_ID); |
446 | dbg(DEBUG_INIT, "clearing iif"); | 474 | gig_dbg(DEBUG_INIT, "clearing iif"); |
447 | gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); | 475 | gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); |
448 | 476 | ||
449 | /* fall through */ | 477 | /* fall through */ |
450 | case 1: /* error when regestering to LL */ | 478 | case 1: /* error when regestering to LL */ |
451 | dbg(DEBUG_INIT, "clearing at_state"); | 479 | gig_dbg(DEBUG_INIT, "clearing at_state"); |
452 | clear_at_state(&cs->at_state); | 480 | clear_at_state(&cs->at_state); |
453 | dealloc_at_states(cs); | 481 | dealloc_at_states(cs); |
454 | 482 | ||
455 | /* fall through */ | 483 | /* fall through */ |
456 | case 0: /* error in one call to initbcs */ | 484 | case 0: /* error in one call to initbcs */ |
457 | for (i = 0; i < cs->channels; ++i) { | 485 | for (i = 0; i < cs->channels; ++i) { |
458 | dbg(DEBUG_INIT, "clearing bcs[%d]", i); | 486 | gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i); |
459 | gigaset_freebcs(cs->bcs + i); | 487 | gigaset_freebcs(cs->bcs + i); |
460 | } | 488 | } |
461 | 489 | ||
462 | clear_events(cs); | 490 | clear_events(cs); |
463 | dbg(DEBUG_INIT, "freeing inbuf"); | 491 | gig_dbg(DEBUG_INIT, "freeing inbuf"); |
464 | kfree(cs->inbuf); | 492 | kfree(cs->inbuf); |
465 | } | 493 | } |
466 | f_bcs: dbg(DEBUG_INIT, "freeing bcs[]"); | 494 | f_bcs: gig_dbg(DEBUG_INIT, "freeing bcs[]"); |
467 | kfree(cs->bcs); | 495 | kfree(cs->bcs); |
468 | f_cs: dbg(DEBUG_INIT, "freeing cs"); | 496 | f_cs: gig_dbg(DEBUG_INIT, "freeing cs"); |
469 | up(&cs->sem); | 497 | mutex_unlock(&cs->mutex); |
470 | free_cs(cs); | 498 | free_cs(cs); |
471 | } | 499 | } |
472 | EXPORT_SYMBOL_GPL(gigaset_freecs); | 500 | EXPORT_SYMBOL_GPL(gigaset_freecs); |
473 | 501 | ||
474 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | 502 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, |
475 | struct cardstate *cs, int cid) | 503 | struct cardstate *cs, int cid) |
476 | { | 504 | { |
477 | int i; | 505 | int i; |
478 | 506 | ||
@@ -482,8 +510,8 @@ void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | |||
482 | at_state->pending_commands = 0; | 510 | at_state->pending_commands = 0; |
483 | at_state->timer_expires = 0; | 511 | at_state->timer_expires = 0; |
484 | at_state->timer_active = 0; | 512 | at_state->timer_active = 0; |
485 | atomic_set(&at_state->timer_index, 0); | 513 | at_state->timer_index = 0; |
486 | atomic_set(&at_state->seq_index, 0); | 514 | at_state->seq_index = 0; |
487 | at_state->ConState = 0; | 515 | at_state->ConState = 0; |
488 | for (i = 0; i < STR_NUM; ++i) | 516 | for (i = 0; i < STR_NUM; ++i) |
489 | at_state->str_var[i] = NULL; | 517 | at_state->str_var[i] = NULL; |
@@ -501,7 +529,7 @@ void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | |||
501 | 529 | ||
502 | 530 | ||
503 | static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, | 531 | static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, |
504 | struct cardstate *cs, int inputstate) | 532 | struct cardstate *cs, int inputstate) |
505 | /* inbuf->read must be allocated before! */ | 533 | /* inbuf->read must be allocated before! */ |
506 | { | 534 | { |
507 | atomic_set(&inbuf->head, 0); | 535 | atomic_set(&inbuf->head, 0); |
@@ -512,9 +540,50 @@ static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, | |||
512 | inbuf->inputstate = inputstate; | 540 | inbuf->inputstate = inputstate; |
513 | } | 541 | } |
514 | 542 | ||
543 | /* append received bytes to inbuf */ | ||
544 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | ||
545 | unsigned numbytes) | ||
546 | { | ||
547 | unsigned n, head, tail, bytesleft; | ||
548 | |||
549 | gig_dbg(DEBUG_INTR, "received %u bytes", numbytes); | ||
550 | |||
551 | if (!numbytes) | ||
552 | return 0; | ||
553 | |||
554 | bytesleft = numbytes; | ||
555 | tail = atomic_read(&inbuf->tail); | ||
556 | head = atomic_read(&inbuf->head); | ||
557 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | ||
558 | |||
559 | while (bytesleft) { | ||
560 | if (head > tail) | ||
561 | n = head - 1 - tail; | ||
562 | else if (head == 0) | ||
563 | n = (RBUFSIZE-1) - tail; | ||
564 | else | ||
565 | n = RBUFSIZE - tail; | ||
566 | if (!n) { | ||
567 | dev_err(inbuf->cs->dev, | ||
568 | "buffer overflow (%u bytes lost)", bytesleft); | ||
569 | break; | ||
570 | } | ||
571 | if (n > bytesleft) | ||
572 | n = bytesleft; | ||
573 | memcpy(inbuf->data + tail, src, n); | ||
574 | bytesleft -= n; | ||
575 | tail = (tail + n) % RBUFSIZE; | ||
576 | src += n; | ||
577 | } | ||
578 | gig_dbg(DEBUG_INTR, "setting tail to %u", tail); | ||
579 | atomic_set(&inbuf->tail, tail); | ||
580 | return numbytes != bytesleft; | ||
581 | } | ||
582 | EXPORT_SYMBOL_GPL(gigaset_fill_inbuf); | ||
583 | |||
515 | /* Initialize the b-channel structure */ | 584 | /* Initialize the b-channel structure */ |
516 | static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | 585 | static struct bc_state *gigaset_initbcs(struct bc_state *bcs, |
517 | struct cardstate *cs, int channel) | 586 | struct cardstate *cs, int channel) |
518 | { | 587 | { |
519 | int i; | 588 | int i; |
520 | 589 | ||
@@ -526,7 +595,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
526 | bcs->trans_down = 0; | 595 | bcs->trans_down = 0; |
527 | bcs->trans_up = 0; | 596 | bcs->trans_up = 0; |
528 | 597 | ||
529 | dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); | 598 | gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); |
530 | gigaset_at_init(&bcs->at_state, bcs, cs, -1); | 599 | gigaset_at_init(&bcs->at_state, bcs, cs, -1); |
531 | 600 | ||
532 | bcs->rcvbytes = 0; | 601 | bcs->rcvbytes = 0; |
@@ -535,7 +604,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
535 | bcs->emptycount = 0; | 604 | bcs->emptycount = 0; |
536 | #endif | 605 | #endif |
537 | 606 | ||
538 | dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel); | 607 | gig_dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel); |
539 | bcs->fcs = PPP_INITFCS; | 608 | bcs->fcs = PPP_INITFCS; |
540 | bcs->inputstate = 0; | 609 | bcs->inputstate = 0; |
541 | if (cs->ignoreframes) { | 610 | if (cs->ignoreframes) { |
@@ -544,7 +613,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
544 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 613 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
545 | skb_reserve(bcs->skb, HW_HDR_LEN); | 614 | skb_reserve(bcs->skb, HW_HDR_LEN); |
546 | else { | 615 | else { |
547 | warn("could not allocate skb"); | 616 | dev_warn(cs->dev, "could not allocate skb\n"); |
548 | bcs->inputstate |= INS_skip_frame; | 617 | bcs->inputstate |= INS_skip_frame; |
549 | } | 618 | } |
550 | 619 | ||
@@ -559,14 +628,13 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
559 | for (i = 0; i < AT_NUM; ++i) | 628 | for (i = 0; i < AT_NUM; ++i) |
560 | bcs->commands[i] = NULL; | 629 | bcs->commands[i] = NULL; |
561 | 630 | ||
562 | dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel); | 631 | gig_dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel); |
563 | if (cs->ops->initbcshw(bcs)) | 632 | if (cs->ops->initbcshw(bcs)) |
564 | return bcs; | 633 | return bcs; |
565 | 634 | ||
566 | //error: | 635 | gig_dbg(DEBUG_INIT, " failed"); |
567 | dbg(DEBUG_INIT, " failed"); | ||
568 | 636 | ||
569 | dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); | 637 | gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); |
570 | if (bcs->skb) | 638 | if (bcs->skb) |
571 | dev_kfree_skb(bcs->skb); | 639 | dev_kfree_skb(bcs->skb); |
572 | 640 | ||
@@ -578,9 +646,10 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
578 | * Calls hardware dependent gigaset_initcshw() function | 646 | * Calls hardware dependent gigaset_initcshw() function |
579 | * Calls B channel initialization function gigaset_initbcs() for each B channel | 647 | * Calls B channel initialization function gigaset_initbcs() for each B channel |
580 | * parameters: | 648 | * parameters: |
581 | * drv hardware driver the device belongs to | 649 | * drv hardware driver the device belongs to |
582 | * channels number of B channels supported by device | 650 | * channels number of B channels supported by device |
583 | * onechannel !=0: B channel data and AT commands share one communication channel | 651 | * onechannel !=0: B channel data and AT commands share one |
652 | * communication channel | ||
584 | * ==0: B channels have separate communication channels | 653 | * ==0: B channels have separate communication channels |
585 | * ignoreframes number of frames to ignore after setting up B channel | 654 | * ignoreframes number of frames to ignore after setting up B channel |
586 | * cidmode !=0: start in CallID mode | 655 | * cidmode !=0: start in CallID mode |
@@ -593,17 +662,18 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
593 | int cidmode, const char *modulename) | 662 | int cidmode, const char *modulename) |
594 | { | 663 | { |
595 | struct cardstate *cs = NULL; | 664 | struct cardstate *cs = NULL; |
665 | unsigned long flags; | ||
596 | int i; | 666 | int i; |
597 | 667 | ||
598 | dbg(DEBUG_INIT, "allocating cs"); | 668 | gig_dbg(DEBUG_INIT, "allocating cs"); |
599 | cs = alloc_cs(drv); | 669 | cs = alloc_cs(drv); |
600 | if (!cs) | 670 | if (!cs) |
601 | goto error; | 671 | goto error; |
602 | dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); | 672 | gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); |
603 | cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); | 673 | cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); |
604 | if (!cs->bcs) | 674 | if (!cs->bcs) |
605 | goto error; | 675 | goto error; |
606 | dbg(DEBUG_INIT, "allocating inbuf"); | 676 | gig_dbg(DEBUG_INIT, "allocating inbuf"); |
607 | cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); | 677 | cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); |
608 | if (!cs->inbuf) | 678 | if (!cs->inbuf) |
609 | goto error; | 679 | goto error; |
@@ -613,19 +683,23 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
613 | cs->onechannel = onechannel; | 683 | cs->onechannel = onechannel; |
614 | cs->ignoreframes = ignoreframes; | 684 | cs->ignoreframes = ignoreframes; |
615 | INIT_LIST_HEAD(&cs->temp_at_states); | 685 | INIT_LIST_HEAD(&cs->temp_at_states); |
616 | atomic_set(&cs->running, 0); | 686 | cs->running = 0; |
617 | init_timer(&cs->timer); /* clear next & prev */ | 687 | init_timer(&cs->timer); /* clear next & prev */ |
618 | spin_lock_init(&cs->ev_lock); | 688 | spin_lock_init(&cs->ev_lock); |
619 | atomic_set(&cs->ev_tail, 0); | 689 | cs->ev_tail = 0; |
620 | atomic_set(&cs->ev_head, 0); | 690 | cs->ev_head = 0; |
621 | init_MUTEX_LOCKED(&cs->sem); | 691 | mutex_init(&cs->mutex); |
622 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, (unsigned long) cs); | 692 | mutex_lock(&cs->mutex); |
693 | |||
694 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, | ||
695 | (unsigned long) cs); | ||
623 | atomic_set(&cs->commands_pending, 0); | 696 | atomic_set(&cs->commands_pending, 0); |
624 | cs->cur_at_seq = 0; | 697 | cs->cur_at_seq = 0; |
625 | cs->gotfwver = -1; | 698 | cs->gotfwver = -1; |
626 | cs->open_count = 0; | 699 | cs->open_count = 0; |
700 | cs->dev = NULL; | ||
627 | cs->tty = NULL; | 701 | cs->tty = NULL; |
628 | atomic_set(&cs->cidmode, cidmode != 0); | 702 | cs->cidmode = cidmode != 0; |
629 | 703 | ||
630 | //if(onechannel) { //FIXME | 704 | //if(onechannel) { //FIXME |
631 | cs->tabnocid = gigaset_tab_nocid_m10x; | 705 | cs->tabnocid = gigaset_tab_nocid_m10x; |
@@ -642,50 +716,43 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
642 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 716 | atomic_set(&cs->mstate, MS_UNINITIALIZED); |
643 | 717 | ||
644 | for (i = 0; i < channels; ++i) { | 718 | for (i = 0; i < channels; ++i) { |
645 | dbg(DEBUG_INIT, "setting up bcs[%d].read", i); | 719 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); |
646 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) | 720 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) |
647 | goto error; | 721 | goto error; |
648 | } | 722 | } |
649 | 723 | ||
650 | ++cs->cs_init; | 724 | ++cs->cs_init; |
651 | 725 | ||
652 | dbg(DEBUG_INIT, "setting up at_state"); | 726 | gig_dbg(DEBUG_INIT, "setting up at_state"); |
653 | spin_lock_init(&cs->lock); | 727 | spin_lock_init(&cs->lock); |
654 | gigaset_at_init(&cs->at_state, NULL, cs, 0); | 728 | gigaset_at_init(&cs->at_state, NULL, cs, 0); |
655 | cs->dle = 0; | 729 | cs->dle = 0; |
656 | cs->cbytes = 0; | 730 | cs->cbytes = 0; |
657 | 731 | ||
658 | dbg(DEBUG_INIT, "setting up inbuf"); | 732 | gig_dbg(DEBUG_INIT, "setting up inbuf"); |
659 | if (onechannel) { //FIXME distinction necessary? | 733 | if (onechannel) { //FIXME distinction necessary? |
660 | gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command); | 734 | gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command); |
661 | } else | 735 | } else |
662 | gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command); | 736 | gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command); |
663 | 737 | ||
664 | atomic_set(&cs->connected, 0); | 738 | cs->connected = 0; |
739 | cs->isdn_up = 0; | ||
665 | 740 | ||
666 | dbg(DEBUG_INIT, "setting up cmdbuf"); | 741 | gig_dbg(DEBUG_INIT, "setting up cmdbuf"); |
667 | cs->cmdbuf = cs->lastcmdbuf = NULL; | 742 | cs->cmdbuf = cs->lastcmdbuf = NULL; |
668 | spin_lock_init(&cs->cmdlock); | 743 | spin_lock_init(&cs->cmdlock); |
669 | cs->curlen = 0; | 744 | cs->curlen = 0; |
670 | cs->cmdbytes = 0; | 745 | cs->cmdbytes = 0; |
671 | 746 | ||
672 | /* | 747 | gig_dbg(DEBUG_INIT, "setting up iif"); |
673 | * Tell the ISDN4Linux subsystem (the LL) that | ||
674 | * a driver for a USB-Device is available ! | ||
675 | * If this is done, "isdnctrl" is able to bind a device for this driver even | ||
676 | * if no physical usb-device is currently connected. | ||
677 | * But this device will just be accessable if a physical USB device is connected | ||
678 | * (via "gigaset_probe") . | ||
679 | */ | ||
680 | dbg(DEBUG_INIT, "setting up iif"); | ||
681 | if (!gigaset_register_to_LL(cs, modulename)) { | 748 | if (!gigaset_register_to_LL(cs, modulename)) { |
682 | err("register_isdn=>error"); | 749 | err("register_isdn failed"); |
683 | goto error; | 750 | goto error; |
684 | } | 751 | } |
685 | 752 | ||
686 | make_valid(cs, VALID_ID); | 753 | make_valid(cs, VALID_ID); |
687 | ++cs->cs_init; | 754 | ++cs->cs_init; |
688 | dbg(DEBUG_INIT, "setting up hw"); | 755 | gig_dbg(DEBUG_INIT, "setting up hw"); |
689 | if (!cs->ops->initcshw(cs)) | 756 | if (!cs->ops->initcshw(cs)) |
690 | goto error; | 757 | goto error; |
691 | 758 | ||
@@ -693,27 +760,29 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
693 | 760 | ||
694 | gigaset_if_init(cs); | 761 | gigaset_if_init(cs); |
695 | 762 | ||
696 | atomic_set(&cs->running, 1); | 763 | spin_lock_irqsave(&cs->lock, flags); |
697 | cs->timer.data = (unsigned long) cs; | 764 | cs->running = 1; |
698 | cs->timer.function = timer_tick; | 765 | spin_unlock_irqrestore(&cs->lock, flags); |
699 | cs->timer.expires = jiffies + GIG_TICK; | 766 | setup_timer(&cs->timer, timer_tick, (unsigned long) cs); |
767 | cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK); | ||
700 | /* FIXME: can jiffies increase too much until the timer is added? | 768 | /* FIXME: can jiffies increase too much until the timer is added? |
701 | * Same problem(?) with mod_timer() in timer_tick(). */ | 769 | * Same problem(?) with mod_timer() in timer_tick(). */ |
702 | add_timer(&cs->timer); | 770 | add_timer(&cs->timer); |
703 | 771 | ||
704 | dbg(DEBUG_INIT, "cs initialized!"); | 772 | gig_dbg(DEBUG_INIT, "cs initialized"); |
705 | up(&cs->sem); | 773 | mutex_unlock(&cs->mutex); |
706 | return cs; | 774 | return cs; |
707 | 775 | ||
708 | error: if (cs) | 776 | error: if (cs) |
709 | up(&cs->sem); | 777 | mutex_unlock(&cs->mutex); |
710 | dbg(DEBUG_INIT, "failed"); | 778 | gig_dbg(DEBUG_INIT, "failed"); |
711 | gigaset_freecs(cs); | 779 | gigaset_freecs(cs); |
712 | return NULL; | 780 | return NULL; |
713 | } | 781 | } |
714 | EXPORT_SYMBOL_GPL(gigaset_initcs); | 782 | EXPORT_SYMBOL_GPL(gigaset_initcs); |
715 | 783 | ||
716 | /* ReInitialize the b-channel structure */ /* e.g. called on hangup, disconnect */ | 784 | /* ReInitialize the b-channel structure */ |
785 | /* e.g. called on hangup, disconnect */ | ||
717 | void gigaset_bcs_reinit(struct bc_state *bcs) | 786 | void gigaset_bcs_reinit(struct bc_state *bcs) |
718 | { | 787 | { |
719 | struct sk_buff *skb; | 788 | struct sk_buff *skb; |
@@ -723,12 +792,12 @@ void gigaset_bcs_reinit(struct bc_state *bcs) | |||
723 | while ((skb = skb_dequeue(&bcs->squeue)) != NULL) | 792 | while ((skb = skb_dequeue(&bcs->squeue)) != NULL) |
724 | dev_kfree_skb(skb); | 793 | dev_kfree_skb(skb); |
725 | 794 | ||
726 | spin_lock_irqsave(&cs->lock, flags); //FIXME | 795 | spin_lock_irqsave(&cs->lock, flags); |
727 | clear_at_state(&bcs->at_state); | 796 | clear_at_state(&bcs->at_state); |
728 | bcs->at_state.ConState = 0; | 797 | bcs->at_state.ConState = 0; |
729 | bcs->at_state.timer_active = 0; | 798 | bcs->at_state.timer_active = 0; |
730 | bcs->at_state.timer_expires = 0; | 799 | bcs->at_state.timer_expires = 0; |
731 | bcs->at_state.cid = -1; /* No CID defined */ | 800 | bcs->at_state.cid = -1; /* No CID defined */ |
732 | spin_unlock_irqrestore(&cs->lock, flags); | 801 | spin_unlock_irqrestore(&cs->lock, flags); |
733 | 802 | ||
734 | bcs->inputstate = 0; | 803 | bcs->inputstate = 0; |
@@ -803,11 +872,14 @@ static void cleanup_cs(struct cardstate *cs) | |||
803 | 872 | ||
804 | int gigaset_start(struct cardstate *cs) | 873 | int gigaset_start(struct cardstate *cs) |
805 | { | 874 | { |
806 | if (down_interruptible(&cs->sem)) | 875 | unsigned long flags; |
876 | |||
877 | if (mutex_lock_interruptible(&cs->mutex)) | ||
807 | return 0; | 878 | return 0; |
808 | //info("USB device for Gigaset 307x now attached to Dev %d", ucs->minor); | ||
809 | 879 | ||
810 | atomic_set(&cs->connected, 1); | 880 | spin_lock_irqsave(&cs->lock, flags); |
881 | cs->connected = 1; | ||
882 | spin_unlock_irqrestore(&cs->lock, flags); | ||
811 | 883 | ||
812 | if (atomic_read(&cs->mstate) != MS_LOCKED) { | 884 | if (atomic_read(&cs->mstate) != MS_LOCKED) { |
813 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); | 885 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); |
@@ -826,23 +898,26 @@ int gigaset_start(struct cardstate *cs) | |||
826 | goto error; | 898 | goto error; |
827 | } | 899 | } |
828 | 900 | ||
829 | dbg(DEBUG_CMD, "scheduling START"); | 901 | gig_dbg(DEBUG_CMD, "scheduling START"); |
830 | gigaset_schedule_event(cs); | 902 | gigaset_schedule_event(cs); |
831 | 903 | ||
832 | wait_event(cs->waitqueue, !cs->waiting); | 904 | wait_event(cs->waitqueue, !cs->waiting); |
833 | 905 | ||
834 | up(&cs->sem); | 906 | /* set up device sysfs */ |
907 | gigaset_init_dev_sysfs(cs); | ||
908 | |||
909 | mutex_unlock(&cs->mutex); | ||
835 | return 1; | 910 | return 1; |
836 | 911 | ||
837 | error: | 912 | error: |
838 | up(&cs->sem); | 913 | mutex_unlock(&cs->mutex); |
839 | return 0; | 914 | return 0; |
840 | } | 915 | } |
841 | EXPORT_SYMBOL_GPL(gigaset_start); | 916 | EXPORT_SYMBOL_GPL(gigaset_start); |
842 | 917 | ||
843 | void gigaset_shutdown(struct cardstate *cs) | 918 | void gigaset_shutdown(struct cardstate *cs) |
844 | { | 919 | { |
845 | down(&cs->sem); | 920 | mutex_lock(&cs->mutex); |
846 | 921 | ||
847 | cs->waiting = 1; | 922 | cs->waiting = 1; |
848 | 923 | ||
@@ -851,11 +926,11 @@ void gigaset_shutdown(struct cardstate *cs) | |||
851 | goto exit; | 926 | goto exit; |
852 | } | 927 | } |
853 | 928 | ||
854 | dbg(DEBUG_CMD, "scheduling SHUTDOWN"); | 929 | gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN"); |
855 | gigaset_schedule_event(cs); | 930 | gigaset_schedule_event(cs); |
856 | 931 | ||
857 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { | 932 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { |
858 | warn("aborted"); | 933 | warn("%s: aborted", __func__); |
859 | //FIXME | 934 | //FIXME |
860 | } | 935 | } |
861 | 936 | ||
@@ -872,15 +947,13 @@ void gigaset_shutdown(struct cardstate *cs) | |||
872 | cleanup_cs(cs); | 947 | cleanup_cs(cs); |
873 | 948 | ||
874 | exit: | 949 | exit: |
875 | up(&cs->sem); | 950 | mutex_unlock(&cs->mutex); |
876 | } | 951 | } |
877 | EXPORT_SYMBOL_GPL(gigaset_shutdown); | 952 | EXPORT_SYMBOL_GPL(gigaset_shutdown); |
878 | 953 | ||
879 | void gigaset_stop(struct cardstate *cs) | 954 | void gigaset_stop(struct cardstate *cs) |
880 | { | 955 | { |
881 | down(&cs->sem); | 956 | mutex_lock(&cs->mutex); |
882 | |||
883 | atomic_set(&cs->connected, 0); | ||
884 | 957 | ||
885 | cs->waiting = 1; | 958 | cs->waiting = 1; |
886 | 959 | ||
@@ -889,21 +962,21 @@ void gigaset_stop(struct cardstate *cs) | |||
889 | goto exit; | 962 | goto exit; |
890 | } | 963 | } |
891 | 964 | ||
892 | dbg(DEBUG_CMD, "scheduling STOP"); | 965 | gig_dbg(DEBUG_CMD, "scheduling STOP"); |
893 | gigaset_schedule_event(cs); | 966 | gigaset_schedule_event(cs); |
894 | 967 | ||
895 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { | 968 | if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) { |
896 | warn("aborted"); | 969 | warn("%s: aborted", __func__); |
897 | //FIXME | 970 | //FIXME |
898 | } | 971 | } |
899 | 972 | ||
900 | /* Tell the LL that the device is not available .. */ | 973 | /* clear device sysfs */ |
901 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); // FIXME move to event layer? | 974 | gigaset_free_dev_sysfs(cs); |
902 | 975 | ||
903 | cleanup_cs(cs); | 976 | cleanup_cs(cs); |
904 | 977 | ||
905 | exit: | 978 | exit: |
906 | up(&cs->sem); | 979 | mutex_unlock(&cs->mutex); |
907 | } | 980 | } |
908 | EXPORT_SYMBOL_GPL(gigaset_stop); | 981 | EXPORT_SYMBOL_GPL(gigaset_stop); |
909 | 982 | ||
@@ -947,31 +1020,25 @@ void gigaset_debugdrivers(void) | |||
947 | 1020 | ||
948 | spin_lock_irqsave(&driver_lock, flags); | 1021 | spin_lock_irqsave(&driver_lock, flags); |
949 | list_for_each_entry(drv, &drivers, list) { | 1022 | list_for_each_entry(drv, &drivers, list) { |
950 | dbg(DEBUG_DRIVER, "driver %p", drv); | 1023 | gig_dbg(DEBUG_DRIVER, "driver %p", drv); |
951 | spin_lock(&drv->lock); | 1024 | spin_lock(&drv->lock); |
952 | for (i = 0; i < drv->minors; ++i) { | 1025 | for (i = 0; i < drv->minors; ++i) { |
953 | dbg(DEBUG_DRIVER, " index %u", i); | 1026 | gig_dbg(DEBUG_DRIVER, " index %u", i); |
954 | dbg(DEBUG_DRIVER, " flags 0x%02x", drv->flags[i]); | 1027 | gig_dbg(DEBUG_DRIVER, " flags 0x%02x", |
1028 | drv->flags[i]); | ||
955 | cs = drv->cs + i; | 1029 | cs = drv->cs + i; |
956 | dbg(DEBUG_DRIVER, " cardstate %p", cs); | 1030 | gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); |
957 | dbg(DEBUG_DRIVER, " minor_index %u", cs->minor_index); | 1031 | gig_dbg(DEBUG_DRIVER, " minor_index %u", |
958 | dbg(DEBUG_DRIVER, " driver %p", cs->driver); | 1032 | cs->minor_index); |
959 | dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); | 1033 | gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); |
1034 | gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); | ||
960 | } | 1035 | } |
961 | spin_unlock(&drv->lock); | 1036 | spin_unlock(&drv->lock); |
962 | } | 1037 | } |
963 | spin_unlock_irqrestore(&driver_lock, flags); | 1038 | spin_unlock_irqrestore(&driver_lock, flags); |
964 | } | 1039 | } |
965 | EXPORT_SYMBOL_GPL(gigaset_debugdrivers); | ||
966 | |||
967 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) | ||
968 | { | ||
969 | if (tty->index < 0 || tty->index >= tty->driver->num) | ||
970 | return NULL; | ||
971 | return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); | ||
972 | } | ||
973 | 1040 | ||
974 | struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | 1041 | static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) |
975 | { | 1042 | { |
976 | unsigned long flags; | 1043 | unsigned long flags; |
977 | static struct cardstate *ret = NULL; | 1044 | static struct cardstate *ret = NULL; |
@@ -994,6 +1061,13 @@ struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | |||
994 | return ret; | 1061 | return ret; |
995 | } | 1062 | } |
996 | 1063 | ||
1064 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) | ||
1065 | { | ||
1066 | if (tty->index < 0 || tty->index >= tty->driver->num) | ||
1067 | return NULL; | ||
1068 | return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); | ||
1069 | } | ||
1070 | |||
997 | void gigaset_freedriver(struct gigaset_driver *drv) | 1071 | void gigaset_freedriver(struct gigaset_driver *drv) |
998 | { | 1072 | { |
999 | unsigned long flags; | 1073 | unsigned long flags; |
@@ -1014,20 +1088,20 @@ EXPORT_SYMBOL_GPL(gigaset_freedriver); | |||
1014 | /* gigaset_initdriver | 1088 | /* gigaset_initdriver |
1015 | * Allocate and initialize gigaset_driver structure. Initialize interface. | 1089 | * Allocate and initialize gigaset_driver structure. Initialize interface. |
1016 | * parameters: | 1090 | * parameters: |
1017 | * minor First minor number | 1091 | * minor First minor number |
1018 | * minors Number of minors this driver can handle | 1092 | * minors Number of minors this driver can handle |
1019 | * procname Name of the driver (e.g. for /proc/tty/drivers, path in /proc/driver) | 1093 | * procname Name of the driver |
1020 | * devname Name of the device files (prefix without minor number) | 1094 | * devname Name of the device files (prefix without minor number) |
1021 | * devfsname Devfs name of the device files without %d | 1095 | * devfsname Devfs name of the device files without %d |
1022 | * return value: | 1096 | * return value: |
1023 | * Pointer to the gigaset_driver structure on success, NULL on failure. | 1097 | * Pointer to the gigaset_driver structure on success, NULL on failure. |
1024 | */ | 1098 | */ |
1025 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 1099 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, |
1026 | const char *procname, | 1100 | const char *procname, |
1027 | const char *devname, | 1101 | const char *devname, |
1028 | const char *devfsname, | 1102 | const char *devfsname, |
1029 | const struct gigaset_ops *ops, | 1103 | const struct gigaset_ops *ops, |
1030 | struct module *owner) | 1104 | struct module *owner) |
1031 | { | 1105 | { |
1032 | struct gigaset_driver *drv; | 1106 | struct gigaset_driver *drv; |
1033 | unsigned long flags; | 1107 | unsigned long flags; |
@@ -1036,8 +1110,9 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1036 | drv = kmalloc(sizeof *drv, GFP_KERNEL); | 1110 | drv = kmalloc(sizeof *drv, GFP_KERNEL); |
1037 | if (!drv) | 1111 | if (!drv) |
1038 | return NULL; | 1112 | return NULL; |
1113 | |||
1039 | if (!try_module_get(owner)) | 1114 | if (!try_module_get(owner)) |
1040 | return NULL; | 1115 | goto out1; |
1041 | 1116 | ||
1042 | drv->cs = NULL; | 1117 | drv->cs = NULL; |
1043 | drv->have_tty = 0; | 1118 | drv->have_tty = 0; |
@@ -1051,10 +1126,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1051 | 1126 | ||
1052 | drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); | 1127 | drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); |
1053 | if (!drv->cs) | 1128 | if (!drv->cs) |
1054 | goto out1; | 1129 | goto out2; |
1130 | |||
1055 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); | 1131 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); |
1056 | if (!drv->flags) | 1132 | if (!drv->flags) |
1057 | goto out2; | 1133 | goto out3; |
1058 | 1134 | ||
1059 | for (i = 0; i < minors; ++i) { | 1135 | for (i = 0; i < minors; ++i) { |
1060 | drv->flags[i] = 0; | 1136 | drv->flags[i] = 0; |
@@ -1071,61 +1147,16 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1071 | 1147 | ||
1072 | return drv; | 1148 | return drv; |
1073 | 1149 | ||
1074 | out2: | 1150 | out3: |
1075 | kfree(drv->cs); | 1151 | kfree(drv->cs); |
1152 | out2: | ||
1153 | module_put(owner); | ||
1076 | out1: | 1154 | out1: |
1077 | kfree(drv); | 1155 | kfree(drv); |
1078 | module_put(owner); | ||
1079 | return NULL; | 1156 | return NULL; |
1080 | } | 1157 | } |
1081 | EXPORT_SYMBOL_GPL(gigaset_initdriver); | 1158 | EXPORT_SYMBOL_GPL(gigaset_initdriver); |
1082 | 1159 | ||
1083 | static struct cardstate *alloc_cs(struct gigaset_driver *drv) | ||
1084 | { | ||
1085 | unsigned long flags; | ||
1086 | unsigned i; | ||
1087 | static struct cardstate *ret = NULL; | ||
1088 | |||
1089 | spin_lock_irqsave(&drv->lock, flags); | ||
1090 | for (i = 0; i < drv->minors; ++i) { | ||
1091 | if (!(drv->flags[i] & VALID_MINOR)) { | ||
1092 | drv->flags[i] = VALID_MINOR; | ||
1093 | ret = drv->cs + i; | ||
1094 | } | ||
1095 | if (ret) | ||
1096 | break; | ||
1097 | } | ||
1098 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1099 | return ret; | ||
1100 | } | ||
1101 | |||
1102 | static void free_cs(struct cardstate *cs) | ||
1103 | { | ||
1104 | unsigned long flags; | ||
1105 | struct gigaset_driver *drv = cs->driver; | ||
1106 | spin_lock_irqsave(&drv->lock, flags); | ||
1107 | drv->flags[cs->minor_index] = 0; | ||
1108 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1109 | } | ||
1110 | |||
1111 | static void make_valid(struct cardstate *cs, unsigned mask) | ||
1112 | { | ||
1113 | unsigned long flags; | ||
1114 | struct gigaset_driver *drv = cs->driver; | ||
1115 | spin_lock_irqsave(&drv->lock, flags); | ||
1116 | drv->flags[cs->minor_index] |= mask; | ||
1117 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1118 | } | ||
1119 | |||
1120 | static void make_invalid(struct cardstate *cs, unsigned mask) | ||
1121 | { | ||
1122 | unsigned long flags; | ||
1123 | struct gigaset_driver *drv = cs->driver; | ||
1124 | spin_lock_irqsave(&drv->lock, flags); | ||
1125 | drv->flags[cs->minor_index] &= ~mask; | ||
1126 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1127 | } | ||
1128 | |||
1129 | /* For drivers without fixed assignment device<->cardstate (usb) */ | 1160 | /* For drivers without fixed assignment device<->cardstate (usb) */ |
1130 | struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv) | 1161 | struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv) |
1131 | { | 1162 | { |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index fdcb80bb21c7..1ba3424a286b 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,82 +11,78 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: ev-layer.c,v 1.4.2.18 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | 17 | ||
22 | /* ========================================================== */ | 18 | /* ========================================================== */ |
23 | /* bit masks for pending commands */ | 19 | /* bit masks for pending commands */ |
24 | #define PC_INIT 0x004 | 20 | #define PC_DIAL 0x001 |
25 | #define PC_DLE0 0x008 | 21 | #define PC_HUP 0x002 |
26 | #define PC_DLE1 0x010 | 22 | #define PC_INIT 0x004 |
27 | #define PC_CID 0x080 | 23 | #define PC_DLE0 0x008 |
28 | #define PC_NOCID 0x100 | 24 | #define PC_DLE1 0x010 |
29 | #define PC_HUP 0x002 | 25 | #define PC_SHUTDOWN 0x020 |
30 | #define PC_DIAL 0x001 | 26 | #define PC_ACCEPT 0x040 |
31 | #define PC_ACCEPT 0x040 | 27 | #define PC_CID 0x080 |
32 | #define PC_SHUTDOWN 0x020 | 28 | #define PC_NOCID 0x100 |
33 | #define PC_CIDMODE 0x200 | 29 | #define PC_CIDMODE 0x200 |
34 | #define PC_UMMODE 0x400 | 30 | #define PC_UMMODE 0x400 |
35 | 31 | ||
36 | /* types of modem responses */ | 32 | /* types of modem responses */ |
37 | #define RT_NOTHING 0 | 33 | #define RT_NOTHING 0 |
38 | #define RT_ZSAU 1 | 34 | #define RT_ZSAU 1 |
39 | #define RT_RING 2 | 35 | #define RT_RING 2 |
40 | #define RT_NUMBER 3 | 36 | #define RT_NUMBER 3 |
41 | #define RT_STRING 4 | 37 | #define RT_STRING 4 |
42 | #define RT_HEX 5 | 38 | #define RT_HEX 5 |
43 | #define RT_ZCAU 6 | 39 | #define RT_ZCAU 6 |
44 | 40 | ||
45 | /* Possible ASCII responses */ | 41 | /* Possible ASCII responses */ |
46 | #define RSP_OK 0 | 42 | #define RSP_OK 0 |
47 | //#define RSP_BUSY 1 | 43 | //#define RSP_BUSY 1 |
48 | //#define RSP_CONNECT 2 | 44 | //#define RSP_CONNECT 2 |
49 | #define RSP_ZGCI 3 | 45 | #define RSP_ZGCI 3 |
50 | #define RSP_RING 4 | 46 | #define RSP_RING 4 |
51 | #define RSP_ZAOC 5 | 47 | #define RSP_ZAOC 5 |
52 | #define RSP_ZCSTR 6 | 48 | #define RSP_ZCSTR 6 |
53 | #define RSP_ZCFGT 7 | 49 | #define RSP_ZCFGT 7 |
54 | #define RSP_ZCFG 8 | 50 | #define RSP_ZCFG 8 |
55 | #define RSP_ZCCR 9 | 51 | #define RSP_ZCCR 9 |
56 | #define RSP_EMPTY 10 | 52 | #define RSP_EMPTY 10 |
57 | #define RSP_ZLOG 11 | 53 | #define RSP_ZLOG 11 |
58 | #define RSP_ZCAU 12 | 54 | #define RSP_ZCAU 12 |
59 | #define RSP_ZMWI 13 | 55 | #define RSP_ZMWI 13 |
60 | #define RSP_ZABINFO 14 | 56 | #define RSP_ZABINFO 14 |
61 | #define RSP_ZSMLSTCHG 15 | 57 | #define RSP_ZSMLSTCHG 15 |
62 | #define RSP_VAR 100 | 58 | #define RSP_VAR 100 |
63 | #define RSP_ZSAU (RSP_VAR + VAR_ZSAU) | 59 | #define RSP_ZSAU (RSP_VAR + VAR_ZSAU) |
64 | #define RSP_ZDLE (RSP_VAR + VAR_ZDLE) | 60 | #define RSP_ZDLE (RSP_VAR + VAR_ZDLE) |
65 | #define RSP_ZVLS (RSP_VAR + VAR_ZVLS) | 61 | #define RSP_ZVLS (RSP_VAR + VAR_ZVLS) |
66 | #define RSP_ZCTP (RSP_VAR + VAR_ZCTP) | 62 | #define RSP_ZCTP (RSP_VAR + VAR_ZCTP) |
67 | #define RSP_STR (RSP_VAR + VAR_NUM) | 63 | #define RSP_STR (RSP_VAR + VAR_NUM) |
68 | #define RSP_NMBR (RSP_STR + STR_NMBR) | 64 | #define RSP_NMBR (RSP_STR + STR_NMBR) |
69 | #define RSP_ZCPN (RSP_STR + STR_ZCPN) | 65 | #define RSP_ZCPN (RSP_STR + STR_ZCPN) |
70 | #define RSP_ZCON (RSP_STR + STR_ZCON) | 66 | #define RSP_ZCON (RSP_STR + STR_ZCON) |
71 | #define RSP_ZBC (RSP_STR + STR_ZBC) | 67 | #define RSP_ZBC (RSP_STR + STR_ZBC) |
72 | #define RSP_ZHLC (RSP_STR + STR_ZHLC) | 68 | #define RSP_ZHLC (RSP_STR + STR_ZHLC) |
73 | #define RSP_ERROR -1 /* ERROR */ | 69 | #define RSP_ERROR -1 /* ERROR */ |
74 | #define RSP_WRONG_CID -2 /* unknown cid in cmd */ | 70 | #define RSP_WRONG_CID -2 /* unknown cid in cmd */ |
75 | //#define RSP_EMPTY -3 | 71 | //#define RSP_EMPTY -3 |
76 | #define RSP_UNKNOWN -4 /* unknown response */ | 72 | #define RSP_UNKNOWN -4 /* unknown response */ |
77 | #define RSP_FAIL -5 /* internal error */ | 73 | #define RSP_FAIL -5 /* internal error */ |
78 | #define RSP_INVAL -6 /* invalid response */ | 74 | #define RSP_INVAL -6 /* invalid response */ |
79 | 75 | ||
80 | #define RSP_NONE -19 | 76 | #define RSP_NONE -19 |
81 | #define RSP_STRING -20 | 77 | #define RSP_STRING -20 |
82 | #define RSP_NULL -21 | 78 | #define RSP_NULL -21 |
83 | //#define RSP_RETRYFAIL -22 | 79 | //#define RSP_RETRYFAIL -22 |
84 | //#define RSP_RETRY -23 | 80 | //#define RSP_RETRY -23 |
85 | //#define RSP_SKIP -24 | 81 | //#define RSP_SKIP -24 |
86 | #define RSP_INIT -27 | 82 | #define RSP_INIT -27 |
87 | #define RSP_ANY -26 | 83 | #define RSP_ANY -26 |
88 | #define RSP_LAST -28 | 84 | #define RSP_LAST -28 |
89 | #define RSP_NODEV -9 | 85 | #define RSP_NODEV -9 |
90 | 86 | ||
91 | /* actions for process_response */ | 87 | /* actions for process_response */ |
92 | #define ACT_NOTHING 0 | 88 | #define ACT_NOTHING 0 |
@@ -112,7 +108,7 @@ | |||
112 | #define ACT_DISCONNECT 20 | 108 | #define ACT_DISCONNECT 20 |
113 | #define ACT_CONNECT 21 | 109 | #define ACT_CONNECT 21 |
114 | #define ACT_REMOTEREJECT 22 | 110 | #define ACT_REMOTEREJECT 22 |
115 | #define ACT_CONNTIMEOUT 23 | 111 | #define ACT_CONNTIMEOUT 23 |
116 | #define ACT_REMOTEHUP 24 | 112 | #define ACT_REMOTEHUP 24 |
117 | #define ACT_ABORTHUP 25 | 113 | #define ACT_ABORTHUP 25 |
118 | #define ACT_ICALL 26 | 114 | #define ACT_ICALL 26 |
@@ -127,40 +123,40 @@ | |||
127 | #define ACT_ERROR 35 | 123 | #define ACT_ERROR 35 |
128 | #define ACT_ABORTCID 36 | 124 | #define ACT_ABORTCID 36 |
129 | #define ACT_ZCAU 37 | 125 | #define ACT_ZCAU 37 |
130 | #define ACT_NOTIFY_BC_DOWN 38 | 126 | #define ACT_NOTIFY_BC_DOWN 38 |
131 | #define ACT_NOTIFY_BC_UP 39 | 127 | #define ACT_NOTIFY_BC_UP 39 |
132 | #define ACT_DIAL 40 | 128 | #define ACT_DIAL 40 |
133 | #define ACT_ACCEPT 41 | 129 | #define ACT_ACCEPT 41 |
134 | #define ACT_PROTO_L2 42 | 130 | #define ACT_PROTO_L2 42 |
135 | #define ACT_HUP 43 | 131 | #define ACT_HUP 43 |
136 | #define ACT_IF_LOCK 44 | 132 | #define ACT_IF_LOCK 44 |
137 | #define ACT_START 45 | 133 | #define ACT_START 45 |
138 | #define ACT_STOP 46 | 134 | #define ACT_STOP 46 |
139 | #define ACT_FAKEDLE0 47 | 135 | #define ACT_FAKEDLE0 47 |
140 | #define ACT_FAKEHUP 48 | 136 | #define ACT_FAKEHUP 48 |
141 | #define ACT_FAKESDOWN 49 | 137 | #define ACT_FAKESDOWN 49 |
142 | #define ACT_SHUTDOWN 50 | 138 | #define ACT_SHUTDOWN 50 |
143 | #define ACT_PROC_CIDMODE 51 | 139 | #define ACT_PROC_CIDMODE 51 |
144 | #define ACT_UMODESET 52 | 140 | #define ACT_UMODESET 52 |
145 | #define ACT_FAILUMODE 53 | 141 | #define ACT_FAILUMODE 53 |
146 | #define ACT_CMODESET 54 | 142 | #define ACT_CMODESET 54 |
147 | #define ACT_FAILCMODE 55 | 143 | #define ACT_FAILCMODE 55 |
148 | #define ACT_IF_VER 56 | 144 | #define ACT_IF_VER 56 |
149 | #define ACT_CMD 100 | 145 | #define ACT_CMD 100 |
150 | 146 | ||
151 | /* at command sequences */ | 147 | /* at command sequences */ |
152 | #define SEQ_NONE 0 | 148 | #define SEQ_NONE 0 |
153 | #define SEQ_INIT 100 | 149 | #define SEQ_INIT 100 |
154 | #define SEQ_DLE0 200 | 150 | #define SEQ_DLE0 200 |
155 | #define SEQ_DLE1 250 | 151 | #define SEQ_DLE1 250 |
156 | #define SEQ_CID 300 | 152 | #define SEQ_CID 300 |
157 | #define SEQ_NOCID 350 | 153 | #define SEQ_NOCID 350 |
158 | #define SEQ_HUP 400 | 154 | #define SEQ_HUP 400 |
159 | #define SEQ_DIAL 600 | 155 | #define SEQ_DIAL 600 |
160 | #define SEQ_ACCEPT 720 | 156 | #define SEQ_ACCEPT 720 |
161 | #define SEQ_SHUTDOWN 500 | 157 | #define SEQ_SHUTDOWN 500 |
162 | #define SEQ_CIDMODE 10 | 158 | #define SEQ_CIDMODE 10 |
163 | #define SEQ_UMMODE 11 | 159 | #define SEQ_UMMODE 11 |
164 | 160 | ||
165 | 161 | ||
166 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring | 162 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring |
@@ -175,7 +171,7 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
175 | // {ACT_TIMEOUT}}, | 171 | // {ACT_TIMEOUT}}, |
176 | 172 | ||
177 | {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, | 173 | {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, |
178 | {ACT_TIMEOUT}}, /* wait until device is ready */ | 174 | {ACT_TIMEOUT}}, /* wait until device is ready */ |
179 | 175 | ||
180 | {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ | 176 | {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ |
181 | {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ | 177 | {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ |
@@ -190,8 +186,8 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
190 | {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, | 186 | {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, |
191 | 187 | ||
192 | {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, | 188 | {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, |
193 | ACT_HUPMODEM, | 189 | ACT_HUPMODEM, |
194 | ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ | 190 | ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ |
195 | {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, | 191 | {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, |
196 | 192 | ||
197 | {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ | 193 | {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ |
@@ -393,7 +389,7 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | |||
393 | 389 | ||
394 | 390 | ||
395 | #if 0 | 391 | #if 0 |
396 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen uebernehmen | 392 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME |
397 | { | 393 | { |
398 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 394 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
399 | 395 | ||
@@ -401,7 +397,7 @@ static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen ueberne | |||
401 | {RSP_LAST,0,0,0,0,0,0} | 397 | {RSP_LAST,0,0,0,0,0,0} |
402 | }; | 398 | }; |
403 | 399 | ||
404 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen uebernehmen | 400 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME |
405 | { | 401 | { |
406 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 402 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
407 | 403 | ||
@@ -412,30 +408,30 @@ static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen ueberneh | |||
412 | 408 | ||
413 | static struct resp_type_t resp_type[]= | 409 | static struct resp_type_t resp_type[]= |
414 | { | 410 | { |
415 | /*{"", RSP_EMPTY, RT_NOTHING},*/ | 411 | /*{"", RSP_EMPTY, RT_NOTHING},*/ |
416 | {"OK", RSP_OK, RT_NOTHING}, | 412 | {"OK", RSP_OK, RT_NOTHING}, |
417 | {"ERROR", RSP_ERROR, RT_NOTHING}, | 413 | {"ERROR", RSP_ERROR, RT_NOTHING}, |
418 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, | 414 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, |
419 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, | 415 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, |
420 | {"RING", RSP_RING, RT_RING}, | 416 | {"RING", RSP_RING, RT_RING}, |
421 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, | 417 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, |
422 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, | 418 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, |
423 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, | 419 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, |
424 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, | 420 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, |
425 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, | 421 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, |
426 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, | 422 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, |
427 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, | 423 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, |
428 | {"ZHLC", RSP_ZHLC, RT_STRING}, | 424 | {"ZHLC", RSP_ZHLC, RT_STRING}, |
429 | {"ZBC", RSP_ZBC, RT_STRING}, | 425 | {"ZBC", RSP_ZBC, RT_STRING}, |
430 | {"NMBR", RSP_NMBR, RT_STRING}, | 426 | {"NMBR", RSP_NMBR, RT_STRING}, |
431 | {"ZCPN", RSP_ZCPN, RT_STRING}, | 427 | {"ZCPN", RSP_ZCPN, RT_STRING}, |
432 | {"ZCON", RSP_ZCON, RT_STRING}, | 428 | {"ZCON", RSP_ZCON, RT_STRING}, |
433 | {"ZAOC", RSP_ZAOC, RT_STRING}, | 429 | {"ZAOC", RSP_ZAOC, RT_STRING}, |
434 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, | 430 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, |
435 | {"ZCFG", RSP_ZCFG, RT_HEX}, | 431 | {"ZCFG", RSP_ZCFG, RT_HEX}, |
436 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, | 432 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, |
437 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, | 433 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, |
438 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, | 434 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, |
439 | {NULL,0,0} | 435 | {NULL,0,0} |
440 | }; | 436 | }; |
441 | 437 | ||
@@ -446,9 +442,7 @@ static int isdn_getnum(char *p) | |||
446 | { | 442 | { |
447 | int v = -1; | 443 | int v = -1; |
448 | 444 | ||
449 | IFNULLRETVAL(p, -1); | 445 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
450 | |||
451 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
452 | 446 | ||
453 | while (*p >= '0' && *p <= '9') | 447 | while (*p >= '0' && *p <= '9') |
454 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); | 448 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); |
@@ -465,9 +459,7 @@ static int isdn_gethex(char *p) | |||
465 | int v = 0; | 459 | int v = 0; |
466 | int c; | 460 | int c; |
467 | 461 | ||
468 | IFNULLRETVAL(p, -1); | 462 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
469 | |||
470 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
471 | 463 | ||
472 | if (!*p) | 464 | if (!*p) |
473 | return -1; | 465 | return -1; |
@@ -490,14 +482,6 @@ static int isdn_gethex(char *p) | |||
490 | return v; | 482 | return v; |
491 | } | 483 | } |
492 | 484 | ||
493 | static inline void new_index(atomic_t *index, int max) | ||
494 | { | ||
495 | if (atomic_read(index) == max) //FIXME race? | ||
496 | atomic_set(index, 0); | ||
497 | else | ||
498 | atomic_inc(index); | ||
499 | } | ||
500 | |||
501 | /* retrieve CID from parsed response | 485 | /* retrieve CID from parsed response |
502 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 | 486 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 |
503 | */ | 487 | */ |
@@ -536,16 +520,14 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
536 | int cid; | 520 | int cid; |
537 | int rawstring; | 521 | int rawstring; |
538 | 522 | ||
539 | IFNULLRET(cs); | ||
540 | |||
541 | len = cs->cbytes; | 523 | len = cs->cbytes; |
542 | if (!len) { | 524 | if (!len) { |
543 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ | 525 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ |
544 | dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); | 526 | gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); |
545 | return; | 527 | return; |
546 | } | 528 | } |
547 | cs->respdata[len] = 0; | 529 | cs->respdata[len] = 0; |
548 | dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); | 530 | gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); |
549 | argv[0] = cs->respdata; | 531 | argv[0] = cs->respdata; |
550 | params = 1; | 532 | params = 1; |
551 | if (cs->at_state.getstring) { | 533 | if (cs->at_state.getstring) { |
@@ -561,7 +543,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
561 | case ',': | 543 | case ',': |
562 | case '=': | 544 | case '=': |
563 | if (params > MAX_REC_PARAMS) { | 545 | if (params > MAX_REC_PARAMS) { |
564 | warn("too many parameters in response"); | 546 | dev_warn(cs->dev, |
547 | "too many parameters in response\n"); | ||
565 | /* need last parameter (might be CID) */ | 548 | /* need last parameter (might be CID) */ |
566 | params--; | 549 | params--; |
567 | } | 550 | } |
@@ -572,33 +555,33 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
572 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; | 555 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; |
573 | if (cid < 0) { | 556 | if (cid < 0) { |
574 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, | 557 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, |
575 | NULL, 0, NULL); | 558 | NULL, 0, NULL); |
576 | return; | 559 | return; |
577 | } | 560 | } |
578 | 561 | ||
579 | for (j = 1; j < params; ++j) | 562 | for (j = 1; j < params; ++j) |
580 | argv[j][-1] = 0; | 563 | argv[j][-1] = 0; |
581 | 564 | ||
582 | dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); | 565 | gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); |
583 | if (cid) { | 566 | if (cid) { |
584 | --params; | 567 | --params; |
585 | dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); | 568 | gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); |
586 | } | 569 | } |
587 | dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); | 570 | gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); |
588 | for (j = 1; j < params; j++) | 571 | for (j = 1; j < params; j++) |
589 | dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); | 572 | gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); |
590 | } | 573 | } |
591 | 574 | ||
592 | spin_lock_irqsave(&cs->ev_lock, flags); | 575 | spin_lock_irqsave(&cs->ev_lock, flags); |
593 | head = atomic_read(&cs->ev_head); | 576 | head = cs->ev_head; |
594 | tail = atomic_read(&cs->ev_tail); | 577 | tail = cs->ev_tail; |
595 | 578 | ||
596 | abort = 1; | 579 | abort = 1; |
597 | curarg = 0; | 580 | curarg = 0; |
598 | while (curarg < params) { | 581 | while (curarg < params) { |
599 | next = (tail + 1) % MAX_EVENTS; | 582 | next = (tail + 1) % MAX_EVENTS; |
600 | if (unlikely(next == head)) { | 583 | if (unlikely(next == head)) { |
601 | err("event queue full"); | 584 | dev_err(cs->dev, "event queue full\n"); |
602 | break; | 585 | break; |
603 | } | 586 | } |
604 | 587 | ||
@@ -619,8 +602,9 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
619 | 602 | ||
620 | if (!rt->response) { | 603 | if (!rt->response) { |
621 | event->type = RSP_UNKNOWN; | 604 | event->type = RSP_UNKNOWN; |
622 | warn("unknown modem response: %s", | 605 | dev_warn(cs->dev, |
623 | argv[curarg]); | 606 | "unknown modem response: %s\n", |
607 | argv[curarg]); | ||
624 | break; | 608 | break; |
625 | } | 609 | } |
626 | 610 | ||
@@ -636,7 +620,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
636 | break; | 620 | break; |
637 | case RT_RING: | 621 | case RT_RING: |
638 | if (!cid) { | 622 | if (!cid) { |
639 | err("received RING without CID!"); | 623 | dev_err(cs->dev, |
624 | "received RING without CID!\n"); | ||
640 | event->type = RSP_INVAL; | 625 | event->type = RSP_INVAL; |
641 | abort = 1; | 626 | abort = 1; |
642 | } else { | 627 | } else { |
@@ -664,27 +649,25 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
664 | event->parameter = ZSAU_DISCONNECT_REQ; | 649 | event->parameter = ZSAU_DISCONNECT_REQ; |
665 | else { | 650 | else { |
666 | event->parameter = ZSAU_UNKNOWN; | 651 | event->parameter = ZSAU_UNKNOWN; |
667 | warn("%s: unknown parameter %s after ZSAU", | 652 | dev_warn(cs->dev, |
668 | __func__, argv[curarg]); | 653 | "%s: unknown parameter %s after ZSAU\n", |
654 | __func__, argv[curarg]); | ||
669 | } | 655 | } |
670 | ++curarg; | 656 | ++curarg; |
671 | break; | 657 | break; |
672 | case RT_STRING: | 658 | case RT_STRING: |
673 | if (curarg < params) { | 659 | if (curarg < params) { |
674 | len = strlen(argv[curarg]) + 1; | 660 | event->ptr = kstrdup(argv[curarg], GFP_ATOMIC); |
675 | event->ptr = kmalloc(len, GFP_ATOMIC); | 661 | if (!event->ptr) |
676 | if (event->ptr) | 662 | dev_err(cs->dev, "out of memory\n"); |
677 | memcpy(event->ptr, argv[curarg], len); | ||
678 | else | ||
679 | err("no memory for string!"); | ||
680 | ++curarg; | 663 | ++curarg; |
681 | } | 664 | } |
682 | #ifdef CONFIG_GIGASET_DEBUG | 665 | #ifdef CONFIG_GIGASET_DEBUG |
683 | if (!event->ptr) | 666 | if (!event->ptr) |
684 | dbg(DEBUG_CMD, "string==NULL"); | 667 | gig_dbg(DEBUG_CMD, "string==NULL"); |
685 | else | 668 | else |
686 | dbg(DEBUG_CMD, | 669 | gig_dbg(DEBUG_CMD, "string==%s", |
687 | "string==%s", (char *) event->ptr); | 670 | (char *) event->ptr); |
688 | #endif | 671 | #endif |
689 | break; | 672 | break; |
690 | case RT_ZCAU: | 673 | case RT_ZCAU: |
@@ -694,7 +677,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
694 | j = isdn_gethex(argv[curarg + 1]); | 677 | j = isdn_gethex(argv[curarg + 1]); |
695 | if (i >= 0 && i < 256 && j >= 0 && j < 256) | 678 | if (i >= 0 && i < 256 && j >= 0 && j < 256) |
696 | event->parameter = (unsigned) i << 8 | 679 | event->parameter = (unsigned) i << 8 |
697 | | j; | 680 | | j; |
698 | curarg += 2; | 681 | curarg += 2; |
699 | } else | 682 | } else |
700 | curarg = params - 1; | 683 | curarg = params - 1; |
@@ -712,7 +695,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
712 | } else | 695 | } else |
713 | event->parameter = -1; | 696 | event->parameter = -1; |
714 | #ifdef CONFIG_GIGASET_DEBUG | 697 | #ifdef CONFIG_GIGASET_DEBUG |
715 | dbg(DEBUG_CMD, "parameter==%d", event->parameter); | 698 | gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); |
716 | #endif | 699 | #endif |
717 | break; | 700 | break; |
718 | } | 701 | } |
@@ -724,12 +707,13 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
724 | break; | 707 | break; |
725 | } | 708 | } |
726 | 709 | ||
727 | atomic_set(&cs->ev_tail, tail); | 710 | cs->ev_tail = tail; |
728 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 711 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
729 | 712 | ||
730 | if (curarg != params) | 713 | if (curarg != params) |
731 | dbg(DEBUG_ANY, "invalid number of processed parameters: %d/%d", | 714 | gig_dbg(DEBUG_ANY, |
732 | curarg, params); | 715 | "invalid number of processed parameters: %d/%d", |
716 | curarg, params); | ||
733 | } | 717 | } |
734 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | 718 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); |
735 | 719 | ||
@@ -739,23 +723,19 @@ EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | |||
739 | static void disconnect(struct at_state_t **at_state_p) | 723 | static void disconnect(struct at_state_t **at_state_p) |
740 | { | 724 | { |
741 | unsigned long flags; | 725 | unsigned long flags; |
742 | struct bc_state *bcs; | 726 | struct bc_state *bcs = (*at_state_p)->bcs; |
743 | struct cardstate *cs; | 727 | struct cardstate *cs = (*at_state_p)->cs; |
744 | 728 | ||
745 | IFNULLRET(at_state_p); | 729 | spin_lock_irqsave(&cs->lock, flags); |
746 | IFNULLRET(*at_state_p); | 730 | ++(*at_state_p)->seq_index; |
747 | bcs = (*at_state_p)->bcs; | ||
748 | cs = (*at_state_p)->cs; | ||
749 | IFNULLRET(cs); | ||
750 | |||
751 | new_index(&(*at_state_p)->seq_index, MAX_SEQ_INDEX); | ||
752 | 731 | ||
753 | /* revert to selected idle mode */ | 732 | /* revert to selected idle mode */ |
754 | if (!atomic_read(&cs->cidmode)) { | 733 | if (!cs->cidmode) { |
755 | cs->at_state.pending_commands |= PC_UMMODE; | 734 | cs->at_state.pending_commands |= PC_UMMODE; |
756 | atomic_set(&cs->commands_pending, 1); //FIXME | 735 | atomic_set(&cs->commands_pending, 1); //FIXME |
757 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 736 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
758 | } | 737 | } |
738 | spin_unlock_irqrestore(&cs->lock, flags); | ||
759 | 739 | ||
760 | if (bcs) { | 740 | if (bcs) { |
761 | /* B channel assigned: invoke hardware specific handler */ | 741 | /* B channel assigned: invoke hardware specific handler */ |
@@ -777,7 +757,7 @@ static void disconnect(struct at_state_t **at_state_p) | |||
777 | * The structure should be freed by calling disconnect() after use. | 757 | * The structure should be freed by calling disconnect() after use. |
778 | */ | 758 | */ |
779 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, | 759 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, |
780 | int cid) | 760 | int cid) |
781 | /* cids: >0: siemens-cid | 761 | /* cids: >0: siemens-cid |
782 | 0: without cid | 762 | 0: without cid |
783 | -1: no cid assigned yet | 763 | -1: no cid assigned yet |
@@ -826,7 +806,7 @@ static void init_failed(struct cardstate *cs, int mode) | |||
826 | static void schedule_init(struct cardstate *cs, int state) | 806 | static void schedule_init(struct cardstate *cs, int state) |
827 | { | 807 | { |
828 | if (cs->at_state.pending_commands & PC_INIT) { | 808 | if (cs->at_state.pending_commands & PC_INIT) { |
829 | dbg(DEBUG_CMD, "not scheduling PC_INIT again"); | 809 | gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); |
830 | return; | 810 | return; |
831 | } | 811 | } |
832 | atomic_set(&cs->mstate, state); | 812 | atomic_set(&cs->mstate, state); |
@@ -834,52 +814,56 @@ static void schedule_init(struct cardstate *cs, int state) | |||
834 | gigaset_block_channels(cs); | 814 | gigaset_block_channels(cs); |
835 | cs->at_state.pending_commands |= PC_INIT; | 815 | cs->at_state.pending_commands |= PC_INIT; |
836 | atomic_set(&cs->commands_pending, 1); | 816 | atomic_set(&cs->commands_pending, 1); |
837 | dbg(DEBUG_CMD, "Scheduling PC_INIT"); | 817 | gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); |
838 | } | 818 | } |
839 | 819 | ||
840 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the hardware. */ | 820 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the |
821 | hardware. */ | ||
841 | static void send_command(struct cardstate *cs, const char *cmd, int cid, | 822 | static void send_command(struct cardstate *cs, const char *cmd, int cid, |
842 | int dle, gfp_t kmallocflags) | 823 | int dle, gfp_t kmallocflags) |
843 | { | 824 | { |
844 | size_t cmdlen, buflen; | 825 | size_t cmdlen, buflen; |
845 | char *cmdpos, *cmdbuf, *cmdtail; | 826 | char *cmdpos, *cmdbuf, *cmdtail; |
846 | 827 | ||
847 | cmdlen = strlen(cmd); | 828 | cmdlen = strlen(cmd); |
848 | buflen = 11 + cmdlen; | 829 | buflen = 11 + cmdlen; |
830 | if (unlikely(buflen <= cmdlen)) { | ||
831 | dev_err(cs->dev, "integer overflow in buflen\n"); | ||
832 | return; | ||
833 | } | ||
849 | 834 | ||
850 | if (likely(buflen > cmdlen)) { | 835 | cmdbuf = kmalloc(buflen, kmallocflags); |
851 | cmdbuf = kmalloc(buflen, kmallocflags); | 836 | if (unlikely(!cmdbuf)) { |
852 | if (likely(cmdbuf != NULL)) { | 837 | dev_err(cs->dev, "out of memory\n"); |
853 | cmdpos = cmdbuf + 9; | 838 | return; |
854 | cmdtail = cmdpos + cmdlen; | 839 | } |
855 | memcpy(cmdpos, cmd, cmdlen); | ||
856 | |||
857 | if (cid > 0 && cid <= 65535) { | ||
858 | do { | ||
859 | *--cmdpos = '0' + cid % 10; | ||
860 | cid /= 10; | ||
861 | ++cmdlen; | ||
862 | } while (cid); | ||
863 | } | ||
864 | 840 | ||
865 | cmdlen += 2; | 841 | cmdpos = cmdbuf + 9; |
866 | *--cmdpos = 'T'; | 842 | cmdtail = cmdpos + cmdlen; |
867 | *--cmdpos = 'A'; | 843 | memcpy(cmdpos, cmd, cmdlen); |
868 | 844 | ||
869 | if (dle) { | 845 | if (cid > 0 && cid <= 65535) { |
870 | cmdlen += 4; | 846 | do { |
871 | *--cmdpos = '('; | 847 | *--cmdpos = '0' + cid % 10; |
872 | *--cmdpos = 0x10; | 848 | cid /= 10; |
873 | *cmdtail++ = 0x10; | 849 | ++cmdlen; |
874 | *cmdtail++ = ')'; | 850 | } while (cid); |
875 | } | 851 | } |
876 | 852 | ||
877 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | 853 | cmdlen += 2; |
878 | kfree(cmdbuf); | 854 | *--cmdpos = 'T'; |
879 | } else | 855 | *--cmdpos = 'A'; |
880 | err("no memory for command buffer"); | 856 | |
881 | } else | 857 | if (dle) { |
882 | err("overflow in buflen"); | 858 | cmdlen += 4; |
859 | *--cmdpos = '('; | ||
860 | *--cmdpos = 0x10; | ||
861 | *cmdtail++ = 0x10; | ||
862 | *cmdtail++ = ')'; | ||
863 | } | ||
864 | |||
865 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | ||
866 | kfree(cmdbuf); | ||
883 | } | 867 | } |
884 | 868 | ||
885 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | 869 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) |
@@ -910,9 +894,6 @@ static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | |||
910 | 894 | ||
911 | static void bchannel_down(struct bc_state *bcs) | 895 | static void bchannel_down(struct bc_state *bcs) |
912 | { | 896 | { |
913 | IFNULLRET(bcs); | ||
914 | IFNULLRET(bcs->cs); | ||
915 | |||
916 | if (bcs->chstate & CHS_B_UP) { | 897 | if (bcs->chstate & CHS_B_UP) { |
917 | bcs->chstate &= ~CHS_B_UP; | 898 | bcs->chstate &= ~CHS_B_UP; |
918 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); | 899 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); |
@@ -930,16 +911,15 @@ static void bchannel_down(struct bc_state *bcs) | |||
930 | 911 | ||
931 | static void bchannel_up(struct bc_state *bcs) | 912 | static void bchannel_up(struct bc_state *bcs) |
932 | { | 913 | { |
933 | IFNULLRET(bcs); | ||
934 | |||
935 | if (!(bcs->chstate & CHS_D_UP)) { | 914 | if (!(bcs->chstate & CHS_D_UP)) { |
936 | notice("%s: D channel not up", __func__); | 915 | dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__); |
937 | bcs->chstate |= CHS_D_UP; | 916 | bcs->chstate |= CHS_D_UP; |
938 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | 917 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); |
939 | } | 918 | } |
940 | 919 | ||
941 | if (bcs->chstate & CHS_B_UP) { | 920 | if (bcs->chstate & CHS_B_UP) { |
942 | notice("%s: B channel already up", __func__); | 921 | dev_notice(bcs->cs->dev, "%s: B channel already up\n", |
922 | __func__); | ||
943 | return; | 923 | return; |
944 | } | 924 | } |
945 | 925 | ||
@@ -947,17 +927,21 @@ static void bchannel_up(struct bc_state *bcs) | |||
947 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); | 927 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); |
948 | } | 928 | } |
949 | 929 | ||
950 | static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | 930 | static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) |
951 | { | 931 | { |
952 | struct bc_state *bcs = at_state->bcs; | 932 | struct bc_state *bcs = at_state->bcs; |
953 | struct cardstate *cs = at_state->cs; | 933 | struct cardstate *cs = at_state->cs; |
954 | int retval; | 934 | int retval; |
935 | unsigned long flags; | ||
955 | 936 | ||
956 | bcs->chstate |= CHS_NOTIFY_LL; | 937 | bcs->chstate |= CHS_NOTIFY_LL; |
957 | //atomic_set(&bcs->status, BCS_INIT); | ||
958 | 938 | ||
959 | if (atomic_read(&at_state->seq_index) != seq_index) | 939 | spin_lock_irqsave(&cs->lock, flags); |
940 | if (at_state->seq_index != seq_index) { | ||
941 | spin_unlock_irqrestore(&cs->lock, flags); | ||
960 | goto error; | 942 | goto error; |
943 | } | ||
944 | spin_unlock_irqrestore(&cs->lock, flags); | ||
961 | 945 | ||
962 | retval = gigaset_isdn_setup_dial(at_state, data); | 946 | retval = gigaset_isdn_setup_dial(at_state, data); |
963 | if (retval != 0) | 947 | if (retval != 0) |
@@ -965,20 +949,14 @@ static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | |||
965 | 949 | ||
966 | 950 | ||
967 | at_state->pending_commands |= PC_CID; | 951 | at_state->pending_commands |= PC_CID; |
968 | dbg(DEBUG_CMD, "Scheduling PC_CID"); | 952 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); |
969 | //#ifdef GIG_MAYINITONDIAL | 953 | atomic_set(&cs->commands_pending, 1); |
970 | // if (atomic_read(&cs->MState) == MS_UNKNOWN) { | ||
971 | // cs->at_state.pending_commands |= PC_INIT; | ||
972 | // dbg(DEBUG_CMD, "Scheduling PC_INIT"); | ||
973 | // } | ||
974 | //#endif | ||
975 | atomic_set(&cs->commands_pending, 1); //FIXME | ||
976 | return; | 954 | return; |
977 | 955 | ||
978 | error: | 956 | error: |
979 | at_state->pending_commands |= PC_NOCID; | 957 | at_state->pending_commands |= PC_NOCID; |
980 | dbg(DEBUG_CMD, "Scheduling PC_NOCID"); | 958 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); |
981 | atomic_set(&cs->commands_pending, 1); //FIXME | 959 | atomic_set(&cs->commands_pending, 1); |
982 | return; | 960 | return; |
983 | } | 961 | } |
984 | 962 | ||
@@ -991,13 +969,13 @@ static void start_accept(struct at_state_t *at_state) | |||
991 | 969 | ||
992 | if (retval == 0) { | 970 | if (retval == 0) { |
993 | at_state->pending_commands |= PC_ACCEPT; | 971 | at_state->pending_commands |= PC_ACCEPT; |
994 | dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | 972 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); |
995 | atomic_set(&cs->commands_pending, 1); //FIXME | 973 | atomic_set(&cs->commands_pending, 1); |
996 | } else { | 974 | } else { |
997 | //FIXME | 975 | //FIXME |
998 | at_state->pending_commands |= PC_HUP; | 976 | at_state->pending_commands |= PC_HUP; |
999 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 977 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1000 | atomic_set(&cs->commands_pending, 1); //FIXME | 978 | atomic_set(&cs->commands_pending, 1); |
1001 | } | 979 | } |
1002 | } | 980 | } |
1003 | 981 | ||
@@ -1008,9 +986,10 @@ static void do_start(struct cardstate *cs) | |||
1008 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 986 | if (atomic_read(&cs->mstate) != MS_LOCKED) |
1009 | schedule_init(cs, MS_INIT); | 987 | schedule_init(cs, MS_INIT); |
1010 | 988 | ||
989 | cs->isdn_up = 1; | ||
1011 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); | 990 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); |
1012 | // FIXME: not in locked mode | 991 | // FIXME: not in locked mode |
1013 | // FIXME 2: only after init sequence | 992 | // FIXME 2: only after init sequence |
1014 | 993 | ||
1015 | cs->waiting = 0; | 994 | cs->waiting = 0; |
1016 | wake_up(&cs->waitqueue); | 995 | wake_up(&cs->waitqueue); |
@@ -1023,6 +1002,12 @@ static void finish_shutdown(struct cardstate *cs) | |||
1023 | atomic_set(&cs->mode, M_UNKNOWN); | 1002 | atomic_set(&cs->mode, M_UNKNOWN); |
1024 | } | 1003 | } |
1025 | 1004 | ||
1005 | /* Tell the LL that the device is not available .. */ | ||
1006 | if (cs->isdn_up) { | ||
1007 | cs->isdn_up = 0; | ||
1008 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); | ||
1009 | } | ||
1010 | |||
1026 | /* The rest is done by cleanup_cs () in user mode. */ | 1011 | /* The rest is done by cleanup_cs () in user mode. */ |
1027 | 1012 | ||
1028 | cs->cmd_result = -ENODEV; | 1013 | cs->cmd_result = -ENODEV; |
@@ -1037,15 +1022,20 @@ static void do_shutdown(struct cardstate *cs) | |||
1037 | if (atomic_read(&cs->mstate) == MS_READY) { | 1022 | if (atomic_read(&cs->mstate) == MS_READY) { |
1038 | atomic_set(&cs->mstate, MS_SHUTDOWN); | 1023 | atomic_set(&cs->mstate, MS_SHUTDOWN); |
1039 | cs->at_state.pending_commands |= PC_SHUTDOWN; | 1024 | cs->at_state.pending_commands |= PC_SHUTDOWN; |
1040 | atomic_set(&cs->commands_pending, 1); //FIXME | 1025 | atomic_set(&cs->commands_pending, 1); |
1041 | dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); //FIXME | 1026 | gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); |
1042 | //gigaset_schedule_event(cs); //FIXME | ||
1043 | } else | 1027 | } else |
1044 | finish_shutdown(cs); | 1028 | finish_shutdown(cs); |
1045 | } | 1029 | } |
1046 | 1030 | ||
1047 | static void do_stop(struct cardstate *cs) | 1031 | static void do_stop(struct cardstate *cs) |
1048 | { | 1032 | { |
1033 | unsigned long flags; | ||
1034 | |||
1035 | spin_lock_irqsave(&cs->lock, flags); | ||
1036 | cs->connected = 0; | ||
1037 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1038 | |||
1049 | do_shutdown(cs); | 1039 | do_shutdown(cs); |
1050 | } | 1040 | } |
1051 | 1041 | ||
@@ -1069,9 +1059,11 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1069 | return 0; | 1059 | return 0; |
1070 | 1060 | ||
1071 | if (channel < 0) | 1061 | if (channel < 0) |
1072 | warn("Could not enter cid mode. Reinit device and try again."); | 1062 | dev_warn(cs->dev, |
1063 | "Could not enter cid mode. Reinit device and try again.\n"); | ||
1073 | else { | 1064 | else { |
1074 | warn("Could not get a call id. Reinit device and try again."); | 1065 | dev_warn(cs->dev, |
1066 | "Could not get a call id. Reinit device and try again.\n"); | ||
1075 | cs->bcs[channel].at_state.pending_commands |= PC_CID; | 1067 | cs->bcs[channel].at_state.pending_commands |= PC_CID; |
1076 | } | 1068 | } |
1077 | schedule_init(cs, MS_INIT); | 1069 | schedule_init(cs, MS_INIT); |
@@ -1079,7 +1071,7 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1079 | } | 1071 | } |
1080 | 1072 | ||
1081 | static int at_state_invalid(struct cardstate *cs, | 1073 | static int at_state_invalid(struct cardstate *cs, |
1082 | struct at_state_t *test_ptr) | 1074 | struct at_state_t *test_ptr) |
1083 | { | 1075 | { |
1084 | unsigned long flags; | 1076 | unsigned long flags; |
1085 | unsigned channel; | 1077 | unsigned channel; |
@@ -1116,7 +1108,7 @@ static void handle_icall(struct cardstate *cs, struct bc_state *bcs, | |||
1116 | case ICALL_ACCEPT: | 1108 | case ICALL_ACCEPT: |
1117 | break; | 1109 | break; |
1118 | default: | 1110 | default: |
1119 | err("internal error: disposition=%d", retval); | 1111 | dev_err(cs->dev, "internal error: disposition=%d\n", retval); |
1120 | /* --v-- fall through --v-- */ | 1112 | /* --v-- fall through --v-- */ |
1121 | case ICALL_IGNORE: | 1113 | case ICALL_IGNORE: |
1122 | case ICALL_REJECT: | 1114 | case ICALL_REJECT: |
@@ -1160,7 +1152,6 @@ static int do_lock(struct cardstate *cs) | |||
1160 | mode = atomic_read(&cs->mode); | 1152 | mode = atomic_read(&cs->mode); |
1161 | atomic_set(&cs->mstate, MS_LOCKED); | 1153 | atomic_set(&cs->mstate, MS_LOCKED); |
1162 | atomic_set(&cs->mode, M_UNKNOWN); | 1154 | atomic_set(&cs->mode, M_UNKNOWN); |
1163 | //FIXME reset card state / at states / bcs states | ||
1164 | 1155 | ||
1165 | return mode; | 1156 | return mode; |
1166 | } | 1157 | } |
@@ -1173,8 +1164,7 @@ static int do_unlock(struct cardstate *cs) | |||
1173 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 1164 | atomic_set(&cs->mstate, MS_UNINITIALIZED); |
1174 | atomic_set(&cs->mode, M_UNKNOWN); | 1165 | atomic_set(&cs->mode, M_UNKNOWN); |
1175 | gigaset_free_channels(cs); | 1166 | gigaset_free_channels(cs); |
1176 | //FIXME reset card state / at states / bcs states | 1167 | if (cs->connected) |
1177 | if (atomic_read(&cs->connected)) | ||
1178 | schedule_init(cs, MS_INIT); | 1168 | schedule_init(cs, MS_INIT); |
1179 | 1169 | ||
1180 | return 0; | 1170 | return 0; |
@@ -1203,21 +1193,23 @@ static void do_action(int action, struct cardstate *cs, | |||
1203 | at_state->waiting = 1; | 1193 | at_state->waiting = 1; |
1204 | break; | 1194 | break; |
1205 | case ACT_INIT: | 1195 | case ACT_INIT: |
1206 | //FIXME setup everything | ||
1207 | cs->at_state.pending_commands &= ~PC_INIT; | 1196 | cs->at_state.pending_commands &= ~PC_INIT; |
1208 | cs->cur_at_seq = SEQ_NONE; | 1197 | cs->cur_at_seq = SEQ_NONE; |
1209 | atomic_set(&cs->mode, M_UNIMODEM); | 1198 | atomic_set(&cs->mode, M_UNIMODEM); |
1210 | if (!atomic_read(&cs->cidmode)) { | 1199 | spin_lock_irqsave(&cs->lock, flags); |
1200 | if (!cs->cidmode) { | ||
1201 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1211 | gigaset_free_channels(cs); | 1202 | gigaset_free_channels(cs); |
1212 | atomic_set(&cs->mstate, MS_READY); | 1203 | atomic_set(&cs->mstate, MS_READY); |
1213 | break; | 1204 | break; |
1214 | } | 1205 | } |
1206 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1215 | cs->at_state.pending_commands |= PC_CIDMODE; | 1207 | cs->at_state.pending_commands |= PC_CIDMODE; |
1216 | atomic_set(&cs->commands_pending, 1); //FIXME | 1208 | atomic_set(&cs->commands_pending, 1); |
1217 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1209 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1218 | break; | 1210 | break; |
1219 | case ACT_FAILINIT: | 1211 | case ACT_FAILINIT: |
1220 | warn("Could not initialize the device."); | 1212 | dev_warn(cs->dev, "Could not initialize the device.\n"); |
1221 | cs->dle = 0; | 1213 | cs->dle = 0; |
1222 | init_failed(cs, M_UNKNOWN); | 1214 | init_failed(cs, M_UNKNOWN); |
1223 | cs->cur_at_seq = SEQ_NONE; | 1215 | cs->cur_at_seq = SEQ_NONE; |
@@ -1273,8 +1265,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1273 | /* get fresh AT state structure for new CID */ | 1265 | /* get fresh AT state structure for new CID */ |
1274 | at_state2 = get_free_channel(cs, ev->parameter); | 1266 | at_state2 = get_free_channel(cs, ev->parameter); |
1275 | if (!at_state2) { | 1267 | if (!at_state2) { |
1276 | warn("RING ignored: " | 1268 | dev_warn(cs->dev, |
1277 | "could not allocate channel structure"); | 1269 | "RING ignored: could not allocate channel structure\n"); |
1278 | break; | 1270 | break; |
1279 | } | 1271 | } |
1280 | 1272 | ||
@@ -1302,7 +1294,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1302 | at_state = *p_at_state; | 1294 | at_state = *p_at_state; |
1303 | break; | 1295 | break; |
1304 | case ACT_FAILSDOWN: | 1296 | case ACT_FAILSDOWN: |
1305 | warn("Could not shut down the device."); | 1297 | dev_warn(cs->dev, "Could not shut down the device.\n"); |
1306 | /* fall through */ | 1298 | /* fall through */ |
1307 | case ACT_FAKESDOWN: | 1299 | case ACT_FAKESDOWN: |
1308 | case ACT_SDOWN: | 1300 | case ACT_SDOWN: |
@@ -1355,7 +1347,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1355 | break; | 1347 | break; |
1356 | case ACT_ABORTHUP: | 1348 | case ACT_ABORTHUP: |
1357 | cs->cur_at_seq = SEQ_NONE; | 1349 | cs->cur_at_seq = SEQ_NONE; |
1358 | warn("Could not hang up."); | 1350 | dev_warn(cs->dev, "Could not hang up.\n"); |
1359 | at_state->cid = -1; | 1351 | at_state->cid = -1; |
1360 | if (bcs && cs->onechannel) | 1352 | if (bcs && cs->onechannel) |
1361 | at_state->pending_commands |= PC_DLE0; | 1353 | at_state->pending_commands |= PC_DLE0; |
@@ -1367,14 +1359,15 @@ static void do_action(int action, struct cardstate *cs, | |||
1367 | break; | 1359 | break; |
1368 | case ACT_FAILDLE0: | 1360 | case ACT_FAILDLE0: |
1369 | cs->cur_at_seq = SEQ_NONE; | 1361 | cs->cur_at_seq = SEQ_NONE; |
1370 | warn("Could not leave DLE mode."); | 1362 | dev_warn(cs->dev, "Could not leave DLE mode.\n"); |
1371 | at_state2 = &cs->bcs[cs->curchannel].at_state; | 1363 | at_state2 = &cs->bcs[cs->curchannel].at_state; |
1372 | disconnect(&at_state2); | 1364 | disconnect(&at_state2); |
1373 | schedule_init(cs, MS_RECOVER); | 1365 | schedule_init(cs, MS_RECOVER); |
1374 | break; | 1366 | break; |
1375 | case ACT_FAILDLE1: | 1367 | case ACT_FAILDLE1: |
1376 | cs->cur_at_seq = SEQ_NONE; | 1368 | cs->cur_at_seq = SEQ_NONE; |
1377 | warn("Could not enter DLE mode. Try to hang up."); | 1369 | dev_warn(cs->dev, |
1370 | "Could not enter DLE mode. Trying to hang up.\n"); | ||
1378 | channel = cs->curchannel; | 1371 | channel = cs->curchannel; |
1379 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; | 1372 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; |
1380 | atomic_set(&cs->commands_pending, 1); | 1373 | atomic_set(&cs->commands_pending, 1); |
@@ -1395,7 +1388,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1395 | cs->cur_at_seq = SEQ_NONE; | 1388 | cs->cur_at_seq = SEQ_NONE; |
1396 | channel = cs->curchannel; | 1389 | channel = cs->curchannel; |
1397 | if (!reinit_and_retry(cs, channel)) { | 1390 | if (!reinit_and_retry(cs, channel)) { |
1398 | warn("Could not get a call id. Dialing not possible"); | 1391 | dev_warn(cs->dev, |
1392 | "Could not get a call ID. Cannot dial.\n"); | ||
1399 | at_state2 = &cs->bcs[channel].at_state; | 1393 | at_state2 = &cs->bcs[channel].at_state; |
1400 | disconnect(&at_state2); | 1394 | disconnect(&at_state2); |
1401 | } | 1395 | } |
@@ -1428,7 +1422,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1428 | at_state->pending_commands |= PC_HUP; | 1422 | at_state->pending_commands |= PC_HUP; |
1429 | atomic_set(&cs->commands_pending, 1); | 1423 | atomic_set(&cs->commands_pending, 1); |
1430 | break; | 1424 | break; |
1431 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... are not handled properly any more */ | 1425 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... |
1426 | are not handled properly anymore */ | ||
1432 | at_state->getstring = 1; | 1427 | at_state->getstring = 1; |
1433 | break; | 1428 | break; |
1434 | case ACT_SETVER: | 1429 | case ACT_SETVER: |
@@ -1469,16 +1464,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1469 | case ACT_GOTVER: | 1464 | case ACT_GOTVER: |
1470 | if (cs->gotfwver == 0) { | 1465 | if (cs->gotfwver == 0) { |
1471 | cs->gotfwver = 1; | 1466 | cs->gotfwver = 1; |
1472 | dbg(DEBUG_ANY, | 1467 | gig_dbg(DEBUG_ANY, |
1473 | "firmware version %02d.%03d.%02d.%02d", | 1468 | "firmware version %02d.%03d.%02d.%02d", |
1474 | cs->fwver[0], cs->fwver[1], | 1469 | cs->fwver[0], cs->fwver[1], |
1475 | cs->fwver[2], cs->fwver[3]); | 1470 | cs->fwver[2], cs->fwver[3]); |
1476 | break; | 1471 | break; |
1477 | } | 1472 | } |
1478 | /* fall through */ | 1473 | /* fall through */ |
1479 | case ACT_FAILVER: | 1474 | case ACT_FAILVER: |
1480 | cs->gotfwver = -1; | 1475 | cs->gotfwver = -1; |
1481 | err("could not read firmware version."); | 1476 | dev_err(cs->dev, "could not read firmware version.\n"); |
1482 | break; | 1477 | break; |
1483 | #ifdef CONFIG_GIGASET_DEBUG | 1478 | #ifdef CONFIG_GIGASET_DEBUG |
1484 | case ACT_ERROR: | 1479 | case ACT_ERROR: |
@@ -1496,16 +1491,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1496 | break; | 1491 | break; |
1497 | #endif | 1492 | #endif |
1498 | case ACT_DEBUG: | 1493 | case ACT_DEBUG: |
1499 | dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", | 1494 | gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", |
1500 | __func__, ev->type, at_state->ConState); | 1495 | __func__, ev->type, at_state->ConState); |
1501 | break; | 1496 | break; |
1502 | case ACT_WARN: | 1497 | case ACT_WARN: |
1503 | warn("%s: resp_code %d in ConState %d!", | 1498 | dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n", |
1504 | __func__, ev->type, at_state->ConState); | 1499 | __func__, ev->type, at_state->ConState); |
1505 | break; | 1500 | break; |
1506 | case ACT_ZCAU: | 1501 | case ACT_ZCAU: |
1507 | warn("cause code %04x in connection state %d.", | 1502 | dev_warn(cs->dev, "cause code %04x in connection state %d.\n", |
1508 | ev->parameter, at_state->ConState); | 1503 | ev->parameter, at_state->ConState); |
1509 | break; | 1504 | break; |
1510 | 1505 | ||
1511 | /* events from the LL */ | 1506 | /* events from the LL */ |
@@ -1516,14 +1511,14 @@ static void do_action(int action, struct cardstate *cs, | |||
1516 | start_accept(at_state); | 1511 | start_accept(at_state); |
1517 | break; | 1512 | break; |
1518 | case ACT_PROTO_L2: | 1513 | case ACT_PROTO_L2: |
1519 | dbg(DEBUG_CMD, | 1514 | gig_dbg(DEBUG_CMD, "set protocol to %u", |
1520 | "set protocol to %u", (unsigned) ev->parameter); | 1515 | (unsigned) ev->parameter); |
1521 | at_state->bcs->proto2 = ev->parameter; | 1516 | at_state->bcs->proto2 = ev->parameter; |
1522 | break; | 1517 | break; |
1523 | case ACT_HUP: | 1518 | case ACT_HUP: |
1524 | at_state->pending_commands |= PC_HUP; | 1519 | at_state->pending_commands |= PC_HUP; |
1525 | atomic_set(&cs->commands_pending, 1); //FIXME | 1520 | atomic_set(&cs->commands_pending, 1); |
1526 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 1521 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1527 | break; | 1522 | break; |
1528 | 1523 | ||
1529 | /* hotplug events */ | 1524 | /* hotplug events */ |
@@ -1555,17 +1550,19 @@ static void do_action(int action, struct cardstate *cs, | |||
1555 | 1550 | ||
1556 | /* events from the proc file system */ // FIXME without ACT_xxxx? | 1551 | /* events from the proc file system */ // FIXME without ACT_xxxx? |
1557 | case ACT_PROC_CIDMODE: | 1552 | case ACT_PROC_CIDMODE: |
1558 | if (ev->parameter != atomic_read(&cs->cidmode)) { | 1553 | spin_lock_irqsave(&cs->lock, flags); |
1559 | atomic_set(&cs->cidmode, ev->parameter); | 1554 | if (ev->parameter != cs->cidmode) { |
1555 | cs->cidmode = ev->parameter; | ||
1560 | if (ev->parameter) { | 1556 | if (ev->parameter) { |
1561 | cs->at_state.pending_commands |= PC_CIDMODE; | 1557 | cs->at_state.pending_commands |= PC_CIDMODE; |
1562 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1558 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1563 | } else { | 1559 | } else { |
1564 | cs->at_state.pending_commands |= PC_UMMODE; | 1560 | cs->at_state.pending_commands |= PC_UMMODE; |
1565 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 1561 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
1566 | } | 1562 | } |
1567 | atomic_set(&cs->commands_pending, 1); | 1563 | atomic_set(&cs->commands_pending, 1); |
1568 | } | 1564 | } |
1565 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1569 | cs->waiting = 0; | 1566 | cs->waiting = 0; |
1570 | wake_up(&cs->waitqueue); | 1567 | wake_up(&cs->waitqueue); |
1571 | break; | 1568 | break; |
@@ -1590,7 +1587,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1590 | *p_resp_code = RSP_NULL; | 1587 | *p_resp_code = RSP_NULL; |
1591 | } | 1588 | } |
1592 | } else | 1589 | } else |
1593 | err("%s: action==%d!", __func__, action); | 1590 | dev_err(cs->dev, "%s: action==%d!\n", __func__, action); |
1594 | } | 1591 | } |
1595 | } | 1592 | } |
1596 | 1593 | ||
@@ -1609,47 +1606,46 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1609 | int curact; | 1606 | int curact; |
1610 | unsigned long flags; | 1607 | unsigned long flags; |
1611 | 1608 | ||
1612 | IFNULLRET(cs); | ||
1613 | IFNULLRET(ev); | ||
1614 | |||
1615 | if (ev->cid >= 0) { | 1609 | if (ev->cid >= 0) { |
1616 | at_state = at_state_from_cid(cs, ev->cid); | 1610 | at_state = at_state_from_cid(cs, ev->cid); |
1617 | if (!at_state) { | 1611 | if (!at_state) { |
1618 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, | 1612 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, |
1619 | NULL, 0, NULL); | 1613 | NULL, 0, NULL); |
1620 | return; | 1614 | return; |
1621 | } | 1615 | } |
1622 | } else { | 1616 | } else { |
1623 | at_state = ev->at_state; | 1617 | at_state = ev->at_state; |
1624 | if (at_state_invalid(cs, at_state)) { | 1618 | if (at_state_invalid(cs, at_state)) { |
1625 | dbg(DEBUG_ANY, | 1619 | gig_dbg(DEBUG_ANY, "event for invalid at_state %p", |
1626 | "event for invalid at_state %p", at_state); | 1620 | at_state); |
1627 | return; | 1621 | return; |
1628 | } | 1622 | } |
1629 | } | 1623 | } |
1630 | 1624 | ||
1631 | dbg(DEBUG_CMD, | 1625 | gig_dbg(DEBUG_CMD, "connection state %d, event %d", |
1632 | "connection state %d, event %d", at_state->ConState, ev->type); | 1626 | at_state->ConState, ev->type); |
1633 | 1627 | ||
1634 | bcs = at_state->bcs; | 1628 | bcs = at_state->bcs; |
1635 | sendcid = at_state->cid; | 1629 | sendcid = at_state->cid; |
1636 | 1630 | ||
1637 | /* Setting the pointer to the dial array */ | 1631 | /* Setting the pointer to the dial array */ |
1638 | rep = at_state->replystruct; | 1632 | rep = at_state->replystruct; |
1639 | IFNULLRET(rep); | ||
1640 | 1633 | ||
1634 | spin_lock_irqsave(&cs->lock, flags); | ||
1641 | if (ev->type == EV_TIMEOUT) { | 1635 | if (ev->type == EV_TIMEOUT) { |
1642 | if (ev->parameter != atomic_read(&at_state->timer_index) | 1636 | if (ev->parameter != at_state->timer_index |
1643 | || !at_state->timer_active) { | 1637 | || !at_state->timer_active) { |
1644 | ev->type = RSP_NONE; /* old timeout */ | 1638 | ev->type = RSP_NONE; /* old timeout */ |
1645 | dbg(DEBUG_ANY, "old timeout"); | 1639 | gig_dbg(DEBUG_ANY, "old timeout"); |
1646 | } else if (!at_state->waiting) | 1640 | } else if (!at_state->waiting) |
1647 | dbg(DEBUG_ANY, "timeout occured"); | 1641 | gig_dbg(DEBUG_ANY, "timeout occurred"); |
1648 | else | 1642 | else |
1649 | dbg(DEBUG_ANY, "stopped waiting"); | 1643 | gig_dbg(DEBUG_ANY, "stopped waiting"); |
1650 | } | 1644 | } |
1645 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1651 | 1646 | ||
1652 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] or at_state->str_var[STR_XXXX], set it */ | 1647 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] |
1648 | or at_state->str_var[STR_XXXX], set it */ | ||
1653 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { | 1649 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { |
1654 | index = ev->type - RSP_VAR; | 1650 | index = ev->type - RSP_VAR; |
1655 | at_state->int_var[index] = ev->parameter; | 1651 | at_state->int_var[index] = ev->parameter; |
@@ -1657,20 +1653,22 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1657 | index = ev->type - RSP_STR; | 1653 | index = ev->type - RSP_STR; |
1658 | kfree(at_state->str_var[index]); | 1654 | kfree(at_state->str_var[index]); |
1659 | at_state->str_var[index] = ev->ptr; | 1655 | at_state->str_var[index] = ev->ptr; |
1660 | ev->ptr = NULL; /* prevent process_events() from deallocating ptr */ | 1656 | ev->ptr = NULL; /* prevent process_events() from |
1657 | deallocating ptr */ | ||
1661 | } | 1658 | } |
1662 | 1659 | ||
1663 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) | 1660 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) |
1664 | at_state->getstring = 0; | 1661 | at_state->getstring = 0; |
1665 | 1662 | ||
1666 | /* Search row in dial array which matches modem response and current constate */ | 1663 | /* Search row in dial array which matches modem response and current |
1664 | constate */ | ||
1667 | for (;; rep++) { | 1665 | for (;; rep++) { |
1668 | rcode = rep->resp_code; | 1666 | rcode = rep->resp_code; |
1669 | /* dbg (DEBUG_ANY, "rcode %d", rcode); */ | ||
1670 | if (rcode == RSP_LAST) { | 1667 | if (rcode == RSP_LAST) { |
1671 | /* found nothing...*/ | 1668 | /* found nothing...*/ |
1672 | warn("%s: rcode=RSP_LAST: resp_code %d in ConState %d!", | 1669 | dev_warn(cs->dev, "%s: rcode=RSP_LAST: " |
1673 | __func__, ev->type, at_state->ConState); | 1670 | "resp_code %d in ConState %d!\n", |
1671 | __func__, ev->type, at_state->ConState); | ||
1674 | return; | 1672 | return; |
1675 | } | 1673 | } |
1676 | if ((rcode == RSP_ANY || rcode == ev->type) | 1674 | if ((rcode == RSP_ANY || rcode == ev->type) |
@@ -1706,14 +1704,14 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1706 | } else { | 1704 | } else { |
1707 | /* Send command to modem if not NULL... */ | 1705 | /* Send command to modem if not NULL... */ |
1708 | if (p_command/*rep->command*/) { | 1706 | if (p_command/*rep->command*/) { |
1709 | if (atomic_read(&cs->connected)) | 1707 | if (cs->connected) |
1710 | send_command(cs, p_command, | 1708 | send_command(cs, p_command, |
1711 | sendcid, cs->dle, | 1709 | sendcid, cs->dle, |
1712 | GFP_ATOMIC); | 1710 | GFP_ATOMIC); |
1713 | else | 1711 | else |
1714 | gigaset_add_event(cs, at_state, | 1712 | gigaset_add_event(cs, at_state, |
1715 | RSP_NODEV, | 1713 | RSP_NODEV, |
1716 | NULL, 0, NULL); | 1714 | NULL, 0, NULL); |
1717 | } | 1715 | } |
1718 | 1716 | ||
1719 | spin_lock_irqsave(&cs->lock, flags); | 1717 | spin_lock_irqsave(&cs->lock, flags); |
@@ -1723,8 +1721,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1723 | } else if (rep->timeout > 0) { /* new timeout */ | 1721 | } else if (rep->timeout > 0) { /* new timeout */ |
1724 | at_state->timer_expires = rep->timeout * 10; | 1722 | at_state->timer_expires = rep->timeout * 10; |
1725 | at_state->timer_active = 1; | 1723 | at_state->timer_active = 1; |
1726 | new_index(&at_state->timer_index, | 1724 | ++at_state->timer_index; |
1727 | MAX_TIMER_INDEX); | ||
1728 | } | 1725 | } |
1729 | spin_unlock_irqrestore(&cs->lock, flags); | 1726 | spin_unlock_irqrestore(&cs->lock, flags); |
1730 | } | 1727 | } |
@@ -1744,17 +1741,16 @@ static void process_command_flags(struct cardstate *cs) | |||
1744 | struct bc_state *bcs; | 1741 | struct bc_state *bcs; |
1745 | int i; | 1742 | int i; |
1746 | int sequence; | 1743 | int sequence; |
1747 | 1744 | unsigned long flags; | |
1748 | IFNULLRET(cs); | ||
1749 | 1745 | ||
1750 | atomic_set(&cs->commands_pending, 0); | 1746 | atomic_set(&cs->commands_pending, 0); |
1751 | 1747 | ||
1752 | if (cs->cur_at_seq) { | 1748 | if (cs->cur_at_seq) { |
1753 | dbg(DEBUG_CMD, "not searching scheduled commands: busy"); | 1749 | gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); |
1754 | return; | 1750 | return; |
1755 | } | 1751 | } |
1756 | 1752 | ||
1757 | dbg(DEBUG_CMD, "searching scheduled commands"); | 1753 | gig_dbg(DEBUG_CMD, "searching scheduled commands"); |
1758 | 1754 | ||
1759 | sequence = SEQ_NONE; | 1755 | sequence = SEQ_NONE; |
1760 | 1756 | ||
@@ -1795,8 +1791,9 @@ static void process_command_flags(struct cardstate *cs) | |||
1795 | } | 1791 | } |
1796 | 1792 | ||
1797 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ | 1793 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ |
1794 | spin_lock_irqsave(&cs->lock, flags); | ||
1798 | if (cs->at_state.pending_commands == PC_UMMODE | 1795 | if (cs->at_state.pending_commands == PC_UMMODE |
1799 | && !atomic_read(&cs->cidmode) | 1796 | && !cs->cidmode |
1800 | && list_empty(&cs->temp_at_states) | 1797 | && list_empty(&cs->temp_at_states) |
1801 | && atomic_read(&cs->mode) == M_CID) { | 1798 | && atomic_read(&cs->mode) == M_CID) { |
1802 | sequence = SEQ_UMMODE; | 1799 | sequence = SEQ_UMMODE; |
@@ -1810,6 +1807,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1810 | } | 1807 | } |
1811 | } | 1808 | } |
1812 | } | 1809 | } |
1810 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1813 | cs->at_state.pending_commands &= ~PC_UMMODE; | 1811 | cs->at_state.pending_commands &= ~PC_UMMODE; |
1814 | if (sequence != SEQ_NONE) { | 1812 | if (sequence != SEQ_NONE) { |
1815 | schedule_sequence(cs, at_state, sequence); | 1813 | schedule_sequence(cs, at_state, sequence); |
@@ -1865,11 +1863,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1865 | if (cs->at_state.pending_commands & PC_CIDMODE) { | 1863 | if (cs->at_state.pending_commands & PC_CIDMODE) { |
1866 | cs->at_state.pending_commands &= ~PC_CIDMODE; | 1864 | cs->at_state.pending_commands &= ~PC_CIDMODE; |
1867 | if (atomic_read(&cs->mode) == M_UNIMODEM) { | 1865 | if (atomic_read(&cs->mode) == M_UNIMODEM) { |
1868 | #if 0 | ||
1869 | cs->retry_count = 2; | ||
1870 | #else | ||
1871 | cs->retry_count = 1; | 1866 | cs->retry_count = 1; |
1872 | #endif | ||
1873 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); | 1867 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); |
1874 | return; | 1868 | return; |
1875 | } | 1869 | } |
@@ -1897,7 +1891,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1897 | switch (atomic_read(&cs->mode)) { | 1891 | switch (atomic_read(&cs->mode)) { |
1898 | case M_UNIMODEM: | 1892 | case M_UNIMODEM: |
1899 | cs->at_state.pending_commands |= PC_CIDMODE; | 1893 | cs->at_state.pending_commands |= PC_CIDMODE; |
1900 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1894 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1901 | atomic_set(&cs->commands_pending, 1); | 1895 | atomic_set(&cs->commands_pending, 1); |
1902 | return; | 1896 | return; |
1903 | #ifdef GIG_MAYINITONDIAL | 1897 | #ifdef GIG_MAYINITONDIAL |
@@ -1926,18 +1920,21 @@ static void process_events(struct cardstate *cs) | |||
1926 | int i; | 1920 | int i; |
1927 | int check_flags = 0; | 1921 | int check_flags = 0; |
1928 | int was_busy; | 1922 | int was_busy; |
1923 | unsigned long flags; | ||
1929 | 1924 | ||
1930 | /* no locking needed (only one reader) */ | 1925 | spin_lock_irqsave(&cs->ev_lock, flags); |
1931 | head = atomic_read(&cs->ev_head); | 1926 | head = cs->ev_head; |
1932 | 1927 | ||
1933 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { | 1928 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { |
1934 | tail = atomic_read(&cs->ev_tail); | 1929 | tail = cs->ev_tail; |
1935 | if (tail == head) { | 1930 | if (tail == head) { |
1936 | if (!check_flags && !atomic_read(&cs->commands_pending)) | 1931 | if (!check_flags && !atomic_read(&cs->commands_pending)) |
1937 | break; | 1932 | break; |
1938 | check_flags = 0; | 1933 | check_flags = 0; |
1934 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1939 | process_command_flags(cs); | 1935 | process_command_flags(cs); |
1940 | tail = atomic_read(&cs->ev_tail); | 1936 | spin_lock_irqsave(&cs->ev_lock, flags); |
1937 | tail = cs->ev_tail; | ||
1941 | if (tail == head) { | 1938 | if (tail == head) { |
1942 | if (!atomic_read(&cs->commands_pending)) | 1939 | if (!atomic_read(&cs->commands_pending)) |
1943 | break; | 1940 | break; |
@@ -1947,18 +1944,23 @@ static void process_events(struct cardstate *cs) | |||
1947 | 1944 | ||
1948 | ev = cs->events + head; | 1945 | ev = cs->events + head; |
1949 | was_busy = cs->cur_at_seq != SEQ_NONE; | 1946 | was_busy = cs->cur_at_seq != SEQ_NONE; |
1947 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1950 | process_event(cs, ev); | 1948 | process_event(cs, ev); |
1949 | spin_lock_irqsave(&cs->ev_lock, flags); | ||
1951 | kfree(ev->ptr); | 1950 | kfree(ev->ptr); |
1952 | ev->ptr = NULL; | 1951 | ev->ptr = NULL; |
1953 | if (was_busy && cs->cur_at_seq == SEQ_NONE) | 1952 | if (was_busy && cs->cur_at_seq == SEQ_NONE) |
1954 | check_flags = 1; | 1953 | check_flags = 1; |
1955 | 1954 | ||
1956 | head = (head + 1) % MAX_EVENTS; | 1955 | head = (head + 1) % MAX_EVENTS; |
1957 | atomic_set(&cs->ev_head, head); | 1956 | cs->ev_head = head; |
1958 | } | 1957 | } |
1959 | 1958 | ||
1959 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1960 | |||
1960 | if (i == 2 * MAX_EVENTS) { | 1961 | if (i == 2 * MAX_EVENTS) { |
1961 | err("infinite loop in process_events; aborting."); | 1962 | dev_err(cs->dev, |
1963 | "infinite loop in process_events; aborting.\n"); | ||
1962 | } | 1964 | } |
1963 | } | 1965 | } |
1964 | 1966 | ||
@@ -1970,12 +1972,9 @@ void gigaset_handle_event(unsigned long data) | |||
1970 | { | 1972 | { |
1971 | struct cardstate *cs = (struct cardstate *) data; | 1973 | struct cardstate *cs = (struct cardstate *) data; |
1972 | 1974 | ||
1973 | IFNULLRET(cs); | ||
1974 | IFNULLRET(cs->inbuf); | ||
1975 | |||
1976 | /* handle incoming data on control/common channel */ | 1975 | /* handle incoming data on control/common channel */ |
1977 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { | 1976 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { |
1978 | dbg(DEBUG_INTR, "processing new data"); | 1977 | gig_dbg(DEBUG_INTR, "processing new data"); |
1979 | cs->ops->handle_input(cs->inbuf); | 1978 | cs->ops->handle_input(cs->inbuf); |
1980 | } | 1979 | } |
1981 | 1980 | ||
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 729edcdb6dac..9d21ba8757b0 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -1,11 +1,16 @@ | |||
1 | /* Siemens Gigaset 307x driver | 1 | /* |
2 | * Siemens Gigaset 307x driver | ||
2 | * Common header file for all connection variants | 3 | * Common header file for all connection variants |
3 | * | 4 | * |
4 | * Written by Stefan Eilers <Eilers.Stefan@epost.de> | 5 | * Written by Stefan Eilers |
5 | * and Hansjoerg Lipp <hjlipp@web.de> | 6 | * and Hansjoerg Lipp <hjlipp@web.de> |
6 | * | 7 | * |
7 | * Version: $Id: gigaset.h,v 1.97.4.26 2006/02/04 18:28:16 hjlipp Exp $ | 8 | * ===================================================================== |
8 | * =========================================================================== | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of | ||
12 | * the License, or (at your option) any later version. | ||
13 | * ===================================================================== | ||
9 | */ | 14 | */ |
10 | 15 | ||
11 | #ifndef GIGASET_H | 16 | #ifndef GIGASET_H |
@@ -15,7 +20,6 @@ | |||
15 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
16 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
17 | #include <linux/types.h> | 22 | #include <linux/types.h> |
18 | #include <asm/atomic.h> | ||
19 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
20 | #include <linux/isdnif.h> | 24 | #include <linux/isdnif.h> |
21 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
@@ -27,21 +31,22 @@ | |||
27 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
28 | #include <linux/tty_driver.h> | 32 | #include <linux/tty_driver.h> |
29 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <asm/atomic.h> | ||
30 | 35 | ||
31 | #define GIG_VERSION {0,5,0,0} | 36 | #define GIG_VERSION {0,5,0,0} |
32 | #define GIG_COMPAT {0,4,0,0} | 37 | #define GIG_COMPAT {0,4,0,0} |
33 | 38 | ||
34 | #define MAX_REC_PARAMS 10 /* Max. number of params in response string */ | 39 | #define MAX_REC_PARAMS 10 /* Max. number of params in response string */ |
35 | #define MAX_RESP_SIZE 512 /* Max. size of a response string */ | 40 | #define MAX_RESP_SIZE 512 /* Max. size of a response string */ |
36 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ | 41 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ |
37 | 42 | ||
38 | #define MAX_EVENTS 64 /* size of event queue */ | 43 | #define MAX_EVENTS 64 /* size of event queue */ |
39 | 44 | ||
40 | #define RBUFSIZE 8192 | 45 | #define RBUFSIZE 8192 |
41 | #define SBUFSIZE 4096 /* sk_buff payload size */ | 46 | #define SBUFSIZE 4096 /* sk_buff payload size */ |
42 | 47 | ||
43 | #define MAX_BUF_SIZE (SBUFSIZE - 2) /* Max. size of a data packet from LL */ | 48 | #define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ |
44 | #define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ | 49 | #define MAX_BUF_SIZE (SBUFSIZE - 2) /* Max. size of a data packet from LL */ |
45 | 50 | ||
46 | /* compile time options */ | 51 | /* compile time options */ |
47 | #define GIG_MAJOR 0 | 52 | #define GIG_MAJOR 0 |
@@ -50,10 +55,7 @@ | |||
50 | #define GIG_RETRYCID | 55 | #define GIG_RETRYCID |
51 | #define GIG_X75 | 56 | #define GIG_X75 |
52 | 57 | ||
53 | #define MAX_TIMER_INDEX 1000 | 58 | #define GIG_TICK 100 /* in milliseconds */ |
54 | #define MAX_SEQ_INDEX 1000 | ||
55 | |||
56 | #define GIG_TICK (HZ / 10) | ||
57 | 59 | ||
58 | /* timeout values (unit: 1 sec) */ | 60 | /* timeout values (unit: 1 sec) */ |
59 | #define INIT_TIMEOUT 1 | 61 | #define INIT_TIMEOUT 1 |
@@ -67,74 +69,89 @@ | |||
67 | 69 | ||
68 | #define MAXACT 3 | 70 | #define MAXACT 3 |
69 | 71 | ||
70 | #define IFNULL(a) if (unlikely(!(a))) | ||
71 | #define IFNULLRET(a) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); return; } | ||
72 | #define IFNULLRETVAL(a,b) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); return (b); } | ||
73 | #define IFNULLCONT(a) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); continue; } | ||
74 | #define IFNULLGOTO(a,b) if (unlikely(!(a))) {err("%s==NULL at %s:%d!", #a, __FILE__, __LINE__); goto b; } | ||
75 | |||
76 | extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ | 72 | extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ |
77 | 73 | ||
78 | /* any combination of these can be given with the 'debug=' parameter to insmod, e.g. | 74 | /* any combination of these can be given with the 'debug=' parameter to insmod, |
79 | * 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and DEBUG_INTR. */ | 75 | * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and |
76 | * DEBUG_INTR. | ||
77 | */ | ||
80 | enum debuglevel { /* up to 24 bits (atomic_t) */ | 78 | enum debuglevel { /* up to 24 bits (atomic_t) */ |
81 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ | 79 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ |
82 | DEBUG_OPEN = 0x0004, /* open/close serial port */ | 80 | DEBUG_OPEN = 0x0004, /* open/close serial port */ |
83 | DEBUG_INTR = 0x0008, /* interrupt processing */ | 81 | DEBUG_INTR = 0x0008, /* interrupt processing */ |
84 | DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on interrupt | 82 | DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on |
85 | requests, not available as run-time option */ | 83 | interrupt requests, not available as |
84 | run-time option */ | ||
86 | DEBUG_CMD = 0x00020, /* sent/received LL commands */ | 85 | DEBUG_CMD = 0x00020, /* sent/received LL commands */ |
87 | DEBUG_STREAM = 0x00040, /* application data stream I/O events */ | 86 | DEBUG_STREAM = 0x00040, /* application data stream I/O events */ |
88 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ | 87 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ |
89 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ | 88 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ |
90 | DEBUG_INTR_0 = 0x00200, /* serial port output interrupt processing */ | 89 | DEBUG_INTR_0 = 0x00200, /* serial port interrupt processing */ |
91 | DEBUG_DRIVER = 0x00400, /* driver structure */ | 90 | DEBUG_DRIVER = 0x00400, /* driver structure */ |
92 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ | 91 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ |
93 | DEBUG_WRITE = 0x01000, /* M105 data write */ | 92 | DEBUG_WRITE = 0x01000, /* M105 data write */ |
94 | DEBUG_TRANSCMD = 0x02000, /*AT-COMMANDS+RESPONSES*/ | 93 | DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ |
95 | DEBUG_MCMD = 0x04000, /*COMMANDS THAT ARE SENT VERY OFTEN*/ | 94 | DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ |
96 | DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data structures */ | 95 | DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data |
96 | structures */ | ||
97 | DEBUG_LOCK = 0x10000, /* semaphore operations */ | 97 | DEBUG_LOCK = 0x10000, /* semaphore operations */ |
98 | DEBUG_OUTPUT = 0x20000, /* output to device */ | 98 | DEBUG_OUTPUT = 0x20000, /* output to device */ |
99 | DEBUG_ISO = 0x40000, /* isochronous transfers */ | 99 | DEBUG_ISO = 0x40000, /* isochronous transfers */ |
100 | DEBUG_IF = 0x80000, /* character device operations */ | 100 | DEBUG_IF = 0x80000, /* character device operations */ |
101 | DEBUG_USBREQ = 0x100000, /* USB communication (except payload data) */ | 101 | DEBUG_USBREQ = 0x100000, /* USB communication (except payload |
102 | DEBUG_LOCKCMD = 0x200000, /* AT commands and responses when MS_LOCKED */ | 102 | data) */ |
103 | DEBUG_LOCKCMD = 0x200000, /* AT commands and responses when | ||
104 | MS_LOCKED */ | ||
103 | 105 | ||
104 | DEBUG_ANY = 0x3fffff, /* print message if any of the others is activated */ | 106 | DEBUG_ANY = 0x3fffff, /* print message if any of the others is |
107 | activated */ | ||
105 | }; | 108 | }; |
106 | 109 | ||
107 | #ifdef CONFIG_GIGASET_DEBUG | 110 | /* missing from linux/device.h ... */ |
108 | #define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) | 111 | #ifndef dev_notice |
109 | //#define DEBUG_DEFAULT (DEBUG_LOCK | DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUF_IF | DEBUG_DRIVER | DEBUG_OUTPUT | DEBUG_INTR) | 112 | #define dev_notice(dev, format, arg...) \ |
110 | #else | 113 | dev_printk(KERN_NOTICE , dev , format , ## arg) |
111 | #define DEBUG_DEFAULT 0 | ||
112 | #endif | 114 | #endif |
113 | 115 | ||
114 | /* redefine syslog macros to prepend module name instead of entire source path */ | 116 | /* Kernel message macros for situations where dev_printk and friends cannot be |
115 | /* The space before the comma in ", ##" is needed by gcc 2.95 */ | 117 | * used for lack of reliable access to a device structure. |
118 | * linux/usb.h already contains these but in an obsolete form which clutters | ||
119 | * the log needlessly, and according to the USB maintainer those should be | ||
120 | * removed rather than fixed anyway. | ||
121 | */ | ||
122 | #undef err | ||
116 | #undef info | 123 | #undef info |
117 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | ||
118 | |||
119 | #undef notice | ||
120 | #define notice(format, arg...) printk(KERN_NOTICE "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | ||
121 | |||
122 | #undef warn | 124 | #undef warn |
123 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | 125 | #undef notice |
124 | 126 | ||
125 | #undef err | 127 | #define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ |
126 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg) | 128 | format "\n" , ## arg) |
129 | #define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \ | ||
130 | format "\n" , ## arg) | ||
131 | #define warn(format, arg...) printk(KERN_WARNING KBUILD_MODNAME ": " \ | ||
132 | format "\n" , ## arg) | ||
133 | #define notice(format, arg...) printk(KERN_NOTICE KBUILD_MODNAME ": " \ | ||
134 | format "\n" , ## arg) | ||
127 | 135 | ||
128 | #undef dbg | ||
129 | #ifdef CONFIG_GIGASET_DEBUG | 136 | #ifdef CONFIG_GIGASET_DEBUG |
130 | #define dbg(level, format, arg...) do { if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \ | 137 | |
131 | printk(KERN_DEBUG "%s: " format "\n", THIS_MODULE ? THIS_MODULE->name : "gigaset_hw" , ## arg); } while (0) | 138 | #define gig_dbg(level, format, arg...) \ |
139 | do { \ | ||
140 | if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \ | ||
141 | printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ | ||
142 | ## arg); \ | ||
143 | } while (0) | ||
144 | #define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) | ||
145 | |||
132 | #else | 146 | #else |
133 | #define dbg(level, format, arg...) do {} while (0) | 147 | |
148 | #define gig_dbg(level, format, arg...) do {} while (0) | ||
149 | #define DEBUG_DEFAULT 0 | ||
150 | |||
134 | #endif | 151 | #endif |
135 | 152 | ||
136 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | 153 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, |
137 | size_t len, const unsigned char *buf, int from_user); | 154 | size_t len, const unsigned char *buf); |
138 | 155 | ||
139 | /* connection state */ | 156 | /* connection state */ |
140 | #define ZSAU_NONE 0 | 157 | #define ZSAU_NONE 0 |
@@ -148,13 +165,14 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
148 | #define ZSAU_UNKNOWN -1 | 165 | #define ZSAU_UNKNOWN -1 |
149 | 166 | ||
150 | /* USB control transfer requests */ | 167 | /* USB control transfer requests */ |
151 | #define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) | 168 | #define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) |
152 | #define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) | 169 | #define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) |
153 | 170 | ||
154 | /* int-in-events 3070 */ | 171 | /* int-in-events 3070 */ |
155 | #define HD_B1_FLOW_CONTROL 0x80 | 172 | #define HD_B1_FLOW_CONTROL 0x80 |
156 | #define HD_B2_FLOW_CONTROL 0x81 | 173 | #define HD_B2_FLOW_CONTROL 0x81 |
157 | #define HD_RECEIVEATDATA_ACK (0x35) // 3070 // att: HD_RECEIVE>>AT<<DATA_ACK | 174 | #define HD_RECEIVEATDATA_ACK (0x35) // 3070 |
175 | // att: HD_RECEIVE>>AT<<DATA_ACK | ||
158 | #define HD_READY_SEND_ATDATA (0x36) // 3070 | 176 | #define HD_READY_SEND_ATDATA (0x36) // 3070 |
159 | #define HD_OPEN_ATCHANNEL_ACK (0x37) // 3070 | 177 | #define HD_OPEN_ATCHANNEL_ACK (0x37) // 3070 |
160 | #define HD_CLOSE_ATCHANNEL_ACK (0x38) // 3070 | 178 | #define HD_CLOSE_ATCHANNEL_ACK (0x38) // 3070 |
@@ -181,17 +199,18 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
181 | #define HD_CLOSE_ATCHANNEL (0x29) // 3070 | 199 | #define HD_CLOSE_ATCHANNEL (0x29) // 3070 |
182 | 200 | ||
183 | /* USB frames for isochronous transfer */ | 201 | /* USB frames for isochronous transfer */ |
184 | #define BAS_FRAMETIME 1 /* number of milliseconds between frames */ | 202 | #define BAS_FRAMETIME 1 /* number of milliseconds between frames */ |
185 | #define BAS_NUMFRAMES 8 /* number of frames per URB */ | 203 | #define BAS_NUMFRAMES 8 /* number of frames per URB */ |
186 | #define BAS_MAXFRAME 16 /* allocated bytes per frame */ | 204 | #define BAS_MAXFRAME 16 /* allocated bytes per frame */ |
187 | #define BAS_NORMFRAME 8 /* send size without flow control */ | 205 | #define BAS_NORMFRAME 8 /* send size without flow control */ |
188 | #define BAS_HIGHFRAME 10 /* " " with positive flow control */ | 206 | #define BAS_HIGHFRAME 10 /* " " with positive flow control */ |
189 | #define BAS_LOWFRAME 5 /* " " with negative flow control */ | 207 | #define BAS_LOWFRAME 5 /* " " with negative flow control */ |
190 | #define BAS_CORRFRAMES 4 /* flow control multiplicator */ | 208 | #define BAS_CORRFRAMES 4 /* flow control multiplicator */ |
191 | 209 | ||
192 | #define BAS_INBUFSIZE (BAS_MAXFRAME * BAS_NUMFRAMES) /* size of isochronous input buffer per URB */ | 210 | #define BAS_INBUFSIZE (BAS_MAXFRAME * BAS_NUMFRAMES) |
193 | #define BAS_OUTBUFSIZE 4096 /* size of common isochronous output buffer */ | 211 | /* size of isoc in buf per URB */ |
194 | #define BAS_OUTBUFPAD BAS_MAXFRAME /* size of pad area for isochronous output buffer */ | 212 | #define BAS_OUTBUFSIZE 4096 /* size of common isoc out buffer */ |
213 | #define BAS_OUTBUFPAD BAS_MAXFRAME /* size of pad area for isoc out buf */ | ||
195 | 214 | ||
196 | #define BAS_INURBS 3 | 215 | #define BAS_INURBS 3 |
197 | #define BAS_OUTURBS 3 | 216 | #define BAS_OUTURBS 3 |
@@ -207,40 +226,40 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
207 | #define AT_NUM 7 | 226 | #define AT_NUM 7 |
208 | 227 | ||
209 | /* variables in struct at_state_t */ | 228 | /* variables in struct at_state_t */ |
210 | #define VAR_ZSAU 0 | 229 | #define VAR_ZSAU 0 |
211 | #define VAR_ZDLE 1 | 230 | #define VAR_ZDLE 1 |
212 | #define VAR_ZVLS 2 | 231 | #define VAR_ZVLS 2 |
213 | #define VAR_ZCTP 3 | 232 | #define VAR_ZCTP 3 |
214 | #define VAR_NUM 4 | 233 | #define VAR_NUM 4 |
215 | 234 | ||
216 | #define STR_NMBR 0 | 235 | #define STR_NMBR 0 |
217 | #define STR_ZCPN 1 | 236 | #define STR_ZCPN 1 |
218 | #define STR_ZCON 2 | 237 | #define STR_ZCON 2 |
219 | #define STR_ZBC 3 | 238 | #define STR_ZBC 3 |
220 | #define STR_ZHLC 4 | 239 | #define STR_ZHLC 4 |
221 | #define STR_NUM 5 | 240 | #define STR_NUM 5 |
222 | 241 | ||
223 | #define EV_TIMEOUT -105 | 242 | #define EV_TIMEOUT -105 |
224 | #define EV_IF_VER -106 | 243 | #define EV_IF_VER -106 |
225 | #define EV_PROC_CIDMODE -107 | 244 | #define EV_PROC_CIDMODE -107 |
226 | #define EV_SHUTDOWN -108 | 245 | #define EV_SHUTDOWN -108 |
227 | #define EV_START -110 | 246 | #define EV_START -110 |
228 | #define EV_STOP -111 | 247 | #define EV_STOP -111 |
229 | #define EV_IF_LOCK -112 | 248 | #define EV_IF_LOCK -112 |
230 | #define EV_PROTO_L2 -113 | 249 | #define EV_PROTO_L2 -113 |
231 | #define EV_ACCEPT -114 | 250 | #define EV_ACCEPT -114 |
232 | #define EV_DIAL -115 | 251 | #define EV_DIAL -115 |
233 | #define EV_HUP -116 | 252 | #define EV_HUP -116 |
234 | #define EV_BC_OPEN -117 | 253 | #define EV_BC_OPEN -117 |
235 | #define EV_BC_CLOSED -118 | 254 | #define EV_BC_CLOSED -118 |
236 | 255 | ||
237 | /* input state */ | 256 | /* input state */ |
238 | #define INS_command 0x0001 | 257 | #define INS_command 0x0001 |
239 | #define INS_DLE_char 0x0002 | 258 | #define INS_DLE_char 0x0002 |
240 | #define INS_byte_stuff 0x0004 | 259 | #define INS_byte_stuff 0x0004 |
241 | #define INS_have_data 0x0008 | 260 | #define INS_have_data 0x0008 |
242 | #define INS_skip_frame 0x0010 | 261 | #define INS_skip_frame 0x0010 |
243 | #define INS_DLE_command 0x0020 | 262 | #define INS_DLE_command 0x0020 |
244 | #define INS_flag_hunt 0x0040 | 263 | #define INS_flag_hunt 0x0040 |
245 | 264 | ||
246 | /* channel state */ | 265 | /* channel state */ |
@@ -248,27 +267,27 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
248 | #define CHS_B_UP 0x02 | 267 | #define CHS_B_UP 0x02 |
249 | #define CHS_NOTIFY_LL 0x04 | 268 | #define CHS_NOTIFY_LL 0x04 |
250 | 269 | ||
251 | #define ICALL_REJECT 0 | 270 | #define ICALL_REJECT 0 |
252 | #define ICALL_ACCEPT 1 | 271 | #define ICALL_ACCEPT 1 |
253 | #define ICALL_IGNORE 2 | 272 | #define ICALL_IGNORE 2 |
254 | 273 | ||
255 | /* device state */ | 274 | /* device state */ |
256 | #define MS_UNINITIALIZED 0 | 275 | #define MS_UNINITIALIZED 0 |
257 | #define MS_INIT 1 | 276 | #define MS_INIT 1 |
258 | #define MS_LOCKED 2 | 277 | #define MS_LOCKED 2 |
259 | #define MS_SHUTDOWN 3 | 278 | #define MS_SHUTDOWN 3 |
260 | #define MS_RECOVER 4 | 279 | #define MS_RECOVER 4 |
261 | #define MS_READY 5 | 280 | #define MS_READY 5 |
262 | 281 | ||
263 | /* mode */ | 282 | /* mode */ |
264 | #define M_UNKNOWN 0 | 283 | #define M_UNKNOWN 0 |
265 | #define M_CONFIG 1 | 284 | #define M_CONFIG 1 |
266 | #define M_UNIMODEM 2 | 285 | #define M_UNIMODEM 2 |
267 | #define M_CID 3 | 286 | #define M_CID 3 |
268 | 287 | ||
269 | /* start mode */ | 288 | /* start mode */ |
270 | #define SM_LOCKED 0 | 289 | #define SM_LOCKED 0 |
271 | #define SM_ISDN 1 /* default */ | 290 | #define SM_ISDN 1 /* default */ |
272 | 291 | ||
273 | struct gigaset_ops; | 292 | struct gigaset_ops; |
274 | struct gigaset_driver; | 293 | struct gigaset_driver; |
@@ -283,27 +302,26 @@ struct ser_bc_state; | |||
283 | struct bas_bc_state; | 302 | struct bas_bc_state; |
284 | 303 | ||
285 | struct reply_t { | 304 | struct reply_t { |
286 | int resp_code; /* RSP_XXXX */ | 305 | int resp_code; /* RSP_XXXX */ |
287 | int min_ConState; /* <0 => ignore */ | 306 | int min_ConState; /* <0 => ignore */ |
288 | int max_ConState; /* <0 => ignore */ | 307 | int max_ConState; /* <0 => ignore */ |
289 | int parameter; /* e.g. ZSAU_XXXX <0: ignore*/ | 308 | int parameter; /* e.g. ZSAU_XXXX <0: ignore*/ |
290 | int new_ConState; /* <0 => ignore */ | 309 | int new_ConState; /* <0 => ignore */ |
291 | int timeout; /* >0 => *HZ; <=0 => TOUT_XXXX*/ | 310 | int timeout; /* >0 => *HZ; <=0 => TOUT_XXXX*/ |
292 | int action[MAXACT]; /* ACT_XXXX */ | 311 | int action[MAXACT]; /* ACT_XXXX */ |
293 | char *command; /* NULL==none */ | 312 | char *command; /* NULL==none */ |
294 | }; | 313 | }; |
295 | 314 | ||
296 | extern struct reply_t gigaset_tab_cid_m10x[]; | 315 | extern struct reply_t gigaset_tab_cid_m10x[]; |
297 | extern struct reply_t gigaset_tab_nocid_m10x[]; | 316 | extern struct reply_t gigaset_tab_nocid_m10x[]; |
298 | 317 | ||
299 | struct inbuf_t { | 318 | struct inbuf_t { |
300 | unsigned char *rcvbuf; /* usb-gigaset receive buffer */ | 319 | unsigned char *rcvbuf; /* usb-gigaset receive buffer */ |
301 | struct bc_state *bcs; | 320 | struct bc_state *bcs; |
302 | struct cardstate *cs; | 321 | struct cardstate *cs; |
303 | int inputstate; | 322 | int inputstate; |
304 | 323 | atomic_t head, tail; | |
305 | atomic_t head, tail; | 324 | unsigned char data[RBUFSIZE]; |
306 | unsigned char data[RBUFSIZE]; | ||
307 | }; | 325 | }; |
308 | 326 | ||
309 | /* isochronous write buffer structure | 327 | /* isochronous write buffer structure |
@@ -319,16 +337,9 @@ struct inbuf_t { | |||
319 | * if writesem <= 0, data[write..read-1] is currently being written to | 337 | * if writesem <= 0, data[write..read-1] is currently being written to |
320 | * - idle contains the byte value to repeat when the end of valid data is | 338 | * - idle contains the byte value to repeat when the end of valid data is |
321 | * reached; if nextread==write (buffer contains no data to send), either the | 339 | * reached; if nextread==write (buffer contains no data to send), either the |
322 | * BAS_OUTBUFPAD bytes immediately before data[write] (if write>=BAS_OUTBUFPAD) | 340 | * BAS_OUTBUFPAD bytes immediately before data[write] (if |
323 | * or those of the pad area (if write<BAS_OUTBUFPAD) are also filled with that | 341 | * write>=BAS_OUTBUFPAD) or those of the pad area (if write<BAS_OUTBUFPAD) |
324 | * value | 342 | * are also filled with that value |
325 | * - optionally, the following statistics on the buffer's usage can be collected: | ||
326 | * maxfill: maximum number of bytes occupied | ||
327 | * idlefills: number of times a frame of idle bytes is prepared | ||
328 | * emptygets: number of times the buffer was empty when a data frame was requested | ||
329 | * backtoback: number of times two data packets were entered into the buffer | ||
330 | * without intervening idle flags | ||
331 | * nakedback: set if no idle flags have been inserted since the last data packet | ||
332 | */ | 343 | */ |
333 | struct isowbuf_t { | 344 | struct isowbuf_t { |
334 | atomic_t read; | 345 | atomic_t read; |
@@ -358,34 +369,28 @@ struct isow_urbctx_t { | |||
358 | * it is currently assigned a B channel | 369 | * it is currently assigned a B channel |
359 | */ | 370 | */ |
360 | struct at_state_t { | 371 | struct at_state_t { |
361 | struct list_head list; | 372 | struct list_head list; |
362 | int waiting; | 373 | int waiting; |
363 | int getstring; | 374 | int getstring; |
364 | atomic_t timer_index; | 375 | unsigned timer_index; |
365 | unsigned long timer_expires; | 376 | unsigned long timer_expires; |
366 | int timer_active; | 377 | int timer_active; |
367 | unsigned int ConState; /* State of connection */ | 378 | unsigned int ConState; /* State of connection */ |
368 | struct reply_t *replystruct; | 379 | struct reply_t *replystruct; |
369 | int cid; | 380 | int cid; |
370 | int int_var[VAR_NUM]; /* see VAR_XXXX */ | 381 | int int_var[VAR_NUM]; /* see VAR_XXXX */ |
371 | char *str_var[STR_NUM]; /* see STR_XXXX */ | 382 | char *str_var[STR_NUM]; /* see STR_XXXX */ |
372 | unsigned pending_commands; /* see PC_XXXX */ | 383 | unsigned pending_commands; /* see PC_XXXX */ |
373 | atomic_t seq_index; | 384 | unsigned seq_index; |
374 | 385 | ||
375 | struct cardstate *cs; | 386 | struct cardstate *cs; |
376 | struct bc_state *bcs; | 387 | struct bc_state *bcs; |
377 | }; | 388 | }; |
378 | 389 | ||
379 | struct resp_type_t { | 390 | struct resp_type_t { |
380 | unsigned char *response; | 391 | unsigned char *response; |
381 | int resp_code; /* RSP_XXXX */ | 392 | int resp_code; /* RSP_XXXX */ |
382 | int type; /* RT_XXXX */ | 393 | int type; /* RT_XXXX */ |
383 | }; | ||
384 | |||
385 | struct prot_skb { | ||
386 | atomic_t empty; | ||
387 | struct semaphore *sem; | ||
388 | struct sk_buff *skb; | ||
389 | }; | 394 | }; |
390 | 395 | ||
391 | struct event_t { | 396 | struct event_t { |
@@ -398,29 +403,29 @@ struct event_t { | |||
398 | 403 | ||
399 | /* This buffer holds all information about the used B-Channel */ | 404 | /* This buffer holds all information about the used B-Channel */ |
400 | struct bc_state { | 405 | struct bc_state { |
401 | struct sk_buff *tx_skb; /* Current transfer buffer to modem */ | 406 | struct sk_buff *tx_skb; /* Current transfer buffer to modem */ |
402 | struct sk_buff_head squeue; /* B-Channel send Queue */ | 407 | struct sk_buff_head squeue; /* B-Channel send Queue */ |
403 | 408 | ||
404 | /* Variables for debugging .. */ | 409 | /* Variables for debugging .. */ |
405 | int corrupted; /* Counter for corrupted packages */ | 410 | int corrupted; /* Counter for corrupted packages */ |
406 | int trans_down; /* Counter of packages (downstream) */ | 411 | int trans_down; /* Counter of packages (downstream) */ |
407 | int trans_up; /* Counter of packages (upstream) */ | 412 | int trans_up; /* Counter of packages (upstream) */ |
408 | 413 | ||
409 | struct at_state_t at_state; | 414 | struct at_state_t at_state; |
410 | unsigned long rcvbytes; | 415 | unsigned long rcvbytes; |
411 | 416 | ||
412 | __u16 fcs; | 417 | __u16 fcs; |
413 | struct sk_buff *skb; | 418 | struct sk_buff *skb; |
414 | int inputstate; /* see INS_XXXX */ | 419 | int inputstate; /* see INS_XXXX */ |
415 | 420 | ||
416 | int channel; | 421 | int channel; |
417 | 422 | ||
418 | struct cardstate *cs; | 423 | struct cardstate *cs; |
419 | 424 | ||
420 | unsigned chstate; /* bitmap (CHS_*) */ | 425 | unsigned chstate; /* bitmap (CHS_*) */ |
421 | int ignore; | 426 | int ignore; |
422 | unsigned proto2; /* Layer 2 protocol (ISDN_PROTO_L2_*) */ | 427 | unsigned proto2; /* Layer 2 protocol (ISDN_PROTO_L2_*) */ |
423 | char *commands[AT_NUM]; /* see AT_XXXX */ | 428 | char *commands[AT_NUM]; /* see AT_XXXX */ |
424 | 429 | ||
425 | #ifdef CONFIG_GIGASET_DEBUG | 430 | #ifdef CONFIG_GIGASET_DEBUG |
426 | int emptycount; | 431 | int emptycount; |
@@ -428,37 +433,39 @@ struct bc_state { | |||
428 | int busy; | 433 | int busy; |
429 | int use_count; | 434 | int use_count; |
430 | 435 | ||
431 | /* hardware drivers */ | 436 | /* private data of hardware drivers */ |
432 | union { | 437 | union { |
433 | struct ser_bc_state *ser; /* private data of serial hardware driver */ | 438 | struct ser_bc_state *ser; /* serial hardware driver */ |
434 | struct usb_bc_state *usb; /* private data of usb hardware driver */ | 439 | struct usb_bc_state *usb; /* usb hardware driver (m105) */ |
435 | struct bas_bc_state *bas; | 440 | struct bas_bc_state *bas; /* usb hardware driver (base) */ |
436 | } hw; | 441 | } hw; |
437 | }; | 442 | }; |
438 | 443 | ||
439 | struct cardstate { | 444 | struct cardstate { |
440 | struct gigaset_driver *driver; | 445 | struct gigaset_driver *driver; |
441 | unsigned minor_index; | 446 | unsigned minor_index; |
447 | struct device *dev; | ||
442 | 448 | ||
443 | const struct gigaset_ops *ops; | 449 | const struct gigaset_ops *ops; |
444 | 450 | ||
445 | /* Stuff to handle communication */ | 451 | /* Stuff to handle communication */ |
446 | //wait_queue_head_t initwait; | ||
447 | wait_queue_head_t waitqueue; | 452 | wait_queue_head_t waitqueue; |
448 | int waiting; | 453 | int waiting; |
449 | atomic_t mode; /* see M_XXXX */ | 454 | atomic_t mode; /* see M_XXXX */ |
450 | atomic_t mstate; /* Modem state: see MS_XXXX */ | 455 | atomic_t mstate; /* Modem state: see MS_XXXX */ |
451 | /* only changed by the event layer */ | 456 | /* only changed by the event layer */ |
452 | int cmd_result; | 457 | int cmd_result; |
453 | 458 | ||
454 | int channels; | 459 | int channels; |
455 | struct bc_state *bcs; /* Array of struct bc_state */ | 460 | struct bc_state *bcs; /* Array of struct bc_state */ |
456 | 461 | ||
457 | int onechannel; /* data and commands transmitted in one stream (M10x) */ | 462 | int onechannel; /* data and commands transmitted in one |
463 | stream (M10x) */ | ||
458 | 464 | ||
459 | spinlock_t lock; | 465 | spinlock_t lock; |
460 | struct at_state_t at_state; /* at_state_t for cid == 0 */ | 466 | struct at_state_t at_state; /* at_state_t for cid == 0 */ |
461 | struct list_head temp_at_states; /* list of temporary "struct at_state_t"s without B channel */ | 467 | struct list_head temp_at_states;/* list of temporary "struct |
468 | at_state_t"s without B channel */ | ||
462 | 469 | ||
463 | struct inbuf_t *inbuf; | 470 | struct inbuf_t *inbuf; |
464 | 471 | ||
@@ -474,58 +481,69 @@ struct cardstate { | |||
474 | unsigned fwver[4]; | 481 | unsigned fwver[4]; |
475 | int gotfwver; | 482 | int gotfwver; |
476 | 483 | ||
477 | atomic_t running; /* !=0 if events are handled */ | 484 | unsigned running; /* !=0 if events are handled */ |
478 | atomic_t connected; /* !=0 if hardware is connected */ | 485 | unsigned connected; /* !=0 if hardware is connected */ |
486 | unsigned isdn_up; /* !=0 after ISDN_STAT_RUN */ | ||
479 | 487 | ||
480 | atomic_t cidmode; | 488 | unsigned cidmode; |
481 | 489 | ||
482 | int myid; /* id for communication with LL */ | 490 | int myid; /* id for communication with LL */ |
483 | isdn_if iif; | 491 | isdn_if iif; |
484 | 492 | ||
485 | struct reply_t *tabnocid; | 493 | struct reply_t *tabnocid; |
486 | struct reply_t *tabcid; | 494 | struct reply_t *tabcid; |
487 | int cs_init; | 495 | int cs_init; |
488 | int ignoreframes; /* frames to ignore after setting up the B channel */ | 496 | int ignoreframes; /* frames to ignore after setting up the |
489 | struct semaphore sem; /* locks this structure: */ | 497 | B channel */ |
490 | /* connected is not changed, */ | 498 | struct mutex mutex; /* locks this structure: |
491 | /* hardware_up is not changed, */ | 499 | * connected is not changed, |
492 | /* MState is not changed to or from MS_LOCKED */ | 500 | * hardware_up is not changed, |
501 | * MState is not changed to or from | ||
502 | * MS_LOCKED */ | ||
493 | 503 | ||
494 | struct timer_list timer; | 504 | struct timer_list timer; |
495 | int retry_count; | 505 | int retry_count; |
496 | int dle; /* !=0 if modem commands/responses are dle encoded */ | 506 | int dle; /* !=0 if modem commands/responses are |
497 | int cur_at_seq; /* sequence of AT commands being processed */ | 507 | dle encoded */ |
498 | int curchannel; /* channel, those commands are meant for */ | 508 | int cur_at_seq; /* sequence of AT commands being |
499 | atomic_t commands_pending; /* flag(s) in xxx.commands_pending have been set */ | 509 | processed */ |
500 | struct tasklet_struct event_tasklet; /* tasklet for serializing AT commands. Scheduled | 510 | int curchannel; /* channel those commands are meant |
501 | * -> for modem reponses (and incomming data for M10x) | 511 | for */ |
502 | * -> on timeout | 512 | atomic_t commands_pending; /* flag(s) in xxx.commands_pending have |
503 | * -> after setting bits in xxx.at_state.pending_command | 513 | been set */ |
504 | * (e.g. command from LL) */ | 514 | struct tasklet_struct event_tasklet; |
505 | struct tasklet_struct write_tasklet; /* tasklet for serial output | 515 | /* tasklet for serializing AT commands. |
506 | * (not used in base driver) */ | 516 | * Scheduled |
517 | * -> for modem reponses (and | ||
518 | * incoming data for M10x) | ||
519 | * -> on timeout | ||
520 | * -> after setting bits in | ||
521 | * xxx.at_state.pending_command | ||
522 | * (e.g. command from LL) */ | ||
523 | struct tasklet_struct write_tasklet; | ||
524 | /* tasklet for serial output | ||
525 | * (not used in base driver) */ | ||
507 | 526 | ||
508 | /* event queue */ | 527 | /* event queue */ |
509 | struct event_t events[MAX_EVENTS]; | 528 | struct event_t events[MAX_EVENTS]; |
510 | atomic_t ev_tail, ev_head; | 529 | unsigned ev_tail, ev_head; |
511 | spinlock_t ev_lock; | 530 | spinlock_t ev_lock; |
512 | 531 | ||
513 | /* current modem response */ | 532 | /* current modem response */ |
514 | unsigned char respdata[MAX_RESP_SIZE]; | 533 | unsigned char respdata[MAX_RESP_SIZE]; |
515 | unsigned cbytes; | 534 | unsigned cbytes; |
516 | 535 | ||
517 | /* hardware drivers */ | 536 | /* private data of hardware drivers */ |
518 | union { | 537 | union { |
519 | struct usb_cardstate *usb; /* private data of USB hardware driver */ | 538 | struct usb_cardstate *usb; /* USB hardware driver (m105) */ |
520 | struct ser_cardstate *ser; /* private data of serial hardware driver */ | 539 | struct ser_cardstate *ser; /* serial hardware driver */ |
521 | struct bas_cardstate *bas; /* private data of base hardware driver */ | 540 | struct bas_cardstate *bas; /* USB hardware driver (base) */ |
522 | } hw; | 541 | } hw; |
523 | }; | 542 | }; |
524 | 543 | ||
525 | struct gigaset_driver { | 544 | struct gigaset_driver { |
526 | struct list_head list; | 545 | struct list_head list; |
527 | spinlock_t lock; /* locks minor tables and blocked */ | 546 | spinlock_t lock; /* locks minor tables and blocked */ |
528 | //struct semaphore sem; /* locks this structure */ | ||
529 | struct tty_driver *tty; | 547 | struct tty_driver *tty; |
530 | unsigned have_tty; | 548 | unsigned have_tty; |
531 | unsigned minor; | 549 | unsigned minor; |
@@ -553,37 +571,42 @@ struct bas_bc_state { | |||
553 | struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; | 571 | struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; |
554 | struct isow_urbctx_t *isooutdone, *isooutfree, *isooutovfl; | 572 | struct isow_urbctx_t *isooutdone, *isooutfree, *isooutovfl; |
555 | struct isowbuf_t *isooutbuf; | 573 | struct isowbuf_t *isooutbuf; |
556 | unsigned numsub; /* submitted URB counter (for diagnostic messages only) */ | 574 | unsigned numsub; /* submitted URB counter |
575 | (for diagnostic messages only) */ | ||
557 | struct tasklet_struct sent_tasklet; | 576 | struct tasklet_struct sent_tasklet; |
558 | 577 | ||
559 | /* isochronous input state */ | 578 | /* isochronous input state */ |
560 | spinlock_t isoinlock; | 579 | spinlock_t isoinlock; |
561 | struct urb *isoinurbs[BAS_INURBS]; | 580 | struct urb *isoinurbs[BAS_INURBS]; |
562 | unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; | 581 | unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; |
563 | struct urb *isoindone; /* completed isoc read URB */ | 582 | struct urb *isoindone; /* completed isoc read URB */ |
564 | int loststatus; /* status of dropped URB */ | 583 | int loststatus; /* status of dropped URB */ |
565 | unsigned isoinlost; /* number of bytes lost */ | 584 | unsigned isoinlost; /* number of bytes lost */ |
566 | /* state of bit unstuffing algorithm (in addition to BC_state.inputstate) */ | 585 | /* state of bit unstuffing algorithm |
567 | unsigned seqlen; /* number of '1' bits not yet unstuffed */ | 586 | (in addition to BC_state.inputstate) */ |
568 | unsigned inbyte, inbits; /* collected bits for next byte */ | 587 | unsigned seqlen; /* number of '1' bits not yet |
588 | unstuffed */ | ||
589 | unsigned inbyte, inbits; /* collected bits for next byte */ | ||
569 | /* statistics */ | 590 | /* statistics */ |
570 | unsigned goodbytes; /* bytes correctly received */ | 591 | unsigned goodbytes; /* bytes correctly received */ |
571 | unsigned alignerrs; /* frames with incomplete byte at end */ | 592 | unsigned alignerrs; /* frames with incomplete byte at end */ |
572 | unsigned fcserrs; /* FCS errors */ | 593 | unsigned fcserrs; /* FCS errors */ |
573 | unsigned frameerrs; /* framing errors */ | 594 | unsigned frameerrs; /* framing errors */ |
574 | unsigned giants; /* long frames */ | 595 | unsigned giants; /* long frames */ |
575 | unsigned runts; /* short frames */ | 596 | unsigned runts; /* short frames */ |
576 | unsigned aborts; /* HDLC aborts */ | 597 | unsigned aborts; /* HDLC aborts */ |
577 | unsigned shared0s; /* '0' bits shared between flags */ | 598 | unsigned shared0s; /* '0' bits shared between flags */ |
578 | unsigned stolen0s; /* '0' stuff bits also serving as leading flag bits */ | 599 | unsigned stolen0s; /* '0' stuff bits also serving as |
600 | leading flag bits */ | ||
579 | struct tasklet_struct rcvd_tasklet; | 601 | struct tasklet_struct rcvd_tasklet; |
580 | }; | 602 | }; |
581 | 603 | ||
582 | struct gigaset_ops { | 604 | struct gigaset_ops { |
583 | /* Called from ev-layer.c/interface.c for sending AT commands to the device */ | 605 | /* Called from ev-layer.c/interface.c for sending AT commands to the |
606 | device */ | ||
584 | int (*write_cmd)(struct cardstate *cs, | 607 | int (*write_cmd)(struct cardstate *cs, |
585 | const unsigned char *buf, int len, | 608 | const unsigned char *buf, int len, |
586 | struct tasklet_struct *wake_tasklet); | 609 | struct tasklet_struct *wake_tasklet); |
587 | 610 | ||
588 | /* Called from interface.c for additional device control */ | 611 | /* Called from interface.c for additional device control */ |
589 | int (*write_room)(struct cardstate *cs); | 612 | int (*write_room)(struct cardstate *cs); |
@@ -604,7 +627,8 @@ struct gigaset_ops { | |||
604 | /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ | 627 | /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ |
605 | int (*freebcshw)(struct bc_state *bcs); | 628 | int (*freebcshw)(struct bc_state *bcs); |
606 | 629 | ||
607 | /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting bcs->hw.xxx */ | 630 | /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting |
631 | bcs->hw.xxx */ | ||
608 | void (*reinitbcshw)(struct bc_state *bcs); | 632 | void (*reinitbcshw)(struct bc_state *bcs); |
609 | 633 | ||
610 | /* Called by gigaset_initcs() for setting up cs->hw.xxx */ | 634 | /* Called by gigaset_initcs() for setting up cs->hw.xxx */ |
@@ -613,13 +637,10 @@ struct gigaset_ops { | |||
613 | /* Called by gigaset_freecs() for freeing cs->hw.xxx */ | 637 | /* Called by gigaset_freecs() for freeing cs->hw.xxx */ |
614 | void (*freecshw)(struct cardstate *cs); | 638 | void (*freecshw)(struct cardstate *cs); |
615 | 639 | ||
616 | ///* Called by gigaset_stop() for killing URBs, shutting down the device, ... | 640 | /* Called from common.c/interface.c for additional serial port |
617 | // hardwareup: ==0: don't try to shut down the device, hardware is really not accessible | 641 | control */ |
618 | // !=0: hardware still up */ | 642 | int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state, |
619 | //void (*stophw)(struct cardstate *cs, int hardwareup); | 643 | unsigned new_state); |
620 | |||
621 | /* Called from common.c/interface.c for additional serial port control */ | ||
622 | int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state, unsigned new_state); | ||
623 | int (*baud_rate)(struct cardstate *cs, unsigned cflag); | 644 | int (*baud_rate)(struct cardstate *cs, unsigned cflag); |
624 | int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); | 645 | int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); |
625 | 646 | ||
@@ -639,7 +660,7 @@ struct gigaset_ops { | |||
639 | * <DLE_FLAG>: 0x10 | 660 | * <DLE_FLAG>: 0x10 |
640 | * <EVENT>: ((a-z)* | (A-Z)* | (0-10)*)+ | 661 | * <EVENT>: ((a-z)* | (A-Z)* | (0-10)*)+ |
641 | */ | 662 | */ |
642 | #define DLE_FLAG 0x10 | 663 | #define DLE_FLAG 0x10 |
643 | 664 | ||
644 | /* =========================================================================== | 665 | /* =========================================================================== |
645 | * Functions implemented in asyncdata.c | 666 | * Functions implemented in asyncdata.c |
@@ -667,7 +688,8 @@ void gigaset_isoc_input(struct inbuf_t *inbuf); | |||
667 | 688 | ||
668 | /* Called from bas-gigaset.c to process a block of data | 689 | /* Called from bas-gigaset.c to process a block of data |
669 | * received through the isochronous channel */ | 690 | * received through the isochronous channel */ |
670 | void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs); | 691 | void gigaset_isoc_receive(unsigned char *src, unsigned count, |
692 | struct bc_state *bcs); | ||
671 | 693 | ||
672 | /* Called from bas-gigaset.c to put a block of data | 694 | /* Called from bas-gigaset.c to put a block of data |
673 | * into the isochronous output buffer */ | 695 | * into the isochronous output buffer */ |
@@ -703,7 +725,7 @@ static inline void gigaset_isdn_rcv_err(struct bc_state *bcs) | |||
703 | isdn_ctrl response; | 725 | isdn_ctrl response; |
704 | 726 | ||
705 | /* error -> LL */ | 727 | /* error -> LL */ |
706 | dbg(DEBUG_CMD, "sending L1ERR"); | 728 | gig_dbg(DEBUG_CMD, "sending L1ERR"); |
707 | response.driver = bcs->cs->myid; | 729 | response.driver = bcs->cs->myid; |
708 | response.command = ISDN_STAT_L1ERR; | 730 | response.command = ISDN_STAT_L1ERR; |
709 | response.arg = bcs->channel; | 731 | response.arg = bcs->channel; |
@@ -727,8 +749,8 @@ void gigaset_handle_modem_response(struct cardstate *cs); | |||
727 | */ | 749 | */ |
728 | 750 | ||
729 | /* initialize sysfs for device */ | 751 | /* initialize sysfs for device */ |
730 | void gigaset_init_dev_sysfs(struct usb_interface *interface); | 752 | void gigaset_init_dev_sysfs(struct cardstate *cs); |
731 | void gigaset_free_dev_sysfs(struct usb_interface *interface); | 753 | void gigaset_free_dev_sysfs(struct cardstate *cs); |
732 | 754 | ||
733 | /* =========================================================================== | 755 | /* =========================================================================== |
734 | * Functions implemented in common.c/gigaset.h | 756 | * Functions implemented in common.c/gigaset.h |
@@ -736,7 +758,7 @@ void gigaset_free_dev_sysfs(struct usb_interface *interface); | |||
736 | 758 | ||
737 | void gigaset_bcs_reinit(struct bc_state *bcs); | 759 | void gigaset_bcs_reinit(struct bc_state *bcs); |
738 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | 760 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, |
739 | struct cardstate *cs, int cid); | 761 | struct cardstate *cs, int cid); |
740 | int gigaset_get_channel(struct bc_state *bcs); | 762 | int gigaset_get_channel(struct bc_state *bcs); |
741 | void gigaset_free_channel(struct bc_state *bcs); | 763 | void gigaset_free_channel(struct bc_state *bcs); |
742 | int gigaset_get_channels(struct cardstate *cs); | 764 | int gigaset_get_channels(struct cardstate *cs); |
@@ -745,16 +767,15 @@ void gigaset_block_channels(struct cardstate *cs); | |||
745 | 767 | ||
746 | /* Allocate and initialize driver structure. */ | 768 | /* Allocate and initialize driver structure. */ |
747 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 769 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, |
748 | const char *procname, | 770 | const char *procname, |
749 | const char *devname, | 771 | const char *devname, |
750 | const char *devfsname, | 772 | const char *devfsname, |
751 | const struct gigaset_ops *ops, | 773 | const struct gigaset_ops *ops, |
752 | struct module *owner); | 774 | struct module *owner); |
753 | 775 | ||
754 | /* Deallocate driver structure. */ | 776 | /* Deallocate driver structure. */ |
755 | void gigaset_freedriver(struct gigaset_driver *drv); | 777 | void gigaset_freedriver(struct gigaset_driver *drv); |
756 | void gigaset_debugdrivers(void); | 778 | void gigaset_debugdrivers(void); |
757 | struct cardstate *gigaset_get_cs_by_minor(unsigned minor); | ||
758 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); | 779 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); |
759 | struct cardstate *gigaset_get_cs_by_id(int id); | 780 | struct cardstate *gigaset_get_cs_by_id(int id); |
760 | 781 | ||
@@ -763,7 +784,8 @@ struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv); | |||
763 | void gigaset_unassign(struct cardstate *cs); | 784 | void gigaset_unassign(struct cardstate *cs); |
764 | void gigaset_blockdriver(struct gigaset_driver *drv); | 785 | void gigaset_blockdriver(struct gigaset_driver *drv); |
765 | 786 | ||
766 | /* Allocate and initialize card state. Calls hardware dependent gigaset_init[b]cs(). */ | 787 | /* Allocate and initialize card state. Calls hardware dependent |
788 | gigaset_init[b]cs(). */ | ||
767 | struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | 789 | struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, |
768 | int onechannel, int ignoreframes, | 790 | int onechannel, int ignoreframes, |
769 | int cidmode, const char *modulename); | 791 | int cidmode, const char *modulename); |
@@ -788,8 +810,8 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); | |||
788 | * ptr must be kmalloc()ed (and not be freed by the caller). | 810 | * ptr must be kmalloc()ed (and not be freed by the caller). |
789 | */ | 811 | */ |
790 | struct event_t *gigaset_add_event(struct cardstate *cs, | 812 | struct event_t *gigaset_add_event(struct cardstate *cs, |
791 | struct at_state_t *at_state, int type, | 813 | struct at_state_t *at_state, int type, |
792 | void *ptr, int parameter, void *arg); | 814 | void *ptr, int parameter, void *arg); |
793 | 815 | ||
794 | /* Called on CONFIG1 command from frontend. */ | 816 | /* Called on CONFIG1 command from frontend. */ |
795 | int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode | 817 | int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode |
@@ -799,7 +821,7 @@ static inline void gigaset_schedule_event(struct cardstate *cs) | |||
799 | { | 821 | { |
800 | unsigned long flags; | 822 | unsigned long flags; |
801 | spin_lock_irqsave(&cs->lock, flags); | 823 | spin_lock_irqsave(&cs->lock, flags); |
802 | if (atomic_read(&cs->running)) | 824 | if (cs->running) |
803 | tasklet_schedule(&cs->event_tasklet); | 825 | tasklet_schedule(&cs->event_tasklet); |
804 | spin_unlock_irqrestore(&cs->lock, flags); | 826 | spin_unlock_irqrestore(&cs->lock, flags); |
805 | } | 827 | } |
@@ -810,7 +832,7 @@ static inline void gigaset_bchannel_down(struct bc_state *bcs) | |||
810 | { | 832 | { |
811 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); | 833 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); |
812 | 834 | ||
813 | dbg(DEBUG_CMD, "scheduling BC_CLOSED"); | 835 | gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED"); |
814 | gigaset_schedule_event(bcs->cs); | 836 | gigaset_schedule_event(bcs->cs); |
815 | } | 837 | } |
816 | 838 | ||
@@ -820,36 +842,19 @@ static inline void gigaset_bchannel_up(struct bc_state *bcs) | |||
820 | { | 842 | { |
821 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); | 843 | gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); |
822 | 844 | ||
823 | dbg(DEBUG_CMD, "scheduling BC_OPEN"); | 845 | gig_dbg(DEBUG_CMD, "scheduling BC_OPEN"); |
824 | gigaset_schedule_event(bcs->cs); | 846 | gigaset_schedule_event(bcs->cs); |
825 | } | 847 | } |
826 | 848 | ||
827 | /* handling routines for sk_buff */ | 849 | /* handling routines for sk_buff */ |
828 | /* ============================= */ | 850 | /* ============================= */ |
829 | 851 | ||
830 | /* private version of __skb_put() | ||
831 | * append 'len' bytes to the content of 'skb', already knowing that the | ||
832 | * existing buffer can accomodate them | ||
833 | * returns a pointer to the location where the new bytes should be copied to | ||
834 | * This function does not take any locks so it must be called with the | ||
835 | * appropriate locks held only. | ||
836 | */ | ||
837 | static inline unsigned char *gigaset_skb_put_quick(struct sk_buff *skb, | ||
838 | unsigned int len) | ||
839 | { | ||
840 | unsigned char *tmp = skb->tail; | ||
841 | /*SKB_LINEAR_ASSERT(skb);*/ /* not needed here */ | ||
842 | skb->tail += len; | ||
843 | skb->len += len; | ||
844 | return tmp; | ||
845 | } | ||
846 | |||
847 | /* pass received skb to LL | 852 | /* pass received skb to LL |
848 | * Warning: skb must not be accessed anymore! | 853 | * Warning: skb must not be accessed anymore! |
849 | */ | 854 | */ |
850 | static inline void gigaset_rcv_skb(struct sk_buff *skb, | 855 | static inline void gigaset_rcv_skb(struct sk_buff *skb, |
851 | struct cardstate *cs, | 856 | struct cardstate *cs, |
852 | struct bc_state *bcs) | 857 | struct bc_state *bcs) |
853 | { | 858 | { |
854 | cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); | 859 | cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); |
855 | bcs->trans_down++; | 860 | bcs->trans_down++; |
@@ -859,8 +864,8 @@ static inline void gigaset_rcv_skb(struct sk_buff *skb, | |||
859 | * Warning: skb must not be accessed anymore! | 864 | * Warning: skb must not be accessed anymore! |
860 | */ | 865 | */ |
861 | static inline void gigaset_rcv_error(struct sk_buff *procskb, | 866 | static inline void gigaset_rcv_error(struct sk_buff *procskb, |
862 | struct cardstate *cs, | 867 | struct cardstate *cs, |
863 | struct bc_state *bcs) | 868 | struct bc_state *bcs) |
864 | { | 869 | { |
865 | if (procskb) | 870 | if (procskb) |
866 | dev_kfree_skb(procskb); | 871 | dev_kfree_skb(procskb); |
@@ -877,46 +882,9 @@ static inline void gigaset_rcv_error(struct sk_buff *procskb, | |||
877 | /* bitwise byte inversion table */ | 882 | /* bitwise byte inversion table */ |
878 | extern __u8 gigaset_invtab[]; /* in common.c */ | 883 | extern __u8 gigaset_invtab[]; /* in common.c */ |
879 | 884 | ||
880 | |||
881 | /* append received bytes to inbuf */ | 885 | /* append received bytes to inbuf */ |
882 | static inline int gigaset_fill_inbuf(struct inbuf_t *inbuf, | 886 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, |
883 | const unsigned char *src, | 887 | unsigned numbytes); |
884 | unsigned numbytes) | ||
885 | { | ||
886 | unsigned n, head, tail, bytesleft; | ||
887 | |||
888 | dbg(DEBUG_INTR, "received %u bytes", numbytes); | ||
889 | |||
890 | if (!numbytes) | ||
891 | return 0; | ||
892 | |||
893 | bytesleft = numbytes; | ||
894 | tail = atomic_read(&inbuf->tail); | ||
895 | head = atomic_read(&inbuf->head); | ||
896 | dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | ||
897 | |||
898 | while (bytesleft) { | ||
899 | if (head > tail) | ||
900 | n = head - 1 - tail; | ||
901 | else if (head == 0) | ||
902 | n = (RBUFSIZE-1) - tail; | ||
903 | else | ||
904 | n = RBUFSIZE - tail; | ||
905 | if (!n) { | ||
906 | err("buffer overflow (%u bytes lost)", bytesleft); | ||
907 | break; | ||
908 | } | ||
909 | if (n > bytesleft) | ||
910 | n = bytesleft; | ||
911 | memcpy(inbuf->data + tail, src, n); | ||
912 | bytesleft -= n; | ||
913 | tail = (tail + n) % RBUFSIZE; | ||
914 | src += n; | ||
915 | } | ||
916 | dbg(DEBUG_INTR, "setting tail to %u", tail); | ||
917 | atomic_set(&inbuf->tail, tail); | ||
918 | return numbytes != bytesleft; | ||
919 | } | ||
920 | 888 | ||
921 | /* =========================================================================== | 889 | /* =========================================================================== |
922 | * Functions implemented in interface.c | 890 | * Functions implemented in interface.c |
@@ -924,7 +892,7 @@ static inline int gigaset_fill_inbuf(struct inbuf_t *inbuf, | |||
924 | 892 | ||
925 | /* initialize interface */ | 893 | /* initialize interface */ |
926 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 894 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
927 | const char *devname, const char *devfsname); | 895 | const char *devname, const char *devfsname); |
928 | /* release interface */ | 896 | /* release interface */ |
929 | void gigaset_if_freedriver(struct gigaset_driver *drv); | 897 | void gigaset_if_freedriver(struct gigaset_driver *drv); |
930 | /* add minor */ | 898 | /* add minor */ |
@@ -933,6 +901,6 @@ void gigaset_if_init(struct cardstate *cs); | |||
933 | void gigaset_if_free(struct cardstate *cs); | 901 | void gigaset_if_free(struct cardstate *cs); |
934 | /* device received data */ | 902 | /* device received data */ |
935 | void gigaset_if_receive(struct cardstate *cs, | 903 | void gigaset_if_receive(struct cardstate *cs, |
936 | unsigned char *buffer, size_t len); | 904 | unsigned char *buffer, size_t len); |
937 | 905 | ||
938 | #endif | 906 | #endif |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 731a675f21b0..0815dbfb8291 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers (Eilers.Stefan@epost.de), | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp (hjlipp@web.de), | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt (tilman@imap.cc). | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
8 | * ===================================================================== | 8 | * ===================================================================== |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
@@ -11,15 +11,11 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: i4l.c,v 1.3.2.9 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | 17 | ||
22 | /* == Handling of I4L IO ============================================================================*/ | 18 | /* == Handling of I4L IO =====================================================*/ |
23 | 19 | ||
24 | /* writebuf_from_LL | 20 | /* writebuf_from_LL |
25 | * called by LL to transmit data on an open channel | 21 | * called by LL to transmit data on an open channel |
@@ -29,14 +25,16 @@ | |||
29 | * parameters: | 25 | * parameters: |
30 | * driverID driver ID as assigned by LL | 26 | * driverID driver ID as assigned by LL |
31 | * channel channel number | 27 | * channel channel number |
32 | * ack if != 0 LL wants to be notified on completion via statcallb(ISDN_STAT_BSENT) | 28 | * ack if != 0 LL wants to be notified on completion via |
29 | * statcallb(ISDN_STAT_BSENT) | ||
33 | * skb skb containing data to send | 30 | * skb skb containing data to send |
34 | * return value: | 31 | * return value: |
35 | * number of accepted bytes | 32 | * number of accepted bytes |
36 | * 0 if temporarily unable to accept data (out of buffer space) | 33 | * 0 if temporarily unable to accept data (out of buffer space) |
37 | * <0 on error (eg. -EINVAL) | 34 | * <0 on error (eg. -EINVAL) |
38 | */ | 35 | */ |
39 | static int writebuf_from_LL(int driverID, int channel, int ack, struct sk_buff *skb) | 36 | static int writebuf_from_LL(int driverID, int channel, int ack, |
37 | struct sk_buff *skb) | ||
40 | { | 38 | { |
41 | struct cardstate *cs; | 39 | struct cardstate *cs; |
42 | struct bc_state *bcs; | 40 | struct bc_state *bcs; |
@@ -54,31 +52,28 @@ static int writebuf_from_LL(int driverID, int channel, int ack, struct sk_buff * | |||
54 | bcs = &cs->bcs[channel]; | 52 | bcs = &cs->bcs[channel]; |
55 | len = skb->len; | 53 | len = skb->len; |
56 | 54 | ||
57 | dbg(DEBUG_LLDATA, | 55 | gig_dbg(DEBUG_LLDATA, |
58 | "Receiving data from LL (id: %d, channel: %d, ack: %d, size: %d)", | 56 | "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)", |
59 | driverID, channel, ack, len); | 57 | driverID, channel, ack, len); |
60 | 58 | ||
61 | if (!len) { | 59 | if (!len) { |
62 | if (ack) | 60 | if (ack) |
63 | warn("not ACKing empty packet from LL"); | 61 | notice("%s: not ACKing empty packet", __func__); |
64 | return 0; | 62 | return 0; |
65 | } | 63 | } |
66 | if (len > MAX_BUF_SIZE) { | 64 | if (len > MAX_BUF_SIZE) { |
67 | err("%s: packet too large (%d bytes)", __func__, channel); | 65 | err("%s: packet too large (%d bytes)", __func__, len); |
68 | return -EINVAL; | 66 | return -EINVAL; |
69 | } | 67 | } |
70 | 68 | ||
71 | if (!atomic_read(&cs->connected)) | ||
72 | return -ENODEV; | ||
73 | |||
74 | skblen = ack ? len : 0; | 69 | skblen = ack ? len : 0; |
75 | skb->head[0] = skblen & 0xff; | 70 | skb->head[0] = skblen & 0xff; |
76 | skb->head[1] = skblen >> 8; | 71 | skb->head[1] = skblen >> 8; |
77 | dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x", len, skblen, | 72 | gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x", |
78 | (unsigned) skb->head[0], (unsigned) skb->head[1]); | 73 | len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); |
79 | 74 | ||
80 | /* pass to device-specific module */ | 75 | /* pass to device-specific module */ |
81 | return cs->ops->send_skb(bcs, skb); | 76 | return cs->ops->send_skb(bcs, skb); //FIXME cs->ops->send_skb() must handle !cs->connected correctly |
82 | } | 77 | } |
83 | 78 | ||
84 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | 79 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) |
@@ -89,14 +84,14 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | |||
89 | ++bcs->trans_up; | 84 | ++bcs->trans_up; |
90 | 85 | ||
91 | if (skb->len) | 86 | if (skb->len) |
92 | warn("%s: skb->len==%d", __func__, skb->len); | 87 | dev_warn(bcs->cs->dev, "%s: skb->len==%d\n", |
88 | __func__, skb->len); | ||
93 | 89 | ||
94 | len = (unsigned char) skb->head[0] | | 90 | len = (unsigned char) skb->head[0] | |
95 | (unsigned) (unsigned char) skb->head[1] << 8; | 91 | (unsigned) (unsigned char) skb->head[1] << 8; |
96 | if (len) { | 92 | if (len) { |
97 | dbg(DEBUG_MCMD, | 93 | gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)", |
98 | "Acknowledge sending to LL (id: %d, channel: %d size: %u)", | 94 | bcs->cs->myid, bcs->channel, len); |
99 | bcs->cs->myid, bcs->channel, len); | ||
100 | 95 | ||
101 | response.driver = bcs->cs->myid; | 96 | response.driver = bcs->cs->myid; |
102 | response.command = ISDN_STAT_BSENT; | 97 | response.command = ISDN_STAT_BSENT; |
@@ -119,15 +114,12 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
119 | struct bc_state *bcs; | 114 | struct bc_state *bcs; |
120 | int retval = 0; | 115 | int retval = 0; |
121 | struct setup_parm *sp; | 116 | struct setup_parm *sp; |
117 | unsigned param; | ||
118 | unsigned long flags; | ||
122 | 119 | ||
123 | //dbg(DEBUG_ANY, "Gigaset_HW: Receiving command"); | ||
124 | gigaset_debugdrivers(); | 120 | gigaset_debugdrivers(); |
125 | 121 | ||
126 | /* Terminate this call if no device is present. Bt if the command is "ISDN_CMD_LOCK" or | 122 | if (!cs) { |
127 | * "ISDN_CMD_UNLOCK" then execute it due to the fact that they are device independent ! | ||
128 | */ | ||
129 | //FIXME "remove test for &connected" | ||
130 | if ((!cs || !atomic_read(&cs->connected))) { | ||
131 | warn("LL tried to access unknown device with nr. %d", | 123 | warn("LL tried to access unknown device with nr. %d", |
132 | cntrl->driver); | 124 | cntrl->driver); |
133 | return -ENODEV; | 125 | return -ENODEV; |
@@ -135,29 +127,30 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
135 | 127 | ||
136 | switch (cntrl->command) { | 128 | switch (cntrl->command) { |
137 | case ISDN_CMD_IOCTL: | 129 | case ISDN_CMD_IOCTL: |
138 | 130 | gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)", | |
139 | dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver:%d,arg: %ld)", | 131 | cntrl->driver, cntrl->arg); |
140 | cntrl->driver, cntrl->arg); | ||
141 | 132 | ||
142 | warn("ISDN_CMD_IOCTL is not supported."); | 133 | warn("ISDN_CMD_IOCTL is not supported."); |
143 | return -EINVAL; | 134 | return -EINVAL; |
144 | 135 | ||
145 | case ISDN_CMD_DIAL: | 136 | case ISDN_CMD_DIAL: |
146 | dbg(DEBUG_ANY, "ISDN_CMD_DIAL (driver: %d, channel: %ld, " | 137 | gig_dbg(DEBUG_ANY, |
147 | "phone: %s,ownmsn: %s, si1: %d, si2: %d)", | 138 | "ISDN_CMD_DIAL (driver: %d, ch: %ld, " |
148 | cntrl->driver, cntrl->arg, | 139 | "phone: %s, ownmsn: %s, si1: %d, si2: %d)", |
149 | cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, | 140 | cntrl->driver, cntrl->arg, |
150 | cntrl->parm.setup.si1, cntrl->parm.setup.si2); | 141 | cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, |
142 | cntrl->parm.setup.si1, cntrl->parm.setup.si2); | ||
151 | 143 | ||
152 | if (cntrl->arg >= cs->channels) { | 144 | if (cntrl->arg >= cs->channels) { |
153 | err("invalid channel (%d)", (int) cntrl->arg); | 145 | err("ISDN_CMD_DIAL: invalid channel (%d)", |
146 | (int) cntrl->arg); | ||
154 | return -EINVAL; | 147 | return -EINVAL; |
155 | } | 148 | } |
156 | 149 | ||
157 | bcs = cs->bcs + cntrl->arg; | 150 | bcs = cs->bcs + cntrl->arg; |
158 | 151 | ||
159 | if (!gigaset_get_channel(bcs)) { | 152 | if (!gigaset_get_channel(bcs)) { |
160 | err("channel not free"); | 153 | err("ISDN_CMD_DIAL: channel not free"); |
161 | return -EBUSY; | 154 | return -EBUSY; |
162 | } | 155 | } |
163 | 156 | ||
@@ -169,42 +162,46 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
169 | } | 162 | } |
170 | *sp = cntrl->parm.setup; | 163 | *sp = cntrl->parm.setup; |
171 | 164 | ||
172 | if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, | 165 | spin_lock_irqsave(&cs->lock, flags); |
173 | atomic_read(&bcs->at_state.seq_index), | 166 | param = bcs->at_state.seq_index; |
174 | NULL)) { | 167 | spin_unlock_irqrestore(&cs->lock, flags); |
168 | |||
169 | if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param, | ||
170 | NULL)) { | ||
175 | //FIXME what should we do? | 171 | //FIXME what should we do? |
176 | kfree(sp); | 172 | kfree(sp); |
177 | gigaset_free_channel(bcs); | 173 | gigaset_free_channel(bcs); |
178 | return -ENOMEM; | 174 | return -ENOMEM; |
179 | } | 175 | } |
180 | 176 | ||
181 | dbg(DEBUG_CMD, "scheduling DIAL"); | 177 | gig_dbg(DEBUG_CMD, "scheduling DIAL"); |
182 | gigaset_schedule_event(cs); | 178 | gigaset_schedule_event(cs); |
183 | break; | 179 | break; |
184 | case ISDN_CMD_ACCEPTD: //FIXME | 180 | case ISDN_CMD_ACCEPTD: //FIXME |
185 | dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); | 181 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); |
186 | 182 | ||
187 | if (cntrl->arg >= cs->channels) { | 183 | if (cntrl->arg >= cs->channels) { |
188 | err("invalid channel (%d)", (int) cntrl->arg); | 184 | err("ISDN_CMD_ACCEPTD: invalid channel (%d)", |
185 | (int) cntrl->arg); | ||
189 | return -EINVAL; | 186 | return -EINVAL; |
190 | } | 187 | } |
191 | 188 | ||
192 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, | 189 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, |
193 | EV_ACCEPT, NULL, 0, NULL)) { | 190 | EV_ACCEPT, NULL, 0, NULL)) { |
194 | //FIXME what should we do? | 191 | //FIXME what should we do? |
195 | return -ENOMEM; | 192 | return -ENOMEM; |
196 | } | 193 | } |
197 | 194 | ||
198 | dbg(DEBUG_CMD, "scheduling ACCEPT"); | 195 | gig_dbg(DEBUG_CMD, "scheduling ACCEPT"); |
199 | gigaset_schedule_event(cs); | 196 | gigaset_schedule_event(cs); |
200 | 197 | ||
201 | break; | 198 | break; |
202 | case ISDN_CMD_ACCEPTB: | 199 | case ISDN_CMD_ACCEPTB: |
203 | dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB"); | 200 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB"); |
204 | break; | 201 | break; |
205 | case ISDN_CMD_HANGUP: | 202 | case ISDN_CMD_HANGUP: |
206 | dbg(DEBUG_ANY, | 203 | gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)", |
207 | "ISDN_CMD_HANGUP (channel: %d)", (int) cntrl->arg); | 204 | (int) cntrl->arg); |
208 | 205 | ||
209 | if (cntrl->arg >= cs->channels) { | 206 | if (cntrl->arg >= cs->channels) { |
210 | err("ISDN_CMD_HANGUP: invalid channel (%u)", | 207 | err("ISDN_CMD_HANGUP: invalid channel (%u)", |
@@ -213,66 +210,68 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
213 | } | 210 | } |
214 | 211 | ||
215 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, | 212 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, |
216 | EV_HUP, NULL, 0, NULL)) { | 213 | EV_HUP, NULL, 0, NULL)) { |
217 | //FIXME what should we do? | 214 | //FIXME what should we do? |
218 | return -ENOMEM; | 215 | return -ENOMEM; |
219 | } | 216 | } |
220 | 217 | ||
221 | dbg(DEBUG_CMD, "scheduling HUP"); | 218 | gig_dbg(DEBUG_CMD, "scheduling HUP"); |
222 | gigaset_schedule_event(cs); | 219 | gigaset_schedule_event(cs); |
223 | 220 | ||
224 | break; | 221 | break; |
225 | case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME | 222 | case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME |
226 | dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); | 223 | gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); |
227 | break; | 224 | break; |
228 | case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME | 225 | case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME |
229 | dbg(DEBUG_ANY, | 226 | gig_dbg(DEBUG_ANY, |
230 | "ISDN_CMD_SETEAZ (id:%d, channel: %ld, number: %s)", | 227 | "ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)", |
231 | cntrl->driver, cntrl->arg, cntrl->parm.num); | 228 | cntrl->driver, cntrl->arg, cntrl->parm.num); |
232 | break; | 229 | break; |
233 | case ISDN_CMD_SETL2: /* Set L2 to given protocol */ | 230 | case ISDN_CMD_SETL2: /* Set L2 to given protocol */ |
234 | dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (Channel: %ld, Proto: %lx)", | 231 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)", |
235 | cntrl->arg & 0xff, (cntrl->arg >> 8)); | 232 | cntrl->arg & 0xff, (cntrl->arg >> 8)); |
236 | 233 | ||
237 | if ((cntrl->arg & 0xff) >= cs->channels) { | 234 | if ((cntrl->arg & 0xff) >= cs->channels) { |
238 | err("invalid channel (%u)", | 235 | err("ISDN_CMD_SETL2: invalid channel (%u)", |
239 | (unsigned) cntrl->arg & 0xff); | 236 | (unsigned) cntrl->arg & 0xff); |
240 | return -EINVAL; | 237 | return -EINVAL; |
241 | } | 238 | } |
242 | 239 | ||
243 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, | 240 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, |
244 | EV_PROTO_L2, NULL, cntrl->arg >> 8, | 241 | EV_PROTO_L2, NULL, cntrl->arg >> 8, |
245 | NULL)) { | 242 | NULL)) { |
246 | //FIXME what should we do? | 243 | //FIXME what should we do? |
247 | return -ENOMEM; | 244 | return -ENOMEM; |
248 | } | 245 | } |
249 | 246 | ||
250 | dbg(DEBUG_CMD, "scheduling PROTO_L2"); | 247 | gig_dbg(DEBUG_CMD, "scheduling PROTO_L2"); |
251 | gigaset_schedule_event(cs); | 248 | gigaset_schedule_event(cs); |
252 | break; | 249 | break; |
253 | case ISDN_CMD_SETL3: /* Set L3 to given protocol */ | 250 | case ISDN_CMD_SETL3: /* Set L3 to given protocol */ |
254 | dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (Channel: %ld, Proto: %lx)", | 251 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)", |
255 | cntrl->arg & 0xff, (cntrl->arg >> 8)); | 252 | cntrl->arg & 0xff, (cntrl->arg >> 8)); |
256 | 253 | ||
257 | if ((cntrl->arg & 0xff) >= cs->channels) { | 254 | if ((cntrl->arg & 0xff) >= cs->channels) { |
258 | err("invalid channel (%u)", | 255 | err("ISDN_CMD_SETL3: invalid channel (%u)", |
259 | (unsigned) cntrl->arg & 0xff); | 256 | (unsigned) cntrl->arg & 0xff); |
260 | return -EINVAL; | 257 | return -EINVAL; |
261 | } | 258 | } |
262 | 259 | ||
263 | if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { | 260 | if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { |
264 | err("invalid protocol %lu", cntrl->arg >> 8); | 261 | err("ISDN_CMD_SETL3: invalid protocol %lu", |
262 | cntrl->arg >> 8); | ||
265 | return -EINVAL; | 263 | return -EINVAL; |
266 | } | 264 | } |
267 | 265 | ||
268 | break; | 266 | break; |
269 | case ISDN_CMD_PROCEED: | 267 | case ISDN_CMD_PROCEED: |
270 | dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME | 268 | gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME |
271 | break; | 269 | break; |
272 | case ISDN_CMD_ALERT: | 270 | case ISDN_CMD_ALERT: |
273 | dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME | 271 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME |
274 | if (cntrl->arg >= cs->channels) { | 272 | if (cntrl->arg >= cs->channels) { |
275 | err("invalid channel (%d)", (int) cntrl->arg); | 273 | err("ISDN_CMD_ALERT: invalid channel (%d)", |
274 | (int) cntrl->arg); | ||
276 | return -EINVAL; | 275 | return -EINVAL; |
277 | } | 276 | } |
278 | //bcs = cs->bcs + cntrl->arg; | 277 | //bcs = cs->bcs + cntrl->arg; |
@@ -280,32 +279,31 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
280 | // FIXME | 279 | // FIXME |
281 | break; | 280 | break; |
282 | case ISDN_CMD_REDIR: | 281 | case ISDN_CMD_REDIR: |
283 | dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME | 282 | gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME |
284 | break; | 283 | break; |
285 | case ISDN_CMD_PROT_IO: | 284 | case ISDN_CMD_PROT_IO: |
286 | dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO"); | 285 | gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO"); |
287 | break; | 286 | break; |
288 | case ISDN_CMD_FAXCMD: | 287 | case ISDN_CMD_FAXCMD: |
289 | dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD"); | 288 | gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD"); |
290 | break; | 289 | break; |
291 | case ISDN_CMD_GETL2: | 290 | case ISDN_CMD_GETL2: |
292 | dbg(DEBUG_ANY, "ISDN_CMD_GETL2"); | 291 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2"); |
293 | break; | 292 | break; |
294 | case ISDN_CMD_GETL3: | 293 | case ISDN_CMD_GETL3: |
295 | dbg(DEBUG_ANY, "ISDN_CMD_GETL3"); | 294 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3"); |
296 | break; | 295 | break; |
297 | case ISDN_CMD_GETEAZ: | 296 | case ISDN_CMD_GETEAZ: |
298 | dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ"); | 297 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ"); |
299 | break; | 298 | break; |
300 | case ISDN_CMD_SETSIL: | 299 | case ISDN_CMD_SETSIL: |
301 | dbg(DEBUG_ANY, "ISDN_CMD_SETSIL"); | 300 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL"); |
302 | break; | 301 | break; |
303 | case ISDN_CMD_GETSIL: | 302 | case ISDN_CMD_GETSIL: |
304 | dbg(DEBUG_ANY, "ISDN_CMD_GETSIL"); | 303 | gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL"); |
305 | break; | 304 | break; |
306 | default: | 305 | default: |
307 | err("unknown command %d from LL", | 306 | err("unknown command %d from LL", cntrl->command); |
308 | cntrl->command); | ||
309 | return -EINVAL; | 307 | return -EINVAL; |
310 | } | 308 | } |
311 | 309 | ||
@@ -350,7 +348,8 @@ int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | |||
350 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | 348 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ |
351 | break; | 349 | break; |
352 | default: | 350 | default: |
353 | err("invalid protocol: %u", bcs->proto2); | 351 | dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n", |
352 | __func__, bcs->proto2); | ||
354 | return -EINVAL; | 353 | return -EINVAL; |
355 | } | 354 | } |
356 | 355 | ||
@@ -378,7 +377,7 @@ int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | |||
378 | bcs->commands[i] = NULL; | 377 | bcs->commands[i] = NULL; |
379 | if (length[i] && | 378 | if (length[i] && |
380 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { | 379 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { |
381 | err("out of memory"); | 380 | dev_err(bcs->cs->dev, "out of memory\n"); |
382 | return -ENOMEM; | 381 | return -ENOMEM; |
383 | } | 382 | } |
384 | } | 383 | } |
@@ -396,10 +395,14 @@ int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | |||
396 | } | 395 | } |
397 | 396 | ||
398 | if (bcs->commands[AT_MSN]) | 397 | if (bcs->commands[AT_MSN]) |
399 | snprintf(bcs->commands[AT_MSN], length[AT_MSN], "^SMSN=%s\r", sp->eazmsn); | 398 | snprintf(bcs->commands[AT_MSN], length[AT_MSN], |
400 | snprintf(bcs->commands[AT_BC ], length[AT_BC ], "^SBC=%s\r", bc); | 399 | "^SMSN=%s\r", sp->eazmsn); |
401 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], "^SBPR=%u\r", proto); | 400 | snprintf(bcs->commands[AT_BC ], length[AT_BC ], |
402 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], "^SISO=%u\r", (unsigned)bcs->channel + 1); | 401 | "^SBC=%s\r", bc); |
402 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], | ||
403 | "^SBPR=%u\r", proto); | ||
404 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], | ||
405 | "^SISO=%u\r", (unsigned)bcs->channel + 1); | ||
403 | 406 | ||
404 | return 0; | 407 | return 0; |
405 | } | 408 | } |
@@ -419,7 +422,8 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state) | |||
419 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | 422 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ |
420 | break; | 423 | break; |
421 | default: | 424 | default: |
422 | err("invalid protocol: %u", bcs->proto2); | 425 | dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n", |
426 | __func__, bcs->proto2); | ||
423 | return -EINVAL; | 427 | return -EINVAL; |
424 | } | 428 | } |
425 | 429 | ||
@@ -436,13 +440,15 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state) | |||
436 | bcs->commands[i] = NULL; | 440 | bcs->commands[i] = NULL; |
437 | if (length[i] && | 441 | if (length[i] && |
438 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { | 442 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { |
439 | err("out of memory"); | 443 | dev_err(at_state->cs->dev, "out of memory\n"); |
440 | return -ENOMEM; | 444 | return -ENOMEM; |
441 | } | 445 | } |
442 | } | 446 | } |
443 | 447 | ||
444 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], "^SBPR=%u\r", proto); | 448 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], |
445 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], "^SISO=%u\r", (unsigned) bcs->channel + 1); | 449 | "^SBPR=%u\r", proto); |
450 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], | ||
451 | "^SISO=%u\r", (unsigned) bcs->channel + 1); | ||
446 | 452 | ||
447 | return 0; | 453 | return 0; |
448 | } | 454 | } |
@@ -473,7 +479,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
473 | response.parm.setup.si1 = 1; | 479 | response.parm.setup.si1 = 1; |
474 | response.parm.setup.si2 = 2; | 480 | response.parm.setup.si2 = 2; |
475 | } else { | 481 | } else { |
476 | warn("RING ignored - unsupported BC %s", | 482 | dev_warn(cs->dev, "RING ignored - unsupported BC %s\n", |
477 | at_state->str_var[STR_ZBC]); | 483 | at_state->str_var[STR_ZBC]); |
478 | return ICALL_IGNORE; | 484 | return ICALL_IGNORE; |
479 | } | 485 | } |
@@ -491,18 +497,17 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
491 | response.parm.setup.eazmsn[0] = 0; | 497 | response.parm.setup.eazmsn[0] = 0; |
492 | 498 | ||
493 | if (!bcs) { | 499 | if (!bcs) { |
494 | notice("no channel for incoming call"); | 500 | dev_notice(cs->dev, "no channel for incoming call\n"); |
495 | dbg(DEBUG_CMD, "Sending ICALLW"); | ||
496 | response.command = ISDN_STAT_ICALLW; | 501 | response.command = ISDN_STAT_ICALLW; |
497 | response.arg = 0; //FIXME | 502 | response.arg = 0; //FIXME |
498 | } else { | 503 | } else { |
499 | dbg(DEBUG_CMD, "Sending ICALL"); | 504 | gig_dbg(DEBUG_CMD, "Sending ICALL"); |
500 | response.command = ISDN_STAT_ICALL; | 505 | response.command = ISDN_STAT_ICALL; |
501 | response.arg = bcs->channel; //FIXME | 506 | response.arg = bcs->channel; //FIXME |
502 | } | 507 | } |
503 | response.driver = cs->myid; | 508 | response.driver = cs->myid; |
504 | retval = cs->iif.statcallb(&response); | 509 | retval = cs->iif.statcallb(&response); |
505 | dbg(DEBUG_CMD, "Response: %d", retval); | 510 | gig_dbg(DEBUG_CMD, "Response: %d", retval); |
506 | switch (retval) { | 511 | switch (retval) { |
507 | case 0: /* no takers */ | 512 | case 0: /* no takers */ |
508 | return ICALL_IGNORE; | 513 | return ICALL_IGNORE; |
@@ -512,7 +517,8 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
512 | case 2: /* reject */ | 517 | case 2: /* reject */ |
513 | return ICALL_REJECT; | 518 | return ICALL_REJECT; |
514 | case 3: /* incomplete */ | 519 | case 3: /* incomplete */ |
515 | warn("LL requested unsupported feature: Incomplete Number"); | 520 | dev_warn(cs->dev, |
521 | "LL requested unsupported feature: Incomplete Number\n"); | ||
516 | return ICALL_IGNORE; | 522 | return ICALL_IGNORE; |
517 | case 4: /* proceeding */ | 523 | case 4: /* proceeding */ |
518 | /* Gigaset will send ALERTING anyway. | 524 | /* Gigaset will send ALERTING anyway. |
@@ -520,10 +526,11 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
520 | */ | 526 | */ |
521 | return ICALL_ACCEPT; | 527 | return ICALL_ACCEPT; |
522 | case 5: /* deflect */ | 528 | case 5: /* deflect */ |
523 | warn("LL requested unsupported feature: Call Deflection"); | 529 | dev_warn(cs->dev, |
530 | "LL requested unsupported feature: Call Deflection\n"); | ||
524 | return ICALL_IGNORE; | 531 | return ICALL_IGNORE; |
525 | default: | 532 | default: |
526 | err("LL error %d on ICALL", retval); | 533 | dev_err(cs->dev, "LL error %d on ICALL\n", retval); |
527 | return ICALL_IGNORE; | 534 | return ICALL_IGNORE; |
528 | } | 535 | } |
529 | } | 536 | } |
@@ -533,7 +540,7 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
533 | { | 540 | { |
534 | isdn_if *iif = &cs->iif; | 541 | isdn_if *iif = &cs->iif; |
535 | 542 | ||
536 | dbg(DEBUG_ANY, "Register driver capabilities to LL"); | 543 | gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); |
537 | 544 | ||
538 | //iif->id[sizeof(iif->id) - 1]=0; | 545 | //iif->id[sizeof(iif->id) - 1]=0; |
539 | //strncpy(iif->id, isdnid, sizeof(iif->id) - 1); | 546 | //strncpy(iif->id, isdnid, sizeof(iif->id) - 1); |
@@ -542,26 +549,26 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
542 | return -ENOMEM; //FIXME EINVAL/...?? | 549 | return -ENOMEM; //FIXME EINVAL/...?? |
543 | 550 | ||
544 | iif->owner = THIS_MODULE; | 551 | iif->owner = THIS_MODULE; |
545 | iif->channels = cs->channels; /* I am supporting just one channel *//* I was supporting...*/ | 552 | iif->channels = cs->channels; |
546 | iif->maxbufsize = MAX_BUF_SIZE; | 553 | iif->maxbufsize = MAX_BUF_SIZE; |
547 | iif->features = ISDN_FEATURE_L2_TRANS | /* Our device is very advanced, therefore */ | 554 | iif->features = ISDN_FEATURE_L2_TRANS | |
548 | ISDN_FEATURE_L2_HDLC | | 555 | ISDN_FEATURE_L2_HDLC | |
549 | #ifdef GIG_X75 | 556 | #ifdef GIG_X75 |
550 | ISDN_FEATURE_L2_X75I | | 557 | ISDN_FEATURE_L2_X75I | |
551 | #endif | 558 | #endif |
552 | ISDN_FEATURE_L3_TRANS | | 559 | ISDN_FEATURE_L3_TRANS | |
553 | ISDN_FEATURE_P_EURO; | 560 | ISDN_FEATURE_P_EURO; |
554 | iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */ | 561 | iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */ |
555 | iif->command = command_from_LL; | 562 | iif->command = command_from_LL; |
556 | iif->writebuf_skb = writebuf_from_LL; | 563 | iif->writebuf_skb = writebuf_from_LL; |
557 | iif->writecmd = NULL; /* Don't support isdnctrl */ | 564 | iif->writecmd = NULL; /* Don't support isdnctrl */ |
558 | iif->readstat = NULL; /* Don't support isdnctrl */ | 565 | iif->readstat = NULL; /* Don't support isdnctrl */ |
559 | iif->rcvcallb_skb = NULL; /* Will be set by LL */ | 566 | iif->rcvcallb_skb = NULL; /* Will be set by LL */ |
560 | iif->statcallb = NULL; /* Will be set by LL */ | 567 | iif->statcallb = NULL; /* Will be set by LL */ |
561 | 568 | ||
562 | if (!register_isdn(iif)) | 569 | if (!register_isdn(iif)) |
563 | return 0; | 570 | return 0; |
564 | 571 | ||
565 | cs->myid = iif->channels; /* Set my device id */ | 572 | cs->myid = iif->channels; /* Set my device id */ |
566 | return 1; | 573 | return 1; |
567 | } | 574 | } |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 3a81d9c65141..08e4c4eea14d 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * published by the Free Software Foundation; either version 2 of | 9 | * published by the Free Software Foundation; either version 2 of |
10 | * the License, or (at your option) any later version. | 10 | * the License, or (at your option) any later version. |
11 | * ===================================================================== | 11 | * ===================================================================== |
12 | * Version: $Id: interface.c,v 1.14.4.15 2006/02/04 18:28:16 hjlipp Exp $ | ||
13 | * ===================================================================== | ||
14 | */ | 12 | */ |
15 | 13 | ||
16 | #include "gigaset.h" | 14 | #include "gigaset.h" |
@@ -24,7 +22,7 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
24 | { | 22 | { |
25 | int cmd = *arg; | 23 | int cmd = *arg; |
26 | 24 | ||
27 | dbg(DEBUG_IF, "%u: if_lock (%d)", cs->minor_index, cmd); | 25 | gig_dbg(DEBUG_IF, "%u: if_lock (%d)", cs->minor_index, cmd); |
28 | 26 | ||
29 | if (cmd > 1) | 27 | if (cmd > 1) |
30 | return -EINVAL; | 28 | return -EINVAL; |
@@ -35,7 +33,7 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
35 | } | 33 | } |
36 | 34 | ||
37 | if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED | 35 | if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED |
38 | && atomic_read(&cs->connected)) { | 36 | && cs->connected) { |
39 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); | 37 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); |
40 | cs->ops->baud_rate(cs, B115200); | 38 | cs->ops->baud_rate(cs, B115200); |
41 | cs->ops->set_line_ctrl(cs, CS8); | 39 | cs->ops->set_line_ctrl(cs, CS8); |
@@ -44,12 +42,12 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
44 | 42 | ||
45 | cs->waiting = 1; | 43 | cs->waiting = 1; |
46 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_LOCK, | 44 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_LOCK, |
47 | NULL, cmd, NULL)) { | 45 | NULL, cmd, NULL)) { |
48 | cs->waiting = 0; | 46 | cs->waiting = 0; |
49 | return -ENOMEM; | 47 | return -ENOMEM; |
50 | } | 48 | } |
51 | 49 | ||
52 | dbg(DEBUG_CMD, "scheduling IF_LOCK"); | 50 | gig_dbg(DEBUG_CMD, "scheduling IF_LOCK"); |
53 | gigaset_schedule_event(cs); | 51 | gigaset_schedule_event(cs); |
54 | 52 | ||
55 | wait_event(cs->waitqueue, !cs->waiting); | 53 | wait_event(cs->waitqueue, !cs->waiting); |
@@ -68,7 +66,7 @@ static int if_version(struct cardstate *cs, unsigned arg[4]) | |||
68 | static const unsigned compat[4] = GIG_COMPAT; | 66 | static const unsigned compat[4] = GIG_COMPAT; |
69 | unsigned cmd = arg[0]; | 67 | unsigned cmd = arg[0]; |
70 | 68 | ||
71 | dbg(DEBUG_IF, "%u: if_version (%d)", cs->minor_index, cmd); | 69 | gig_dbg(DEBUG_IF, "%u: if_version (%d)", cs->minor_index, cmd); |
72 | 70 | ||
73 | switch (cmd) { | 71 | switch (cmd) { |
74 | case GIGVER_DRIVER: | 72 | case GIGVER_DRIVER: |
@@ -80,12 +78,12 @@ static int if_version(struct cardstate *cs, unsigned arg[4]) | |||
80 | case GIGVER_FWBASE: | 78 | case GIGVER_FWBASE: |
81 | cs->waiting = 1; | 79 | cs->waiting = 1; |
82 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_VER, | 80 | if (!gigaset_add_event(cs, &cs->at_state, EV_IF_VER, |
83 | NULL, 0, arg)) { | 81 | NULL, 0, arg)) { |
84 | cs->waiting = 0; | 82 | cs->waiting = 0; |
85 | return -ENOMEM; | 83 | return -ENOMEM; |
86 | } | 84 | } |
87 | 85 | ||
88 | dbg(DEBUG_CMD, "scheduling IF_VER"); | 86 | gig_dbg(DEBUG_CMD, "scheduling IF_VER"); |
89 | gigaset_schedule_event(cs); | 87 | gigaset_schedule_event(cs); |
90 | 88 | ||
91 | wait_event(cs->waitqueue, !cs->waiting); | 89 | wait_event(cs->waitqueue, !cs->waiting); |
@@ -101,7 +99,7 @@ static int if_version(struct cardstate *cs, unsigned arg[4]) | |||
101 | 99 | ||
102 | static int if_config(struct cardstate *cs, int *arg) | 100 | static int if_config(struct cardstate *cs, int *arg) |
103 | { | 101 | { |
104 | dbg(DEBUG_IF, "%u: if_config (%d)", cs->minor_index, *arg); | 102 | gig_dbg(DEBUG_IF, "%u: if_config (%d)", cs->minor_index, *arg); |
105 | 103 | ||
106 | if (*arg != 1) | 104 | if (*arg != 1) |
107 | return -EINVAL; | 105 | return -EINVAL; |
@@ -109,6 +107,11 @@ static int if_config(struct cardstate *cs, int *arg) | |||
109 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 107 | if (atomic_read(&cs->mstate) != MS_LOCKED) |
110 | return -EBUSY; | 108 | return -EBUSY; |
111 | 109 | ||
110 | if (!cs->connected) { | ||
111 | err("not connected!"); | ||
112 | return -ENODEV; | ||
113 | } | ||
114 | |||
112 | *arg = 0; | 115 | *arg = 0; |
113 | return gigaset_enterconfigmode(cs); | 116 | return gigaset_enterconfigmode(cs); |
114 | } | 117 | } |
@@ -119,7 +122,7 @@ static int if_config(struct cardstate *cs, int *arg) | |||
119 | static int if_open(struct tty_struct *tty, struct file *filp); | 122 | static int if_open(struct tty_struct *tty, struct file *filp); |
120 | static void if_close(struct tty_struct *tty, struct file *filp); | 123 | static void if_close(struct tty_struct *tty, struct file *filp); |
121 | static int if_ioctl(struct tty_struct *tty, struct file *file, | 124 | static int if_ioctl(struct tty_struct *tty, struct file *file, |
122 | unsigned int cmd, unsigned long arg); | 125 | unsigned int cmd, unsigned long arg); |
123 | static int if_write_room(struct tty_struct *tty); | 126 | static int if_write_room(struct tty_struct *tty); |
124 | static int if_chars_in_buffer(struct tty_struct *tty); | 127 | static int if_chars_in_buffer(struct tty_struct *tty); |
125 | static void if_throttle(struct tty_struct *tty); | 128 | static void if_throttle(struct tty_struct *tty); |
@@ -127,9 +130,9 @@ static void if_unthrottle(struct tty_struct *tty); | |||
127 | static void if_set_termios(struct tty_struct *tty, struct termios *old); | 130 | static void if_set_termios(struct tty_struct *tty, struct termios *old); |
128 | static int if_tiocmget(struct tty_struct *tty, struct file *file); | 131 | static int if_tiocmget(struct tty_struct *tty, struct file *file); |
129 | static int if_tiocmset(struct tty_struct *tty, struct file *file, | 132 | static int if_tiocmset(struct tty_struct *tty, struct file *file, |
130 | unsigned int set, unsigned int clear); | 133 | unsigned int set, unsigned int clear); |
131 | static int if_write(struct tty_struct *tty, | 134 | static int if_write(struct tty_struct *tty, |
132 | const unsigned char *buf, int count); | 135 | const unsigned char *buf, int count); |
133 | 136 | ||
134 | static struct tty_operations if_ops = { | 137 | static struct tty_operations if_ops = { |
135 | .open = if_open, | 138 | .open = if_open, |
@@ -153,8 +156,8 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
153 | struct cardstate *cs; | 156 | struct cardstate *cs; |
154 | unsigned long flags; | 157 | unsigned long flags; |
155 | 158 | ||
156 | dbg(DEBUG_IF, "%d+%d: %s()", tty->driver->minor_start, tty->index, | 159 | gig_dbg(DEBUG_IF, "%d+%d: %s()", |
157 | __FUNCTION__); | 160 | tty->driver->minor_start, tty->index, __func__); |
158 | 161 | ||
159 | tty->driver_data = NULL; | 162 | tty->driver_data = NULL; |
160 | 163 | ||
@@ -162,7 +165,7 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
162 | if (!cs) | 165 | if (!cs) |
163 | return -ENODEV; | 166 | return -ENODEV; |
164 | 167 | ||
165 | if (down_interruptible(&cs->sem)) | 168 | if (mutex_lock_interruptible(&cs->mutex)) |
166 | return -ERESTARTSYS; // FIXME -EINTR? | 169 | return -ERESTARTSYS; // FIXME -EINTR? |
167 | tty->driver_data = cs; | 170 | tty->driver_data = cs; |
168 | 171 | ||
@@ -173,10 +176,9 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
173 | cs->tty = tty; | 176 | cs->tty = tty; |
174 | spin_unlock_irqrestore(&cs->lock, flags); | 177 | spin_unlock_irqrestore(&cs->lock, flags); |
175 | tty->low_latency = 1; //FIXME test | 178 | tty->low_latency = 1; //FIXME test |
176 | //FIXME | ||
177 | } | 179 | } |
178 | 180 | ||
179 | up(&cs->sem); | 181 | mutex_unlock(&cs->mutex); |
180 | return 0; | 182 | return 0; |
181 | } | 183 | } |
182 | 184 | ||
@@ -187,30 +189,29 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
187 | 189 | ||
188 | cs = (struct cardstate *) tty->driver_data; | 190 | cs = (struct cardstate *) tty->driver_data; |
189 | if (!cs) { | 191 | if (!cs) { |
190 | err("cs==NULL in %s", __FUNCTION__); | 192 | err("cs==NULL in %s", __func__); |
191 | return; | 193 | return; |
192 | } | 194 | } |
193 | 195 | ||
194 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 196 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
195 | 197 | ||
196 | down(&cs->sem); | 198 | mutex_lock(&cs->mutex); |
197 | 199 | ||
198 | if (!cs->open_count) | 200 | if (!cs->open_count) |
199 | warn("%s: device not opened", __FUNCTION__); | 201 | warn("%s: device not opened", __func__); |
200 | else { | 202 | else { |
201 | if (!--cs->open_count) { | 203 | if (!--cs->open_count) { |
202 | spin_lock_irqsave(&cs->lock, flags); | 204 | spin_lock_irqsave(&cs->lock, flags); |
203 | cs->tty = NULL; | 205 | cs->tty = NULL; |
204 | spin_unlock_irqrestore(&cs->lock, flags); | 206 | spin_unlock_irqrestore(&cs->lock, flags); |
205 | //FIXME | ||
206 | } | 207 | } |
207 | } | 208 | } |
208 | 209 | ||
209 | up(&cs->sem); | 210 | mutex_unlock(&cs->mutex); |
210 | } | 211 | } |
211 | 212 | ||
212 | static int if_ioctl(struct tty_struct *tty, struct file *file, | 213 | static int if_ioctl(struct tty_struct *tty, struct file *file, |
213 | unsigned int cmd, unsigned long arg) | 214 | unsigned int cmd, unsigned long arg) |
214 | { | 215 | { |
215 | struct cardstate *cs; | 216 | struct cardstate *cs; |
216 | int retval = -ENODEV; | 217 | int retval = -ENODEV; |
@@ -220,17 +221,17 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, | |||
220 | 221 | ||
221 | cs = (struct cardstate *) tty->driver_data; | 222 | cs = (struct cardstate *) tty->driver_data; |
222 | if (!cs) { | 223 | if (!cs) { |
223 | err("cs==NULL in %s", __FUNCTION__); | 224 | err("cs==NULL in %s", __func__); |
224 | return -ENODEV; | 225 | return -ENODEV; |
225 | } | 226 | } |
226 | 227 | ||
227 | dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __FUNCTION__, cmd); | 228 | gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); |
228 | 229 | ||
229 | if (down_interruptible(&cs->sem)) | 230 | if (mutex_lock_interruptible(&cs->mutex)) |
230 | return -ERESTARTSYS; // FIXME -EINTR? | 231 | return -ERESTARTSYS; // FIXME -EINTR? |
231 | 232 | ||
232 | if (!cs->open_count) | 233 | if (!cs->open_count) |
233 | warn("%s: device not opened", __FUNCTION__); | 234 | warn("%s: device not opened", __func__); |
234 | else { | 235 | else { |
235 | retval = 0; | 236 | retval = 0; |
236 | switch (cmd) { | 237 | switch (cmd) { |
@@ -250,37 +251,40 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, | |||
250 | break; | 251 | break; |
251 | case GIGASET_BRKCHARS: | 252 | case GIGASET_BRKCHARS: |
252 | //FIXME test if MS_LOCKED | 253 | //FIXME test if MS_LOCKED |
253 | gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS", | 254 | if (!cs->connected) { |
254 | 6, (const unsigned char *) arg, 1); | 255 | gig_dbg(DEBUG_ANY, |
255 | if (!atomic_read(&cs->connected)) { | 256 | "can't communicate with unplugged device"); |
256 | dbg(DEBUG_ANY, "can't communicate with unplugged device"); | ||
257 | retval = -ENODEV; | 257 | retval = -ENODEV; |
258 | break; | 258 | break; |
259 | } | 259 | } |
260 | retval = copy_from_user(&buf, | 260 | retval = copy_from_user(&buf, |
261 | (const unsigned char __user *) arg, 6) | 261 | (const unsigned char __user *) arg, 6) |
262 | ? -EFAULT : 0; | 262 | ? -EFAULT : 0; |
263 | if (retval >= 0) | 263 | if (retval >= 0) { |
264 | gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS", | ||
265 | 6, (const unsigned char *) arg); | ||
264 | retval = cs->ops->brkchars(cs, buf); | 266 | retval = cs->ops->brkchars(cs, buf); |
267 | } | ||
265 | break; | 268 | break; |
266 | case GIGASET_VERSION: | 269 | case GIGASET_VERSION: |
267 | retval = copy_from_user(version, (unsigned __user *) arg, | 270 | retval = copy_from_user(version, |
268 | sizeof version) ? -EFAULT : 0; | 271 | (unsigned __user *) arg, sizeof version) |
272 | ? -EFAULT : 0; | ||
269 | if (retval >= 0) | 273 | if (retval >= 0) |
270 | retval = if_version(cs, version); | 274 | retval = if_version(cs, version); |
271 | if (retval >= 0) | 275 | if (retval >= 0) |
272 | retval = copy_to_user((unsigned __user *) arg, version, | 276 | retval = copy_to_user((unsigned __user *) arg, |
273 | sizeof version) | 277 | version, sizeof version) |
274 | ? -EFAULT : 0; | 278 | ? -EFAULT : 0; |
275 | break; | 279 | break; |
276 | default: | 280 | default: |
277 | dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", | 281 | gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", |
278 | __FUNCTION__, cmd); | 282 | __func__, cmd); |
279 | retval = -ENOIOCTLCMD; | 283 | retval = -ENOIOCTLCMD; |
280 | } | 284 | } |
281 | } | 285 | } |
282 | 286 | ||
283 | up(&cs->sem); | 287 | mutex_unlock(&cs->mutex); |
284 | 288 | ||
285 | return retval; | 289 | return retval; |
286 | } | 290 | } |
@@ -292,25 +296,25 @@ static int if_tiocmget(struct tty_struct *tty, struct file *file) | |||
292 | 296 | ||
293 | cs = (struct cardstate *) tty->driver_data; | 297 | cs = (struct cardstate *) tty->driver_data; |
294 | if (!cs) { | 298 | if (!cs) { |
295 | err("cs==NULL in %s", __FUNCTION__); | 299 | err("cs==NULL in %s", __func__); |
296 | return -ENODEV; | 300 | return -ENODEV; |
297 | } | 301 | } |
298 | 302 | ||
299 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 303 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
300 | 304 | ||
301 | if (down_interruptible(&cs->sem)) | 305 | if (mutex_lock_interruptible(&cs->mutex)) |
302 | return -ERESTARTSYS; // FIXME -EINTR? | 306 | return -ERESTARTSYS; // FIXME -EINTR? |
303 | 307 | ||
304 | // FIXME read from device? | 308 | // FIXME read from device? |
305 | retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR); | 309 | retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR); |
306 | 310 | ||
307 | up(&cs->sem); | 311 | mutex_unlock(&cs->mutex); |
308 | 312 | ||
309 | return retval; | 313 | return retval; |
310 | } | 314 | } |
311 | 315 | ||
312 | static int if_tiocmset(struct tty_struct *tty, struct file *file, | 316 | static int if_tiocmset(struct tty_struct *tty, struct file *file, |
313 | unsigned int set, unsigned int clear) | 317 | unsigned int set, unsigned int clear) |
314 | { | 318 | { |
315 | struct cardstate *cs; | 319 | struct cardstate *cs; |
316 | int retval; | 320 | int retval; |
@@ -318,18 +322,18 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, | |||
318 | 322 | ||
319 | cs = (struct cardstate *) tty->driver_data; | 323 | cs = (struct cardstate *) tty->driver_data; |
320 | if (!cs) { | 324 | if (!cs) { |
321 | err("cs==NULL in %s", __FUNCTION__); | 325 | err("cs==NULL in %s", __func__); |
322 | return -ENODEV; | 326 | return -ENODEV; |
323 | } | 327 | } |
324 | 328 | ||
325 | dbg(DEBUG_IF, | 329 | gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)", |
326 | "%u: %s(0x%x, 0x%x)", cs->minor_index, __FUNCTION__, set, clear); | 330 | cs->minor_index, __func__, set, clear); |
327 | 331 | ||
328 | if (down_interruptible(&cs->sem)) | 332 | if (mutex_lock_interruptible(&cs->mutex)) |
329 | return -ERESTARTSYS; // FIXME -EINTR? | 333 | return -ERESTARTSYS; // FIXME -EINTR? |
330 | 334 | ||
331 | if (!atomic_read(&cs->connected)) { | 335 | if (!cs->connected) { |
332 | dbg(DEBUG_ANY, "can't communicate with unplugged device"); | 336 | gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); |
333 | retval = -ENODEV; | 337 | retval = -ENODEV; |
334 | } else { | 338 | } else { |
335 | mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); | 339 | mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); |
@@ -337,7 +341,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, | |||
337 | cs->control_state = mc; | 341 | cs->control_state = mc; |
338 | } | 342 | } |
339 | 343 | ||
340 | up(&cs->sem); | 344 | mutex_unlock(&cs->mutex); |
341 | 345 | ||
342 | return retval; | 346 | return retval; |
343 | } | 347 | } |
@@ -349,29 +353,29 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
349 | 353 | ||
350 | cs = (struct cardstate *) tty->driver_data; | 354 | cs = (struct cardstate *) tty->driver_data; |
351 | if (!cs) { | 355 | if (!cs) { |
352 | err("cs==NULL in %s", __FUNCTION__); | 356 | err("cs==NULL in %s", __func__); |
353 | return -ENODEV; | 357 | return -ENODEV; |
354 | } | 358 | } |
355 | 359 | ||
356 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 360 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
357 | 361 | ||
358 | if (down_interruptible(&cs->sem)) | 362 | if (mutex_lock_interruptible(&cs->mutex)) |
359 | return -ERESTARTSYS; // FIXME -EINTR? | 363 | return -ERESTARTSYS; // FIXME -EINTR? |
360 | 364 | ||
361 | if (!cs->open_count) | 365 | if (!cs->open_count) |
362 | warn("%s: device not opened", __FUNCTION__); | 366 | warn("%s: device not opened", __func__); |
363 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 367 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { |
364 | warn("can't write to unlocked device"); | 368 | warn("can't write to unlocked device"); |
365 | retval = -EBUSY; | 369 | retval = -EBUSY; |
366 | } else if (!atomic_read(&cs->connected)) { | 370 | } else if (!cs->connected) { |
367 | dbg(DEBUG_ANY, "can't write to unplugged device"); | 371 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
368 | retval = -EBUSY; //FIXME | 372 | retval = -EBUSY; //FIXME |
369 | } else { | 373 | } else { |
370 | retval = cs->ops->write_cmd(cs, buf, count, | 374 | retval = cs->ops->write_cmd(cs, buf, count, |
371 | &cs->if_wake_tasklet); | 375 | &cs->if_wake_tasklet); |
372 | } | 376 | } |
373 | 377 | ||
374 | up(&cs->sem); | 378 | mutex_unlock(&cs->mutex); |
375 | 379 | ||
376 | return retval; | 380 | return retval; |
377 | } | 381 | } |
@@ -383,27 +387,27 @@ static int if_write_room(struct tty_struct *tty) | |||
383 | 387 | ||
384 | cs = (struct cardstate *) tty->driver_data; | 388 | cs = (struct cardstate *) tty->driver_data; |
385 | if (!cs) { | 389 | if (!cs) { |
386 | err("cs==NULL in %s", __FUNCTION__); | 390 | err("cs==NULL in %s", __func__); |
387 | return -ENODEV; | 391 | return -ENODEV; |
388 | } | 392 | } |
389 | 393 | ||
390 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 394 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
391 | 395 | ||
392 | if (down_interruptible(&cs->sem)) | 396 | if (mutex_lock_interruptible(&cs->mutex)) |
393 | return -ERESTARTSYS; // FIXME -EINTR? | 397 | return -ERESTARTSYS; // FIXME -EINTR? |
394 | 398 | ||
395 | if (!cs->open_count) | 399 | if (!cs->open_count) |
396 | warn("%s: device not opened", __FUNCTION__); | 400 | warn("%s: device not opened", __func__); |
397 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 401 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { |
398 | warn("can't write to unlocked device"); | 402 | warn("can't write to unlocked device"); |
399 | retval = -EBUSY; //FIXME | 403 | retval = -EBUSY; //FIXME |
400 | } else if (!atomic_read(&cs->connected)) { | 404 | } else if (!cs->connected) { |
401 | dbg(DEBUG_ANY, "can't write to unplugged device"); | 405 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
402 | retval = -EBUSY; //FIXME | 406 | retval = -EBUSY; //FIXME |
403 | } else | 407 | } else |
404 | retval = cs->ops->write_room(cs); | 408 | retval = cs->ops->write_room(cs); |
405 | 409 | ||
406 | up(&cs->sem); | 410 | mutex_unlock(&cs->mutex); |
407 | 411 | ||
408 | return retval; | 412 | return retval; |
409 | } | 413 | } |
@@ -415,27 +419,27 @@ static int if_chars_in_buffer(struct tty_struct *tty) | |||
415 | 419 | ||
416 | cs = (struct cardstate *) tty->driver_data; | 420 | cs = (struct cardstate *) tty->driver_data; |
417 | if (!cs) { | 421 | if (!cs) { |
418 | err("cs==NULL in %s", __FUNCTION__); | 422 | err("cs==NULL in %s", __func__); |
419 | return -ENODEV; | 423 | return -ENODEV; |
420 | } | 424 | } |
421 | 425 | ||
422 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 426 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
423 | 427 | ||
424 | if (down_interruptible(&cs->sem)) | 428 | if (mutex_lock_interruptible(&cs->mutex)) |
425 | return -ERESTARTSYS; // FIXME -EINTR? | 429 | return -ERESTARTSYS; // FIXME -EINTR? |
426 | 430 | ||
427 | if (!cs->open_count) | 431 | if (!cs->open_count) |
428 | warn("%s: device not opened", __FUNCTION__); | 432 | warn("%s: device not opened", __func__); |
429 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 433 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { |
430 | warn("can't write to unlocked device"); | 434 | warn("can't write to unlocked device"); |
431 | retval = -EBUSY; | 435 | retval = -EBUSY; |
432 | } else if (!atomic_read(&cs->connected)) { | 436 | } else if (!cs->connected) { |
433 | dbg(DEBUG_ANY, "can't write to unplugged device"); | 437 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
434 | retval = -EBUSY; //FIXME | 438 | retval = -EBUSY; //FIXME |
435 | } else | 439 | } else |
436 | retval = cs->ops->chars_in_buffer(cs); | 440 | retval = cs->ops->chars_in_buffer(cs); |
437 | 441 | ||
438 | up(&cs->sem); | 442 | mutex_unlock(&cs->mutex); |
439 | 443 | ||
440 | return retval; | 444 | return retval; |
441 | } | 445 | } |
@@ -446,21 +450,21 @@ static void if_throttle(struct tty_struct *tty) | |||
446 | 450 | ||
447 | cs = (struct cardstate *) tty->driver_data; | 451 | cs = (struct cardstate *) tty->driver_data; |
448 | if (!cs) { | 452 | if (!cs) { |
449 | err("cs==NULL in %s", __FUNCTION__); | 453 | err("cs==NULL in %s", __func__); |
450 | return; | 454 | return; |
451 | } | 455 | } |
452 | 456 | ||
453 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 457 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
454 | 458 | ||
455 | down(&cs->sem); | 459 | mutex_lock(&cs->mutex); |
456 | 460 | ||
457 | if (!cs->open_count) | 461 | if (!cs->open_count) |
458 | warn("%s: device not opened", __FUNCTION__); | 462 | warn("%s: device not opened", __func__); |
459 | else { | 463 | else { |
460 | //FIXME | 464 | //FIXME |
461 | } | 465 | } |
462 | 466 | ||
463 | up(&cs->sem); | 467 | mutex_unlock(&cs->mutex); |
464 | } | 468 | } |
465 | 469 | ||
466 | static void if_unthrottle(struct tty_struct *tty) | 470 | static void if_unthrottle(struct tty_struct *tty) |
@@ -469,21 +473,21 @@ static void if_unthrottle(struct tty_struct *tty) | |||
469 | 473 | ||
470 | cs = (struct cardstate *) tty->driver_data; | 474 | cs = (struct cardstate *) tty->driver_data; |
471 | if (!cs) { | 475 | if (!cs) { |
472 | err("cs==NULL in %s", __FUNCTION__); | 476 | err("cs==NULL in %s", __func__); |
473 | return; | 477 | return; |
474 | } | 478 | } |
475 | 479 | ||
476 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 480 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
477 | 481 | ||
478 | down(&cs->sem); | 482 | mutex_lock(&cs->mutex); |
479 | 483 | ||
480 | if (!cs->open_count) | 484 | if (!cs->open_count) |
481 | warn("%s: device not opened", __FUNCTION__); | 485 | warn("%s: device not opened", __func__); |
482 | else { | 486 | else { |
483 | //FIXME | 487 | //FIXME |
484 | } | 488 | } |
485 | 489 | ||
486 | up(&cs->sem); | 490 | mutex_unlock(&cs->mutex); |
487 | } | 491 | } |
488 | 492 | ||
489 | static void if_set_termios(struct tty_struct *tty, struct termios *old) | 493 | static void if_set_termios(struct tty_struct *tty, struct termios *old) |
@@ -496,21 +500,21 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
496 | 500 | ||
497 | cs = (struct cardstate *) tty->driver_data; | 501 | cs = (struct cardstate *) tty->driver_data; |
498 | if (!cs) { | 502 | if (!cs) { |
499 | err("cs==NULL in %s", __FUNCTION__); | 503 | err("cs==NULL in %s", __func__); |
500 | return; | 504 | return; |
501 | } | 505 | } |
502 | 506 | ||
503 | dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __FUNCTION__); | 507 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
504 | 508 | ||
505 | down(&cs->sem); | 509 | mutex_lock(&cs->mutex); |
506 | 510 | ||
507 | if (!cs->open_count) { | 511 | if (!cs->open_count) { |
508 | warn("%s: device not opened", __FUNCTION__); | 512 | warn("%s: device not opened", __func__); |
509 | goto out; | 513 | goto out; |
510 | } | 514 | } |
511 | 515 | ||
512 | if (!atomic_read(&cs->connected)) { | 516 | if (!cs->connected) { |
513 | dbg(DEBUG_ANY, "can't communicate with unplugged device"); | 517 | gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); |
514 | goto out; | 518 | goto out; |
515 | } | 519 | } |
516 | 520 | ||
@@ -518,8 +522,8 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
518 | iflag = tty->termios->c_iflag; | 522 | iflag = tty->termios->c_iflag; |
519 | cflag = tty->termios->c_cflag; | 523 | cflag = tty->termios->c_cflag; |
520 | old_cflag = old ? old->c_cflag : cflag; //FIXME? | 524 | old_cflag = old ? old->c_cflag : cflag; //FIXME? |
521 | dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", cs->minor_index, | 525 | gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", |
522 | iflag, cflag, old_cflag); | 526 | cs->minor_index, iflag, cflag, old_cflag); |
523 | 527 | ||
524 | /* get a local copy of the current port settings */ | 528 | /* get a local copy of the current port settings */ |
525 | control_state = cs->control_state; | 529 | control_state = cs->control_state; |
@@ -531,14 +535,15 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
531 | * Premature optimization is the root of all evil. | 535 | * Premature optimization is the root of all evil. |
532 | */ | 536 | */ |
533 | 537 | ||
534 | /* reassert DTR and (maybe) RTS on transition from B0 */ | 538 | /* reassert DTR and (maybe) RTS on transition from B0 */ |
535 | if ((old_cflag & CBAUD) == B0) { | 539 | if ((old_cflag & CBAUD) == B0) { |
536 | new_state = control_state | TIOCM_DTR; | 540 | new_state = control_state | TIOCM_DTR; |
537 | /* don't set RTS if using hardware flow control */ | 541 | /* don't set RTS if using hardware flow control */ |
538 | if (!(old_cflag & CRTSCTS)) | 542 | if (!(old_cflag & CRTSCTS)) |
539 | new_state |= TIOCM_RTS; | 543 | new_state |= TIOCM_RTS; |
540 | dbg(DEBUG_IF, "%u: from B0 - set DTR%s", cs->minor_index, | 544 | gig_dbg(DEBUG_IF, "%u: from B0 - set DTR%s", |
541 | (new_state & TIOCM_RTS) ? " only" : "/RTS"); | 545 | cs->minor_index, |
546 | (new_state & TIOCM_RTS) ? " only" : "/RTS"); | ||
542 | cs->ops->set_modem_ctrl(cs, control_state, new_state); | 547 | cs->ops->set_modem_ctrl(cs, control_state, new_state); |
543 | control_state = new_state; | 548 | control_state = new_state; |
544 | } | 549 | } |
@@ -547,7 +552,7 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
547 | 552 | ||
548 | if ((cflag & CBAUD) == B0) { | 553 | if ((cflag & CBAUD) == B0) { |
549 | /* Drop RTS and DTR */ | 554 | /* Drop RTS and DTR */ |
550 | dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index); | 555 | gig_dbg(DEBUG_IF, "%u: to B0 - drop DTR/RTS", cs->minor_index); |
551 | new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS); | 556 | new_state = control_state & ~(TIOCM_DTR | TIOCM_RTS); |
552 | cs->ops->set_modem_ctrl(cs, control_state, new_state); | 557 | cs->ops->set_modem_ctrl(cs, control_state, new_state); |
553 | control_state = new_state; | 558 | control_state = new_state; |
@@ -567,15 +572,17 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
567 | * Just do what we have seen with SniffUSB on Win98. | 572 | * Just do what we have seen with SniffUSB on Win98. |
568 | */ | 573 | */ |
569 | /* Drop DTR/RTS if no flow control otherwise assert */ | 574 | /* Drop DTR/RTS if no flow control otherwise assert */ |
570 | dbg(DEBUG_IF, "%u: control_state %x", cs->minor_index, control_state); | 575 | gig_dbg(DEBUG_IF, "%u: control_state %x", |
576 | cs->minor_index, control_state); | ||
571 | new_state = control_state; | 577 | new_state = control_state; |
572 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) | 578 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) |
573 | new_state |= TIOCM_DTR | TIOCM_RTS; | 579 | new_state |= TIOCM_DTR | TIOCM_RTS; |
574 | else | 580 | else |
575 | new_state &= ~(TIOCM_DTR | TIOCM_RTS); | 581 | new_state &= ~(TIOCM_DTR | TIOCM_RTS); |
576 | if (new_state != control_state) { | 582 | if (new_state != control_state) { |
577 | dbg(DEBUG_IF, "%u: new_state %x", cs->minor_index, new_state); | 583 | gig_dbg(DEBUG_IF, "%u: new_state %x", |
578 | gigaset_set_modem_ctrl(cs, control_state, new_state); // FIXME: mct_u232.c sets the old state here. is this a bug? | 584 | cs->minor_index, new_state); |
585 | gigaset_set_modem_ctrl(cs, control_state, new_state); | ||
579 | control_state = new_state; | 586 | control_state = new_state; |
580 | } | 587 | } |
581 | #endif | 588 | #endif |
@@ -584,7 +591,7 @@ static void if_set_termios(struct tty_struct *tty, struct termios *old) | |||
584 | cs->control_state = control_state; | 591 | cs->control_state = control_state; |
585 | 592 | ||
586 | out: | 593 | out: |
587 | up(&cs->sem); | 594 | mutex_unlock(&cs->mutex); |
588 | } | 595 | } |
589 | 596 | ||
590 | 597 | ||
@@ -600,7 +607,7 @@ static void if_wake(unsigned long data) | |||
600 | 607 | ||
601 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 608 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && |
602 | tty->ldisc.write_wakeup) { | 609 | tty->ldisc.write_wakeup) { |
603 | dbg(DEBUG_IF, "write wakeup call"); | 610 | gig_dbg(DEBUG_IF, "write wakeup call"); |
604 | tty->ldisc.write_wakeup(tty); | 611 | tty->ldisc.write_wakeup(tty); |
605 | } | 612 | } |
606 | 613 | ||
@@ -635,14 +642,14 @@ void gigaset_if_free(struct cardstate *cs) | |||
635 | } | 642 | } |
636 | 643 | ||
637 | void gigaset_if_receive(struct cardstate *cs, | 644 | void gigaset_if_receive(struct cardstate *cs, |
638 | unsigned char *buffer, size_t len) | 645 | unsigned char *buffer, size_t len) |
639 | { | 646 | { |
640 | unsigned long flags; | 647 | unsigned long flags; |
641 | struct tty_struct *tty; | 648 | struct tty_struct *tty; |
642 | 649 | ||
643 | spin_lock_irqsave(&cs->lock, flags); | 650 | spin_lock_irqsave(&cs->lock, flags); |
644 | if ((tty = cs->tty) == NULL) | 651 | if ((tty = cs->tty) == NULL) |
645 | dbg(DEBUG_ANY, "receive on closed device"); | 652 | gig_dbg(DEBUG_ANY, "receive on closed device"); |
646 | else { | 653 | else { |
647 | tty_buffer_request_room(tty, len); | 654 | tty_buffer_request_room(tty, len); |
648 | tty_insert_flip_string(tty, buffer, len); | 655 | tty_insert_flip_string(tty, buffer, len); |
@@ -655,13 +662,13 @@ EXPORT_SYMBOL_GPL(gigaset_if_receive); | |||
655 | /* gigaset_if_initdriver | 662 | /* gigaset_if_initdriver |
656 | * Initialize tty interface. | 663 | * Initialize tty interface. |
657 | * parameters: | 664 | * parameters: |
658 | * drv Driver | 665 | * drv Driver |
659 | * procname Name of the driver (e.g. for /proc/tty/drivers) | 666 | * procname Name of the driver (e.g. for /proc/tty/drivers) |
660 | * devname Name of the device files (prefix without minor number) | 667 | * devname Name of the device files (prefix without minor number) |
661 | * devfsname Devfs name of the device files without %d | 668 | * devfsname Devfs name of the device files without %d |
662 | */ | 669 | */ |
663 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 670 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
664 | const char *devname, const char *devfsname) | 671 | const char *devname, const char *devfsname) |
665 | { | 672 | { |
666 | unsigned minors = drv->minors; | 673 | unsigned minors = drv->minors; |
667 | int ret; | 674 | int ret; |
@@ -696,7 +703,7 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | |||
696 | warn("failed to register tty driver (error %d)", ret); | 703 | warn("failed to register tty driver (error %d)", ret); |
697 | goto error; | 704 | goto error; |
698 | } | 705 | } |
699 | dbg(DEBUG_IF, "tty driver initialized"); | 706 | gig_dbg(DEBUG_IF, "tty driver initialized"); |
700 | drv->have_tty = 1; | 707 | drv->have_tty = 1; |
701 | return; | 708 | return; |
702 | 709 | ||
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 5744eb91b315..45f017ed6e8c 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -10,10 +10,6 @@ | |||
10 | * published by the Free Software Foundation; either version 2 of | 10 | * published by the Free Software Foundation; either version 2 of |
11 | * the License, or (at your option) any later version. | 11 | * the License, or (at your option) any later version. |
12 | * ===================================================================== | 12 | * ===================================================================== |
13 | * ToDo: ... | ||
14 | * ===================================================================== | ||
15 | * Version: $Id: isocdata.c,v 1.2.2.5 2005/11/13 23:05:19 hjlipp Exp $ | ||
16 | * ===================================================================== | ||
17 | */ | 13 | */ |
18 | 14 | ||
19 | #include "gigaset.h" | 15 | #include "gigaset.h" |
@@ -87,14 +83,14 @@ static inline int isowbuf_startwrite(struct isowbuf_t *iwb) | |||
87 | { | 83 | { |
88 | if (!atomic_dec_and_test(&iwb->writesem)) { | 84 | if (!atomic_dec_and_test(&iwb->writesem)) { |
89 | atomic_inc(&iwb->writesem); | 85 | atomic_inc(&iwb->writesem); |
90 | dbg(DEBUG_ISO, | 86 | gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore", |
91 | "%s: couldn't acquire iso write semaphore", __func__); | 87 | __func__); |
92 | return 0; | 88 | return 0; |
93 | } | 89 | } |
94 | #ifdef CONFIG_GIGASET_DEBUG | 90 | #ifdef CONFIG_GIGASET_DEBUG |
95 | dbg(DEBUG_ISO, | 91 | gig_dbg(DEBUG_ISO, |
96 | "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", | 92 | "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", |
97 | __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits); | 93 | __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits); |
98 | #endif | 94 | #endif |
99 | return 1; | 95 | return 1; |
100 | } | 96 | } |
@@ -147,7 +143,7 @@ static inline void isowbuf_putflag(struct isowbuf_t *iwb) | |||
147 | /* recover the idle flag byte */ | 143 | /* recover the idle flag byte */ |
148 | write = atomic_read(&iwb->write); | 144 | write = atomic_read(&iwb->write); |
149 | iwb->idle = iwb->data[write]; | 145 | iwb->idle = iwb->data[write]; |
150 | dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); | 146 | gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); |
151 | /* mask extraneous bits in buffer */ | 147 | /* mask extraneous bits in buffer */ |
152 | iwb->data[write] &= (1 << iwb->wbits) - 1; | 148 | iwb->data[write] &= (1 << iwb->wbits) - 1; |
153 | } | 149 | } |
@@ -166,15 +162,14 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
166 | read = atomic_read(&iwb->nextread); | 162 | read = atomic_read(&iwb->nextread); |
167 | write = atomic_read(&iwb->write); | 163 | write = atomic_read(&iwb->write); |
168 | if (likely(read == write)) { | 164 | if (likely(read == write)) { |
169 | //dbg(DEBUG_STREAM, "%s: send buffer empty", __func__); | ||
170 | /* return idle frame */ | 165 | /* return idle frame */ |
171 | return read < BAS_OUTBUFPAD ? | 166 | return read < BAS_OUTBUFPAD ? |
172 | BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD; | 167 | BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD; |
173 | } | 168 | } |
174 | 169 | ||
175 | limit = read + size; | 170 | limit = read + size; |
176 | dbg(DEBUG_STREAM, | 171 | gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d", |
177 | "%s: read=%d write=%d limit=%d", __func__, read, write, limit); | 172 | __func__, read, write, limit); |
178 | #ifdef CONFIG_GIGASET_DEBUG | 173 | #ifdef CONFIG_GIGASET_DEBUG |
179 | if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) { | 174 | if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) { |
180 | err("invalid size %d", size); | 175 | err("invalid size %d", size); |
@@ -196,11 +191,12 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
196 | return -EBUSY; | 191 | return -EBUSY; |
197 | /* write position could have changed */ | 192 | /* write position could have changed */ |
198 | if (limit >= (write = atomic_read(&iwb->write))) { | 193 | if (limit >= (write = atomic_read(&iwb->write))) { |
199 | pbyte = iwb->data[write]; /* save partial byte */ | 194 | pbyte = iwb->data[write]; /* save |
195 | partial byte */ | ||
200 | limit = write + BAS_OUTBUFPAD; | 196 | limit = write + BAS_OUTBUFPAD; |
201 | dbg(DEBUG_STREAM, | 197 | gig_dbg(DEBUG_STREAM, |
202 | "%s: filling %d->%d with %02x", | 198 | "%s: filling %d->%d with %02x", |
203 | __func__, write, limit, iwb->idle); | 199 | __func__, write, limit, iwb->idle); |
204 | if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE) | 200 | if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE) |
205 | memset(iwb->data + write, iwb->idle, | 201 | memset(iwb->data + write, iwb->idle, |
206 | BAS_OUTBUFPAD); | 202 | BAS_OUTBUFPAD); |
@@ -211,9 +207,11 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
211 | - write); | 207 | - write); |
212 | limit = 0; | 208 | limit = 0; |
213 | } | 209 | } |
214 | dbg(DEBUG_STREAM, "%s: restoring %02x at %d", | 210 | gig_dbg(DEBUG_STREAM, |
215 | __func__, pbyte, limit); | 211 | "%s: restoring %02x at %d", |
216 | iwb->data[limit] = pbyte; /* restore partial byte */ | 212 | __func__, pbyte, limit); |
213 | iwb->data[limit] = pbyte; /* restore | ||
214 | partial byte */ | ||
217 | atomic_set(&iwb->write, limit); | 215 | atomic_set(&iwb->write, limit); |
218 | } | 216 | } |
219 | isowbuf_donewrite(iwb); | 217 | isowbuf_donewrite(iwb); |
@@ -242,19 +240,17 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
242 | * write hex bytes to syslog for debugging | 240 | * write hex bytes to syslog for debugging |
243 | */ | 241 | */ |
244 | static inline void dump_bytes(enum debuglevel level, const char *tag, | 242 | static inline void dump_bytes(enum debuglevel level, const char *tag, |
245 | unsigned char *bytes, int count) | 243 | unsigned char *bytes, int count) |
246 | { | 244 | { |
247 | #ifdef CONFIG_GIGASET_DEBUG | 245 | #ifdef CONFIG_GIGASET_DEBUG |
248 | unsigned char c; | 246 | unsigned char c; |
249 | static char dbgline[3 * 32 + 1]; | 247 | static char dbgline[3 * 32 + 1]; |
250 | static const char hexdigit[] = "0123456789abcdef"; | 248 | static const char hexdigit[] = "0123456789abcdef"; |
251 | int i = 0; | 249 | int i = 0; |
252 | IFNULLRET(tag); | ||
253 | IFNULLRET(bytes); | ||
254 | while (count-- > 0) { | 250 | while (count-- > 0) { |
255 | if (i > sizeof(dbgline) - 4) { | 251 | if (i > sizeof(dbgline) - 4) { |
256 | dbgline[i] = '\0'; | 252 | dbgline[i] = '\0'; |
257 | dbg(level, "%s:%s", tag, dbgline); | 253 | gig_dbg(level, "%s:%s", tag, dbgline); |
258 | i = 0; | 254 | i = 0; |
259 | } | 255 | } |
260 | c = *bytes++; | 256 | c = *bytes++; |
@@ -264,7 +260,7 @@ static inline void dump_bytes(enum debuglevel level, const char *tag, | |||
264 | dbgline[i++] = hexdigit[c & 0x0f]; | 260 | dbgline[i++] = hexdigit[c & 0x0f]; |
265 | } | 261 | } |
266 | dbgline[i] = '\0'; | 262 | dbgline[i] = '\0'; |
267 | dbg(level, "%s:%s", tag, dbgline); | 263 | gig_dbg(level, "%s:%s", tag, dbgline); |
268 | #endif | 264 | #endif |
269 | } | 265 | } |
270 | 266 | ||
@@ -380,7 +376,7 @@ static u16 stufftab[5 * 256] = { | |||
380 | */ | 376 | */ |
381 | 377 | ||
382 | static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, | 378 | static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, |
383 | int ones) | 379 | int ones) |
384 | { | 380 | { |
385 | u16 stuff; | 381 | u16 stuff; |
386 | int shiftinc, newones; | 382 | int shiftinc, newones; |
@@ -422,7 +418,7 @@ static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin, | |||
422 | */ | 418 | */ |
423 | 419 | ||
424 | static inline int hdlc_buildframe(struct isowbuf_t *iwb, | 420 | static inline int hdlc_buildframe(struct isowbuf_t *iwb, |
425 | unsigned char *in, int count) | 421 | unsigned char *in, int count) |
426 | { | 422 | { |
427 | int ones; | 423 | int ones; |
428 | u16 fcs; | 424 | u16 fcs; |
@@ -431,8 +427,8 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb, | |||
431 | 427 | ||
432 | if (isowbuf_freebytes(iwb) < count + count / 5 + 6 || | 428 | if (isowbuf_freebytes(iwb) < count + count / 5 + 6 || |
433 | !isowbuf_startwrite(iwb)) { | 429 | !isowbuf_startwrite(iwb)) { |
434 | dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN", | 430 | gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN", |
435 | __func__, isowbuf_freebytes(iwb)); | 431 | __func__, isowbuf_freebytes(iwb)); |
436 | return -EAGAIN; | 432 | return -EAGAIN; |
437 | } | 433 | } |
438 | 434 | ||
@@ -484,11 +480,11 @@ static inline int trans_buildframe(struct isowbuf_t *iwb, | |||
484 | 480 | ||
485 | if (isowbuf_freebytes(iwb) < count || | 481 | if (isowbuf_freebytes(iwb) < count || |
486 | !isowbuf_startwrite(iwb)) { | 482 | !isowbuf_startwrite(iwb)) { |
487 | dbg(DEBUG_ISO, "can't put %d bytes", count); | 483 | gig_dbg(DEBUG_ISO, "can't put %d bytes", count); |
488 | return -EAGAIN; | 484 | return -EAGAIN; |
489 | } | 485 | } |
490 | 486 | ||
491 | dbg(DEBUG_STREAM, "put %d bytes", count); | 487 | gig_dbg(DEBUG_STREAM, "put %d bytes", count); |
492 | write = atomic_read(&iwb->write); | 488 | write = atomic_read(&iwb->write); |
493 | do { | 489 | do { |
494 | c = gigaset_invtab[*in++]; | 490 | c = gigaset_invtab[*in++]; |
@@ -508,11 +504,13 @@ int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len) | |||
508 | switch (bcs->proto2) { | 504 | switch (bcs->proto2) { |
509 | case ISDN_PROTO_L2_HDLC: | 505 | case ISDN_PROTO_L2_HDLC: |
510 | result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); | 506 | result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); |
511 | dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", __func__, len, result); | 507 | gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", |
508 | __func__, len, result); | ||
512 | break; | 509 | break; |
513 | default: /* assume transparent */ | 510 | default: /* assume transparent */ |
514 | result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len); | 511 | result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len); |
515 | dbg(DEBUG_ISO, "%s: %d bytes trans -> %d", __func__, len, result); | 512 | gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d", |
513 | __func__, len, result); | ||
516 | } | 514 | } |
517 | return result; | 515 | return result; |
518 | } | 516 | } |
@@ -528,13 +526,13 @@ static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs) | |||
528 | return; | 526 | return; |
529 | } | 527 | } |
530 | if (unlikely(bcs->skb->len == SBUFSIZE)) { | 528 | if (unlikely(bcs->skb->len == SBUFSIZE)) { |
531 | warn("received oversized packet discarded"); | 529 | dev_warn(bcs->cs->dev, "received oversized packet discarded\n"); |
532 | bcs->hw.bas->giants++; | 530 | bcs->hw.bas->giants++; |
533 | dev_kfree_skb_any(bcs->skb); | 531 | dev_kfree_skb_any(bcs->skb); |
534 | bcs->skb = NULL; | 532 | bcs->skb = NULL; |
535 | return; | 533 | return; |
536 | } | 534 | } |
537 | *gigaset_skb_put_quick(bcs->skb, 1) = c; | 535 | *__skb_put(bcs->skb, 1) = c; |
538 | } | 536 | } |
539 | 537 | ||
540 | /* hdlc_flush | 538 | /* hdlc_flush |
@@ -549,7 +547,7 @@ static inline void hdlc_flush(struct bc_state *bcs) | |||
549 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 547 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
550 | skb_reserve(bcs->skb, HW_HDR_LEN); | 548 | skb_reserve(bcs->skb, HW_HDR_LEN); |
551 | else | 549 | else |
552 | err("could not allocate skb"); | 550 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
553 | } | 551 | } |
554 | 552 | ||
555 | /* reset packet state */ | 553 | /* reset packet state */ |
@@ -571,23 +569,25 @@ static inline void hdlc_done(struct bc_state *bcs) | |||
571 | 569 | ||
572 | if ((procskb = bcs->skb) == NULL) { | 570 | if ((procskb = bcs->skb) == NULL) { |
573 | /* previous error */ | 571 | /* previous error */ |
574 | dbg(DEBUG_ISO, "%s: skb=NULL", __func__); | 572 | gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); |
575 | gigaset_rcv_error(NULL, bcs->cs, bcs); | 573 | gigaset_rcv_error(NULL, bcs->cs, bcs); |
576 | } else if (procskb->len < 2) { | 574 | } else if (procskb->len < 2) { |
577 | notice("received short frame (%d octets)", procskb->len); | 575 | dev_notice(bcs->cs->dev, "received short frame (%d octets)\n", |
576 | procskb->len); | ||
578 | bcs->hw.bas->runts++; | 577 | bcs->hw.bas->runts++; |
579 | gigaset_rcv_error(procskb, bcs->cs, bcs); | 578 | gigaset_rcv_error(procskb, bcs->cs, bcs); |
580 | } else if (bcs->fcs != PPP_GOODFCS) { | 579 | } else if (bcs->fcs != PPP_GOODFCS) { |
581 | notice("frame check error (0x%04x)", bcs->fcs); | 580 | dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n", |
581 | bcs->fcs); | ||
582 | bcs->hw.bas->fcserrs++; | 582 | bcs->hw.bas->fcserrs++; |
583 | gigaset_rcv_error(procskb, bcs->cs, bcs); | 583 | gigaset_rcv_error(procskb, bcs->cs, bcs); |
584 | } else { | 584 | } else { |
585 | procskb->len -= 2; /* subtract FCS */ | 585 | procskb->len -= 2; /* subtract FCS */ |
586 | procskb->tail -= 2; | 586 | procskb->tail -= 2; |
587 | dbg(DEBUG_ISO, | 587 | gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", |
588 | "%s: good frame (%d octets)", __func__, procskb->len); | 588 | __func__, procskb->len); |
589 | dump_bytes(DEBUG_STREAM, | 589 | dump_bytes(DEBUG_STREAM, |
590 | "rcv data", procskb->data, procskb->len); | 590 | "rcv data", procskb->data, procskb->len); |
591 | bcs->hw.bas->goodbytes += procskb->len; | 591 | bcs->hw.bas->goodbytes += procskb->len; |
592 | gigaset_rcv_skb(procskb, bcs->cs, bcs); | 592 | gigaset_rcv_skb(procskb, bcs->cs, bcs); |
593 | } | 593 | } |
@@ -595,7 +595,7 @@ static inline void hdlc_done(struct bc_state *bcs) | |||
595 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 595 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
596 | skb_reserve(bcs->skb, HW_HDR_LEN); | 596 | skb_reserve(bcs->skb, HW_HDR_LEN); |
597 | else | 597 | else |
598 | err("could not allocate skb"); | 598 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
599 | bcs->fcs = PPP_INITFCS; | 599 | bcs->fcs = PPP_INITFCS; |
600 | } | 600 | } |
601 | 601 | ||
@@ -610,14 +610,14 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits) | |||
610 | return; | 610 | return; |
611 | } | 611 | } |
612 | 612 | ||
613 | notice("received partial byte (%d bits)", inbits); | 613 | dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); |
614 | bcs->hw.bas->alignerrs++; | 614 | bcs->hw.bas->alignerrs++; |
615 | gigaset_rcv_error(bcs->skb, bcs->cs, bcs); | 615 | gigaset_rcv_error(bcs->skb, bcs->cs, bcs); |
616 | 616 | ||
617 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 617 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
618 | skb_reserve(bcs->skb, HW_HDR_LEN); | 618 | skb_reserve(bcs->skb, HW_HDR_LEN); |
619 | else | 619 | else |
620 | err("could not allocate skb"); | 620 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
621 | bcs->fcs = PPP_INITFCS; | 621 | bcs->fcs = PPP_INITFCS; |
622 | } | 622 | } |
623 | 623 | ||
@@ -659,16 +659,12 @@ static unsigned char bitcounts[256] = { | |||
659 | * bcs receiving B channel structure | 659 | * bcs receiving B channel structure |
660 | */ | 660 | */ |
661 | static inline void hdlc_unpack(unsigned char *src, unsigned count, | 661 | static inline void hdlc_unpack(unsigned char *src, unsigned count, |
662 | struct bc_state *bcs) | 662 | struct bc_state *bcs) |
663 | { | 663 | { |
664 | struct bas_bc_state *ubc; | 664 | struct bas_bc_state *ubc = bcs->hw.bas; |
665 | int inputstate; | 665 | int inputstate; |
666 | unsigned seqlen, inbyte, inbits; | 666 | unsigned seqlen, inbyte, inbits; |
667 | 667 | ||
668 | IFNULLRET(bcs); | ||
669 | ubc = bcs->hw.bas; | ||
670 | IFNULLRET(ubc); | ||
671 | |||
672 | /* load previous state: | 668 | /* load previous state: |
673 | * inputstate = set of flag bits: | 669 | * inputstate = set of flag bits: |
674 | * - INS_flag_hunt: no complete opening flag received since connection setup or last abort | 670 | * - INS_flag_hunt: no complete opening flag received since connection setup or last abort |
@@ -856,7 +852,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count, | |||
856 | * bcs receiving B channel structure | 852 | * bcs receiving B channel structure |
857 | */ | 853 | */ |
858 | static inline void trans_receive(unsigned char *src, unsigned count, | 854 | static inline void trans_receive(unsigned char *src, unsigned count, |
859 | struct bc_state *bcs) | 855 | struct bc_state *bcs) |
860 | { | 856 | { |
861 | struct sk_buff *skb; | 857 | struct sk_buff *skb; |
862 | int dobytes; | 858 | int dobytes; |
@@ -870,7 +866,7 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
870 | if (unlikely((skb = bcs->skb) == NULL)) { | 866 | if (unlikely((skb = bcs->skb) == NULL)) { |
871 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); | 867 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); |
872 | if (!skb) { | 868 | if (!skb) { |
873 | err("could not allocate skb"); | 869 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
874 | return; | 870 | return; |
875 | } | 871 | } |
876 | skb_reserve(skb, HW_HDR_LEN); | 872 | skb_reserve(skb, HW_HDR_LEN); |
@@ -888,7 +884,8 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
888 | gigaset_rcv_skb(skb, bcs->cs, bcs); | 884 | gigaset_rcv_skb(skb, bcs->cs, bcs); |
889 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); | 885 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); |
890 | if (!skb) { | 886 | if (!skb) { |
891 | err("could not allocate skb"); | 887 | dev_err(bcs->cs->dev, |
888 | "could not allocate skb\n"); | ||
892 | return; | 889 | return; |
893 | } | 890 | } |
894 | skb_reserve(bcs->skb, HW_HDR_LEN); | 891 | skb_reserve(bcs->skb, HW_HDR_LEN); |
@@ -921,8 +918,8 @@ static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) | |||
921 | case '\r': | 918 | case '\r': |
922 | case '\n': | 919 | case '\n': |
923 | /* end of line */ | 920 | /* end of line */ |
924 | dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", | 921 | gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", |
925 | __func__, cbytes); | 922 | __func__, cbytes); |
926 | cs->cbytes = cbytes; | 923 | cs->cbytes = cbytes; |
927 | gigaset_handle_modem_response(cs); | 924 | gigaset_handle_modem_response(cs); |
928 | cbytes = 0; | 925 | cbytes = 0; |
@@ -932,7 +929,7 @@ static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) | |||
932 | if (cbytes < MAX_RESP_SIZE - 1) | 929 | if (cbytes < MAX_RESP_SIZE - 1) |
933 | cbytes++; | 930 | cbytes++; |
934 | else | 931 | else |
935 | warn("response too large"); | 932 | dev_warn(cs->dev, "response too large\n"); |
936 | } | 933 | } |
937 | } | 934 | } |
938 | 935 | ||
@@ -951,27 +948,27 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
951 | 948 | ||
952 | head = atomic_read(&inbuf->head); | 949 | head = atomic_read(&inbuf->head); |
953 | while (head != (tail = atomic_read(&inbuf->tail))) { | 950 | while (head != (tail = atomic_read(&inbuf->tail))) { |
954 | dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 951 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
955 | if (head > tail) | 952 | if (head > tail) |
956 | tail = RBUFSIZE; | 953 | tail = RBUFSIZE; |
957 | src = inbuf->data + head; | 954 | src = inbuf->data + head; |
958 | numbytes = tail - head; | 955 | numbytes = tail - head; |
959 | dbg(DEBUG_INTR, "processing %u bytes", numbytes); | 956 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); |
960 | 957 | ||
961 | if (atomic_read(&cs->mstate) == MS_LOCKED) { | 958 | if (atomic_read(&cs->mstate) == MS_LOCKED) { |
962 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", | 959 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", |
963 | numbytes, src, 0); | 960 | numbytes, src); |
964 | gigaset_if_receive(inbuf->cs, src, numbytes); | 961 | gigaset_if_receive(inbuf->cs, src, numbytes); |
965 | } else { | 962 | } else { |
966 | gigaset_dbg_buffer(DEBUG_CMD, "received response", | 963 | gigaset_dbg_buffer(DEBUG_CMD, "received response", |
967 | numbytes, src, 0); | 964 | numbytes, src); |
968 | cmd_loop(src, numbytes, inbuf); | 965 | cmd_loop(src, numbytes, inbuf); |
969 | } | 966 | } |
970 | 967 | ||
971 | head += numbytes; | 968 | head += numbytes; |
972 | if (head == RBUFSIZE) | 969 | if (head == RBUFSIZE) |
973 | head = 0; | 970 | head = 0; |
974 | dbg(DEBUG_INTR, "setting head to %u", head); | 971 | gig_dbg(DEBUG_INTR, "setting head to %u", head); |
975 | atomic_set(&inbuf->head, head); | 972 | atomic_set(&inbuf->head, head); |
976 | } | 973 | } |
977 | } | 974 | } |
@@ -992,18 +989,18 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
992 | */ | 989 | */ |
993 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) | 990 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) |
994 | { | 991 | { |
995 | int len; | 992 | int len = skb->len; |
996 | 993 | unsigned long flags; | |
997 | IFNULLRETVAL(bcs, -EFAULT); | ||
998 | IFNULLRETVAL(skb, -EFAULT); | ||
999 | len = skb->len; | ||
1000 | 994 | ||
1001 | skb_queue_tail(&bcs->squeue, skb); | 995 | skb_queue_tail(&bcs->squeue, skb); |
1002 | dbg(DEBUG_ISO, | 996 | gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", |
1003 | "%s: skb queued, qlen=%d", __func__, skb_queue_len(&bcs->squeue)); | 997 | __func__, skb_queue_len(&bcs->squeue)); |
1004 | 998 | ||
1005 | /* tasklet submits URB if necessary */ | 999 | /* tasklet submits URB if necessary */ |
1006 | tasklet_schedule(&bcs->hw.bas->sent_tasklet); | 1000 | spin_lock_irqsave(&bcs->cs->lock, flags); |
1001 | if (bcs->cs->connected) | ||
1002 | tasklet_schedule(&bcs->hw.bas->sent_tasklet); | ||
1003 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1007 | 1004 | ||
1008 | return len; /* ok so far */ | 1005 | return len; /* ok so far */ |
1009 | } | 1006 | } |
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c index c6915fa2be6c..d267a636b53c 100644 --- a/drivers/isdn/gigaset/proc.c +++ b/drivers/isdn/gigaset/proc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,26 +11,29 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: proc.c,v 1.5.2.13 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
22 | 18 | ||
23 | static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, char *buf) | 19 | static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, |
20 | char *buf) | ||
24 | { | 21 | { |
25 | struct usb_interface *intf = to_usb_interface(dev); | 22 | int ret; |
26 | struct cardstate *cs = usb_get_intfdata(intf); | 23 | unsigned long flags; |
27 | return sprintf(buf, "%d\n", atomic_read(&cs->cidmode)); // FIXME use scnprintf for 13607 bit architectures (if PAGE_SIZE==4096) | 24 | struct cardstate *cs = dev_get_drvdata(dev); |
25 | |||
26 | spin_lock_irqsave(&cs->lock, flags); | ||
27 | ret = sprintf(buf, "%u\n", cs->cidmode); | ||
28 | spin_unlock_irqrestore(&cs->lock, flags); | ||
29 | |||
30 | return ret; | ||
28 | } | 31 | } |
29 | 32 | ||
30 | static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 33 | static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, |
34 | const char *buf, size_t count) | ||
31 | { | 35 | { |
32 | struct usb_interface *intf = to_usb_interface(dev); | 36 | struct cardstate *cs = dev_get_drvdata(dev); |
33 | struct cardstate *cs = usb_get_intfdata(intf); | ||
34 | long int value; | 37 | long int value; |
35 | char *end; | 38 | char *end; |
36 | 39 | ||
@@ -41,23 +44,23 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, co | |||
41 | if (value < 0 || value > 1) | 44 | if (value < 0 || value > 1) |
42 | return -EINVAL; | 45 | return -EINVAL; |
43 | 46 | ||
44 | if (down_interruptible(&cs->sem)) | 47 | if (mutex_lock_interruptible(&cs->mutex)) |
45 | return -ERESTARTSYS; // FIXME -EINTR? | 48 | return -ERESTARTSYS; // FIXME -EINTR? |
46 | 49 | ||
47 | cs->waiting = 1; | 50 | cs->waiting = 1; |
48 | if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE, | 51 | if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE, |
49 | NULL, value, NULL)) { | 52 | NULL, value, NULL)) { |
50 | cs->waiting = 0; | 53 | cs->waiting = 0; |
51 | up(&cs->sem); | 54 | mutex_unlock(&cs->mutex); |
52 | return -ENOMEM; | 55 | return -ENOMEM; |
53 | } | 56 | } |
54 | 57 | ||
55 | dbg(DEBUG_CMD, "scheduling PROC_CIDMODE"); | 58 | gig_dbg(DEBUG_CMD, "scheduling PROC_CIDMODE"); |
56 | gigaset_schedule_event(cs); | 59 | gigaset_schedule_event(cs); |
57 | 60 | ||
58 | wait_event(cs->waitqueue, !cs->waiting); | 61 | wait_event(cs->waitqueue, !cs->waiting); |
59 | 62 | ||
60 | up(&cs->sem); | 63 | mutex_unlock(&cs->mutex); |
61 | 64 | ||
62 | return count; | 65 | return count; |
63 | } | 66 | } |
@@ -65,17 +68,15 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, co | |||
65 | static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); | 68 | static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); |
66 | 69 | ||
67 | /* free sysfs for device */ | 70 | /* free sysfs for device */ |
68 | void gigaset_free_dev_sysfs(struct usb_interface *interface) | 71 | void gigaset_free_dev_sysfs(struct cardstate *cs) |
69 | { | 72 | { |
70 | dbg(DEBUG_INIT, "removing sysfs entries"); | 73 | gig_dbg(DEBUG_INIT, "removing sysfs entries"); |
71 | device_remove_file(&interface->dev, &dev_attr_cidmode); | 74 | device_remove_file(cs->dev, &dev_attr_cidmode); |
72 | } | 75 | } |
73 | EXPORT_SYMBOL_GPL(gigaset_free_dev_sysfs); | ||
74 | 76 | ||
75 | /* initialize sysfs for device */ | 77 | /* initialize sysfs for device */ |
76 | void gigaset_init_dev_sysfs(struct usb_interface *interface) | 78 | void gigaset_init_dev_sysfs(struct cardstate *cs) |
77 | { | 79 | { |
78 | dbg(DEBUG_INIT, "setting up sysfs"); | 80 | gig_dbg(DEBUG_INIT, "setting up sysfs"); |
79 | device_create_file(&interface->dev, &dev_attr_cidmode); | 81 | device_create_file(cs->dev, &dev_attr_cidmode); |
80 | } | 82 | } |
81 | EXPORT_SYMBOL_GPL(gigaset_init_dev_sysfs); | ||
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 323fc7349dec..bfb73fd5077e 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB driver for Gigaset 307x directly or using M105 Data. | 2 | * USB driver for Gigaset 307x directly or using M105 Data. |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de> | 4 | * Copyright (c) 2001 by Stefan Eilers |
5 | * and Hansjoerg Lipp <hjlipp@web.de>. | 5 | * and Hansjoerg Lipp <hjlipp@web.de>. |
6 | * | 6 | * |
7 | * This driver was derived from the USB skeleton driver by | 7 | * This driver was derived from the USB skeleton driver by |
@@ -13,10 +13,6 @@ | |||
13 | * published by the Free Software Foundation; either version 2 of | 13 | * published by the Free Software Foundation; either version 2 of |
14 | * the License, or (at your option) any later version. | 14 | * the License, or (at your option) any later version. |
15 | * ===================================================================== | 15 | * ===================================================================== |
16 | * ToDo: ... | ||
17 | * ===================================================================== | ||
18 | * Version: $Id: usb-gigaset.c,v 1.85.4.18 2006/02/04 18:28:16 hjlipp Exp $ | ||
19 | * ===================================================================== | ||
20 | */ | 16 | */ |
21 | 17 | ||
22 | #include "gigaset.h" | 18 | #include "gigaset.h" |
@@ -29,7 +25,7 @@ | |||
29 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
30 | 26 | ||
31 | /* Version Information */ | 27 | /* Version Information */ |
32 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers <Eilers.Stefan@epost.de>" | 28 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Stefan Eilers" |
33 | #define DRIVER_DESC "USB Driver for Gigaset 307x using M105" | 29 | #define DRIVER_DESC "USB Driver for Gigaset 307x using M105" |
34 | 30 | ||
35 | /* Module parameters */ | 31 | /* Module parameters */ |
@@ -62,10 +58,6 @@ static struct usb_device_id gigaset_table [] = { | |||
62 | 58 | ||
63 | MODULE_DEVICE_TABLE(usb, gigaset_table); | 59 | MODULE_DEVICE_TABLE(usb, gigaset_table); |
64 | 60 | ||
65 | /* Get a minor range for your devices from the usb maintainer */ | ||
66 | #define USB_SKEL_MINOR_BASE 200 | ||
67 | |||
68 | |||
69 | /* | 61 | /* |
70 | * Control requests (empty fields: 00) | 62 | * Control requests (empty fields: 00) |
71 | * | 63 | * |
@@ -114,7 +106,7 @@ MODULE_DEVICE_TABLE(usb, gigaset_table); | |||
114 | */ | 106 | */ |
115 | 107 | ||
116 | static int gigaset_probe(struct usb_interface *interface, | 108 | static int gigaset_probe(struct usb_interface *interface, |
117 | const struct usb_device_id *id); | 109 | const struct usb_device_id *id); |
118 | static void gigaset_disconnect(struct usb_interface *interface); | 110 | static void gigaset_disconnect(struct usb_interface *interface); |
119 | 111 | ||
120 | static struct gigaset_driver *driver = NULL; | 112 | static struct gigaset_driver *driver = NULL; |
@@ -122,29 +114,29 @@ static struct cardstate *cardstate = NULL; | |||
122 | 114 | ||
123 | /* usb specific object needed to register this driver with the usb subsystem */ | 115 | /* usb specific object needed to register this driver with the usb subsystem */ |
124 | static struct usb_driver gigaset_usb_driver = { | 116 | static struct usb_driver gigaset_usb_driver = { |
125 | .name = GIGASET_MODULENAME, | 117 | .name = GIGASET_MODULENAME, |
126 | .probe = gigaset_probe, | 118 | .probe = gigaset_probe, |
127 | .disconnect = gigaset_disconnect, | 119 | .disconnect = gigaset_disconnect, |
128 | .id_table = gigaset_table, | 120 | .id_table = gigaset_table, |
129 | }; | 121 | }; |
130 | 122 | ||
131 | struct usb_cardstate { | 123 | struct usb_cardstate { |
132 | struct usb_device *udev; /* save off the usb device pointer */ | 124 | struct usb_device *udev; /* usb device pointer */ |
133 | struct usb_interface *interface; /* the interface for this device */ | 125 | struct usb_interface *interface; /* interface for this device */ |
134 | atomic_t busy; /* bulk output in progress */ | 126 | atomic_t busy; /* bulk output in progress */ |
135 | 127 | ||
136 | /* Output buffer for commands (M105: and data)*/ | 128 | /* Output buffer */ |
137 | unsigned char *bulk_out_buffer; /* the buffer to send data */ | 129 | unsigned char *bulk_out_buffer; |
138 | int bulk_out_size; /* the size of the send buffer */ | 130 | int bulk_out_size; |
139 | __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ | 131 | __u8 bulk_out_endpointAddr; |
140 | struct urb *bulk_out_urb; /* the urb used to transmit data */ | 132 | struct urb *bulk_out_urb; |
141 | 133 | ||
142 | /* Input buffer for command responses (M105: and data)*/ | 134 | /* Input buffer */ |
143 | int rcvbuf_size; /* the size of the receive buffer */ | 135 | int rcvbuf_size; |
144 | struct urb *read_urb; /* the urb used to receive data */ | 136 | struct urb *read_urb; |
145 | __u8 int_in_endpointAddr; /* the address of the bulk in endpoint */ | 137 | __u8 int_in_endpointAddr; |
146 | 138 | ||
147 | char bchars[6]; /* req. 0x19 */ | 139 | char bchars[6]; /* for request 0x19 */ |
148 | }; | 140 | }; |
149 | 141 | ||
150 | struct usb_bc_state {}; | 142 | struct usb_bc_state {}; |
@@ -157,19 +149,20 @@ static inline unsigned tiocm_to_gigaset(unsigned state) | |||
157 | #ifdef CONFIG_GIGASET_UNDOCREQ | 149 | #ifdef CONFIG_GIGASET_UNDOCREQ |
158 | /* WARNING: EXPERIMENTAL! */ | 150 | /* WARNING: EXPERIMENTAL! */ |
159 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 151 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
160 | unsigned new_state) | 152 | unsigned new_state) |
161 | { | 153 | { |
154 | struct usb_device *udev = cs->hw.usb->udev; | ||
162 | unsigned mask, val; | 155 | unsigned mask, val; |
163 | int r; | 156 | int r; |
164 | 157 | ||
165 | mask = tiocm_to_gigaset(old_state ^ new_state); | 158 | mask = tiocm_to_gigaset(old_state ^ new_state); |
166 | val = tiocm_to_gigaset(new_state); | 159 | val = tiocm_to_gigaset(new_state); |
167 | 160 | ||
168 | dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); | 161 | gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); |
169 | r = usb_control_msg(cs->hw.usb->udev, | 162 | // don't use this in an interrupt/BH |
170 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 7, 0x41, | 163 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41, |
171 | (val & 0xff) | ((mask & 0xff) << 8), 0, | 164 | (val & 0xff) | ((mask & 0xff) << 8), 0, |
172 | NULL, 0, 2000 /*timeout??*/); // don't use this in an interrupt/BH | 165 | NULL, 0, 2000 /* timeout? */); |
173 | if (r < 0) | 166 | if (r < 0) |
174 | return r; | 167 | return r; |
175 | //.. | 168 | //.. |
@@ -178,30 +171,29 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | |||
178 | 171 | ||
179 | static int set_value(struct cardstate *cs, u8 req, u16 val) | 172 | static int set_value(struct cardstate *cs, u8 req, u16 val) |
180 | { | 173 | { |
174 | struct usb_device *udev = cs->hw.usb->udev; | ||
181 | int r, r2; | 175 | int r, r2; |
182 | 176 | ||
183 | dbg(DEBUG_USBREQ, "request %02x (%04x)", (unsigned)req, (unsigned)val); | 177 | gig_dbg(DEBUG_USBREQ, "request %02x (%04x)", |
184 | r = usb_control_msg(cs->hw.usb->udev, | 178 | (unsigned)req, (unsigned)val); |
185 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x12, 0x41, | 179 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41, |
186 | 0xf /*?*/, 0, | 180 | 0xf /*?*/, 0, NULL, 0, 2000 /*?*/); |
187 | NULL, 0, 2000 /*?*/); /* no idea, what this does */ | 181 | /* no idea what this does */ |
188 | if (r < 0) { | 182 | if (r < 0) { |
189 | err("error %d on request 0x12", -r); | 183 | dev_err(&udev->dev, "error %d on request 0x12\n", -r); |
190 | return r; | 184 | return r; |
191 | } | 185 | } |
192 | 186 | ||
193 | r = usb_control_msg(cs->hw.usb->udev, | 187 | r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), req, 0x41, |
194 | usb_sndctrlpipe(cs->hw.usb->udev, 0), req, 0x41, | 188 | val, 0, NULL, 0, 2000 /*?*/); |
195 | val, 0, | ||
196 | NULL, 0, 2000 /*?*/); | ||
197 | if (r < 0) | 189 | if (r < 0) |
198 | err("error %d on request 0x%02x", -r, (unsigned)req); | 190 | dev_err(&udev->dev, "error %d on request 0x%02x\n", |
191 | -r, (unsigned)req); | ||
199 | 192 | ||
200 | r2 = usb_control_msg(cs->hw.usb->udev, | 193 | r2 = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
201 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x19, 0x41, | 194 | 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); |
202 | 0, 0, cs->hw.usb->bchars, 6, 2000 /*?*/); | ||
203 | if (r2 < 0) | 195 | if (r2 < 0) |
204 | err("error %d on request 0x19", -r2); | 196 | dev_err(&udev->dev, "error %d on request 0x19\n", -r2); |
205 | 197 | ||
206 | return r < 0 ? r : (r2 < 0 ? r2 : 0); | 198 | return r < 0 ? r : (r2 < 0 ? r2 : 0); |
207 | } | 199 | } |
@@ -229,8 +221,8 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) | |||
229 | case B115200: rate = 115200; break; | 221 | case B115200: rate = 115200; break; |
230 | default: | 222 | default: |
231 | rate = 9600; | 223 | rate = 9600; |
232 | err("unsupported baudrate request 0x%x," | 224 | dev_err(cs->dev, "unsupported baudrate request 0x%x," |
233 | " using default of B9600", cflag); | 225 | " using default of B9600\n", cflag); |
234 | } | 226 | } |
235 | 227 | ||
236 | val = 0x383fff / rate + 1; | 228 | val = 0x383fff / rate + 1; |
@@ -259,7 +251,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
259 | case CS8: | 251 | case CS8: |
260 | val |= 8 << 8; break; | 252 | val |= 8 << 8; break; |
261 | default: | 253 | default: |
262 | err("CSIZE was not CS5-CS8, using default of 8"); | 254 | dev_err(cs->dev, "CSIZE was not CS5-CS8, using default of 8\n"); |
263 | val |= 8 << 8; | 255 | val |= 8 << 8; |
264 | break; | 256 | break; |
265 | } | 257 | } |
@@ -277,7 +269,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
277 | 269 | ||
278 | #else | 270 | #else |
279 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 271 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
280 | unsigned new_state) | 272 | unsigned new_state) |
281 | { | 273 | { |
282 | return -EINVAL; | 274 | return -EINVAL; |
283 | } | 275 | } |
@@ -309,15 +301,12 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
309 | return 0; | 301 | return 0; |
310 | } | 302 | } |
311 | 303 | ||
312 | //void send_ack_to_LL(void *data); | ||
313 | static int write_modem(struct cardstate *cs); | 304 | static int write_modem(struct cardstate *cs); |
314 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); | 305 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb); |
315 | 306 | ||
316 | 307 | ||
317 | /* Handling of send queue. If there is already a skb opened, put data to | 308 | /* Write tasklet handler: Continue sending current skb, or send command, or |
318 | * the transfer buffer by calling "write_modem". Otherwise take a new skb out of the queue. | 309 | * start sending an skb from the send queue. |
319 | * This function will be called by the ISR via "transmit_chars" (USB: B-Channel Bulk callback handler | ||
320 | * via immediate task queue) or by writebuf_from_LL if the LL wants to transmit data. | ||
321 | */ | 310 | */ |
322 | static void gigaset_modem_fill(unsigned long data) | 311 | static void gigaset_modem_fill(unsigned long data) |
323 | { | 312 | { |
@@ -327,10 +316,10 @@ static void gigaset_modem_fill(unsigned long data) | |||
327 | unsigned long flags; | 316 | unsigned long flags; |
328 | int again; | 317 | int again; |
329 | 318 | ||
330 | dbg(DEBUG_OUTPUT, "modem_fill"); | 319 | gig_dbg(DEBUG_OUTPUT, "modem_fill"); |
331 | 320 | ||
332 | if (atomic_read(&cs->hw.usb->busy)) { | 321 | if (atomic_read(&cs->hw.usb->busy)) { |
333 | dbg(DEBUG_OUTPUT, "modem_fill: busy"); | 322 | gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); |
334 | return; | 323 | return; |
335 | } | 324 | } |
336 | 325 | ||
@@ -341,26 +330,27 @@ static void gigaset_modem_fill(unsigned long data) | |||
341 | cb = cs->cmdbuf; | 330 | cb = cs->cmdbuf; |
342 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 331 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
343 | if (cb) { /* commands to send? */ | 332 | if (cb) { /* commands to send? */ |
344 | dbg(DEBUG_OUTPUT, "modem_fill: cb"); | 333 | gig_dbg(DEBUG_OUTPUT, "modem_fill: cb"); |
345 | if (send_cb(cs, cb) < 0) { | 334 | if (send_cb(cs, cb) < 0) { |
346 | dbg(DEBUG_OUTPUT, | 335 | gig_dbg(DEBUG_OUTPUT, |
347 | "modem_fill: send_cb failed"); | 336 | "modem_fill: send_cb failed"); |
348 | again = 1; /* no callback will be called! */ | 337 | again = 1; /* no callback will be |
338 | called! */ | ||
349 | } | 339 | } |
350 | } else { /* skbs to send? */ | 340 | } else { /* skbs to send? */ |
351 | bcs->tx_skb = skb_dequeue(&bcs->squeue); | 341 | bcs->tx_skb = skb_dequeue(&bcs->squeue); |
352 | if (bcs->tx_skb) | 342 | if (bcs->tx_skb) |
353 | dbg(DEBUG_INTR, | 343 | gig_dbg(DEBUG_INTR, |
354 | "Dequeued skb (Adr: %lx)!", | 344 | "Dequeued skb (Adr: %lx)!", |
355 | (unsigned long) bcs->tx_skb); | 345 | (unsigned long) bcs->tx_skb); |
356 | } | 346 | } |
357 | } | 347 | } |
358 | 348 | ||
359 | if (bcs->tx_skb) { | 349 | if (bcs->tx_skb) { |
360 | dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); | 350 | gig_dbg(DEBUG_OUTPUT, "modem_fill: tx_skb"); |
361 | if (write_modem(cs) < 0) { | 351 | if (write_modem(cs) < 0) { |
362 | dbg(DEBUG_OUTPUT, | 352 | gig_dbg(DEBUG_OUTPUT, |
363 | "modem_fill: write_modem failed"); | 353 | "modem_fill: write_modem failed"); |
364 | // FIXME should we tell the LL? | 354 | // FIXME should we tell the LL? |
365 | again = 1; /* no callback will be called! */ | 355 | again = 1; /* no callback will be called! */ |
366 | } | 356 | } |
@@ -371,88 +361,85 @@ static void gigaset_modem_fill(unsigned long data) | |||
371 | /** | 361 | /** |
372 | * gigaset_read_int_callback | 362 | * gigaset_read_int_callback |
373 | * | 363 | * |
374 | * It is called if the data was received from the device. This is almost similiar to | 364 | * It is called if the data was received from the device. |
375 | * the interrupt service routine in the serial device. | ||
376 | */ | 365 | */ |
377 | static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) | 366 | static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs) |
378 | { | 367 | { |
368 | struct inbuf_t *inbuf = urb->context; | ||
369 | struct cardstate *cs = inbuf->cs; | ||
379 | int resubmit = 0; | 370 | int resubmit = 0; |
380 | int r; | 371 | int r; |
381 | struct cardstate *cs; | ||
382 | unsigned numbytes; | 372 | unsigned numbytes; |
383 | unsigned char *src; | 373 | unsigned char *src; |
384 | //unsigned long flags; | 374 | unsigned long flags; |
385 | struct inbuf_t *inbuf; | ||
386 | |||
387 | IFNULLRET(urb); | ||
388 | inbuf = (struct inbuf_t *) urb->context; | ||
389 | IFNULLRET(inbuf); | ||
390 | //spin_lock_irqsave(&inbuf->lock, flags); | ||
391 | cs = inbuf->cs; | ||
392 | IFNULLGOTO(cs, exit); | ||
393 | IFNULLGOTO(cardstate, exit); | ||
394 | |||
395 | if (!atomic_read(&cs->connected)) { | ||
396 | err("%s: disconnected", __func__); | ||
397 | goto exit; | ||
398 | } | ||
399 | 375 | ||
400 | if (!urb->status) { | 376 | if (!urb->status) { |
377 | if (!cs->connected) { | ||
378 | err("%s: disconnected", __func__); /* should never happen */ | ||
379 | return; | ||
380 | } | ||
381 | |||
401 | numbytes = urb->actual_length; | 382 | numbytes = urb->actual_length; |
402 | 383 | ||
403 | if (numbytes) { | 384 | if (numbytes) { |
404 | src = inbuf->rcvbuf; | 385 | src = inbuf->rcvbuf; |
405 | if (unlikely(*src)) | 386 | if (unlikely(*src)) |
406 | warn("%s: There was no leading 0, but 0x%02x!", | 387 | dev_warn(cs->dev, |
407 | __func__, (unsigned) *src); | 388 | "%s: There was no leading 0, but 0x%02x!\n", |
389 | __func__, (unsigned) *src); | ||
408 | ++src; /* skip leading 0x00 */ | 390 | ++src; /* skip leading 0x00 */ |
409 | --numbytes; | 391 | --numbytes; |
410 | if (gigaset_fill_inbuf(inbuf, src, numbytes)) { | 392 | if (gigaset_fill_inbuf(inbuf, src, numbytes)) { |
411 | dbg(DEBUG_INTR, "%s-->BH", __func__); | 393 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
412 | gigaset_schedule_event(inbuf->cs); | 394 | gigaset_schedule_event(inbuf->cs); |
413 | } | 395 | } |
414 | } else | 396 | } else |
415 | dbg(DEBUG_INTR, "Received zero block length"); | 397 | gig_dbg(DEBUG_INTR, "Received zero block length"); |
416 | resubmit = 1; | 398 | resubmit = 1; |
417 | } else { | 399 | } else { |
418 | /* The urb might have been killed. */ | 400 | /* The urb might have been killed. */ |
419 | dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", | 401 | gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", |
420 | __func__, urb->status); | 402 | __func__, urb->status); |
421 | if (urb->status != -ENOENT) /* not killed */ | 403 | if (urb->status != -ENOENT) { /* not killed */ |
404 | if (!cs->connected) { | ||
405 | err("%s: disconnected", __func__); /* should never happen */ | ||
406 | return; | ||
407 | } | ||
422 | resubmit = 1; | 408 | resubmit = 1; |
409 | } | ||
423 | } | 410 | } |
424 | exit: | 411 | |
425 | //spin_unlock_irqrestore(&inbuf->lock, flags); | ||
426 | if (resubmit) { | 412 | if (resubmit) { |
427 | r = usb_submit_urb(urb, SLAB_ATOMIC); | 413 | spin_lock_irqsave(&cs->lock, flags); |
414 | r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
415 | spin_unlock_irqrestore(&cs->lock, flags); | ||
428 | if (r) | 416 | if (r) |
429 | err("error %d when resubmitting urb.", -r); | 417 | dev_err(cs->dev, "error %d when resubmitting urb.\n", |
418 | -r); | ||
430 | } | 419 | } |
431 | } | 420 | } |
432 | 421 | ||
433 | 422 | ||
434 | /* This callback routine is called when data was transmitted to a B-Channel. | 423 | /* This callback routine is called when data was transmitted to the device. */ |
435 | * Therefore it has to check if there is still data to transmit. This | ||
436 | * happens by calling modem_fill via task queue. | ||
437 | * | ||
438 | */ | ||
439 | static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | 424 | static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs) |
440 | { | 425 | { |
441 | struct cardstate *cs = (struct cardstate *) urb->context; | 426 | struct cardstate *cs = urb->context; |
427 | unsigned long flags; | ||
442 | 428 | ||
443 | IFNULLRET(cs); | ||
444 | #ifdef CONFIG_GIGASET_DEBUG | ||
445 | if (!atomic_read(&cs->connected)) { | ||
446 | err("%s:not connected", __func__); | ||
447 | return; | ||
448 | } | ||
449 | #endif | ||
450 | if (urb->status) | 429 | if (urb->status) |
451 | err("bulk transfer failed (status %d)", -urb->status); /* That's all we can do. Communication problems | 430 | dev_err(cs->dev, "bulk transfer failed (status %d)\n", |
452 | are handeled by timeouts or network protocols */ | 431 | -urb->status); |
432 | /* That's all we can do. Communication problems | ||
433 | are handled by timeouts or network protocols. */ | ||
453 | 434 | ||
454 | atomic_set(&cs->hw.usb->busy, 0); | 435 | spin_lock_irqsave(&cs->lock, flags); |
455 | tasklet_schedule(&cs->write_tasklet); | 436 | if (!cs->connected) { |
437 | err("%s: not connected", __func__); | ||
438 | } else { | ||
439 | atomic_set(&cs->hw.usb->busy, 0); | ||
440 | tasklet_schedule(&cs->write_tasklet); | ||
441 | } | ||
442 | spin_unlock_irqrestore(&cs->lock, flags); | ||
456 | } | 443 | } |
457 | 444 | ||
458 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | 445 | static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) |
@@ -469,8 +456,8 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
469 | 456 | ||
470 | spin_lock_irqsave(&cs->cmdlock, flags); | 457 | spin_lock_irqsave(&cs->cmdlock, flags); |
471 | cs->cmdbytes -= cs->curlen; | 458 | cs->cmdbytes -= cs->curlen; |
472 | dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", | 459 | gig_dbg(DEBUG_OUTPUT, "send_cb: sent %u bytes, %u left", |
473 | cs->curlen, cs->cmdbytes); | 460 | cs->curlen, cs->cmdbytes); |
474 | cs->cmdbuf = cb = cb->next; | 461 | cs->cmdbuf = cb = cb->next; |
475 | if (cb) { | 462 | if (cb) { |
476 | cb->prev = NULL; | 463 | cb->prev = NULL; |
@@ -487,52 +474,51 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
487 | } | 474 | } |
488 | if (cb) { | 475 | if (cb) { |
489 | count = min(cb->len, ucs->bulk_out_size); | 476 | count = min(cb->len, ucs->bulk_out_size); |
477 | gig_dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); | ||
478 | |||
490 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | 479 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, |
491 | usb_sndbulkpipe(ucs->udev, | 480 | usb_sndbulkpipe(ucs->udev, |
492 | ucs->bulk_out_endpointAddr & 0x0f), | 481 | ucs->bulk_out_endpointAddr & 0x0f), |
493 | cb->buf + cb->offset, count, | 482 | cb->buf + cb->offset, count, |
494 | gigaset_write_bulk_callback, cs); | 483 | gigaset_write_bulk_callback, cs); |
495 | 484 | ||
496 | cb->offset += count; | 485 | cb->offset += count; |
497 | cb->len -= count; | 486 | cb->len -= count; |
498 | atomic_set(&ucs->busy, 1); | 487 | atomic_set(&ucs->busy, 1); |
499 | dbg(DEBUG_OUTPUT, "send_cb: send %d bytes", count); | ||
500 | 488 | ||
501 | status = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | 489 | spin_lock_irqsave(&cs->lock, flags); |
490 | status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC) : -ENODEV; | ||
491 | spin_unlock_irqrestore(&cs->lock, flags); | ||
492 | |||
502 | if (status) { | 493 | if (status) { |
503 | atomic_set(&ucs->busy, 0); | 494 | atomic_set(&ucs->busy, 0); |
504 | err("could not submit urb (error %d).", | 495 | err("could not submit urb (error %d)\n", |
505 | -status); | 496 | -status); |
506 | cb->len = 0; /* skip urb => remove cb+wakeup in next loop cycle */ | 497 | cb->len = 0; /* skip urb => remove cb+wakeup |
498 | in next loop cycle */ | ||
507 | } | 499 | } |
508 | } | 500 | } |
509 | } while (cb && status); /* bei Fehler naechster Befehl //FIXME: ist das OK? */ | 501 | } while (cb && status); /* next command on error */ |
510 | 502 | ||
511 | return status; | 503 | return status; |
512 | } | 504 | } |
513 | 505 | ||
514 | /* Write string into transbuf and send it to modem. | 506 | /* Send command to device. */ |
515 | */ | ||
516 | static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | 507 | static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, |
517 | int len, struct tasklet_struct *wake_tasklet) | 508 | int len, struct tasklet_struct *wake_tasklet) |
518 | { | 509 | { |
519 | struct cmdbuf_t *cb; | 510 | struct cmdbuf_t *cb; |
520 | unsigned long flags; | 511 | unsigned long flags; |
521 | 512 | ||
522 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 513 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? |
523 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 514 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
524 | "CMD Transmit", len, buf, 0); | 515 | "CMD Transmit", len, buf); |
525 | |||
526 | if (!atomic_read(&cs->connected)) { | ||
527 | err("%s: not connected", __func__); | ||
528 | return -ENODEV; | ||
529 | } | ||
530 | 516 | ||
531 | if (len <= 0) | 517 | if (len <= 0) |
532 | return 0; | 518 | return 0; |
533 | 519 | ||
534 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { | 520 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { |
535 | err("%s: out of memory", __func__); | 521 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
536 | return -ENOMEM; | 522 | return -ENOMEM; |
537 | } | 523 | } |
538 | 524 | ||
@@ -554,7 +540,10 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | |||
554 | cs->lastcmdbuf = cb; | 540 | cs->lastcmdbuf = cb; |
555 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 541 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
556 | 542 | ||
557 | tasklet_schedule(&cs->write_tasklet); | 543 | spin_lock_irqsave(&cs->lock, flags); |
544 | if (cs->connected) | ||
545 | tasklet_schedule(&cs->write_tasklet); | ||
546 | spin_unlock_irqrestore(&cs->lock, flags); | ||
558 | return len; | 547 | return len; |
559 | } | 548 | } |
560 | 549 | ||
@@ -578,11 +567,12 @@ static int gigaset_chars_in_buffer(struct cardstate *cs) | |||
578 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) | 567 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) |
579 | { | 568 | { |
580 | #ifdef CONFIG_GIGASET_UNDOCREQ | 569 | #ifdef CONFIG_GIGASET_UNDOCREQ |
581 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf, 0); | 570 | struct usb_device *udev = cs->hw.usb->udev; |
571 | |||
572 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); | ||
582 | memcpy(cs->hw.usb->bchars, buf, 6); | 573 | memcpy(cs->hw.usb->bchars, buf, 6); |
583 | return usb_control_msg(cs->hw.usb->udev, | 574 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
584 | usb_sndctrlpipe(cs->hw.usb->udev, 0), 0x19, 0x41, | 575 | 0, 0, &buf, 6, 2000); |
585 | 0, 0, &buf, 6, 2000); | ||
586 | #else | 576 | #else |
587 | return -EINVAL; | 577 | return -EINVAL; |
588 | #endif | 578 | #endif |
@@ -604,7 +594,6 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
604 | if (!bcs->hw.usb) | 594 | if (!bcs->hw.usb) |
605 | return 0; | 595 | return 0; |
606 | 596 | ||
607 | //bcs->hw.usb->trans_flg = READY_TO_TRNSMIT; /* B-Channel ready to transmit */ | ||
608 | return 1; | 597 | return 1; |
609 | } | 598 | } |
610 | 599 | ||
@@ -614,7 +603,6 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) | |||
614 | 603 | ||
615 | static void gigaset_freecshw(struct cardstate *cs) | 604 | static void gigaset_freecshw(struct cardstate *cs) |
616 | { | 605 | { |
617 | //FIXME | ||
618 | tasklet_kill(&cs->write_tasklet); | 606 | tasklet_kill(&cs->write_tasklet); |
619 | kfree(cs->hw.usb); | 607 | kfree(cs->hw.usb); |
620 | } | 608 | } |
@@ -639,33 +627,21 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
639 | //ucs->urb_cmd_out = NULL; | 627 | //ucs->urb_cmd_out = NULL; |
640 | ucs->read_urb = NULL; | 628 | ucs->read_urb = NULL; |
641 | tasklet_init(&cs->write_tasklet, | 629 | tasklet_init(&cs->write_tasklet, |
642 | &gigaset_modem_fill, (unsigned long) cs); | 630 | &gigaset_modem_fill, (unsigned long) cs); |
643 | 631 | ||
644 | return 1; | 632 | return 1; |
645 | } | 633 | } |
646 | 634 | ||
647 | /* Writes the data of the current open skb into the modem. | 635 | /* Send data from current skb to the device. */ |
648 | * We have to protect against multiple calls until the | ||
649 | * callback handler () is called , due to the fact that we | ||
650 | * are just allowed to send data once to an endpoint. Therefore | ||
651 | * we using "trans_flg" to synchonize ... | ||
652 | */ | ||
653 | static int write_modem(struct cardstate *cs) | 636 | static int write_modem(struct cardstate *cs) |
654 | { | 637 | { |
655 | int ret; | 638 | int ret = 0; |
656 | int count; | 639 | int count; |
657 | struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ | 640 | struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ |
658 | struct usb_cardstate *ucs = cs->hw.usb; | 641 | struct usb_cardstate *ucs = cs->hw.usb; |
659 | //unsigned long flags; | 642 | unsigned long flags; |
660 | |||
661 | IFNULLRETVAL(bcs->tx_skb, -EINVAL); | ||
662 | |||
663 | dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); | ||
664 | 643 | ||
665 | ret = -ENODEV; | 644 | gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); |
666 | IFNULLGOTO(ucs->bulk_out_buffer, error); | ||
667 | IFNULLGOTO(ucs->bulk_out_urb, error); | ||
668 | ret = 0; | ||
669 | 645 | ||
670 | if (!bcs->tx_skb->len) { | 646 | if (!bcs->tx_skb->len) { |
671 | dev_kfree_skb_any(bcs->tx_skb); | 647 | dev_kfree_skb_any(bcs->tx_skb); |
@@ -679,40 +655,42 @@ static int write_modem(struct cardstate *cs) | |||
679 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); | 655 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); |
680 | memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); | 656 | memcpy(ucs->bulk_out_buffer, bcs->tx_skb->data, count); |
681 | skb_pull(bcs->tx_skb, count); | 657 | skb_pull(bcs->tx_skb, count); |
682 | |||
683 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | ||
684 | usb_sndbulkpipe(ucs->udev, | ||
685 | ucs->bulk_out_endpointAddr & 0x0f), | ||
686 | ucs->bulk_out_buffer, count, | ||
687 | gigaset_write_bulk_callback, cs); | ||
688 | atomic_set(&ucs->busy, 1); | 658 | atomic_set(&ucs->busy, 1); |
689 | dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); | 659 | gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); |
660 | |||
661 | spin_lock_irqsave(&cs->lock, flags); | ||
662 | if (cs->connected) { | ||
663 | usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, | ||
664 | usb_sndbulkpipe(ucs->udev, | ||
665 | ucs->bulk_out_endpointAddr & 0x0f), | ||
666 | ucs->bulk_out_buffer, count, | ||
667 | gigaset_write_bulk_callback, cs); | ||
668 | ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | ||
669 | } else { | ||
670 | ret = -ENODEV; | ||
671 | } | ||
672 | spin_unlock_irqrestore(&cs->lock, flags); | ||
690 | 673 | ||
691 | ret = usb_submit_urb(ucs->bulk_out_urb, SLAB_ATOMIC); | ||
692 | if (ret) { | 674 | if (ret) { |
693 | err("could not submit urb (error %d).", -ret); | 675 | err("could not submit urb (error %d)\n", -ret); |
694 | atomic_set(&ucs->busy, 0); | 676 | atomic_set(&ucs->busy, 0); |
695 | } | 677 | } |
678 | |||
696 | if (!bcs->tx_skb->len) { | 679 | if (!bcs->tx_skb->len) { |
697 | /* skb sent completely */ | 680 | /* skb sent completely */ |
698 | gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? | 681 | gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? |
699 | 682 | ||
700 | dbg(DEBUG_INTR, | 683 | gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!", |
701 | "kfree skb (Adr: %lx)!", (unsigned long) bcs->tx_skb); | 684 | (unsigned long) bcs->tx_skb); |
702 | dev_kfree_skb_any(bcs->tx_skb); | 685 | dev_kfree_skb_any(bcs->tx_skb); |
703 | bcs->tx_skb = NULL; | 686 | bcs->tx_skb = NULL; |
704 | } | 687 | } |
705 | 688 | ||
706 | return ret; | 689 | return ret; |
707 | error: | ||
708 | dev_kfree_skb_any(bcs->tx_skb); | ||
709 | bcs->tx_skb = NULL; | ||
710 | return ret; | ||
711 | |||
712 | } | 690 | } |
713 | 691 | ||
714 | static int gigaset_probe(struct usb_interface *interface, | 692 | static int gigaset_probe(struct usb_interface *interface, |
715 | const struct usb_device_id *id) | 693 | const struct usb_device_id *id) |
716 | { | 694 | { |
717 | int retval; | 695 | int retval; |
718 | struct usb_device *udev = interface_to_usbdev(interface); | 696 | struct usb_device *udev = interface_to_usbdev(interface); |
@@ -720,16 +698,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
720 | struct usb_host_interface *hostif; | 698 | struct usb_host_interface *hostif; |
721 | struct cardstate *cs = NULL; | 699 | struct cardstate *cs = NULL; |
722 | struct usb_cardstate *ucs = NULL; | 700 | struct usb_cardstate *ucs = NULL; |
723 | //struct usb_interface_descriptor *iface_desc; | ||
724 | struct usb_endpoint_descriptor *endpoint; | 701 | struct usb_endpoint_descriptor *endpoint; |
725 | //isdn_ctrl command; | ||
726 | int buffer_size; | 702 | int buffer_size; |
727 | int alt; | 703 | int alt; |
728 | //unsigned long flags; | ||
729 | 704 | ||
730 | info("%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | 705 | gig_dbg(DEBUG_ANY, |
731 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 706 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", |
732 | le16_to_cpu(udev->descriptor.idProduct)); | 707 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
708 | le16_to_cpu(udev->descriptor.idProduct)); | ||
733 | 709 | ||
734 | retval = -ENODEV; //FIXME | 710 | retval = -ENODEV; //FIXME |
735 | 711 | ||
@@ -744,7 +720,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
744 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? | 720 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? |
745 | 721 | ||
746 | if (alt != 0 || ifnum != 0) { | 722 | if (alt != 0 || ifnum != 0) { |
747 | warn("ifnum %d, alt %d", ifnum, alt); | 723 | dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); |
748 | return -ENODEV; | 724 | return -ENODEV; |
749 | } | 725 | } |
750 | 726 | ||
@@ -752,42 +728,29 @@ static int gigaset_probe(struct usb_interface *interface, | |||
752 | * | 728 | * |
753 | */ | 729 | */ |
754 | if (hostif->desc.bInterfaceClass != 255) { | 730 | if (hostif->desc.bInterfaceClass != 255) { |
755 | info("%s: Device matched, but iface_desc[%d]->bInterfaceClass==%d !", | 731 | dev_info(&udev->dev, |
756 | __func__, ifnum, hostif->desc.bInterfaceClass); | 732 | "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", |
733 | __func__, ifnum, hostif->desc.bInterfaceClass); | ||
757 | return -ENODEV; | 734 | return -ENODEV; |
758 | } | 735 | } |
759 | 736 | ||
760 | info("%s: Device matched ... !", __func__); | 737 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); |
761 | 738 | ||
762 | cs = gigaset_getunassignedcs(driver); | 739 | cs = gigaset_getunassignedcs(driver); |
763 | if (!cs) { | 740 | if (!cs) { |
764 | warn("No free cardstate!"); | 741 | dev_warn(&udev->dev, "no free cardstate\n"); |
765 | return -ENODEV; | 742 | return -ENODEV; |
766 | } | 743 | } |
767 | ucs = cs->hw.usb; | 744 | ucs = cs->hw.usb; |
768 | 745 | ||
769 | #if 0 | 746 | /* save off device structure ptrs for later use */ |
770 | if (usb_set_configuration(udev, udev->config[0].desc.bConfigurationValue) < 0) { | 747 | usb_get_dev(udev); |
771 | warn("set_configuration failed"); | 748 | ucs->udev = udev; |
772 | goto error; | 749 | ucs->interface = interface; |
773 | } | 750 | cs->dev = &interface->dev; |
774 | |||
775 | |||
776 | if (usb_set_interface(udev, ifnum/*==0*/, alt/*==0*/) < 0) { | ||
777 | warn("usb_set_interface failed, device %d interface %d altsetting %d", | ||
778 | udev->devnum, ifnum, alt); | ||
779 | goto error; | ||
780 | } | ||
781 | #endif | ||
782 | 751 | ||
783 | /* set up the endpoint information */ | 752 | /* save address of controller structure */ |
784 | /* check out the endpoints */ | 753 | usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs); |
785 | /* We will get 2 endpoints: One for sending commands to the device (bulk out) and one to | ||
786 | * poll messages from the device(int in). | ||
787 | * Therefore we will have an almost similiar situation as with our serial port handler. | ||
788 | * If an connection will be established, we will have to create data in/out pipes | ||
789 | * dynamically... | ||
790 | */ | ||
791 | 754 | ||
792 | endpoint = &hostif->endpoint[0].desc; | 755 | endpoint = &hostif->endpoint[0].desc; |
793 | 756 | ||
@@ -796,14 +759,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
796 | ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; | 759 | ucs->bulk_out_endpointAddr = endpoint->bEndpointAddress; |
797 | ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | 760 | ucs->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); |
798 | if (!ucs->bulk_out_buffer) { | 761 | if (!ucs->bulk_out_buffer) { |
799 | err("Couldn't allocate bulk_out_buffer"); | 762 | dev_err(cs->dev, "Couldn't allocate bulk_out_buffer\n"); |
800 | retval = -ENOMEM; | 763 | retval = -ENOMEM; |
801 | goto error; | 764 | goto error; |
802 | } | 765 | } |
803 | 766 | ||
804 | ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); | 767 | ucs->bulk_out_urb = usb_alloc_urb(0, SLAB_KERNEL); |
805 | if (!ucs->bulk_out_urb) { | 768 | if (!ucs->bulk_out_urb) { |
806 | err("Couldn't allocate bulk_out_buffer"); | 769 | dev_err(cs->dev, "Couldn't allocate bulk_out_urb\n"); |
807 | retval = -ENOMEM; | 770 | retval = -ENOMEM; |
808 | goto error; | 771 | goto error; |
809 | } | 772 | } |
@@ -811,12 +774,10 @@ static int gigaset_probe(struct usb_interface *interface, | |||
811 | endpoint = &hostif->endpoint[1].desc; | 774 | endpoint = &hostif->endpoint[1].desc; |
812 | 775 | ||
813 | atomic_set(&ucs->busy, 0); | 776 | atomic_set(&ucs->busy, 0); |
814 | ucs->udev = udev; | ||
815 | ucs->interface = interface; | ||
816 | 777 | ||
817 | ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); | 778 | ucs->read_urb = usb_alloc_urb(0, SLAB_KERNEL); |
818 | if (!ucs->read_urb) { | 779 | if (!ucs->read_urb) { |
819 | err("No free urbs available"); | 780 | dev_err(cs->dev, "No free urbs available\n"); |
820 | retval = -ENOMEM; | 781 | retval = -ENOMEM; |
821 | goto error; | 782 | goto error; |
822 | } | 783 | } |
@@ -825,38 +786,33 @@ static int gigaset_probe(struct usb_interface *interface, | |||
825 | ucs->int_in_endpointAddr = endpoint->bEndpointAddress; | 786 | ucs->int_in_endpointAddr = endpoint->bEndpointAddress; |
826 | cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); | 787 | cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); |
827 | if (!cs->inbuf[0].rcvbuf) { | 788 | if (!cs->inbuf[0].rcvbuf) { |
828 | err("Couldn't allocate rcvbuf"); | 789 | dev_err(cs->dev, "Couldn't allocate rcvbuf\n"); |
829 | retval = -ENOMEM; | 790 | retval = -ENOMEM; |
830 | goto error; | 791 | goto error; |
831 | } | 792 | } |
832 | /* Fill the interrupt urb and send it to the core */ | 793 | /* Fill the interrupt urb and send it to the core */ |
833 | usb_fill_int_urb(ucs->read_urb, udev, | 794 | usb_fill_int_urb(ucs->read_urb, udev, |
834 | usb_rcvintpipe(udev, | 795 | usb_rcvintpipe(udev, |
835 | endpoint->bEndpointAddress & 0x0f), | 796 | endpoint->bEndpointAddress & 0x0f), |
836 | cs->inbuf[0].rcvbuf, buffer_size, | 797 | cs->inbuf[0].rcvbuf, buffer_size, |
837 | gigaset_read_int_callback, | 798 | gigaset_read_int_callback, |
838 | cs->inbuf + 0, endpoint->bInterval); | 799 | cs->inbuf + 0, endpoint->bInterval); |
839 | 800 | ||
840 | retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); | 801 | retval = usb_submit_urb(ucs->read_urb, SLAB_KERNEL); |
841 | if (retval) { | 802 | if (retval) { |
842 | err("Could not submit URB!"); | 803 | dev_err(cs->dev, "Could not submit URB (error %d)\n", -retval); |
843 | goto error; | 804 | goto error; |
844 | } | 805 | } |
845 | 806 | ||
846 | /* tell common part that the device is ready */ | 807 | /* tell common part that the device is ready */ |
847 | if (startmode == SM_LOCKED) | 808 | if (startmode == SM_LOCKED) |
848 | atomic_set(&cs->mstate, MS_LOCKED); | 809 | atomic_set(&cs->mstate, MS_LOCKED); |
810 | |||
849 | if (!gigaset_start(cs)) { | 811 | if (!gigaset_start(cs)) { |
850 | tasklet_kill(&cs->write_tasklet); | 812 | tasklet_kill(&cs->write_tasklet); |
851 | retval = -ENODEV; //FIXME | 813 | retval = -ENODEV; //FIXME |
852 | goto error; | 814 | goto error; |
853 | } | 815 | } |
854 | |||
855 | /* save address of controller structure */ | ||
856 | usb_set_intfdata(interface, cs); | ||
857 | |||
858 | /* set up device sysfs */ | ||
859 | gigaset_init_dev_sysfs(interface); | ||
860 | return 0; | 816 | return 0; |
861 | 817 | ||
862 | error: | 818 | error: |
@@ -868,48 +824,45 @@ error: | |||
868 | kfree(cs->inbuf[0].rcvbuf); | 824 | kfree(cs->inbuf[0].rcvbuf); |
869 | if (ucs->read_urb != NULL) | 825 | if (ucs->read_urb != NULL) |
870 | usb_free_urb(ucs->read_urb); | 826 | usb_free_urb(ucs->read_urb); |
827 | usb_set_intfdata(interface, NULL); | ||
871 | ucs->read_urb = ucs->bulk_out_urb = NULL; | 828 | ucs->read_urb = ucs->bulk_out_urb = NULL; |
872 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; | 829 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; |
830 | usb_put_dev(ucs->udev); | ||
831 | ucs->udev = NULL; | ||
832 | ucs->interface = NULL; | ||
873 | gigaset_unassign(cs); | 833 | gigaset_unassign(cs); |
874 | return retval; | 834 | return retval; |
875 | } | 835 | } |
876 | 836 | ||
877 | /** | ||
878 | * skel_disconnect | ||
879 | */ | ||
880 | static void gigaset_disconnect(struct usb_interface *interface) | 837 | static void gigaset_disconnect(struct usb_interface *interface) |
881 | { | 838 | { |
882 | struct cardstate *cs; | 839 | struct cardstate *cs; |
883 | struct usb_cardstate *ucs; | 840 | struct usb_cardstate *ucs; |
884 | 841 | ||
885 | cs = usb_get_intfdata(interface); | 842 | cs = usb_get_intfdata(interface); |
886 | |||
887 | /* clear device sysfs */ | ||
888 | gigaset_free_dev_sysfs(interface); | ||
889 | |||
890 | usb_set_intfdata(interface, NULL); | ||
891 | ucs = cs->hw.usb; | 843 | ucs = cs->hw.usb; |
892 | usb_kill_urb(ucs->read_urb); | 844 | usb_kill_urb(ucs->read_urb); |
893 | //info("GigaSet USB device #%d will be disconnected", minor); | ||
894 | 845 | ||
895 | gigaset_stop(cs); | 846 | gigaset_stop(cs); |
896 | 847 | ||
848 | usb_set_intfdata(interface, NULL); | ||
897 | tasklet_kill(&cs->write_tasklet); | 849 | tasklet_kill(&cs->write_tasklet); |
898 | 850 | ||
899 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: nur, wenn noetig */ | 851 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ |
900 | //usb_kill_urb(ucs->urb_cmd_out); /* FIXME: nur, wenn noetig */ | ||
901 | 852 | ||
902 | kfree(ucs->bulk_out_buffer); | 853 | kfree(ucs->bulk_out_buffer); |
903 | if (ucs->bulk_out_urb != NULL) | 854 | if (ucs->bulk_out_urb != NULL) |
904 | usb_free_urb(ucs->bulk_out_urb); | 855 | usb_free_urb(ucs->bulk_out_urb); |
905 | //if(ucs->urb_cmd_out != NULL) | ||
906 | // usb_free_urb(ucs->urb_cmd_out); | ||
907 | kfree(cs->inbuf[0].rcvbuf); | 856 | kfree(cs->inbuf[0].rcvbuf); |
908 | if (ucs->read_urb != NULL) | 857 | if (ucs->read_urb != NULL) |
909 | usb_free_urb(ucs->read_urb); | 858 | usb_free_urb(ucs->read_urb); |
910 | ucs->read_urb = ucs->bulk_out_urb/*=ucs->urb_cmd_out*/=NULL; | 859 | ucs->read_urb = ucs->bulk_out_urb = NULL; |
911 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; | 860 | cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; |
912 | 861 | ||
862 | usb_put_dev(ucs->udev); | ||
863 | ucs->interface = NULL; | ||
864 | ucs->udev = NULL; | ||
865 | cs->dev = NULL; | ||
913 | gigaset_unassign(cs); | 866 | gigaset_unassign(cs); |
914 | } | 867 | } |
915 | 868 | ||
@@ -942,9 +895,9 @@ static int __init usb_gigaset_init(void) | |||
942 | 895 | ||
943 | /* allocate memory for our driver state and intialize it */ | 896 | /* allocate memory for our driver state and intialize it */ |
944 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 897 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
945 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 898 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
946 | GIGASET_DEVFSNAME, &ops, | 899 | GIGASET_DEVFSNAME, &ops, |
947 | THIS_MODULE)) == NULL) | 900 | THIS_MODULE)) == NULL) |
948 | goto error; | 901 | goto error; |
949 | 902 | ||
950 | /* allocate memory for our device state and intialize it */ | 903 | /* allocate memory for our device state and intialize it */ |
@@ -981,8 +934,8 @@ error: if (cardstate) | |||
981 | static void __exit usb_gigaset_exit(void) | 934 | static void __exit usb_gigaset_exit(void) |
982 | { | 935 | { |
983 | gigaset_blockdriver(driver); /* => probe will fail | 936 | gigaset_blockdriver(driver); /* => probe will fail |
984 | * => no gigaset_start any more | 937 | * => no gigaset_start any more |
985 | */ | 938 | */ |
986 | 939 | ||
987 | gigaset_shutdown(cardstate); | 940 | gigaset_shutdown(cardstate); |
988 | /* from now on, no isdn callback should be possible */ | 941 | /* from now on, no isdn callback should be possible */ |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 2c4f20b7f021..3f5b64794542 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -14,13 +14,7 @@ config LEDS_CLASS | |||
14 | This option enables the led sysfs class in /sys/class/leds. You'll | 14 | This option enables the led sysfs class in /sys/class/leds. You'll |
15 | need this to do anything useful with LEDs. If unsure, say N. | 15 | need this to do anything useful with LEDs. If unsure, say N. |
16 | 16 | ||
17 | config LEDS_TRIGGERS | 17 | comment "LED drivers" |
18 | bool "LED Trigger support" | ||
19 | depends NEW_LEDS | ||
20 | help | ||
21 | This option enables trigger support for the leds class. | ||
22 | These triggers allow kernel events to drive the LEDs and can | ||
23 | be configured via sysfs. If unsure, say Y. | ||
24 | 18 | ||
25 | config LEDS_CORGI | 19 | config LEDS_CORGI |
26 | tristate "LED Support for the Sharp SL-C7x0 series" | 20 | tristate "LED Support for the Sharp SL-C7x0 series" |
@@ -59,6 +53,23 @@ config LEDS_TOSA | |||
59 | This option enables support for the LEDs on Sharp Zaurus | 53 | This option enables support for the LEDs on Sharp Zaurus |
60 | SL-6000 series. | 54 | SL-6000 series. |
61 | 55 | ||
56 | config LEDS_S3C24XX | ||
57 | tristate "LED Support for Samsung S3C24XX GPIO LEDs" | ||
58 | depends on LEDS_CLASS && ARCH_S3C2410 | ||
59 | help | ||
60 | This option enables support for LEDs connected to GPIO lines | ||
61 | on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. | ||
62 | |||
63 | comment "LED Triggers" | ||
64 | |||
65 | config LEDS_TRIGGERS | ||
66 | bool "LED Trigger support" | ||
67 | depends NEW_LEDS | ||
68 | help | ||
69 | This option enables trigger support for the leds class. | ||
70 | These triggers allow kernel events to drive the LEDs and can | ||
71 | be configured via sysfs. If unsure, say Y. | ||
72 | |||
62 | config LEDS_TRIGGER_TIMER | 73 | config LEDS_TRIGGER_TIMER |
63 | tristate "LED Timer Trigger" | 74 | tristate "LED Timer Trigger" |
64 | depends LEDS_TRIGGERS | 75 | depends LEDS_TRIGGERS |
@@ -67,7 +78,7 @@ config LEDS_TRIGGER_TIMER | |||
67 | via sysfs. If unsure, say Y. | 78 | via sysfs. If unsure, say Y. |
68 | 79 | ||
69 | config LEDS_TRIGGER_IDE_DISK | 80 | config LEDS_TRIGGER_IDE_DISK |
70 | bool "LED Timer Trigger" | 81 | bool "LED IDE Disk Trigger" |
71 | depends LEDS_TRIGGERS && BLK_DEV_IDEDISK | 82 | depends LEDS_TRIGGERS && BLK_DEV_IDEDISK |
72 | help | 83 | help |
73 | This allows LEDs to be controlled by IDE disk activity. | 84 | This allows LEDs to be controlled by IDE disk activity. |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 40699d3cabbf..40f042633bf5 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o | |||
10 | obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o | 10 | obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o |
11 | obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o | 11 | obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o |
12 | obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o | 12 | obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o |
13 | obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o | ||
13 | 14 | ||
14 | # LED Triggers | 15 | # LED Triggers |
15 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o | 16 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o |
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c new file mode 100644 index 000000000000..650cf72dc675 --- /dev/null +++ b/drivers/leds/leds-s3c24xx.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* drivers/leds/leds-s3c24xx.c | ||
2 | * | ||
3 | * (c) 2006 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX - LEDs GPIO driver | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/leds.h> | ||
19 | |||
20 | #include <asm/arch/hardware.h> | ||
21 | #include <asm/arch/regs-gpio.h> | ||
22 | #include <asm/arch/leds-gpio.h> | ||
23 | |||
24 | /* our context */ | ||
25 | |||
26 | struct s3c24xx_gpio_led { | ||
27 | struct led_classdev cdev; | ||
28 | struct s3c24xx_led_platdata *pdata; | ||
29 | }; | ||
30 | |||
31 | static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev) | ||
32 | { | ||
33 | return platform_get_drvdata(dev); | ||
34 | } | ||
35 | |||
36 | static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev) | ||
37 | { | ||
38 | return container_of(led_cdev, struct s3c24xx_gpio_led, cdev); | ||
39 | } | ||
40 | |||
41 | static void s3c24xx_led_set(struct led_classdev *led_cdev, | ||
42 | enum led_brightness value) | ||
43 | { | ||
44 | struct s3c24xx_gpio_led *led = to_gpio(led_cdev); | ||
45 | struct s3c24xx_led_platdata *pd = led->pdata; | ||
46 | |||
47 | /* there will be a sort delay between setting the output and | ||
48 | * going from output to input when using tristate. */ | ||
49 | |||
50 | s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^ | ||
51 | (pd->flags & S3C24XX_LEDF_ACTLOW)); | ||
52 | |||
53 | if (pd->flags & S3C24XX_LEDF_TRISTATE) | ||
54 | s3c2410_gpio_cfgpin(pd->gpio, | ||
55 | value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT); | ||
56 | |||
57 | } | ||
58 | |||
59 | static int s3c24xx_led_remove(struct platform_device *dev) | ||
60 | { | ||
61 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
62 | |||
63 | led_classdev_unregister(&led->cdev); | ||
64 | kfree(led); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int s3c24xx_led_probe(struct platform_device *dev) | ||
70 | { | ||
71 | struct s3c24xx_led_platdata *pdata = dev->dev.platform_data; | ||
72 | struct s3c24xx_gpio_led *led; | ||
73 | int ret; | ||
74 | |||
75 | led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL); | ||
76 | if (led == NULL) { | ||
77 | dev_err(&dev->dev, "No memory for device\n"); | ||
78 | return -ENOMEM; | ||
79 | } | ||
80 | |||
81 | platform_set_drvdata(dev, led); | ||
82 | |||
83 | led->cdev.brightness_set = s3c24xx_led_set; | ||
84 | led->cdev.default_trigger = pdata->def_trigger; | ||
85 | led->cdev.name = pdata->name; | ||
86 | |||
87 | led->pdata = pdata; | ||
88 | |||
89 | /* no point in having a pull-up if we are always driving */ | ||
90 | |||
91 | if (pdata->flags & S3C24XX_LEDF_TRISTATE) { | ||
92 | s3c2410_gpio_setpin(pdata->gpio, 0); | ||
93 | s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT); | ||
94 | } else { | ||
95 | s3c2410_gpio_pullup(pdata->gpio, 0); | ||
96 | s3c2410_gpio_setpin(pdata->gpio, 0); | ||
97 | s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT); | ||
98 | } | ||
99 | |||
100 | /* register our new led device */ | ||
101 | |||
102 | ret = led_classdev_register(&dev->dev, &led->cdev); | ||
103 | if (ret < 0) { | ||
104 | dev_err(&dev->dev, "led_classdev_register failed\n"); | ||
105 | goto exit_err1; | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | |||
110 | exit_err1: | ||
111 | kfree(led); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | |||
116 | #ifdef CONFIG_PM | ||
117 | static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state) | ||
118 | { | ||
119 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
120 | |||
121 | led_classdev_suspend(&led->cdev); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int s3c24xx_led_resume(struct platform_device *dev) | ||
126 | { | ||
127 | struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); | ||
128 | |||
129 | led_classdev_resume(&led->cdev); | ||
130 | return 0; | ||
131 | } | ||
132 | #else | ||
133 | #define s3c24xx_led_suspend NULL | ||
134 | #define s3c24xx_led_resume NULL | ||
135 | #endif | ||
136 | |||
137 | static struct platform_driver s3c24xx_led_driver = { | ||
138 | .probe = s3c24xx_led_probe, | ||
139 | .remove = s3c24xx_led_remove, | ||
140 | .suspend = s3c24xx_led_suspend, | ||
141 | .resume = s3c24xx_led_resume, | ||
142 | .driver = { | ||
143 | .name = "s3c24xx_led", | ||
144 | .owner = THIS_MODULE, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | static int __init s3c24xx_led_init(void) | ||
149 | { | ||
150 | return platform_driver_register(&s3c24xx_led_driver); | ||
151 | } | ||
152 | |||
153 | static void __exit s3c24xx_led_exit(void) | ||
154 | { | ||
155 | platform_driver_unregister(&s3c24xx_led_driver); | ||
156 | } | ||
157 | |||
158 | module_init(s3c24xx_led_init); | ||
159 | module_exit(s3c24xx_led_exit); | ||
160 | |||
161 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
162 | MODULE_DESCRIPTION("S3C24XX LED driver"); | ||
163 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index fd2aae150ccc..ac25a48362ac 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
@@ -139,11 +139,12 @@ config MD_RAID5_RESHAPE | |||
139 | is online. However it is still EXPERIMENTAL code. It should | 139 | is online. However it is still EXPERIMENTAL code. It should |
140 | work, but please be sure that you have backups. | 140 | work, but please be sure that you have backups. |
141 | 141 | ||
142 | You will need a version of mdadm newer than 2.3.1. During the | 142 | You will need mdadm verion 2.4.1 or later to use this |
143 | early stage of reshape there is a critical section where live data | 143 | feature safely. During the early stage of reshape there is |
144 | is being over-written. A crash during this time needs extra care | 144 | a critical section where live data is being over-written. A |
145 | for recovery. The newer mdadm takes a copy of the data in the | 145 | crash during this time needs extra care for recovery. The |
146 | critical section and will restore it, if necessary, after a crash. | 146 | newer mdadm takes a copy of the data in the critical section |
147 | and will restore it, if necessary, after a crash. | ||
147 | 148 | ||
148 | The mdadm usage is e.g. | 149 | The mdadm usage is e.g. |
149 | mdadm --grow /dev/md1 --raid-disks=6 | 150 | mdadm --grow /dev/md1 --raid-disks=6 |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 4092a5e37ffc..b3ea2d63db9b 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -84,4 +84,4 @@ obj-$(CONFIG_USB_IBMCAM) += usbvideo/ | |||
84 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ | 84 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ |
85 | obj-$(CONFIG_USB_VICAM) += usbvideo/ | 85 | obj-$(CONFIG_USB_VICAM) += usbvideo/ |
86 | 86 | ||
87 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 87 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile index 94350f21cdc0..db641a36b197 100644 --- a/drivers/media/video/bt8xx/Makefile +++ b/drivers/media/video/bt8xx/Makefile | |||
@@ -9,4 +9,4 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ | |||
9 | obj-$(CONFIG_VIDEO_BT848) += bttv.o | 9 | obj-$(CONFIG_VIDEO_BT848) += bttv.o |
10 | 10 | ||
11 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -I$(src)/.. |
12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile index 32a896c23d1e..6e8665be8954 100644 --- a/drivers/media/video/cx25840/Makefile +++ b/drivers/media/video/cx25840/Makefile | |||
@@ -3,4 +3,4 @@ cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \ | |||
3 | 3 | ||
4 | obj-$(CONFIG_VIDEO_CX25840) += cx25840.o | 4 | obj-$(CONFIG_VIDEO_CX25840) += cx25840.o |
5 | 5 | ||
6 | EXTRA_CFLAGS += -I$(src)/.. | 6 | EXTRA_CFLAGS += -Idrivers/media/video |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 6482b9aa6a1f..0dcd09b9b727 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -8,9 +8,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o | |||
8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o | 8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o |
9 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o | 9 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o |
10 | 10 | ||
11 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -Idrivers/media/video |
12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
13 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends | 13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
14 | 14 | ||
15 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 | 15 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 |
16 | extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 | 16 | extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 |
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile index da457a05b0dd..826d0e340753 100644 --- a/drivers/media/video/em28xx/Makefile +++ b/drivers/media/video/em28xx/Makefile | |||
@@ -3,4 +3,4 @@ em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ | |||
3 | 3 | ||
4 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o | 4 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o |
5 | 5 | ||
6 | EXTRA_CFLAGS += -I$(src)/.. | 6 | EXTRA_CFLAGS += -Idrivers/media/video |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 1ba998424bbd..be7b9ee697d6 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -11,9 +11,9 @@ obj-$(CONFIG_VIDEO_SAA7134_OSS) += saa7134-oss.o | |||
11 | 11 | ||
12 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o | 12 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o |
13 | 13 | ||
14 | EXTRA_CFLAGS += -I$(src)/.. | 14 | EXTRA_CFLAGS += -Idrivers/media/video |
15 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 15 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
16 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends | 16 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
17 | 17 | ||
18 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 | 18 | extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 |
19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 | 19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index c98571c9d5a6..13de05532e0a 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/dma-mapping.h> | ||
35 | 36 | ||
36 | #include "saa7134-reg.h" | 37 | #include "saa7134-reg.h" |
37 | #include "saa7134.h" | 38 | #include "saa7134.h" |
@@ -870,7 +871,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
870 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 871 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
871 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 872 | dev->pci_lat,pci_resource_start(pci_dev,0)); |
872 | pci_set_master(pci_dev); | 873 | pci_set_master(pci_dev); |
873 | if (!pci_dma_supported(pci_dev,0xffffffff)) { | 874 | if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { |
874 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); | 875 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); |
875 | err = -EIO; | 876 | err = -EIO; |
876 | goto fail1; | 877 | goto fail1; |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index dd628cb51e31..7fac438b5c32 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -129,8 +129,8 @@ config MTDRAM_ABS_POS | |||
129 | allocating space from Linux's available memory. Otherwise, leave | 129 | allocating space from Linux's available memory. Otherwise, leave |
130 | this set to zero. Most people will want to leave this as zero. | 130 | this set to zero. Most people will want to leave this as zero. |
131 | 131 | ||
132 | config MTD_BLKMTD | 132 | config MTD_BLOCK2MTD |
133 | tristate "MTD emulation using block device" | 133 | tristate "MTD using block device" |
134 | depends on MTD | 134 | depends on MTD |
135 | help | 135 | help |
136 | This driver allows a block device to appear as an MTD. It would | 136 | This driver allows a block device to appear as an MTD. It would |
@@ -141,15 +141,6 @@ config MTD_BLKMTD | |||
141 | Testing MTD users (eg JFFS2) on large media and media that might | 141 | Testing MTD users (eg JFFS2) on large media and media that might |
142 | be removed during a write (using the floppy drive). | 142 | be removed during a write (using the floppy drive). |
143 | 143 | ||
144 | config MTD_BLOCK2MTD | ||
145 | tristate "MTD using block device (rewrite)" | ||
146 | depends on MTD && EXPERIMENTAL | ||
147 | help | ||
148 | This driver is basically the same at MTD_BLKMTD above, but | ||
149 | experienced some interface changes plus serious speedups. In | ||
150 | the long term, it should replace MTD_BLKMTD. Right now, you | ||
151 | shouldn't entrust important data to it yet. | ||
152 | |||
153 | comment "Disk-On-Chip Device Drivers" | 144 | comment "Disk-On-Chip Device Drivers" |
154 | 145 | ||
155 | config MTD_DOC2000 | 146 | config MTD_DOC2000 |
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 7c5ed2178380..b6573670316f 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile | |||
@@ -21,7 +21,6 @@ obj-$(CONFIG_MTD_PMC551) += pmc551.o | |||
21 | obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o | 21 | obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o |
22 | obj-$(CONFIG_MTD_MTDRAM) += mtdram.o | 22 | obj-$(CONFIG_MTD_MTDRAM) += mtdram.o |
23 | obj-$(CONFIG_MTD_LART) += lart.o | 23 | obj-$(CONFIG_MTD_LART) += lart.o |
24 | obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o | ||
25 | obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o | 24 | obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o |
26 | obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o | 25 | obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o |
27 | obj-$(CONFIG_MTD_M25P80) += m25p80.o | 26 | obj-$(CONFIG_MTD_M25P80) += m25p80.o |
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c deleted file mode 100644 index 79f2e1f23ebd..000000000000 --- a/drivers/mtd/devices/blkmtd.c +++ /dev/null | |||
@@ -1,819 +0,0 @@ | |||
1 | /* | ||
2 | * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $ | ||
3 | * | ||
4 | * blkmtd.c - use a block device as a fake MTD | ||
5 | * | ||
6 | * Author: Simon Evans <spse@secret.org.uk> | ||
7 | * | ||
8 | * Copyright (C) 2001,2002 Simon Evans | ||
9 | * | ||
10 | * Licence: GPL | ||
11 | * | ||
12 | * How it works: | ||
13 | * The driver uses raw/io to read/write the device and the page | ||
14 | * cache to cache access. Writes update the page cache with the | ||
15 | * new data and mark it dirty and add the page into a BIO which | ||
16 | * is then written out. | ||
17 | * | ||
18 | * It can be loaded Read-Only to prevent erases and writes to the | ||
19 | * medium. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/fs.h> | ||
26 | #include <linux/blkdev.h> | ||
27 | #include <linux/bio.h> | ||
28 | #include <linux/pagemap.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/mount.h> | ||
32 | #include <linux/mtd/mtd.h> | ||
33 | #include <linux/mutex.h> | ||
34 | |||
35 | #define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) | ||
36 | #define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) | ||
37 | #define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg) | ||
38 | #define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg) | ||
39 | |||
40 | |||
41 | /* Default erase size in K, always make it a multiple of PAGE_SIZE */ | ||
42 | #define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ | ||
43 | #define VERSION "$Revision: 1.27 $" | ||
44 | |||
45 | /* Info for the block device */ | ||
46 | struct blkmtd_dev { | ||
47 | struct list_head list; | ||
48 | struct block_device *blkdev; | ||
49 | struct mtd_info mtd_info; | ||
50 | struct mutex wrbuf_mutex; | ||
51 | }; | ||
52 | |||
53 | |||
54 | /* Static info about the MTD, used in cleanup_module */ | ||
55 | static LIST_HEAD(blkmtd_device_list); | ||
56 | |||
57 | |||
58 | static void blkmtd_sync(struct mtd_info *mtd); | ||
59 | |||
60 | #define MAX_DEVICES 4 | ||
61 | |||
62 | /* Module parameters passed by insmod/modprobe */ | ||
63 | static char *device[MAX_DEVICES]; /* the block device to use */ | ||
64 | static int erasesz[MAX_DEVICES]; /* optional default erase size */ | ||
65 | static int ro[MAX_DEVICES]; /* optional read only flag */ | ||
66 | static int sync; | ||
67 | |||
68 | |||
69 | MODULE_LICENSE("GPL"); | ||
70 | MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>"); | ||
71 | MODULE_DESCRIPTION("Emulate an MTD using a block device"); | ||
72 | module_param_array(device, charp, NULL, 0); | ||
73 | MODULE_PARM_DESC(device, "block device to use"); | ||
74 | module_param_array(erasesz, int, NULL, 0); | ||
75 | MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB."); | ||
76 | module_param_array(ro, bool, NULL, 0); | ||
77 | MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors"); | ||
78 | module_param(sync, bool, 0); | ||
79 | MODULE_PARM_DESC(sync, "1=Synchronous writes"); | ||
80 | |||
81 | |||
82 | /* completion handler for BIO reads */ | ||
83 | static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error) | ||
84 | { | ||
85 | if (bio->bi_size) | ||
86 | return 1; | ||
87 | |||
88 | complete((struct completion*)bio->bi_private); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | |||
93 | /* completion handler for BIO writes */ | ||
94 | static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error) | ||
95 | { | ||
96 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | ||
97 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | ||
98 | |||
99 | if (bio->bi_size) | ||
100 | return 1; | ||
101 | |||
102 | if(!uptodate) | ||
103 | err("bi_write_complete: not uptodate\n"); | ||
104 | |||
105 | do { | ||
106 | struct page *page = bvec->bv_page; | ||
107 | DEBUG(3, "Cleaning up page %ld\n", page->index); | ||
108 | if (--bvec >= bio->bi_io_vec) | ||
109 | prefetchw(&bvec->bv_page->flags); | ||
110 | |||
111 | if (uptodate) { | ||
112 | SetPageUptodate(page); | ||
113 | } else { | ||
114 | ClearPageUptodate(page); | ||
115 | SetPageError(page); | ||
116 | } | ||
117 | clear_page_dirty(page); | ||
118 | unlock_page(page); | ||
119 | page_cache_release(page); | ||
120 | } while (bvec >= bio->bi_io_vec); | ||
121 | |||
122 | complete((struct completion*)bio->bi_private); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | |||
127 | /* read one page from the block device */ | ||
128 | static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page) | ||
129 | { | ||
130 | struct bio *bio; | ||
131 | struct completion event; | ||
132 | int err = -ENOMEM; | ||
133 | |||
134 | if(PageUptodate(page)) { | ||
135 | DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index); | ||
136 | unlock_page(page); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | ClearPageUptodate(page); | ||
141 | ClearPageError(page); | ||
142 | |||
143 | bio = bio_alloc(GFP_KERNEL, 1); | ||
144 | if(bio) { | ||
145 | init_completion(&event); | ||
146 | bio->bi_bdev = dev->blkdev; | ||
147 | bio->bi_sector = page->index << (PAGE_SHIFT-9); | ||
148 | bio->bi_private = &event; | ||
149 | bio->bi_end_io = bi_read_complete; | ||
150 | if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) { | ||
151 | submit_bio(READ_SYNC, bio); | ||
152 | wait_for_completion(&event); | ||
153 | err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; | ||
154 | bio_put(bio); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | if(err) | ||
159 | SetPageError(page); | ||
160 | else | ||
161 | SetPageUptodate(page); | ||
162 | flush_dcache_page(page); | ||
163 | unlock_page(page); | ||
164 | return err; | ||
165 | } | ||
166 | |||
167 | |||
168 | /* write out the current BIO and wait for it to finish */ | ||
169 | static int blkmtd_write_out(struct bio *bio) | ||
170 | { | ||
171 | struct completion event; | ||
172 | int err; | ||
173 | |||
174 | if(!bio->bi_vcnt) { | ||
175 | bio_put(bio); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | init_completion(&event); | ||
180 | bio->bi_private = &event; | ||
181 | bio->bi_end_io = bi_write_complete; | ||
182 | submit_bio(WRITE_SYNC, bio); | ||
183 | wait_for_completion(&event); | ||
184 | DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt); | ||
185 | err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; | ||
186 | bio_put(bio); | ||
187 | return err; | ||
188 | } | ||
189 | |||
190 | |||
191 | /** | ||
192 | * blkmtd_add_page - add a page to the current BIO | ||
193 | * @bio: bio to add to (NULL to alloc initial bio) | ||
194 | * @blkdev: block device | ||
195 | * @page: page to add | ||
196 | * @pagecnt: pages left to add | ||
197 | * | ||
198 | * Adds a page to the current bio, allocating it if necessary. If it cannot be | ||
199 | * added, the current bio is written out and a new one is allocated. Returns | ||
200 | * the new bio to add or NULL on error | ||
201 | */ | ||
202 | static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev, | ||
203 | struct page *page, int pagecnt) | ||
204 | { | ||
205 | |||
206 | retry: | ||
207 | if(!bio) { | ||
208 | bio = bio_alloc(GFP_KERNEL, pagecnt); | ||
209 | if(!bio) | ||
210 | return NULL; | ||
211 | bio->bi_sector = page->index << (PAGE_SHIFT-9); | ||
212 | bio->bi_bdev = blkdev; | ||
213 | } | ||
214 | |||
215 | if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { | ||
216 | blkmtd_write_out(bio); | ||
217 | bio = NULL; | ||
218 | goto retry; | ||
219 | } | ||
220 | return bio; | ||
221 | } | ||
222 | |||
223 | |||
224 | /** | ||
225 | * write_pages - write block of data to device via the page cache | ||
226 | * @dev: device to write to | ||
227 | * @buf: data source or NULL if erase (output is set to 0xff) | ||
228 | * @to: offset into output device | ||
229 | * @len: amount to data to write | ||
230 | * @retlen: amount of data written | ||
231 | * | ||
232 | * Grab pages from the page cache and fill them with the source data. | ||
233 | * Non page aligned start and end result in a readin of the page and | ||
234 | * part of the page being modified. Pages are added to the bio and then written | ||
235 | * out. | ||
236 | */ | ||
237 | static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, | ||
238 | size_t len, size_t *retlen) | ||
239 | { | ||
240 | int pagenr, offset; | ||
241 | size_t start_len = 0, end_len; | ||
242 | int pagecnt = 0; | ||
243 | int err = 0; | ||
244 | struct bio *bio = NULL; | ||
245 | size_t thislen = 0; | ||
246 | |||
247 | pagenr = to >> PAGE_SHIFT; | ||
248 | offset = to & ~PAGE_MASK; | ||
249 | |||
250 | DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %zd pagenr = %d offset = %d\n", | ||
251 | buf, (long)to, len, pagenr, offset); | ||
252 | |||
253 | /* see if we have to do a partial write at the start */ | ||
254 | if(offset) { | ||
255 | start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len; | ||
256 | len -= start_len; | ||
257 | } | ||
258 | |||
259 | /* calculate the length of the other two regions */ | ||
260 | end_len = len & ~PAGE_MASK; | ||
261 | len -= end_len; | ||
262 | |||
263 | if(start_len) | ||
264 | pagecnt++; | ||
265 | |||
266 | if(len) | ||
267 | pagecnt += len >> PAGE_SHIFT; | ||
268 | |||
269 | if(end_len) | ||
270 | pagecnt++; | ||
271 | |||
272 | mutex_lock(&dev->wrbuf_mutex); | ||
273 | |||
274 | DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", | ||
275 | start_len, len, end_len, pagecnt); | ||
276 | |||
277 | if(start_len) { | ||
278 | /* do partial start region */ | ||
279 | struct page *page; | ||
280 | |||
281 | DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %zd offset = %d\n", | ||
282 | pagenr, start_len, offset); | ||
283 | |||
284 | BUG_ON(!buf); | ||
285 | page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); | ||
286 | lock_page(page); | ||
287 | if(PageDirty(page)) { | ||
288 | err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", | ||
289 | to, start_len, len, end_len, pagenr); | ||
290 | BUG(); | ||
291 | } | ||
292 | memcpy(page_address(page)+offset, buf, start_len); | ||
293 | set_page_dirty(page); | ||
294 | SetPageUptodate(page); | ||
295 | buf += start_len; | ||
296 | thislen = start_len; | ||
297 | bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); | ||
298 | if(!bio) { | ||
299 | err = -ENOMEM; | ||
300 | err("bio_add_page failed\n"); | ||
301 | goto write_err; | ||
302 | } | ||
303 | pagecnt--; | ||
304 | pagenr++; | ||
305 | } | ||
306 | |||
307 | /* Now do the main loop to a page aligned, n page sized output */ | ||
308 | if(len) { | ||
309 | int pagesc = len >> PAGE_SHIFT; | ||
310 | DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n", | ||
311 | pagenr, pagesc); | ||
312 | while(pagesc) { | ||
313 | struct page *page; | ||
314 | |||
315 | /* see if page is in the page cache */ | ||
316 | DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr); | ||
317 | page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr); | ||
318 | if(PageDirty(page)) { | ||
319 | BUG(); | ||
320 | } | ||
321 | if(!page) { | ||
322 | warn("write: cannot grab cache page %d", pagenr); | ||
323 | err = -ENOMEM; | ||
324 | goto write_err; | ||
325 | } | ||
326 | if(!buf) { | ||
327 | memset(page_address(page), 0xff, PAGE_SIZE); | ||
328 | } else { | ||
329 | memcpy(page_address(page), buf, PAGE_SIZE); | ||
330 | buf += PAGE_SIZE; | ||
331 | } | ||
332 | bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); | ||
333 | if(!bio) { | ||
334 | err = -ENOMEM; | ||
335 | err("bio_add_page failed\n"); | ||
336 | goto write_err; | ||
337 | } | ||
338 | pagenr++; | ||
339 | pagecnt--; | ||
340 | set_page_dirty(page); | ||
341 | SetPageUptodate(page); | ||
342 | pagesc--; | ||
343 | thislen += PAGE_SIZE; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | if(end_len) { | ||
348 | /* do the third region */ | ||
349 | struct page *page; | ||
350 | DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %zd\n", | ||
351 | pagenr, end_len); | ||
352 | BUG_ON(!buf); | ||
353 | page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); | ||
354 | lock_page(page); | ||
355 | if(PageDirty(page)) { | ||
356 | err("to = %lld start_len = %zd len = %zd end_len = %zd pagenr = %d\n", | ||
357 | to, start_len, len, end_len, pagenr); | ||
358 | BUG(); | ||
359 | } | ||
360 | memcpy(page_address(page), buf, end_len); | ||
361 | set_page_dirty(page); | ||
362 | SetPageUptodate(page); | ||
363 | DEBUG(3, "blkmtd: write: writing out partial end\n"); | ||
364 | thislen += end_len; | ||
365 | bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); | ||
366 | if(!bio) { | ||
367 | err = -ENOMEM; | ||
368 | err("bio_add_page failed\n"); | ||
369 | goto write_err; | ||
370 | } | ||
371 | pagenr++; | ||
372 | } | ||
373 | |||
374 | DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt); | ||
375 | write_err: | ||
376 | if(bio) | ||
377 | blkmtd_write_out(bio); | ||
378 | |||
379 | DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); | ||
380 | mutex_unlock(&dev->wrbuf_mutex); | ||
381 | |||
382 | if(retlen) | ||
383 | *retlen = thislen; | ||
384 | return err; | ||
385 | } | ||
386 | |||
387 | |||
388 | /* erase a specified part of the device */ | ||
389 | static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr) | ||
390 | { | ||
391 | struct blkmtd_dev *dev = mtd->priv; | ||
392 | struct mtd_erase_region_info *einfo = mtd->eraseregions; | ||
393 | int numregions = mtd->numeraseregions; | ||
394 | size_t from; | ||
395 | u_long len; | ||
396 | int err = -EIO; | ||
397 | size_t retlen; | ||
398 | |||
399 | instr->state = MTD_ERASING; | ||
400 | from = instr->addr; | ||
401 | len = instr->len; | ||
402 | |||
403 | /* check erase region has valid start and length */ | ||
404 | DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%zx len = 0x%lx\n", | ||
405 | mtd->name+9, from, len); | ||
406 | while(numregions) { | ||
407 | DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n", | ||
408 | einfo->offset, einfo->erasesize, einfo->numblocks); | ||
409 | if(from >= einfo->offset | ||
410 | && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) { | ||
411 | if(len == einfo->erasesize | ||
412 | && ( (from - einfo->offset) % einfo->erasesize == 0)) | ||
413 | break; | ||
414 | } | ||
415 | numregions--; | ||
416 | einfo++; | ||
417 | } | ||
418 | |||
419 | if(!numregions) { | ||
420 | /* Not a valid erase block */ | ||
421 | err("erase: invalid erase request 0x%lX @ 0x%08zX", len, from); | ||
422 | instr->state = MTD_ERASE_FAILED; | ||
423 | err = -EIO; | ||
424 | } | ||
425 | |||
426 | if(instr->state != MTD_ERASE_FAILED) { | ||
427 | /* do the erase */ | ||
428 | DEBUG(3, "Doing erase from = %zd len = %ld\n", from, len); | ||
429 | err = write_pages(dev, NULL, from, len, &retlen); | ||
430 | if(err || retlen != len) { | ||
431 | err("erase failed err = %d", err); | ||
432 | instr->state = MTD_ERASE_FAILED; | ||
433 | } else { | ||
434 | instr->state = MTD_ERASE_DONE; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | DEBUG(3, "blkmtd: erase: checking callback\n"); | ||
439 | mtd_erase_callback(instr); | ||
440 | DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err); | ||
441 | return err; | ||
442 | } | ||
443 | |||
444 | |||
445 | /* read a range of the data via the page cache */ | ||
446 | static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
447 | size_t *retlen, u_char *buf) | ||
448 | { | ||
449 | struct blkmtd_dev *dev = mtd->priv; | ||
450 | int err = 0; | ||
451 | int offset; | ||
452 | int pagenr, pages; | ||
453 | size_t thislen = 0; | ||
454 | |||
455 | DEBUG(2, "blkmtd: read: dev = `%s' from = %lld len = %zd buf = %p\n", | ||
456 | mtd->name+9, from, len, buf); | ||
457 | |||
458 | if(from > mtd->size) | ||
459 | return -EINVAL; | ||
460 | if(from + len > mtd->size) | ||
461 | len = mtd->size - from; | ||
462 | |||
463 | pagenr = from >> PAGE_SHIFT; | ||
464 | offset = from - (pagenr << PAGE_SHIFT); | ||
465 | |||
466 | pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT; | ||
467 | DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", | ||
468 | pagenr, offset, pages); | ||
469 | |||
470 | while(pages) { | ||
471 | struct page *page; | ||
472 | int cpylen; | ||
473 | |||
474 | DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr); | ||
475 | page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); | ||
476 | if(IS_ERR(page)) { | ||
477 | err = -EIO; | ||
478 | goto readerr; | ||
479 | } | ||
480 | |||
481 | cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE; | ||
482 | if(offset+cpylen > PAGE_SIZE) | ||
483 | cpylen = PAGE_SIZE-offset; | ||
484 | |||
485 | memcpy(buf + thislen, page_address(page) + offset, cpylen); | ||
486 | offset = 0; | ||
487 | len -= cpylen; | ||
488 | thislen += cpylen; | ||
489 | pagenr++; | ||
490 | pages--; | ||
491 | if(!PageDirty(page)) | ||
492 | page_cache_release(page); | ||
493 | } | ||
494 | |||
495 | readerr: | ||
496 | if(retlen) | ||
497 | *retlen = thislen; | ||
498 | DEBUG(2, "blkmtd: end read: retlen = %zd, err = %d\n", thislen, err); | ||
499 | return err; | ||
500 | } | ||
501 | |||
502 | |||
503 | /* write data to the underlying device */ | ||
504 | static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
505 | size_t *retlen, const u_char *buf) | ||
506 | { | ||
507 | struct blkmtd_dev *dev = mtd->priv; | ||
508 | int err; | ||
509 | |||
510 | if(!len) | ||
511 | return 0; | ||
512 | |||
513 | DEBUG(2, "blkmtd: write: dev = `%s' to = %lld len = %zd buf = %p\n", | ||
514 | mtd->name+9, to, len, buf); | ||
515 | |||
516 | if(to >= mtd->size) { | ||
517 | return -ENOSPC; | ||
518 | } | ||
519 | |||
520 | if(to + len > mtd->size) { | ||
521 | len = mtd->size - to; | ||
522 | } | ||
523 | |||
524 | err = write_pages(dev, buf, to, len, retlen); | ||
525 | if(err > 0) | ||
526 | err = 0; | ||
527 | DEBUG(2, "blkmtd: write: end, err = %d\n", err); | ||
528 | return err; | ||
529 | } | ||
530 | |||
531 | |||
532 | /* sync the device - wait until the write queue is empty */ | ||
533 | static void blkmtd_sync(struct mtd_info *mtd) | ||
534 | { | ||
535 | /* Currently all writes are synchronous */ | ||
536 | } | ||
537 | |||
538 | |||
539 | static void free_device(struct blkmtd_dev *dev) | ||
540 | { | ||
541 | DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); | ||
542 | if(dev) { | ||
543 | kfree(dev->mtd_info.eraseregions); | ||
544 | kfree(dev->mtd_info.name); | ||
545 | if(dev->blkdev) { | ||
546 | invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); | ||
547 | close_bdev_excl(dev->blkdev); | ||
548 | } | ||
549 | kfree(dev); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | |||
554 | /* For a given size and initial erase size, calculate the number | ||
555 | * and size of each erase region. Goes round the loop twice, | ||
556 | * once to find out how many regions, then allocates space, | ||
557 | * then round the loop again to fill it in. | ||
558 | */ | ||
559 | static struct mtd_erase_region_info *calc_erase_regions( | ||
560 | size_t erase_size, size_t total_size, int *regions) | ||
561 | { | ||
562 | struct mtd_erase_region_info *info = NULL; | ||
563 | |||
564 | DEBUG(2, "calc_erase_regions, es = %zd size = %zd regions = %d\n", | ||
565 | erase_size, total_size, *regions); | ||
566 | /* Make any user specified erasesize be a power of 2 | ||
567 | and at least PAGE_SIZE */ | ||
568 | if(erase_size) { | ||
569 | int es = erase_size; | ||
570 | erase_size = 1; | ||
571 | while(es != 1) { | ||
572 | es >>= 1; | ||
573 | erase_size <<= 1; | ||
574 | } | ||
575 | if(erase_size < PAGE_SIZE) | ||
576 | erase_size = PAGE_SIZE; | ||
577 | } else { | ||
578 | erase_size = CONFIG_MTD_BLKDEV_ERASESIZE; | ||
579 | } | ||
580 | |||
581 | *regions = 0; | ||
582 | |||
583 | do { | ||
584 | int tot_size = total_size; | ||
585 | int er_size = erase_size; | ||
586 | int count = 0, offset = 0, regcnt = 0; | ||
587 | |||
588 | while(tot_size) { | ||
589 | count = tot_size / er_size; | ||
590 | if(count) { | ||
591 | tot_size = tot_size % er_size; | ||
592 | if(info) { | ||
593 | DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n", | ||
594 | offset, er_size, count); | ||
595 | (info+regcnt)->offset = offset; | ||
596 | (info+regcnt)->erasesize = er_size; | ||
597 | (info+regcnt)->numblocks = count; | ||
598 | (*regions)++; | ||
599 | } | ||
600 | regcnt++; | ||
601 | offset += (count * er_size); | ||
602 | } | ||
603 | while(er_size > tot_size) | ||
604 | er_size >>= 1; | ||
605 | } | ||
606 | if(info == NULL) { | ||
607 | info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL); | ||
608 | if(!info) | ||
609 | break; | ||
610 | } | ||
611 | } while(!(*regions)); | ||
612 | DEBUG(2, "calc_erase_regions done, es = %zd size = %zd regions = %d\n", | ||
613 | erase_size, total_size, *regions); | ||
614 | return info; | ||
615 | } | ||
616 | |||
617 | |||
618 | static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) | ||
619 | { | ||
620 | struct block_device *bdev; | ||
621 | int mode; | ||
622 | struct blkmtd_dev *dev; | ||
623 | |||
624 | if(!devname) | ||
625 | return NULL; | ||
626 | |||
627 | /* Get a handle on the device */ | ||
628 | |||
629 | |||
630 | #ifdef MODULE | ||
631 | mode = (readonly) ? O_RDONLY : O_RDWR; | ||
632 | bdev = open_bdev_excl(devname, mode, NULL); | ||
633 | #else | ||
634 | mode = (readonly) ? FMODE_READ : FMODE_WRITE; | ||
635 | bdev = open_by_devnum(name_to_dev_t(devname), mode); | ||
636 | #endif | ||
637 | if(IS_ERR(bdev)) { | ||
638 | err("error: cannot open device %s", devname); | ||
639 | DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev)); | ||
640 | return NULL; | ||
641 | } | ||
642 | |||
643 | DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n", | ||
644 | MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); | ||
645 | |||
646 | if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { | ||
647 | err("attempting to use an MTD device as a block device"); | ||
648 | blkdev_put(bdev); | ||
649 | return NULL; | ||
650 | } | ||
651 | |||
652 | dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL); | ||
653 | if(dev == NULL) { | ||
654 | blkdev_put(bdev); | ||
655 | return NULL; | ||
656 | } | ||
657 | |||
658 | memset(dev, 0, sizeof(struct blkmtd_dev)); | ||
659 | dev->blkdev = bdev; | ||
660 | if(!readonly) { | ||
661 | mutex_init(&dev->wrbuf_mutex); | ||
662 | } | ||
663 | |||
664 | dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; | ||
665 | |||
666 | /* Setup the MTD structure */ | ||
667 | /* make the name contain the block device in */ | ||
668 | dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL); | ||
669 | if(dev->mtd_info.name == NULL) | ||
670 | goto devinit_err; | ||
671 | |||
672 | sprintf(dev->mtd_info.name, "blkmtd: %s", devname); | ||
673 | dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size, | ||
674 | &dev->mtd_info.numeraseregions); | ||
675 | if(dev->mtd_info.eraseregions == NULL) | ||
676 | goto devinit_err; | ||
677 | |||
678 | dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize; | ||
679 | DEBUG(1, "blkmtd: init: found %d erase regions\n", | ||
680 | dev->mtd_info.numeraseregions); | ||
681 | |||
682 | if(readonly) { | ||
683 | dev->mtd_info.type = MTD_ROM; | ||
684 | dev->mtd_info.flags = MTD_CAP_ROM; | ||
685 | } else { | ||
686 | dev->mtd_info.type = MTD_RAM; | ||
687 | dev->mtd_info.flags = MTD_CAP_RAM; | ||
688 | dev->mtd_info.erase = blkmtd_erase; | ||
689 | dev->mtd_info.write = blkmtd_write; | ||
690 | dev->mtd_info.writev = default_mtd_writev; | ||
691 | dev->mtd_info.sync = blkmtd_sync; | ||
692 | } | ||
693 | dev->mtd_info.read = blkmtd_read; | ||
694 | dev->mtd_info.readv = default_mtd_readv; | ||
695 | dev->mtd_info.priv = dev; | ||
696 | dev->mtd_info.owner = THIS_MODULE; | ||
697 | |||
698 | list_add(&dev->list, &blkmtd_device_list); | ||
699 | if (add_mtd_device(&dev->mtd_info)) { | ||
700 | /* Device didnt get added, so free the entry */ | ||
701 | list_del(&dev->list); | ||
702 | goto devinit_err; | ||
703 | } else { | ||
704 | info("mtd%d: [%s] erase_size = %dKiB %s", | ||
705 | dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "), | ||
706 | dev->mtd_info.erasesize >> 10, | ||
707 | readonly ? "(read-only)" : ""); | ||
708 | } | ||
709 | |||
710 | return dev; | ||
711 | |||
712 | devinit_err: | ||
713 | free_device(dev); | ||
714 | return NULL; | ||
715 | } | ||
716 | |||
717 | |||
718 | /* Cleanup and exit - sync the device and kill of the kernel thread */ | ||
719 | static void __devexit cleanup_blkmtd(void) | ||
720 | { | ||
721 | struct list_head *temp1, *temp2; | ||
722 | |||
723 | /* Remove the MTD devices */ | ||
724 | list_for_each_safe(temp1, temp2, &blkmtd_device_list) { | ||
725 | struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, | ||
726 | list); | ||
727 | blkmtd_sync(&dev->mtd_info); | ||
728 | del_mtd_device(&dev->mtd_info); | ||
729 | info("mtd%d: [%s] removed", dev->mtd_info.index, | ||
730 | dev->mtd_info.name + strlen("blkmtd: ")); | ||
731 | list_del(&dev->list); | ||
732 | free_device(dev); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | #ifndef MODULE | ||
737 | |||
738 | /* Handle kernel boot params */ | ||
739 | |||
740 | |||
741 | static int __init param_blkmtd_device(char *str) | ||
742 | { | ||
743 | int i; | ||
744 | |||
745 | for(i = 0; i < MAX_DEVICES; i++) { | ||
746 | device[i] = str; | ||
747 | DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]); | ||
748 | strsep(&str, ","); | ||
749 | } | ||
750 | return 1; | ||
751 | } | ||
752 | |||
753 | |||
754 | static int __init param_blkmtd_erasesz(char *str) | ||
755 | { | ||
756 | int i; | ||
757 | for(i = 0; i < MAX_DEVICES; i++) { | ||
758 | char *val = strsep(&str, ","); | ||
759 | if(val) | ||
760 | erasesz[i] = simple_strtoul(val, NULL, 0); | ||
761 | DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]); | ||
762 | } | ||
763 | |||
764 | return 1; | ||
765 | } | ||
766 | |||
767 | |||
768 | static int __init param_blkmtd_ro(char *str) | ||
769 | { | ||
770 | int i; | ||
771 | for(i = 0; i < MAX_DEVICES; i++) { | ||
772 | char *val = strsep(&str, ","); | ||
773 | if(val) | ||
774 | ro[i] = simple_strtoul(val, NULL, 0); | ||
775 | DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]); | ||
776 | } | ||
777 | |||
778 | return 1; | ||
779 | } | ||
780 | |||
781 | |||
782 | static int __init param_blkmtd_sync(char *str) | ||
783 | { | ||
784 | if(str[0] == '1') | ||
785 | sync = 1; | ||
786 | return 1; | ||
787 | } | ||
788 | |||
789 | __setup("blkmtd_device=", param_blkmtd_device); | ||
790 | __setup("blkmtd_erasesz=", param_blkmtd_erasesz); | ||
791 | __setup("blkmtd_ro=", param_blkmtd_ro); | ||
792 | __setup("blkmtd_sync=", param_blkmtd_sync); | ||
793 | |||
794 | #endif | ||
795 | |||
796 | |||
797 | /* Startup */ | ||
798 | static int __init init_blkmtd(void) | ||
799 | { | ||
800 | int i; | ||
801 | |||
802 | info("version " VERSION); | ||
803 | /* Check args - device[0] is the bare minimum*/ | ||
804 | if(!device[0]) { | ||
805 | err("error: missing `device' name\n"); | ||
806 | return -EINVAL; | ||
807 | } | ||
808 | |||
809 | for(i = 0; i < MAX_DEVICES; i++) | ||
810 | add_device(device[i], ro[i], erasesz[i] << 10); | ||
811 | |||
812 | if(list_empty(&blkmtd_device_list)) | ||
813 | return -EINVAL; | ||
814 | |||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | module_init(init_blkmtd); | ||
819 | module_exit(cleanup_blkmtd); | ||
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile index 91e927827c43..54c78d94f48b 100644 --- a/drivers/net/chelsio/Makefile +++ b/drivers/net/chelsio/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o | 5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o |
6 | 6 | ||
7 | EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS) | 7 | EXTRA_CFLAGS += -Idrivers/net/chelsio $(DEBUG_FLAGS) |
8 | 8 | ||
9 | 9 | ||
10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o | 10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6e2ec56cde0b..606243d11793 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Filename: irda-usb.c | 3 | * Filename: irda-usb.c |
4 | * Version: 0.9b | 4 | * Version: 0.10 |
5 | * Description: IrDA-USB Driver | 5 | * Description: IrDA-USB Driver |
6 | * Status: Experimental | 6 | * Status: Experimental |
7 | * Author: Dag Brattli <dag@brattli.net> | 7 | * Author: Dag Brattli <dag@brattli.net> |
@@ -9,6 +9,9 @@ | |||
9 | * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> | 9 | * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at> |
10 | * Copyright (C) 2001, Dag Brattli <dag@brattli.net> | 10 | * Copyright (C) 2001, Dag Brattli <dag@brattli.net> |
11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> | 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> |
12 | * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com> | ||
13 | * Copyright (C) 2005, Milan Beno <beno@pobox.sk> | ||
14 | * Copyright (C) 2006, Nick Fedchik <nick@fedchik.org.ua> | ||
12 | * | 15 | * |
13 | * This program is free software; you can redistribute it and/or modify | 16 | * 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 | 17 | * it under the terms of the GNU General Public License as published by |
@@ -61,6 +64,7 @@ | |||
61 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
62 | #include <linux/rtnetlink.h> | 65 | #include <linux/rtnetlink.h> |
63 | #include <linux/usb.h> | 66 | #include <linux/usb.h> |
67 | #include <linux/firmware.h> | ||
64 | 68 | ||
65 | #include "irda-usb.h" | 69 | #include "irda-usb.h" |
66 | 70 | ||
@@ -78,8 +82,12 @@ static struct usb_device_id dongles[] = { | |||
78 | { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, | 82 | { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, |
79 | /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ | 83 | /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */ |
80 | { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, | 84 | { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW }, |
85 | /* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */ | ||
86 | { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
87 | { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
88 | { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, | ||
81 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | | 89 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | |
82 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | 90 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, |
83 | .bInterfaceClass = USB_CLASS_APP_SPEC, | 91 | .bInterfaceClass = USB_CLASS_APP_SPEC, |
84 | .bInterfaceSubClass = USB_CLASS_IRDA, | 92 | .bInterfaceSubClass = USB_CLASS_IRDA, |
85 | .driver_info = IUC_DEFAULT, }, | 93 | .driver_info = IUC_DEFAULT, }, |
@@ -99,6 +107,7 @@ MODULE_DEVICE_TABLE(usb, dongles); | |||
99 | 107 | ||
100 | /*------------------------------------------------------------------*/ | 108 | /*------------------------------------------------------------------*/ |
101 | 109 | ||
110 | static void irda_usb_init_qos(struct irda_usb_cb *self) ; | ||
102 | static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); | 111 | static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf); |
103 | static void irda_usb_disconnect(struct usb_interface *intf); | 112 | static void irda_usb_disconnect(struct usb_interface *intf); |
104 | static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); | 113 | static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); |
@@ -141,7 +150,24 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
141 | __u8 *header, | 150 | __u8 *header, |
142 | int force) | 151 | int force) |
143 | { | 152 | { |
144 | /* Set the negotiated link speed */ | 153 | /* Here we check if we have an STIR421x chip, |
154 | * and if either speed or xbofs (or both) needs | ||
155 | * to be changed. | ||
156 | */ | ||
157 | if (self->capability & IUC_STIR_4210 && | ||
158 | ((self->new_speed != -1) || (self->new_xbofs != -1))) { | ||
159 | |||
160 | /* With STIR421x, speed and xBOFs must be set at the same | ||
161 | * time, even if only one of them changes. | ||
162 | */ | ||
163 | if (self->new_speed == -1) | ||
164 | self->new_speed = self->speed ; | ||
165 | |||
166 | if (self->new_xbofs == -1) | ||
167 | self->new_xbofs = self->xbofs ; | ||
168 | } | ||
169 | |||
170 | /* Set the link speed */ | ||
145 | if (self->new_speed != -1) { | 171 | if (self->new_speed != -1) { |
146 | /* Hum... Ugly hack :-( | 172 | /* Hum... Ugly hack :-( |
147 | * Some device are not compliant with the spec and change | 173 | * Some device are not compliant with the spec and change |
@@ -191,7 +217,11 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
191 | *header = SPEED_4000000; | 217 | *header = SPEED_4000000; |
192 | self->new_xbofs = 0; | 218 | self->new_xbofs = 0; |
193 | break; | 219 | break; |
194 | } | 220 | case 16000000: |
221 | *header = SPEED_16000000; | ||
222 | self->new_xbofs = 0; | ||
223 | break; | ||
224 | } | ||
195 | } else | 225 | } else |
196 | /* No change */ | 226 | /* No change */ |
197 | *header = 0; | 227 | *header = 0; |
@@ -235,6 +265,32 @@ static void irda_usb_build_header(struct irda_usb_cb *self, | |||
235 | } | 265 | } |
236 | } | 266 | } |
237 | 267 | ||
268 | /* | ||
269 | * calculate turnaround time for SigmaTel header | ||
270 | */ | ||
271 | static __u8 get_turnaround_time(struct sk_buff *skb) | ||
272 | { | ||
273 | int turnaround_time = irda_get_mtt(skb); | ||
274 | |||
275 | if ( turnaround_time == 0 ) | ||
276 | return 0; | ||
277 | else if ( turnaround_time <= 10 ) | ||
278 | return 1; | ||
279 | else if ( turnaround_time <= 50 ) | ||
280 | return 2; | ||
281 | else if ( turnaround_time <= 100 ) | ||
282 | return 3; | ||
283 | else if ( turnaround_time <= 500 ) | ||
284 | return 4; | ||
285 | else if ( turnaround_time <= 1000 ) | ||
286 | return 5; | ||
287 | else if ( turnaround_time <= 5000 ) | ||
288 | return 6; | ||
289 | else | ||
290 | return 7; | ||
291 | } | ||
292 | |||
293 | |||
238 | /*------------------------------------------------------------------*/ | 294 | /*------------------------------------------------------------------*/ |
239 | /* | 295 | /* |
240 | * Send a command to change the speed of the dongle | 296 | * Send a command to change the speed of the dongle |
@@ -262,12 +318,18 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) | |||
262 | /* Set the new speed and xbofs in this fake frame */ | 318 | /* Set the new speed and xbofs in this fake frame */ |
263 | irda_usb_build_header(self, frame, 1); | 319 | irda_usb_build_header(self, frame, 1); |
264 | 320 | ||
321 | if ( self->capability & IUC_STIR_4210 ) { | ||
322 | if (frame[0] == 0) return ; // do nothing if no change | ||
323 | frame[1] = 0; // other parameters don't change here | ||
324 | frame[2] = 0; | ||
325 | } | ||
326 | |||
265 | /* Submit the 0 length IrDA frame to trigger new speed settings */ | 327 | /* Submit the 0 length IrDA frame to trigger new speed settings */ |
266 | usb_fill_bulk_urb(urb, self->usbdev, | 328 | usb_fill_bulk_urb(urb, self->usbdev, |
267 | usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), | 329 | usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), |
268 | frame, IRDA_USB_SPEED_MTU, | 330 | frame, IRDA_USB_SPEED_MTU, |
269 | speed_bulk_callback, self); | 331 | speed_bulk_callback, self); |
270 | urb->transfer_buffer_length = USB_IRDA_HEADER; | 332 | urb->transfer_buffer_length = self->header_length; |
271 | urb->transfer_flags = 0; | 333 | urb->transfer_flags = 0; |
272 | 334 | ||
273 | /* Irq disabled -> GFP_ATOMIC */ | 335 | /* Irq disabled -> GFP_ATOMIC */ |
@@ -383,16 +445,35 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
383 | * allocation will be done lower in skb_push(). | 445 | * allocation will be done lower in skb_push(). |
384 | * Also, we don't use directly skb_cow(), because it require | 446 | * Also, we don't use directly skb_cow(), because it require |
385 | * headroom >= 16, which force unnecessary copies - Jean II */ | 447 | * headroom >= 16, which force unnecessary copies - Jean II */ |
386 | if (skb_headroom(skb) < USB_IRDA_HEADER) { | 448 | if (skb_headroom(skb) < self->header_length) { |
387 | IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); | 449 | IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); |
388 | if (skb_cow(skb, USB_IRDA_HEADER)) { | 450 | if (skb_cow(skb, self->header_length)) { |
389 | IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); | 451 | IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); |
390 | goto drop; | 452 | goto drop; |
391 | } | 453 | } |
392 | } | 454 | } |
393 | 455 | ||
394 | /* Change setting for next frame */ | 456 | /* Change setting for next frame */ |
395 | irda_usb_build_header(self, skb_push(skb, USB_IRDA_HEADER), 0); | 457 | |
458 | if ( self->capability & IUC_STIR_4210 ) { | ||
459 | __u8 turnaround_time; | ||
460 | __u8* frame; | ||
461 | turnaround_time = get_turnaround_time( skb ); | ||
462 | frame= skb_push(skb, self->header_length); | ||
463 | irda_usb_build_header(self, frame, 0); | ||
464 | frame[2] = turnaround_time; | ||
465 | if ((skb->len != 0) && | ||
466 | ((skb->len % 128) == 0) && | ||
467 | ((skb->len % 512) != 0)) { | ||
468 | /* add extra byte for special SigmaTel feature */ | ||
469 | frame[1] = 1; | ||
470 | skb_put(skb, 1); | ||
471 | } else { | ||
472 | frame[1] = 0; | ||
473 | } | ||
474 | } else { | ||
475 | irda_usb_build_header(self, skb_push(skb, self->header_length), 0); | ||
476 | } | ||
396 | 477 | ||
397 | /* FIXME: Make macro out of this one */ | 478 | /* FIXME: Make macro out of this one */ |
398 | ((struct irda_skb_cb *)skb->cb)->context = self; | 479 | ((struct irda_skb_cb *)skb->cb)->context = self; |
@@ -795,7 +876,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
795 | } | 876 | } |
796 | 877 | ||
797 | /* Check for empty frames */ | 878 | /* Check for empty frames */ |
798 | if (urb->actual_length <= USB_IRDA_HEADER) { | 879 | if (urb->actual_length <= self->header_length) { |
799 | IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); | 880 | IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); |
800 | goto done; | 881 | goto done; |
801 | } | 882 | } |
@@ -816,7 +897,11 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
816 | docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); | 897 | docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); |
817 | 898 | ||
818 | /* Allocate a new skb */ | 899 | /* Allocate a new skb */ |
819 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); | 900 | if ( self->capability & IUC_STIR_4210 ) |
901 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER); | ||
902 | else | ||
903 | newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU); | ||
904 | |||
820 | if (!newskb) { | 905 | if (!newskb) { |
821 | self->stats.rx_dropped++; | 906 | self->stats.rx_dropped++; |
822 | /* We could deliver the current skb, but this would stall | 907 | /* We could deliver the current skb, but this would stall |
@@ -845,7 +930,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
845 | 930 | ||
846 | /* Set proper length on skb & remove USB-IrDA header */ | 931 | /* Set proper length on skb & remove USB-IrDA header */ |
847 | skb_put(dataskb, urb->actual_length); | 932 | skb_put(dataskb, urb->actual_length); |
848 | skb_pull(dataskb, USB_IRDA_HEADER); | 933 | skb_pull(dataskb, self->header_length); |
849 | 934 | ||
850 | /* Ask the networking layer to queue the packet for the IrDA stack */ | 935 | /* Ask the networking layer to queue the packet for the IrDA stack */ |
851 | dataskb->dev = self->netdev; | 936 | dataskb->dev = self->netdev; |
@@ -937,6 +1022,191 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) | |||
937 | return 0; /* For now */ | 1022 | return 0; /* For now */ |
938 | } | 1023 | } |
939 | 1024 | ||
1025 | |||
1026 | #define STIR421X_PATCH_PRODUCT_VERSION_STR "Product Version: " | ||
1027 | #define STIR421X_PATCH_COMPONENT_VERSION_STR "Component Version: " | ||
1028 | #define STIR421X_PATCH_DATA_TAG_STR "STMP" | ||
1029 | #define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET 512 /* version info is before here */ | ||
1030 | #define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET 512 /* patch image starts before here */ | ||
1031 | #define STIR421X_PATCH_FILE_END_OF_HEADER_TAG 0x1A /* marks end of patch file header (PC DOS text file EOF character) */ | ||
1032 | |||
1033 | /* | ||
1034 | * Known firmware patches for STIR421x dongles | ||
1035 | */ | ||
1036 | static char * stir421x_patches[] = { | ||
1037 | "42101001.sb", | ||
1038 | "42101002.sb", | ||
1039 | }; | ||
1040 | |||
1041 | static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len) | ||
1042 | { | ||
1043 | unsigned int version_offset; | ||
1044 | unsigned long version_major, version_minor, version_build; | ||
1045 | unsigned char * version_start; | ||
1046 | int version_found = 0; | ||
1047 | |||
1048 | for (version_offset = 0; | ||
1049 | version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG; | ||
1050 | version_offset++) { | ||
1051 | if (!memcmp(patch + version_offset, | ||
1052 | STIR421X_PATCH_PRODUCT_VERSION_STR, | ||
1053 | sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) { | ||
1054 | version_found = 1; | ||
1055 | version_start = patch + | ||
1056 | version_offset + | ||
1057 | sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1; | ||
1058 | break; | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | /* We couldn't find a product version on this patch */ | ||
1063 | if (!version_found) | ||
1064 | return -EINVAL; | ||
1065 | |||
1066 | /* Let's check if the product version is dotted */ | ||
1067 | if (version_start[3] != '.' || | ||
1068 | version_start[7] != '.') | ||
1069 | return -EINVAL; | ||
1070 | |||
1071 | version_major = simple_strtoul(version_start, NULL, 10); | ||
1072 | version_minor = simple_strtoul(version_start + 4, NULL, 10); | ||
1073 | version_build = simple_strtoul(version_start + 8, NULL, 10); | ||
1074 | |||
1075 | IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n", | ||
1076 | __FUNCTION__, | ||
1077 | version_major, version_minor, version_build); | ||
1078 | |||
1079 | return (((version_major) << 12) + | ||
1080 | ((version_minor) << 8) + | ||
1081 | ((version_build / 10) << 4) + | ||
1082 | (version_build % 10)); | ||
1083 | |||
1084 | } | ||
1085 | |||
1086 | |||
1087 | static int stir421x_upload_patch (struct irda_usb_cb *self, | ||
1088 | unsigned char * patch, | ||
1089 | const unsigned int patch_len) | ||
1090 | { | ||
1091 | int retval = 0; | ||
1092 | int actual_len; | ||
1093 | unsigned int i = 0, download_amount = 0; | ||
1094 | unsigned char * patch_chunk; | ||
1095 | |||
1096 | IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__); | ||
1097 | |||
1098 | patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL); | ||
1099 | if (patch_chunk == NULL) | ||
1100 | return -ENOMEM; | ||
1101 | |||
1102 | /* break up patch into 1023-byte sections */ | ||
1103 | for (i = 0; retval >= 0 && i < patch_len; i += download_amount) { | ||
1104 | download_amount = patch_len - i; | ||
1105 | if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE) | ||
1106 | download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE; | ||
1107 | |||
1108 | /* download the patch section */ | ||
1109 | memcpy(patch_chunk, patch + i, download_amount); | ||
1110 | |||
1111 | retval = usb_bulk_msg (self->usbdev, | ||
1112 | usb_sndbulkpipe (self->usbdev, | ||
1113 | self->bulk_out_ep), | ||
1114 | patch_chunk, download_amount, | ||
1115 | &actual_len, msecs_to_jiffies (500)); | ||
1116 | IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__, | ||
1117 | actual_len); | ||
1118 | if (retval == 0) | ||
1119 | mdelay(10); | ||
1120 | } | ||
1121 | |||
1122 | kfree(patch_chunk); | ||
1123 | |||
1124 | if (i != patch_len) { | ||
1125 | IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n", | ||
1126 | __FUNCTION__, i, patch_len); | ||
1127 | retval = -EIO; | ||
1128 | } | ||
1129 | |||
1130 | if (retval < 0) | ||
1131 | /* todo - mark device as not ready */ | ||
1132 | IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n", | ||
1133 | __FUNCTION__, retval); | ||
1134 | |||
1135 | return retval; | ||
1136 | } | ||
1137 | |||
1138 | |||
1139 | static int stir421x_patch_device(struct irda_usb_cb *self) | ||
1140 | { | ||
1141 | unsigned int i, patch_found = 0, data_found = 0, data_offset; | ||
1142 | int patch_version, ret = 0; | ||
1143 | const struct firmware *fw_entry; | ||
1144 | |||
1145 | for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) { | ||
1146 | if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) { | ||
1147 | IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]); | ||
1148 | continue; | ||
1149 | } | ||
1150 | |||
1151 | /* We found a patch from userspace */ | ||
1152 | patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size); | ||
1153 | |||
1154 | if (patch_version < 0) { | ||
1155 | /* Couldn't fetch a version, let's move on to the next file */ | ||
1156 | IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__); | ||
1157 | ret = patch_version; | ||
1158 | release_firmware(fw_entry); | ||
1159 | continue; | ||
1160 | } | ||
1161 | |||
1162 | if (patch_version != self->usbdev->descriptor.bcdDevice) { | ||
1163 | /* Patch version and device don't match */ | ||
1164 | IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n", | ||
1165 | __FUNCTION__, | ||
1166 | patch_version, self->usbdev->descriptor.bcdDevice); | ||
1167 | ret = -EINVAL; | ||
1168 | release_firmware(fw_entry); | ||
1169 | continue; | ||
1170 | } | ||
1171 | |||
1172 | /* If we're here, we've found a correct patch */ | ||
1173 | patch_found = 1; | ||
1174 | break; | ||
1175 | |||
1176 | } | ||
1177 | |||
1178 | /* We couldn't find a valid firmware, let's leave */ | ||
1179 | if (!patch_found) | ||
1180 | return ret; | ||
1181 | |||
1182 | /* The actual image starts after the "STMP" keyword */ | ||
1183 | for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) { | ||
1184 | if (!memcmp(fw_entry->data + data_offset, | ||
1185 | STIR421X_PATCH_DATA_TAG_STR, | ||
1186 | sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) { | ||
1187 | IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n", | ||
1188 | __FUNCTION__, data_offset); | ||
1189 | data_found = 1; | ||
1190 | break; | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | /* We couldn't find "STMP" from the header */ | ||
1195 | if (!data_found) | ||
1196 | return -EINVAL; | ||
1197 | |||
1198 | /* Let's upload the patch to the target */ | ||
1199 | ret = stir421x_upload_patch(self, | ||
1200 | &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)], | ||
1201 | fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))); | ||
1202 | |||
1203 | release_firmware(fw_entry); | ||
1204 | |||
1205 | return ret; | ||
1206 | |||
1207 | } | ||
1208 | |||
1209 | |||
940 | /********************** IRDA DEVICE CALLBACKS **********************/ | 1210 | /********************** IRDA DEVICE CALLBACKS **********************/ |
941 | /* | 1211 | /* |
942 | * Main calls from the IrDA/Network subsystem. | 1212 | * Main calls from the IrDA/Network subsystem. |
@@ -972,6 +1242,11 @@ static int irda_usb_net_open(struct net_device *netdev) | |||
972 | return -1; | 1242 | return -1; |
973 | } | 1243 | } |
974 | 1244 | ||
1245 | if(self->needspatch) { | ||
1246 | IRDA_WARNING("%s(), device needs patch\n", __FUNCTION__) ; | ||
1247 | return -EIO ; | ||
1248 | } | ||
1249 | |||
975 | /* Initialise default speed and xbofs value | 1250 | /* Initialise default speed and xbofs value |
976 | * (IrLAP will change that soon) */ | 1251 | * (IrLAP will change that soon) */ |
977 | self->speed = -1; | 1252 | self->speed = -1; |
@@ -1050,7 +1325,7 @@ static int irda_usb_net_close(struct net_device *netdev) | |||
1050 | del_timer(&self->rx_defer_timer); | 1325 | del_timer(&self->rx_defer_timer); |
1051 | 1326 | ||
1052 | /* Deallocate all the Rx path buffers (URBs and skb) */ | 1327 | /* Deallocate all the Rx path buffers (URBs and skb) */ |
1053 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1328 | for (i = 0; i < self->max_rx_urb; i++) { |
1054 | struct urb *urb = self->rx_urb[i]; | 1329 | struct urb *urb = self->rx_urb[i]; |
1055 | struct sk_buff *skb = (struct sk_buff *) urb->context; | 1330 | struct sk_buff *skb = (struct sk_buff *) urb->context; |
1056 | /* Cancel the receive command */ | 1331 | /* Cancel the receive command */ |
@@ -1426,8 +1701,22 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1426 | spin_lock_init(&self->lock); | 1701 | spin_lock_init(&self->lock); |
1427 | init_timer(&self->rx_defer_timer); | 1702 | init_timer(&self->rx_defer_timer); |
1428 | 1703 | ||
1704 | self->capability = id->driver_info; | ||
1705 | self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ; | ||
1706 | |||
1429 | /* Create all of the needed urbs */ | 1707 | /* Create all of the needed urbs */ |
1430 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1708 | if (self->capability & IUC_STIR_4210) { |
1709 | self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS; | ||
1710 | self->header_length = USB_IRDA_SIGMATEL_HEADER; | ||
1711 | } else { | ||
1712 | self->max_rx_urb = IU_MAX_RX_URBS; | ||
1713 | self->header_length = USB_IRDA_HEADER; | ||
1714 | } | ||
1715 | |||
1716 | self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), | ||
1717 | GFP_KERNEL); | ||
1718 | |||
1719 | for (i = 0; i < self->max_rx_urb; i++) { | ||
1431 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); | 1720 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); |
1432 | if (!self->rx_urb[i]) { | 1721 | if (!self->rx_urb[i]) { |
1433 | goto err_out_1; | 1722 | goto err_out_1; |
@@ -1479,17 +1768,28 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1479 | goto err_out_3; | 1768 | goto err_out_3; |
1480 | } | 1769 | } |
1481 | 1770 | ||
1771 | self->usbdev = dev; | ||
1772 | |||
1482 | /* Find IrDA class descriptor */ | 1773 | /* Find IrDA class descriptor */ |
1483 | irda_desc = irda_usb_find_class_desc(intf); | 1774 | irda_desc = irda_usb_find_class_desc(intf); |
1484 | ret = -ENODEV; | 1775 | ret = -ENODEV; |
1485 | if (irda_desc == NULL) | 1776 | if (irda_desc == NULL) |
1486 | goto err_out_3; | 1777 | goto err_out_3; |
1487 | 1778 | ||
1779 | if (self->needspatch) { | ||
1780 | ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0), | ||
1781 | 0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500)); | ||
1782 | if (ret < 0) { | ||
1783 | IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret); | ||
1784 | goto err_out_3; | ||
1785 | } else { | ||
1786 | mdelay(10); | ||
1787 | } | ||
1788 | } | ||
1789 | |||
1488 | self->irda_desc = irda_desc; | 1790 | self->irda_desc = irda_desc; |
1489 | self->present = 1; | 1791 | self->present = 1; |
1490 | self->netopen = 0; | 1792 | self->netopen = 0; |
1491 | self->capability = id->driver_info; | ||
1492 | self->usbdev = dev; | ||
1493 | self->usbintf = intf; | 1793 | self->usbintf = intf; |
1494 | 1794 | ||
1495 | /* Allocate the buffer for speed changes */ | 1795 | /* Allocate the buffer for speed changes */ |
@@ -1508,6 +1808,28 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1508 | 1808 | ||
1509 | IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); | 1809 | IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); |
1510 | usb_set_intfdata(intf, self); | 1810 | usb_set_intfdata(intf, self); |
1811 | |||
1812 | if (self->needspatch) { | ||
1813 | /* Now we fetch and upload the firmware patch */ | ||
1814 | ret = stir421x_patch_device(self); | ||
1815 | self->needspatch = (ret < 0); | ||
1816 | if (ret < 0) { | ||
1817 | printk("patch_device failed\n"); | ||
1818 | goto err_out_4; | ||
1819 | } | ||
1820 | |||
1821 | /* replace IrDA class descriptor with what patched device is now reporting */ | ||
1822 | irda_desc = irda_usb_find_class_desc (self->usbintf); | ||
1823 | if (irda_desc == NULL) { | ||
1824 | ret = -ENODEV; | ||
1825 | goto err_out_4; | ||
1826 | } | ||
1827 | if (self->irda_desc) | ||
1828 | kfree (self->irda_desc); | ||
1829 | self->irda_desc = irda_desc; | ||
1830 | irda_usb_init_qos(self); | ||
1831 | } | ||
1832 | |||
1511 | return 0; | 1833 | return 0; |
1512 | 1834 | ||
1513 | err_out_4: | 1835 | err_out_4: |
@@ -1518,7 +1840,7 @@ err_out_3: | |||
1518 | err_out_2: | 1840 | err_out_2: |
1519 | usb_free_urb(self->tx_urb); | 1841 | usb_free_urb(self->tx_urb); |
1520 | err_out_1: | 1842 | err_out_1: |
1521 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1843 | for (i = 0; i < self->max_rx_urb; i++) { |
1522 | if (self->rx_urb[i]) | 1844 | if (self->rx_urb[i]) |
1523 | usb_free_urb(self->rx_urb[i]); | 1845 | usb_free_urb(self->rx_urb[i]); |
1524 | } | 1846 | } |
@@ -1571,7 +1893,7 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1571 | /*netif_device_detach(self->netdev);*/ | 1893 | /*netif_device_detach(self->netdev);*/ |
1572 | netif_stop_queue(self->netdev); | 1894 | netif_stop_queue(self->netdev); |
1573 | /* Stop all the receive URBs. Must be synchronous. */ | 1895 | /* Stop all the receive URBs. Must be synchronous. */ |
1574 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1896 | for (i = 0; i < self->max_rx_urb; i++) |
1575 | usb_kill_urb(self->rx_urb[i]); | 1897 | usb_kill_urb(self->rx_urb[i]); |
1576 | /* Cancel Tx and speed URB. | 1898 | /* Cancel Tx and speed URB. |
1577 | * Make sure it's synchronous to avoid races. */ | 1899 | * Make sure it's synchronous to avoid races. */ |
@@ -1586,8 +1908,9 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1586 | self->usbintf = NULL; | 1908 | self->usbintf = NULL; |
1587 | 1909 | ||
1588 | /* Clean up our urbs */ | 1910 | /* Clean up our urbs */ |
1589 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1911 | for (i = 0; i < self->max_rx_urb; i++) |
1590 | usb_free_urb(self->rx_urb[i]); | 1912 | usb_free_urb(self->rx_urb[i]); |
1913 | kfree(self->rx_urb); | ||
1591 | /* Clean up Tx and speed URB */ | 1914 | /* Clean up Tx and speed URB */ |
1592 | usb_free_urb(self->tx_urb); | 1915 | usb_free_urb(self->tx_urb); |
1593 | usb_free_urb(self->speed_urb); | 1916 | usb_free_urb(self->speed_urb); |
@@ -1648,6 +1971,6 @@ module_exit(usb_irda_cleanup); | |||
1648 | */ | 1971 | */ |
1649 | module_param(qos_mtt_bits, int, 0); | 1972 | module_param(qos_mtt_bits, int, 0); |
1650 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); | 1973 | MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time"); |
1651 | MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net> and Jean Tourrilhes <jt@hpl.hp.com>"); | 1974 | MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net>, Jean Tourrilhes <jt@hpl.hp.com> and Nick Fedchik <nick@fedchik.org.ua>"); |
1652 | MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); | 1975 | MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); |
1653 | MODULE_LICENSE("GPL"); | 1976 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index 4026af42dd47..d833db52cebf 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Filename: irda-usb.h | 3 | * Filename: irda-usb.h |
4 | * Version: 0.9b | 4 | * Version: 0.10 |
5 | * Description: IrDA-USB Driver | 5 | * Description: IrDA-USB Driver |
6 | * Status: Experimental | 6 | * Status: Experimental |
7 | * Author: Dag Brattli <dag@brattli.net> | 7 | * Author: Dag Brattli <dag@brattli.net> |
@@ -9,6 +9,9 @@ | |||
9 | * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> | 9 | * Copyright (C) 2001, Roman Weissgaerber <weissg@vienna.at> |
10 | * Copyright (C) 2000, Dag Brattli <dag@brattli.net> | 10 | * Copyright (C) 2000, Dag Brattli <dag@brattli.net> |
11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> | 11 | * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com> |
12 | * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com> | ||
13 | * Copyright (C) 2005, Milan Beno <beno@pobox.sk> | ||
14 | * Copyright (C) 2006, Nick FEdchik <nick@fedchik.org.ua> | ||
12 | * | 15 | * |
13 | * This program is free software; you can redistribute it and/or modify | 16 | * 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 | 17 | * it under the terms of the GNU General Public License as published by |
@@ -31,6 +34,9 @@ | |||
31 | #include <net/irda/irda.h> | 34 | #include <net/irda/irda.h> |
32 | #include <net/irda/irda_device.h> /* struct irlap_cb */ | 35 | #include <net/irda/irda_device.h> /* struct irlap_cb */ |
33 | 36 | ||
37 | #define PATCH_FILE_SIZE_MAX 65536 | ||
38 | #define PATCH_FILE_SIZE_MIN 80 | ||
39 | |||
34 | #define RX_COPY_THRESHOLD 200 | 40 | #define RX_COPY_THRESHOLD 200 |
35 | #define IRDA_USB_MAX_MTU 2051 | 41 | #define IRDA_USB_MAX_MTU 2051 |
36 | #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ | 42 | #define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ |
@@ -79,15 +85,16 @@ | |||
79 | /* Inbound header */ | 85 | /* Inbound header */ |
80 | #define MEDIA_BUSY 0x80 | 86 | #define MEDIA_BUSY 0x80 |
81 | 87 | ||
82 | #define SPEED_2400 0x01 | 88 | #define SPEED_2400 0x01 |
83 | #define SPEED_9600 0x02 | 89 | #define SPEED_9600 0x02 |
84 | #define SPEED_19200 0x03 | 90 | #define SPEED_19200 0x03 |
85 | #define SPEED_38400 0x04 | 91 | #define SPEED_38400 0x04 |
86 | #define SPEED_57600 0x05 | 92 | #define SPEED_57600 0x05 |
87 | #define SPEED_115200 0x06 | 93 | #define SPEED_115200 0x06 |
88 | #define SPEED_576000 0x07 | 94 | #define SPEED_576000 0x07 |
89 | #define SPEED_1152000 0x08 | 95 | #define SPEED_1152000 0x08 |
90 | #define SPEED_4000000 0x09 | 96 | #define SPEED_4000000 0x09 |
97 | #define SPEED_16000000 0x0a | ||
91 | 98 | ||
92 | /* Basic capabilities */ | 99 | /* Basic capabilities */ |
93 | #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ | 100 | #define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ |
@@ -100,11 +107,14 @@ | |||
100 | #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ | 107 | #define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ |
101 | #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ | 108 | #define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ |
102 | #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ | 109 | #define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ |
110 | #define IUC_STIR_4210 0x80 /* SigmaTel 4210/4220/4116 VFIR */ | ||
103 | 111 | ||
104 | /* USB class definitions */ | 112 | /* USB class definitions */ |
105 | #define USB_IRDA_HEADER 0x01 | 113 | #define USB_IRDA_HEADER 0x01 |
106 | #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ | 114 | #define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ |
107 | #define USB_DT_IRDA 0x21 | 115 | #define USB_DT_IRDA 0x21 |
116 | #define USB_IRDA_SIGMATEL_HEADER 0x03 | ||
117 | #define IU_SIGMATEL_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + USB_IRDA_SIGMATEL_HEADER) | ||
108 | 118 | ||
109 | struct irda_class_desc { | 119 | struct irda_class_desc { |
110 | __u8 bLength; | 120 | __u8 bLength; |
@@ -123,6 +133,7 @@ struct irda_class_desc { | |||
123 | * (6.2.5, USB-IrDA class spec 1.0) */ | 133 | * (6.2.5, USB-IrDA class spec 1.0) */ |
124 | 134 | ||
125 | #define IU_REQ_GET_CLASS_DESC 0x06 | 135 | #define IU_REQ_GET_CLASS_DESC 0x06 |
136 | #define STIR421X_MAX_PATCH_DOWNLOAD_SIZE 1023 | ||
126 | 137 | ||
127 | struct irda_usb_cb { | 138 | struct irda_usb_cb { |
128 | struct irda_class_desc *irda_desc; | 139 | struct irda_class_desc *irda_desc; |
@@ -136,7 +147,8 @@ struct irda_usb_cb { | |||
136 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ | 147 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ |
137 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ | 148 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ |
138 | 149 | ||
139 | struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ | 150 | __u8 max_rx_urb; |
151 | struct urb **rx_urb; /* URBs used to receive data frames */ | ||
140 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ | 152 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ |
141 | struct urb *tx_urb; /* URB used to send data frames */ | 153 | struct urb *tx_urb; /* URB used to send data frames */ |
142 | struct urb *speed_urb; /* URB used to send speed commands */ | 154 | struct urb *speed_urb; /* URB used to send speed commands */ |
@@ -157,6 +169,9 @@ struct irda_usb_cb { | |||
157 | __u32 speed; /* Current speed */ | 169 | __u32 speed; /* Current speed */ |
158 | __s32 new_speed; /* speed we need to set */ | 170 | __s32 new_speed; /* speed we need to set */ |
159 | 171 | ||
172 | __u8 header_length; /* USB-IrDA frame header size */ | ||
173 | int needspatch; /* device needs firmware patch */ | ||
174 | |||
160 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ | 175 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ |
161 | }; | 176 | }; |
162 | 177 | ||
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index ec94ecdb103d..bbcfc8ec35a1 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * Copyright (c) 2002 Daniele Peri | 11 | * Copyright (c) 2002 Daniele Peri |
12 | * All Rights Reserved. | 12 | * All Rights Reserved. |
13 | * Copyright (c) 2002 Jean Tourrilhes | 13 | * Copyright (c) 2002 Jean Tourrilhes |
14 | * Copyright (c) 2006 Linus Walleij | ||
14 | * | 15 | * |
15 | * | 16 | * |
16 | * Based on smc-ircc.c: | 17 | * Based on smc-ircc.c: |
@@ -61,6 +62,9 @@ | |||
61 | 62 | ||
62 | #include <linux/spinlock.h> | 63 | #include <linux/spinlock.h> |
63 | #include <linux/pm.h> | 64 | #include <linux/pm.h> |
65 | #ifdef CONFIG_PCI | ||
66 | #include <linux/pci.h> | ||
67 | #endif | ||
64 | 68 | ||
65 | #include <net/irda/wrapper.h> | 69 | #include <net/irda/wrapper.h> |
66 | #include <net/irda/irda.h> | 70 | #include <net/irda/irda.h> |
@@ -100,6 +104,22 @@ MODULE_PARM_DESC(ircc_transceiver, "Transceiver type"); | |||
100 | 104 | ||
101 | /* Types */ | 105 | /* Types */ |
102 | 106 | ||
107 | #ifdef CONFIG_PCI | ||
108 | struct smsc_ircc_subsystem_configuration { | ||
109 | unsigned short vendor; /* PCI vendor ID */ | ||
110 | unsigned short device; /* PCI vendor ID */ | ||
111 | unsigned short subvendor; /* PCI subsystem vendor ID */ | ||
112 | unsigned short subdevice; /* PCI sybsystem device ID */ | ||
113 | unsigned short sir_io; /* I/O port for SIR */ | ||
114 | unsigned short fir_io; /* I/O port for FIR */ | ||
115 | unsigned char fir_irq; /* FIR IRQ */ | ||
116 | unsigned char fir_dma; /* FIR DMA */ | ||
117 | unsigned short cfg_base; /* I/O port for chip configuration */ | ||
118 | int (*preconfigure)(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); /* Preconfig function */ | ||
119 | const char *name; /* name shown as info */ | ||
120 | }; | ||
121 | #endif | ||
122 | |||
103 | struct smsc_transceiver { | 123 | struct smsc_transceiver { |
104 | char *name; | 124 | char *name; |
105 | void (*set_for_speed)(int fir_base, u32 speed); | 125 | void (*set_for_speed)(int fir_base, u32 speed); |
@@ -202,6 +222,16 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor | |||
202 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); | 222 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
203 | static int __init smsc_superio_fdc(unsigned short cfg_base); | 223 | static int __init smsc_superio_fdc(unsigned short cfg_base); |
204 | static int __init smsc_superio_lpc(unsigned short cfg_base); | 224 | static int __init smsc_superio_lpc(unsigned short cfg_base); |
225 | #ifdef CONFIG_PCI | ||
226 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); | ||
227 | static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | ||
228 | static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | ||
229 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | ||
230 | unsigned short ircc_fir, | ||
231 | unsigned short ircc_sir, | ||
232 | unsigned char ircc_dma, | ||
233 | unsigned char ircc_irq); | ||
234 | #endif | ||
205 | 235 | ||
206 | /* Transceivers specific functions */ | 236 | /* Transceivers specific functions */ |
207 | 237 | ||
@@ -353,6 +383,13 @@ static int __init smsc_ircc_init(void) | |||
353 | return ret; | 383 | return ret; |
354 | } | 384 | } |
355 | 385 | ||
386 | #ifdef CONFIG_PCI | ||
387 | if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { | ||
388 | /* Ignore errors from preconfiguration */ | ||
389 | IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); | ||
390 | } | ||
391 | #endif | ||
392 | |||
356 | dev_count = 0; | 393 | dev_count = 0; |
357 | 394 | ||
358 | if (ircc_fir > 0 && ircc_sir > 0) { | 395 | if (ircc_fir > 0 && ircc_sir > 0) { |
@@ -2285,6 +2322,280 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
2285 | return ret; | 2322 | return ret; |
2286 | } | 2323 | } |
2287 | 2324 | ||
2325 | /* | ||
2326 | * Look for some specific subsystem setups that need | ||
2327 | * pre-configuration not properly done by the BIOS (especially laptops) | ||
2328 | * This code is based in part on smcinit.c, tosh1800-smcinit.c | ||
2329 | * and tosh2450-smcinit.c. The table lists the device entries | ||
2330 | * for ISA bridges with an LPC (Local Peripheral Configurator) | ||
2331 | * that are in turn used to configure the SMSC device with default | ||
2332 | * SIR and FIR I/O ports, DMA and IRQ. | ||
2333 | */ | ||
2334 | #ifdef CONFIG_PCI | ||
2335 | #define PCIID_VENDOR_INTEL 0x8086 | ||
2336 | #define PCIID_VENDOR_ALI 0x10b9 | ||
2337 | static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitdata = { | ||
2338 | { | ||
2339 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ | ||
2340 | .device = 0x24cc, | ||
2341 | .subvendor = 0x103c, | ||
2342 | .subdevice = 0x088c, | ||
2343 | .sir_io = 0x02f8, /* Quite certain these are the same for nc8000 as for nc6000 */ | ||
2344 | .fir_io = 0x0130, | ||
2345 | .fir_irq = 0x09, | ||
2346 | .fir_dma = 0x03, | ||
2347 | .cfg_base = 0x004e, | ||
2348 | .preconfigure = preconfigure_through_82801, | ||
2349 | .name = "HP nc8000", | ||
2350 | }, | ||
2351 | { | ||
2352 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ | ||
2353 | .device = 0x24cc, | ||
2354 | .subvendor = 0x103c, | ||
2355 | .subdevice = 0x0890, | ||
2356 | .sir_io = 0x02f8, | ||
2357 | .fir_io = 0x0130, | ||
2358 | .fir_irq = 0x09, | ||
2359 | .fir_dma = 0x03, | ||
2360 | .cfg_base = 0x004e, | ||
2361 | .preconfigure = preconfigure_through_82801, | ||
2362 | .name = "HP nc6000", | ||
2363 | }, | ||
2364 | { | ||
2365 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ | ||
2366 | .device = 0x24c0, | ||
2367 | .subvendor = 0x1179, | ||
2368 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
2369 | .sir_io = 0x03f8, | ||
2370 | .fir_io = 0x0130, | ||
2371 | .fir_irq = 0x07, | ||
2372 | .fir_dma = 0x01, | ||
2373 | .cfg_base = 0x002e, | ||
2374 | .preconfigure = preconfigure_through_82801, | ||
2375 | .name = "Toshiba Satellite 2450", | ||
2376 | }, | ||
2377 | { | ||
2378 | .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ | ||
2379 | .device = 0x248c, /* Some use 24cc? */ | ||
2380 | .subvendor = 0x1179, | ||
2381 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
2382 | .sir_io = 0x03f8, | ||
2383 | .fir_io = 0x0130, | ||
2384 | .fir_irq = 0x03, | ||
2385 | .fir_dma = 0x03, | ||
2386 | .cfg_base = 0x002e, | ||
2387 | .preconfigure = preconfigure_through_82801, | ||
2388 | .name = "Toshiba Satellite 5100/5200, Tecra 9100", | ||
2389 | }, | ||
2390 | { | ||
2391 | .vendor = PCIID_VENDOR_ALI, /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ | ||
2392 | .device = 0x1533, | ||
2393 | .subvendor = 0x1179, | ||
2394 | .subdevice = 0xffff, /* 0xffff is "any", Not sure, 0x0001 or 0x0002 */ | ||
2395 | .sir_io = 0x02e8, | ||
2396 | .fir_io = 0x02f8, | ||
2397 | .fir_irq = 0x07, | ||
2398 | .fir_dma = 0x03, | ||
2399 | .cfg_base = 0x002e, | ||
2400 | .preconfigure = preconfigure_through_ali, | ||
2401 | .name = "Toshiba Satellite 1800", | ||
2402 | }, | ||
2403 | { } // Terminator | ||
2404 | }; | ||
2405 | |||
2406 | |||
2407 | /* | ||
2408 | * This sets up the basic SMSC parameters (FIR port, SIR port, FIR DMA, FIR IRQ) | ||
2409 | * through the chip configuration port. | ||
2410 | */ | ||
2411 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf) | ||
2412 | { | ||
2413 | unsigned short iobase = conf->cfg_base; | ||
2414 | unsigned char tmpbyte; | ||
2415 | |||
2416 | outb(LPC47N227_CFGACCESSKEY, iobase); // enter configuration state | ||
2417 | outb(SMSCSIOFLAT_DEVICEID_REG, iobase); // set for device ID | ||
2418 | tmpbyte = inb(iobase +1); // Read device ID | ||
2419 | IRDA_DEBUG(0, "Detected Chip id: 0x%02x, setting up registers...\n",tmpbyte); | ||
2420 | |||
2421 | /* Disable UART1 and set up SIR I/O port */ | ||
2422 | outb(0x24, iobase); // select CR24 - UART1 base addr | ||
2423 | outb(0x00, iobase + 1); // disable UART1 | ||
2424 | outb(SMSCSIOFLAT_UART2BASEADDR_REG, iobase); // select CR25 - UART2 base addr | ||
2425 | outb( (conf->sir_io >> 2), iobase + 1); // bits 2-9 of 0x3f8 | ||
2426 | tmpbyte = inb(iobase + 1); | ||
2427 | if (tmpbyte != (conf->sir_io >> 2) ) { | ||
2428 | IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); | ||
2429 | return -ENXIO; | ||
2430 | } | ||
2431 | |||
2432 | /* Set up FIR IRQ channel for UART2 */ | ||
2433 | outb(SMSCSIOFLAT_UARTIRQSELECT_REG, iobase); // select CR28 - UART1,2 IRQ select | ||
2434 | tmpbyte = inb(iobase + 1); | ||
2435 | tmpbyte &= SMSCSIOFLAT_UART1IRQSELECT_MASK; // Do not touch the UART1 portion | ||
2436 | tmpbyte |= (conf->fir_irq & SMSCSIOFLAT_UART2IRQSELECT_MASK); | ||
2437 | outb(tmpbyte, iobase + 1); | ||
2438 | tmpbyte = inb(iobase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; | ||
2439 | if (tmpbyte != conf->fir_irq) { | ||
2440 | IRDA_WARNING("ERROR: could not configure FIR IRQ channel.\n"); | ||
2441 | return -ENXIO; | ||
2442 | } | ||
2443 | |||
2444 | /* Set up FIR I/O port */ | ||
2445 | outb(SMSCSIOFLAT_FIRBASEADDR_REG, iobase); // CR2B - SCE (FIR) base addr | ||
2446 | outb((conf->fir_io >> 3), iobase + 1); | ||
2447 | tmpbyte = inb(iobase + 1); | ||
2448 | if (tmpbyte != (conf->fir_io >> 3) ) { | ||
2449 | IRDA_WARNING("ERROR: could not configure FIR I/O port.\n"); | ||
2450 | return -ENXIO; | ||
2451 | } | ||
2452 | |||
2453 | /* Set up FIR DMA channel */ | ||
2454 | outb(SMSCSIOFLAT_FIRDMASELECT_REG, iobase); // CR2C - SCE (FIR) DMA select | ||
2455 | outb((conf->fir_dma & LPC47N227_FIRDMASELECT_MASK), iobase + 1); // DMA | ||
2456 | tmpbyte = inb(iobase + 1) & LPC47N227_FIRDMASELECT_MASK; | ||
2457 | if (tmpbyte != (conf->fir_dma & LPC47N227_FIRDMASELECT_MASK)) { | ||
2458 | IRDA_WARNING("ERROR: could not configure FIR DMA channel.\n"); | ||
2459 | return -ENXIO; | ||
2460 | } | ||
2461 | |||
2462 | outb(SMSCSIOFLAT_UARTMODE0C_REG, iobase); // CR0C - UART mode | ||
2463 | tmpbyte = inb(iobase + 1); | ||
2464 | tmpbyte &= ~SMSCSIOFLAT_UART2MODE_MASK | SMSCSIOFLAT_UART2MODE_VAL_IRDA; | ||
2465 | outb(tmpbyte, iobase + 1); // enable IrDA (HPSIR) mode, high speed | ||
2466 | |||
2467 | outb(LPC47N227_APMBOOTDRIVE_REG, iobase); // CR07 - Auto Pwr Mgt/boot drive sel | ||
2468 | tmpbyte = inb(iobase + 1); | ||
2469 | outb(tmpbyte | LPC47N227_UART2AUTOPWRDOWN_MASK, iobase + 1); // enable UART2 autopower down | ||
2470 | |||
2471 | /* This one was not part of tosh1800 */ | ||
2472 | outb(0x0a, iobase); // CR0a - ecp fifo / ir mux | ||
2473 | tmpbyte = inb(iobase + 1); | ||
2474 | outb(tmpbyte | 0x40, iobase + 1); // send active device to ir port | ||
2475 | |||
2476 | outb(LPC47N227_UART12POWER_REG, iobase); // CR02 - UART 1,2 power | ||
2477 | tmpbyte = inb(iobase + 1); | ||
2478 | outb(tmpbyte | LPC47N227_UART2POWERDOWN_MASK, iobase + 1); // UART2 power up mode, UART1 power down | ||
2479 | |||
2480 | outb(LPC47N227_FDCPOWERVALIDCONF_REG, iobase); // CR00 - FDC Power/valid config cycle | ||
2481 | tmpbyte = inb(iobase + 1); | ||
2482 | outb(tmpbyte | LPC47N227_VALID_MASK, iobase + 1); // valid config cycle done | ||
2483 | |||
2484 | outb(LPC47N227_CFGEXITKEY, iobase); // Exit configuration | ||
2485 | |||
2486 | return 0; | ||
2487 | } | ||
2488 | |||
2489 | /* 82801CAM registers */ | ||
2490 | #define VID 0x00 | ||
2491 | #define DID 0x02 | ||
2492 | #define PIRQA_ROUT 0x60 | ||
2493 | #define PCI_DMA_C 0x90 | ||
2494 | #define COM_DEC 0xe0 | ||
2495 | #define LPC_EN 0xe6 | ||
2496 | #define GEN2_DEC 0xec | ||
2497 | /* | ||
2498 | * Sets up the I/O range using the 82801CAM ISA bridge, 82801DBM LPC bridge or | ||
2499 | * Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. They all work the same way! | ||
2500 | */ | ||
2501 | static int __init preconfigure_through_82801(struct pci_dev *dev, | ||
2502 | struct smsc_ircc_subsystem_configuration *conf) | ||
2503 | { | ||
2504 | unsigned short tmpword; | ||
2505 | int ret; | ||
2506 | |||
2507 | IRDA_MESSAGE("Setting up the SMSC device via the 82801 controller.\n"); | ||
2508 | pci_write_config_byte(dev, COM_DEC, 0x10); | ||
2509 | |||
2510 | /* Enable LPC */ | ||
2511 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | ||
2512 | tmpword &= 0xfffd; /* mask bit 1 */ | ||
2513 | tmpword |= 0x0001; /* set bit 0 : COMA addr range enable */ | ||
2514 | pci_write_config_word(dev, LPC_EN, tmpword); | ||
2515 | |||
2516 | /* Setup DMA */ | ||
2517 | pci_write_config_word(dev, PCI_DMA_C, 0xc0c0); /* LPC I/F DMA on, channel 3 -- rtm (?? PCI DMA ?) */ | ||
2518 | pci_write_config_word(dev, GEN2_DEC, 0x131); /* LPC I/F 2nd decode range */ | ||
2519 | |||
2520 | /* Pre-configure chip */ | ||
2521 | ret = preconfigure_smsc_chip(conf); | ||
2522 | |||
2523 | /* Disable LPC */ | ||
2524 | pci_read_config_word(dev, LPC_EN, &tmpword); /* LPC_EN register */ | ||
2525 | tmpword &= 0xfffc; /* mask bit 1 and bit 0, COMA addr range disable */ | ||
2526 | pci_write_config_word(dev, LPC_EN, tmpword); | ||
2527 | return ret; | ||
2528 | } | ||
2529 | |||
2530 | static int __init preconfigure_through_ali(struct pci_dev *dev, | ||
2531 | struct smsc_ircc_subsystem_configuration *conf) | ||
2532 | { | ||
2533 | /* TODO: put in ALi 1533 configuration here. */ | ||
2534 | IRDA_MESSAGE("SORRY: %s has an unsupported bridge controller (ALi): not pre-configured.\n", conf->name); | ||
2535 | return -ENODEV; | ||
2536 | } | ||
2537 | |||
2538 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | ||
2539 | unsigned short ircc_fir, | ||
2540 | unsigned short ircc_sir, | ||
2541 | unsigned char ircc_dma, | ||
2542 | unsigned char ircc_irq) | ||
2543 | { | ||
2544 | struct pci_dev *dev = NULL; | ||
2545 | unsigned short ss_vendor = 0x0000; | ||
2546 | unsigned short ss_device = 0x0000; | ||
2547 | int ret = 0; | ||
2548 | |||
2549 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
2550 | |||
2551 | while (dev != NULL) { | ||
2552 | struct smsc_ircc_subsystem_configuration *conf; | ||
2553 | |||
2554 | /* | ||
2555 | * Cache the subsystem vendor/device: some manufacturers fail to set | ||
2556 | * this for all components, so we save it in case there is just | ||
2557 | * 0x0000 0x0000 on the device we want to check. | ||
2558 | */ | ||
2559 | if (dev->subsystem_vendor != 0x0000U) { | ||
2560 | ss_vendor = dev->subsystem_vendor; | ||
2561 | ss_device = dev->subsystem_device; | ||
2562 | } | ||
2563 | conf = subsystem_configurations; | ||
2564 | for( ; conf->subvendor; conf++) { | ||
2565 | if(conf->vendor == dev->vendor && | ||
2566 | conf->device == dev->device && | ||
2567 | conf->subvendor == ss_vendor && /* Sometimes these are cached values */ | ||
2568 | (conf->subdevice == ss_device || conf->subdevice == 0xffff)) { | ||
2569 | struct smsc_ircc_subsystem_configuration tmpconf; | ||
2570 | |||
2571 | memcpy(&tmpconf, conf, sizeof(struct smsc_ircc_subsystem_configuration)); | ||
2572 | |||
2573 | /* Override the default values with anything passed in as parameter */ | ||
2574 | if (ircc_cfg != 0) | ||
2575 | tmpconf.cfg_base = ircc_cfg; | ||
2576 | if (ircc_fir != 0) | ||
2577 | tmpconf.fir_io = ircc_fir; | ||
2578 | if (ircc_sir != 0) | ||
2579 | tmpconf.sir_io = ircc_sir; | ||
2580 | if (ircc_dma != 0xff) | ||
2581 | tmpconf.fir_dma = ircc_dma; | ||
2582 | if (ircc_irq != 0xff) | ||
2583 | tmpconf.fir_irq = ircc_irq; | ||
2584 | |||
2585 | IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); | ||
2586 | if (conf->preconfigure) | ||
2587 | ret = conf->preconfigure(dev, &tmpconf); | ||
2588 | else | ||
2589 | ret = -ENODEV; | ||
2590 | } | ||
2591 | } | ||
2592 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
2593 | } | ||
2594 | |||
2595 | return ret; | ||
2596 | } | ||
2597 | #endif // CONFIG_PCI | ||
2598 | |||
2288 | /************************************************ | 2599 | /************************************************ |
2289 | * | 2600 | * |
2290 | * Transceivers specific functions | 2601 | * Transceivers specific functions |
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 75b35ad760de..66e74f740261 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -87,6 +87,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) | |||
87 | } | 87 | } |
88 | 88 | ||
89 | static struct console netconsole = { | 89 | static struct console netconsole = { |
90 | .name = "netcon", | ||
90 | .flags = CON_ENABLED | CON_PRINTBUFFER, | 91 | .flags = CON_ENABLED | CON_PRINTBUFFER, |
91 | .write = write_msg | 92 | .write = write_msg |
92 | }; | 93 | }; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0b5358072172..73e271e59c6a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | |||
497 | unsigned long flags; | 497 | unsigned long flags; |
498 | 498 | ||
499 | spin_lock_irqsave(&tp->indirect_lock, flags); | 499 | spin_lock_irqsave(&tp->indirect_lock, flags); |
500 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 500 | if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { |
501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
502 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
502 | 503 | ||
503 | /* Always leave this as zero. */ | 504 | /* Always leave this as zero. */ |
504 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 505 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
505 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 506 | } else { |
506 | } | 507 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); |
508 | tw32_f(TG3PCI_MEM_WIN_DATA, val); | ||
507 | 509 | ||
508 | static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) | 510 | /* Always leave this as zero. */ |
509 | { | 511 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
510 | /* If no workaround is needed, write to mem space directly */ | 512 | } |
511 | if (tp->write32 != tg3_write_indirect_reg32) | 513 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
512 | tw32(NIC_SRAM_WIN_BASE + off, val); | ||
513 | else | ||
514 | tg3_write_mem(tp, off, val); | ||
515 | } | 514 | } |
516 | 515 | ||
517 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 516 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) |
@@ -519,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | |||
519 | unsigned long flags; | 518 | unsigned long flags; |
520 | 519 | ||
521 | spin_lock_irqsave(&tp->indirect_lock, flags); | 520 | spin_lock_irqsave(&tp->indirect_lock, flags); |
522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 521 | if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { |
523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
524 | 524 | ||
525 | /* Always leave this as zero. */ | 525 | /* Always leave this as zero. */ |
526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
527 | } else { | ||
528 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); | ||
529 | *val = tr32(TG3PCI_MEM_WIN_DATA); | ||
530 | |||
531 | /* Always leave this as zero. */ | ||
532 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); | ||
533 | } | ||
527 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 534 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
528 | } | 535 | } |
529 | 536 | ||
@@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1367 | } | 1374 | } |
1368 | } | 1375 | } |
1369 | 1376 | ||
1377 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
1378 | |||
1370 | /* Finally, set the new power state. */ | 1379 | /* Finally, set the new power state. */ |
1371 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); | 1380 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); |
1372 | udelay(100); /* Delay after power state change */ | 1381 | udelay(100); /* Delay after power state change */ |
1373 | 1382 | ||
1374 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
1375 | |||
1376 | return 0; | 1383 | return 0; |
1377 | } | 1384 | } |
1378 | 1385 | ||
@@ -5828,10 +5835,14 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5828 | GRC_MODE_NO_TX_PHDR_CSUM | | 5835 | GRC_MODE_NO_TX_PHDR_CSUM | |
5829 | GRC_MODE_NO_RX_PHDR_CSUM); | 5836 | GRC_MODE_NO_RX_PHDR_CSUM); |
5830 | tp->grc_mode |= GRC_MODE_HOST_SENDBDS; | 5837 | tp->grc_mode |= GRC_MODE_HOST_SENDBDS; |
5831 | if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM) | 5838 | |
5832 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | 5839 | /* Pseudo-header checksum is done by hardware logic and not |
5833 | if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM) | 5840 | * the offload processers, so make the chip do the pseudo- |
5834 | tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM; | 5841 | * header checksums on receive. For transmit it is more |
5842 | * convenient to do the pseudo-header checksum in software | ||
5843 | * as Linux does that on transmit for us in all cases. | ||
5844 | */ | ||
5845 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | ||
5835 | 5846 | ||
5836 | tw32(GRC_MODE, | 5847 | tw32(GRC_MODE, |
5837 | tp->grc_mode | | 5848 | tp->grc_mode | |
@@ -6535,11 +6546,11 @@ static void tg3_timer(unsigned long __opaque) | |||
6535 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { | 6546 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { |
6536 | u32 val; | 6547 | u32 val; |
6537 | 6548 | ||
6538 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, | 6549 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, |
6539 | FWCMD_NICDRV_ALIVE2); | 6550 | FWCMD_NICDRV_ALIVE2); |
6540 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); | 6551 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); |
6541 | /* 5 seconds timeout */ | 6552 | /* 5 seconds timeout */ |
6542 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); | 6553 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); |
6543 | val = tr32(GRC_RX_CPU_EVENT); | 6554 | val = tr32(GRC_RX_CPU_EVENT); |
6544 | val |= (1 << 14); | 6555 | val |= (1 << 14); |
6545 | tw32(GRC_RX_CPU_EVENT, val); | 6556 | tw32(GRC_RX_CPU_EVENT, val); |
@@ -8034,9 +8045,13 @@ static int tg3_test_nvram(struct tg3 *tp) | |||
8034 | for (i = 0; i < size; i++) | 8045 | for (i = 0; i < size; i++) |
8035 | csum8 += buf8[i]; | 8046 | csum8 += buf8[i]; |
8036 | 8047 | ||
8037 | if (csum8 == 0) | 8048 | if (csum8 == 0) { |
8038 | return 0; | 8049 | err = 0; |
8039 | return -EIO; | 8050 | goto out; |
8051 | } | ||
8052 | |||
8053 | err = -EIO; | ||
8054 | goto out; | ||
8040 | } | 8055 | } |
8041 | 8056 | ||
8042 | /* Bootstrap checksum at offset 0x10 */ | 8057 | /* Bootstrap checksum at offset 0x10 */ |
@@ -9531,8 +9546,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
9531 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; | 9546 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; |
9532 | 9547 | ||
9533 | /* Do not even try poking around in here on Sun parts. */ | 9548 | /* Do not even try poking around in here on Sun parts. */ |
9534 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) | 9549 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { |
9550 | /* All SUN chips are built-in LOMs. */ | ||
9551 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; | ||
9535 | return; | 9552 | return; |
9553 | } | ||
9536 | 9554 | ||
9537 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); | 9555 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); |
9538 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { | 9556 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { |
@@ -9630,9 +9648,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
9630 | tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) | 9648 | tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) |
9631 | tp->led_ctrl = LED_CTRL_MODE_PHY_2; | 9649 | tp->led_ctrl = LED_CTRL_MODE_PHY_2; |
9632 | 9650 | ||
9633 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && | 9651 | if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) |
9634 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) && | ||
9635 | (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) | ||
9636 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; | 9652 | tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; |
9637 | 9653 | ||
9638 | if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { | 9654 | if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { |
@@ -10257,6 +10273,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10257 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); | 10273 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); |
10258 | } | 10274 | } |
10259 | 10275 | ||
10276 | if (tp->write32 == tg3_write_indirect_reg32 || | ||
10277 | ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && | ||
10278 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | ||
10279 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) || | ||
10280 | (tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | ||
10281 | tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; | ||
10282 | |||
10260 | /* Get eeprom hw config before calling tg3_set_power_state(). | 10283 | /* Get eeprom hw config before calling tg3_set_power_state(). |
10261 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be | 10284 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be |
10262 | * determined before calling tg3_set_power_state() so that | 10285 | * determined before calling tg3_set_power_state() so that |
@@ -10299,15 +10322,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10299 | if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) | 10322 | if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) |
10300 | tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; | 10323 | tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; |
10301 | 10324 | ||
10302 | /* Pseudo-header checksum is done by hardware logic and not | ||
10303 | * the offload processers, so make the chip do the pseudo- | ||
10304 | * header checksums on receive. For transmit it is more | ||
10305 | * convenient to do the pseudo-header checksum in software | ||
10306 | * as Linux does that on transmit for us in all cases. | ||
10307 | */ | ||
10308 | tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM; | ||
10309 | tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM; | ||
10310 | |||
10311 | /* Derive initial jumbo mode from MTU assigned in | 10325 | /* Derive initial jumbo mode from MTU assigned in |
10312 | * ether_setup() via the alloc_etherdev() call | 10326 | * ether_setup() via the alloc_etherdev() call |
10313 | */ | 10327 | */ |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index c43cc3264202..8c8b987d1250 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2171,8 +2171,7 @@ struct tg3 { | |||
2171 | #define TG3_FLAG_PCIX_MODE 0x00020000 | 2171 | #define TG3_FLAG_PCIX_MODE 0x00020000 |
2172 | #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 | 2172 | #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 |
2173 | #define TG3_FLAG_PCI_32BIT 0x00080000 | 2173 | #define TG3_FLAG_PCI_32BIT 0x00080000 |
2174 | #define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000 | 2174 | #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 |
2175 | #define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000 | ||
2176 | #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 | 2175 | #define TG3_FLAG_SERDES_WOL_CAP 0x00400000 |
2177 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 | 2176 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 |
2178 | #define TG3_FLAG_10_100_ONLY 0x01000000 | 2177 | #define TG3_FLAG_10_100_ONLY 0x01000000 |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index d121644646b9..98b83a85c60e 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -100,8 +100,6 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
100 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 100 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
101 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | 101 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, |
102 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 102 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
103 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | ||
104 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | ||
105 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, | 103 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, |
106 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, | 104 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, |
107 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, | 105 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 929dd8090578..65d090dbef46 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -147,6 +147,16 @@ config RTC_DRV_SA1100 | |||
147 | To compile this driver as a module, choose M here: the | 147 | To compile this driver as a module, choose M here: the |
148 | module will be called rtc-sa1100. | 148 | module will be called rtc-sa1100. |
149 | 149 | ||
150 | config RTC_DRV_VR41XX | ||
151 | tristate "NEC VR41XX" | ||
152 | depends on RTC_CLASS && CPU_VR41XX | ||
153 | help | ||
154 | If you say Y here you will get access to the real time clock | ||
155 | built into your NEC VR41XX CPU. | ||
156 | |||
157 | To compile this driver as a module, choose M here: the | ||
158 | module will be called rtc-vr41xx. | ||
159 | |||
150 | config RTC_DRV_TEST | 160 | config RTC_DRV_TEST |
151 | tristate "Test driver/device" | 161 | tristate "Test driver/device" |
152 | depends on RTC_CLASS | 162 | depends on RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 8d4c7fe88d58..a9ca0f171686 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -19,3 +19,4 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | |||
19 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 19 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
20 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 20 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
21 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 21 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
22 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | ||
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 8533936d50d8..413c7d54ea10 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -96,6 +96,8 @@ exit_idr: | |||
96 | idr_remove(&rtc_idr, id); | 96 | idr_remove(&rtc_idr, id); |
97 | 97 | ||
98 | exit: | 98 | exit: |
99 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", | ||
100 | name, err); | ||
99 | return ERR_PTR(err); | 101 | return ERR_PTR(err); |
100 | } | 102 | } |
101 | EXPORT_SYMBOL_GPL(rtc_device_register); | 103 | EXPORT_SYMBOL_GPL(rtc_device_register); |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 358695a416f3..9be81fd4737c 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * An rtc/i2c driver for the Dallas DS1672 | 2 | * An rtc/i2c driver for the Dallas DS1672 |
3 | * Copyright 2005 Alessandro Zummo | 3 | * Copyright 2005-06 Tower Technologies |
4 | * | ||
5 | * Author: Alessandro Zummo <a.zummo@towertech.it> | ||
4 | * | 6 | * |
5 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -11,7 +13,7 @@ | |||
11 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
12 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
13 | 15 | ||
14 | #define DRV_VERSION "0.2" | 16 | #define DRV_VERSION "0.3" |
15 | 17 | ||
16 | /* Addresses to scan: none. This chip cannot be detected. */ | 18 | /* Addresses to scan: none. This chip cannot be detected. */ |
17 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | 19 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
@@ -25,6 +27,7 @@ I2C_CLIENT_INSMOD; | |||
25 | #define DS1672_REG_CONTROL 4 | 27 | #define DS1672_REG_CONTROL 4 |
26 | #define DS1672_REG_TRICKLE 5 | 28 | #define DS1672_REG_TRICKLE 5 |
27 | 29 | ||
30 | #define DS1672_REG_CONTROL_EOSC 0x80 | ||
28 | 31 | ||
29 | /* Prototypes */ | 32 | /* Prototypes */ |
30 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); | 33 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind); |
@@ -53,8 +56,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
53 | 56 | ||
54 | dev_dbg(&client->dev, | 57 | dev_dbg(&client->dev, |
55 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" | 58 | "%s: raw read data - counters=%02x,%02x,%02x,%02x\n" |
56 | __FUNCTION__, | 59 | __FUNCTION__, buf[0], buf[1], buf[2], buf[3]); |
57 | buf[0], buf[1], buf[2], buf[3]); | ||
58 | 60 | ||
59 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | 61 | time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; |
60 | 62 | ||
@@ -62,8 +64,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
62 | 64 | ||
63 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 65 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
64 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 66 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
65 | __FUNCTION__, | 67 | __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, |
66 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
67 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 68 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
68 | 69 | ||
69 | return 0; | 70 | return 0; |
@@ -72,16 +73,17 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
72 | static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) | 73 | static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) |
73 | { | 74 | { |
74 | int xfer; | 75 | int xfer; |
75 | unsigned char buf[5]; | 76 | unsigned char buf[6]; |
76 | 77 | ||
77 | buf[0] = DS1672_REG_CNT_BASE; | 78 | buf[0] = DS1672_REG_CNT_BASE; |
78 | buf[1] = secs & 0x000000FF; | 79 | buf[1] = secs & 0x000000FF; |
79 | buf[2] = (secs & 0x0000FF00) >> 8; | 80 | buf[2] = (secs & 0x0000FF00) >> 8; |
80 | buf[3] = (secs & 0x00FF0000) >> 16; | 81 | buf[3] = (secs & 0x00FF0000) >> 16; |
81 | buf[4] = (secs & 0xFF000000) >> 24; | 82 | buf[4] = (secs & 0xFF000000) >> 24; |
83 | buf[5] = 0; /* set control reg to enable counting */ | ||
82 | 84 | ||
83 | xfer = i2c_master_send(client, buf, 5); | 85 | xfer = i2c_master_send(client, buf, 6); |
84 | if (xfer != 5) { | 86 | if (xfer != 6) { |
85 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); | 87 | dev_err(&client->dev, "%s: send: %d\n", __FUNCTION__, xfer); |
86 | return -EIO; | 88 | return -EIO; |
87 | } | 89 | } |
@@ -120,6 +122,40 @@ static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) | |||
120 | return ds1672_set_mmss(to_i2c_client(dev), secs); | 122 | return ds1672_set_mmss(to_i2c_client(dev), secs); |
121 | } | 123 | } |
122 | 124 | ||
125 | static int ds1672_get_control(struct i2c_client *client, u8 *status) | ||
126 | { | ||
127 | unsigned char addr = DS1672_REG_CONTROL; | ||
128 | |||
129 | struct i2c_msg msgs[] = { | ||
130 | { client->addr, 0, 1, &addr }, /* setup read ptr */ | ||
131 | { client->addr, I2C_M_RD, 1, status }, /* read control */ | ||
132 | }; | ||
133 | |||
134 | /* read control register */ | ||
135 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | ||
136 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* following are the sysfs callback functions */ | ||
144 | static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf) | ||
145 | { | ||
146 | struct i2c_client *client = to_i2c_client(dev); | ||
147 | u8 control; | ||
148 | int err; | ||
149 | |||
150 | err = ds1672_get_control(client, &control); | ||
151 | if (err) | ||
152 | return err; | ||
153 | |||
154 | return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) | ||
155 | ? "disabled" : "enabled"); | ||
156 | } | ||
157 | static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); | ||
158 | |||
123 | static struct rtc_class_ops ds1672_rtc_ops = { | 159 | static struct rtc_class_ops ds1672_rtc_ops = { |
124 | .read_time = ds1672_rtc_read_time, | 160 | .read_time = ds1672_rtc_read_time, |
125 | .set_time = ds1672_rtc_set_time, | 161 | .set_time = ds1672_rtc_set_time, |
@@ -128,7 +164,6 @@ static struct rtc_class_ops ds1672_rtc_ops = { | |||
128 | 164 | ||
129 | static int ds1672_attach(struct i2c_adapter *adapter) | 165 | static int ds1672_attach(struct i2c_adapter *adapter) |
130 | { | 166 | { |
131 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
132 | return i2c_probe(adapter, &addr_data, ds1672_probe); | 167 | return i2c_probe(adapter, &addr_data, ds1672_probe); |
133 | } | 168 | } |
134 | 169 | ||
@@ -137,8 +172,6 @@ static int ds1672_detach(struct i2c_client *client) | |||
137 | int err; | 172 | int err; |
138 | struct rtc_device *rtc = i2c_get_clientdata(client); | 173 | struct rtc_device *rtc = i2c_get_clientdata(client); |
139 | 174 | ||
140 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
141 | |||
142 | if (rtc) | 175 | if (rtc) |
143 | rtc_device_unregister(rtc); | 176 | rtc_device_unregister(rtc); |
144 | 177 | ||
@@ -162,6 +195,7 @@ static struct i2c_driver ds1672_driver = { | |||
162 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | 195 | static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) |
163 | { | 196 | { |
164 | int err = 0; | 197 | int err = 0; |
198 | u8 control; | ||
165 | struct i2c_client *client; | 199 | struct i2c_client *client; |
166 | struct rtc_device *rtc; | 200 | struct rtc_device *rtc; |
167 | 201 | ||
@@ -195,13 +229,23 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind) | |||
195 | 229 | ||
196 | if (IS_ERR(rtc)) { | 230 | if (IS_ERR(rtc)) { |
197 | err = PTR_ERR(rtc); | 231 | err = PTR_ERR(rtc); |
198 | dev_err(&client->dev, | ||
199 | "unable to register the class device\n"); | ||
200 | goto exit_detach; | 232 | goto exit_detach; |
201 | } | 233 | } |
202 | 234 | ||
203 | i2c_set_clientdata(client, rtc); | 235 | i2c_set_clientdata(client, rtc); |
204 | 236 | ||
237 | /* read control register */ | ||
238 | err = ds1672_get_control(client, &control); | ||
239 | if (err) | ||
240 | goto exit_detach; | ||
241 | |||
242 | if (control & DS1672_REG_CONTROL_EOSC) | ||
243 | dev_warn(&client->dev, "Oscillator not enabled. " | ||
244 | "Set time to enable.\n"); | ||
245 | |||
246 | /* Register sysfs hooks */ | ||
247 | device_create_file(&client->dev, &dev_attr_control); | ||
248 | |||
205 | return 0; | 249 | return 0; |
206 | 250 | ||
207 | exit_detach: | 251 | exit_detach: |
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 0dd80ea686a9..e1a1169e4664 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -67,7 +67,6 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | |||
67 | 67 | ||
68 | ep93xx_get_swcomp(dev, &preload, &delete); | 68 | ep93xx_get_swcomp(dev, &preload, &delete); |
69 | 69 | ||
70 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
71 | seq_printf(seq, "preload\t\t: %d\n", preload); | 70 | seq_printf(seq, "preload\t\t: %d\n", preload); |
72 | seq_printf(seq, "delete\t\t: %d\n", delete); | 71 | seq_printf(seq, "delete\t\t: %d\n", delete); |
73 | 72 | ||
@@ -110,7 +109,6 @@ static int __devinit ep93xx_rtc_probe(struct platform_device *dev) | |||
110 | &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); | 109 | &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); |
111 | 110 | ||
112 | if (IS_ERR(rtc)) { | 111 | if (IS_ERR(rtc)) { |
113 | dev_err(&dev->dev, "unable to register\n"); | ||
114 | return PTR_ERR(rtc); | 112 | return PTR_ERR(rtc); |
115 | } | 113 | } |
116 | 114 | ||
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index db445c872b1b..f6e7ee04f3dc 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define M48T86_REG_SECALRM 0x01 | 23 | #define M48T86_REG_SECALRM 0x01 |
24 | #define M48T86_REG_MIN 0x02 | 24 | #define M48T86_REG_MIN 0x02 |
25 | #define M48T86_REG_MINALRM 0x03 | 25 | #define M48T86_REG_MINALRM 0x03 |
26 | #define M48T86_REG_HOUR 0x04 | 26 | #define M48T86_REG_HOUR 0x04 |
27 | #define M48T86_REG_HOURALRM 0x05 | 27 | #define M48T86_REG_HOURALRM 0x05 |
28 | #define M48T86_REG_DOW 0x06 /* 1 = sunday */ | 28 | #define M48T86_REG_DOW 0x06 /* 1 = sunday */ |
29 | #define M48T86_REG_DOM 0x07 | 29 | #define M48T86_REG_DOM 0x07 |
@@ -127,9 +127,6 @@ static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq) | |||
127 | 127 | ||
128 | reg = ops->readb(M48T86_REG_B); | 128 | reg = ops->readb(M48T86_REG_B); |
129 | 129 | ||
130 | seq_printf(seq, "24hr\t\t: %s\n", | ||
131 | (reg & M48T86_REG_B_H24) ? "yes" : "no"); | ||
132 | |||
133 | seq_printf(seq, "mode\t\t: %s\n", | 130 | seq_printf(seq, "mode\t\t: %s\n", |
134 | (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); | 131 | (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); |
135 | 132 | ||
@@ -154,10 +151,8 @@ static int __devinit m48t86_rtc_probe(struct platform_device *dev) | |||
154 | struct rtc_device *rtc = rtc_device_register("m48t86", | 151 | struct rtc_device *rtc = rtc_device_register("m48t86", |
155 | &dev->dev, &m48t86_rtc_ops, THIS_MODULE); | 152 | &dev->dev, &m48t86_rtc_ops, THIS_MODULE); |
156 | 153 | ||
157 | if (IS_ERR(rtc)) { | 154 | if (IS_ERR(rtc)) |
158 | dev_err(&dev->dev, "unable to register\n"); | ||
159 | return PTR_ERR(rtc); | 155 | return PTR_ERR(rtc); |
160 | } | ||
161 | 156 | ||
162 | platform_set_drvdata(dev, rtc); | 157 | platform_set_drvdata(dev, rtc); |
163 | 158 | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index d857d45bdbe8..ba9a583b7b68 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -227,14 +227,7 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
227 | return pcf8563_set_datetime(to_i2c_client(dev), tm); | 227 | return pcf8563_set_datetime(to_i2c_client(dev), tm); |
228 | } | 228 | } |
229 | 229 | ||
230 | static int pcf8563_rtc_proc(struct device *dev, struct seq_file *seq) | ||
231 | { | ||
232 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct rtc_class_ops pcf8563_rtc_ops = { | 230 | static struct rtc_class_ops pcf8563_rtc_ops = { |
237 | .proc = pcf8563_rtc_proc, | ||
238 | .read_time = pcf8563_rtc_read_time, | 231 | .read_time = pcf8563_rtc_read_time, |
239 | .set_time = pcf8563_rtc_set_time, | 232 | .set_time = pcf8563_rtc_set_time, |
240 | }; | 233 | }; |
@@ -297,8 +290,6 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) | |||
297 | 290 | ||
298 | if (IS_ERR(rtc)) { | 291 | if (IS_ERR(rtc)) { |
299 | err = PTR_ERR(rtc); | 292 | err = PTR_ERR(rtc); |
300 | dev_err(&client->dev, | ||
301 | "unable to register the class device\n"); | ||
302 | goto exit_detach; | 293 | goto exit_detach; |
303 | } | 294 | } |
304 | 295 | ||
@@ -321,8 +312,6 @@ static int pcf8563_detach(struct i2c_client *client) | |||
321 | int err; | 312 | int err; |
322 | struct rtc_device *rtc = i2c_get_clientdata(client); | 313 | struct rtc_device *rtc = i2c_get_clientdata(client); |
323 | 314 | ||
324 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
325 | |||
326 | if (rtc) | 315 | if (rtc) |
327 | rtc_device_unregister(rtc); | 316 | rtc_device_unregister(rtc); |
328 | 317 | ||
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 90b8a97a0919..cef5f5a3bbf9 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -71,6 +71,8 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
71 | alrm.pending ? "yes" : "no"); | 71 | alrm.pending ? "yes" : "no"); |
72 | } | 72 | } |
73 | 73 | ||
74 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
75 | |||
74 | if (ops->proc) | 76 | if (ops->proc) |
75 | ops->proc(class_dev->dev, seq); | 77 | ops->proc(class_dev->dev, seq); |
76 | 78 | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 396c8681f66c..7553d797603f 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -151,9 +151,8 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) | |||
151 | { | 151 | { |
152 | int err, osc, trim; | 152 | int err, osc, trim; |
153 | 153 | ||
154 | seq_printf(seq, "24hr\t\t: yes\n"); | 154 | err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim); |
155 | 155 | if (err == 0) { | |
156 | if ((err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim)) == 0) { | ||
157 | seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); | 156 | seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); |
158 | seq_printf(seq, "trim\t: %d\n", trim); | 157 | seq_printf(seq, "trim\t: %d\n", trim); |
159 | } | 158 | } |
@@ -170,30 +169,31 @@ static struct rtc_class_ops rs5c372_rtc_ops = { | |||
170 | static ssize_t rs5c372_sysfs_show_trim(struct device *dev, | 169 | static ssize_t rs5c372_sysfs_show_trim(struct device *dev, |
171 | struct device_attribute *attr, char *buf) | 170 | struct device_attribute *attr, char *buf) |
172 | { | 171 | { |
173 | int trim; | 172 | int err, trim; |
174 | 173 | ||
175 | if (rs5c372_get_trim(to_i2c_client(dev), NULL, &trim) == 0) | 174 | err = rs5c372_get_trim(to_i2c_client(dev), NULL, &trim); |
176 | return sprintf(buf, "0x%2x\n", trim); | 175 | if (err) |
176 | return err; | ||
177 | 177 | ||
178 | return 0; | 178 | return sprintf(buf, "0x%2x\n", trim); |
179 | } | 179 | } |
180 | static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); | 180 | static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); |
181 | 181 | ||
182 | static ssize_t rs5c372_sysfs_show_osc(struct device *dev, | 182 | static ssize_t rs5c372_sysfs_show_osc(struct device *dev, |
183 | struct device_attribute *attr, char *buf) | 183 | struct device_attribute *attr, char *buf) |
184 | { | 184 | { |
185 | int osc; | 185 | int err, osc; |
186 | 186 | ||
187 | if (rs5c372_get_trim(to_i2c_client(dev), &osc, NULL) == 0) | 187 | err = rs5c372_get_trim(to_i2c_client(dev), &osc, NULL); |
188 | return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); | 188 | if (err) |
189 | return err; | ||
189 | 190 | ||
190 | return 0; | 191 | return sprintf(buf, "%d.%03d KHz\n", osc / 1000, osc % 1000); |
191 | } | 192 | } |
192 | static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); | 193 | static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); |
193 | 194 | ||
194 | static int rs5c372_attach(struct i2c_adapter *adapter) | 195 | static int rs5c372_attach(struct i2c_adapter *adapter) |
195 | { | 196 | { |
196 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
197 | return i2c_probe(adapter, &addr_data, rs5c372_probe); | 197 | return i2c_probe(adapter, &addr_data, rs5c372_probe); |
198 | } | 198 | } |
199 | 199 | ||
@@ -233,8 +233,6 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) | |||
233 | 233 | ||
234 | if (IS_ERR(rtc)) { | 234 | if (IS_ERR(rtc)) { |
235 | err = PTR_ERR(rtc); | 235 | err = PTR_ERR(rtc); |
236 | dev_err(&client->dev, | ||
237 | "unable to register the class device\n"); | ||
238 | goto exit_detach; | 236 | goto exit_detach; |
239 | } | 237 | } |
240 | 238 | ||
@@ -260,8 +258,6 @@ static int rs5c372_detach(struct i2c_client *client) | |||
260 | int err; | 258 | int err; |
261 | struct rtc_device *rtc = i2c_get_clientdata(client); | 259 | struct rtc_device *rtc = i2c_get_clientdata(client); |
262 | 260 | ||
263 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
264 | |||
265 | if (rtc) | 261 | if (rtc) |
266 | rtc_device_unregister(rtc); | 262 | rtc_device_unregister(rtc); |
267 | 263 | ||
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 83b2bb480a16..a23ec54989f6 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -160,19 +160,19 @@ static int sa1100_rtc_open(struct device *dev) | |||
160 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, | 160 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, SA_INTERRUPT, |
161 | "rtc 1Hz", dev); | 161 | "rtc 1Hz", dev); |
162 | if (ret) { | 162 | if (ret) { |
163 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz); | 163 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
164 | goto fail_ui; | 164 | goto fail_ui; |
165 | } | 165 | } |
166 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, | 166 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, SA_INTERRUPT, |
167 | "rtc Alrm", dev); | 167 | "rtc Alrm", dev); |
168 | if (ret) { | 168 | if (ret) { |
169 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm); | 169 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
170 | goto fail_ai; | 170 | goto fail_ai; |
171 | } | 171 | } |
172 | ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, | 172 | ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, |
173 | "rtc timer", dev); | 173 | "rtc timer", dev); |
174 | if (ret) { | 174 | if (ret) { |
175 | printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1); | 175 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); |
176 | goto fail_pi; | 176 | goto fail_pi; |
177 | } | 177 | } |
178 | return 0; | 178 | return 0; |
@@ -332,7 +332,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
332 | */ | 332 | */ |
333 | if (RTTR == 0) { | 333 | if (RTTR == 0) { |
334 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 334 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
335 | printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n"); | 335 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); |
336 | /* The current RTC value probably doesn't make sense either */ | 336 | /* The current RTC value probably doesn't make sense either */ |
337 | RCNR = 0; | 337 | RCNR = 0; |
338 | } | 338 | } |
@@ -340,15 +340,11 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
340 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 340 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
341 | THIS_MODULE); | 341 | THIS_MODULE); |
342 | 342 | ||
343 | if (IS_ERR(rtc)) { | 343 | if (IS_ERR(rtc)) |
344 | dev_err(&pdev->dev, "Unable to register the RTC device\n"); | ||
345 | return PTR_ERR(rtc); | 344 | return PTR_ERR(rtc); |
346 | } | ||
347 | 345 | ||
348 | platform_set_drvdata(pdev, rtc); | 346 | platform_set_drvdata(pdev, rtc); |
349 | 347 | ||
350 | dev_info(&pdev->dev, "SA11xx/PXA2xx RTC Registered\n"); | ||
351 | |||
352 | return 0; | 348 | return 0; |
353 | } | 349 | } |
354 | 350 | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 43d107487820..e1f7e8e86daf 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -49,7 +49,6 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq) | |||
49 | { | 49 | { |
50 | struct platform_device *plat_dev = to_platform_device(dev); | 50 | struct platform_device *plat_dev = to_platform_device(dev); |
51 | 51 | ||
52 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
53 | seq_printf(seq, "test\t\t: yes\n"); | 52 | seq_printf(seq, "test\t\t: yes\n"); |
54 | seq_printf(seq, "id\t\t: %d\n", plat_dev->id); | 53 | seq_printf(seq, "id\t\t: %d\n", plat_dev->id); |
55 | 54 | ||
@@ -120,8 +119,6 @@ static int test_probe(struct platform_device *plat_dev) | |||
120 | &test_rtc_ops, THIS_MODULE); | 119 | &test_rtc_ops, THIS_MODULE); |
121 | if (IS_ERR(rtc)) { | 120 | if (IS_ERR(rtc)) { |
122 | err = PTR_ERR(rtc); | 121 | err = PTR_ERR(rtc); |
123 | dev_err(&plat_dev->dev, | ||
124 | "unable to register the class device\n"); | ||
125 | return err; | 122 | return err; |
126 | } | 123 | } |
127 | device_create_file(&plat_dev->dev, &dev_attr_irq); | 124 | device_create_file(&plat_dev->dev, &dev_attr_irq); |
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/rtc/rtc-vr41xx.c index b109d9a502d6..4d49fd501198 100644 --- a/drivers/char/vr41xx_rtc.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Real Time Clock unit. | 2 | * Driver for NEC VR4100 series Real Time Clock unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -17,23 +17,18 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
23 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
24 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
25 | #include <linux/mc146818rtc.h> | ||
26 | #include <linux/miscdevice.h> | ||
27 | #include <linux/module.h> | 24 | #include <linux/module.h> |
28 | #include <linux/poll.h> | 25 | #include <linux/platform_device.h> |
29 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> |
30 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
31 | #include <linux/types.h> | 28 | #include <linux/types.h> |
32 | #include <linux/wait.h> | ||
33 | 29 | ||
34 | #include <asm/div64.h> | 30 | #include <asm/div64.h> |
35 | #include <asm/io.h> | 31 | #include <asm/io.h> |
36 | #include <asm/time.h> | ||
37 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
38 | #include <asm/vr41xx/vr41xx.h> | 33 | #include <asm/vr41xx/vr41xx.h> |
39 | 34 | ||
@@ -99,27 +94,11 @@ static void __iomem *rtc2_base; | |||
99 | 94 | ||
100 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ | 95 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ |
101 | 96 | ||
102 | static spinlock_t rtc_task_lock; | 97 | static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; |
103 | static wait_queue_head_t rtc_wait; | ||
104 | static unsigned long rtc_irq_data; | ||
105 | static struct fasync_struct *rtc_async_queue; | ||
106 | static rtc_task_t *rtc_callback; | ||
107 | static char rtc_name[] = "RTC"; | 98 | static char rtc_name[] = "RTC"; |
108 | static unsigned long periodic_frequency; | 99 | static unsigned long periodic_frequency; |
109 | static unsigned long periodic_count; | 100 | static unsigned long periodic_count; |
110 | 101 | ||
111 | typedef enum { | ||
112 | RTC_RELEASE, | ||
113 | RTC_OPEN, | ||
114 | } rtc_status_t; | ||
115 | |||
116 | static rtc_status_t rtc_status; | ||
117 | |||
118 | typedef enum { | ||
119 | FUNCTION_RTC_IOCTL, | ||
120 | FUNCTION_RTC_CONTROL, | ||
121 | } rtc_callfrom_t; | ||
122 | |||
123 | struct resource rtc_resource[2] = { | 102 | struct resource rtc_resource[2] = { |
124 | { .name = rtc_name, | 103 | { .name = rtc_name, |
125 | .flags = IORESOURCE_MEM, }, | 104 | .flags = IORESOURCE_MEM, }, |
@@ -129,7 +108,9 @@ struct resource rtc_resource[2] = { | |||
129 | 108 | ||
130 | static inline unsigned long read_elapsed_second(void) | 109 | static inline unsigned long read_elapsed_second(void) |
131 | { | 110 | { |
111 | |||
132 | unsigned long first_low, first_mid, first_high; | 112 | unsigned long first_low, first_mid, first_high; |
113 | |||
133 | unsigned long second_low, second_mid, second_high; | 114 | unsigned long second_low, second_mid, second_high; |
134 | 115 | ||
135 | do { | 116 | do { |
@@ -156,50 +137,36 @@ static inline void write_elapsed_second(unsigned long sec) | |||
156 | spin_unlock_irq(&rtc_lock); | 137 | spin_unlock_irq(&rtc_lock); |
157 | } | 138 | } |
158 | 139 | ||
159 | static void set_alarm(struct rtc_time *time) | 140 | static void vr41xx_rtc_release(struct device *dev) |
160 | { | 141 | { |
161 | unsigned long alarm_sec; | ||
162 | |||
163 | alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, | ||
164 | time->tm_hour, time->tm_min, time->tm_sec); | ||
165 | |||
166 | spin_lock_irq(&rtc_lock); | ||
167 | |||
168 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); | ||
169 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); | ||
170 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); | ||
171 | |||
172 | spin_unlock_irq(&rtc_lock); | ||
173 | } | ||
174 | |||
175 | static void read_alarm(struct rtc_time *time) | ||
176 | { | ||
177 | unsigned long low, mid, high; | ||
178 | 142 | ||
179 | spin_lock_irq(&rtc_lock); | 143 | spin_lock_irq(&rtc_lock); |
180 | 144 | ||
181 | low = rtc1_read(ECMPLREG); | 145 | rtc1_write(ECMPLREG, 0); |
182 | mid = rtc1_read(ECMPMREG); | 146 | rtc1_write(ECMPMREG, 0); |
183 | high = rtc1_read(ECMPHREG); | 147 | rtc1_write(ECMPHREG, 0); |
148 | rtc1_write(RTCL1LREG, 0); | ||
149 | rtc1_write(RTCL1HREG, 0); | ||
184 | 150 | ||
185 | spin_unlock_irq(&rtc_lock); | 151 | spin_unlock_irq(&rtc_lock); |
186 | 152 | ||
187 | to_tm((high << 17) | (mid << 1) | (low >> 15), time); | 153 | disable_irq(ELAPSEDTIME_IRQ); |
188 | time->tm_year -= 1900; | 154 | disable_irq(RTCLONG1_IRQ); |
189 | } | 155 | } |
190 | 156 | ||
191 | static void read_time(struct rtc_time *time) | 157 | static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time) |
192 | { | 158 | { |
193 | unsigned long epoch_sec, elapsed_sec; | 159 | unsigned long epoch_sec, elapsed_sec; |
194 | 160 | ||
195 | epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); | 161 | epoch_sec = mktime(epoch, 1, 1, 0, 0, 0); |
196 | elapsed_sec = read_elapsed_second(); | 162 | elapsed_sec = read_elapsed_second(); |
197 | 163 | ||
198 | to_tm(epoch_sec + elapsed_sec, time); | 164 | rtc_time_to_tm(epoch_sec + elapsed_sec, time); |
199 | time->tm_year -= 1900; | 165 | |
166 | return 0; | ||
200 | } | 167 | } |
201 | 168 | ||
202 | static void set_time(struct rtc_time *time) | 169 | static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time) |
203 | { | 170 | { |
204 | unsigned long epoch_sec, current_sec; | 171 | unsigned long epoch_sec, current_sec; |
205 | 172 | ||
@@ -208,73 +175,49 @@ static void set_time(struct rtc_time *time) | |||
208 | time->tm_hour, time->tm_min, time->tm_sec); | 175 | time->tm_hour, time->tm_min, time->tm_sec); |
209 | 176 | ||
210 | write_elapsed_second(current_sec - epoch_sec); | 177 | write_elapsed_second(current_sec - epoch_sec); |
178 | |||
179 | return 0; | ||
211 | } | 180 | } |
212 | 181 | ||
213 | static ssize_t rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 182 | static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
214 | { | 183 | { |
215 | DECLARE_WAITQUEUE(wait, current); | 184 | unsigned long low, mid, high; |
216 | unsigned long irq_data; | 185 | struct rtc_time *time = &wkalrm->time; |
217 | int retval = 0; | ||
218 | |||
219 | if (count != sizeof(unsigned int) && count != sizeof(unsigned long)) | ||
220 | return -EINVAL; | ||
221 | |||
222 | add_wait_queue(&rtc_wait, &wait); | ||
223 | |||
224 | do { | ||
225 | __set_current_state(TASK_INTERRUPTIBLE); | ||
226 | 186 | ||
227 | spin_lock_irq(&rtc_lock); | 187 | spin_lock_irq(&rtc_lock); |
228 | irq_data = rtc_irq_data; | ||
229 | rtc_irq_data = 0; | ||
230 | spin_unlock_irq(&rtc_lock); | ||
231 | 188 | ||
232 | if (irq_data != 0) | 189 | low = rtc1_read(ECMPLREG); |
233 | break; | 190 | mid = rtc1_read(ECMPMREG); |
191 | high = rtc1_read(ECMPHREG); | ||
234 | 192 | ||
235 | if (file->f_flags & O_NONBLOCK) { | 193 | spin_unlock_irq(&rtc_lock); |
236 | retval = -EAGAIN; | ||
237 | break; | ||
238 | } | ||
239 | 194 | ||
240 | if (signal_pending(current)) { | 195 | rtc_time_to_tm((high << 17) | (mid << 1) | (low >> 15), time); |
241 | retval = -ERESTARTSYS; | ||
242 | break; | ||
243 | } | ||
244 | } while (1); | ||
245 | 196 | ||
246 | if (retval == 0) { | 197 | return 0; |
247 | if (count == sizeof(unsigned int)) { | 198 | } |
248 | retval = put_user(irq_data, (unsigned int __user *)buf); | ||
249 | if (retval == 0) | ||
250 | retval = sizeof(unsigned int); | ||
251 | } else { | ||
252 | retval = put_user(irq_data, (unsigned long __user *)buf); | ||
253 | if (retval == 0) | ||
254 | retval = sizeof(unsigned long); | ||
255 | } | ||
256 | 199 | ||
257 | } | 200 | static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
201 | { | ||
202 | unsigned long alarm_sec; | ||
203 | struct rtc_time *time = &wkalrm->time; | ||
258 | 204 | ||
259 | __set_current_state(TASK_RUNNING); | 205 | alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, |
260 | remove_wait_queue(&rtc_wait, &wait); | 206 | time->tm_hour, time->tm_min, time->tm_sec); |
261 | 207 | ||
262 | return retval; | 208 | spin_lock_irq(&rtc_lock); |
263 | } | ||
264 | 209 | ||
265 | static unsigned int rtc_poll(struct file *file, struct poll_table_struct *table) | 210 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); |
266 | { | 211 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); |
267 | poll_wait(file, &rtc_wait, table); | 212 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); |
268 | 213 | ||
269 | if (rtc_irq_data != 0) | 214 | spin_unlock_irq(&rtc_lock); |
270 | return POLLIN | POLLRDNORM; | ||
271 | 215 | ||
272 | return 0; | 216 | return 0; |
273 | } | 217 | } |
274 | 218 | ||
275 | static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from) | 219 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
276 | { | 220 | { |
277 | struct rtc_time time; | ||
278 | unsigned long count; | 221 | unsigned long count; |
279 | 222 | ||
280 | switch (cmd) { | 223 | switch (cmd) { |
@@ -290,33 +233,6 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from | |||
290 | case RTC_PIE_OFF: | 233 | case RTC_PIE_OFF: |
291 | disable_irq(RTCLONG1_IRQ); | 234 | disable_irq(RTCLONG1_IRQ); |
292 | break; | 235 | break; |
293 | case RTC_ALM_SET: | ||
294 | if (copy_from_user(&time, (struct rtc_time __user *)arg, | ||
295 | sizeof(struct rtc_time))) | ||
296 | return -EFAULT; | ||
297 | |||
298 | set_alarm(&time); | ||
299 | break; | ||
300 | case RTC_ALM_READ: | ||
301 | memset(&time, 0, sizeof(struct rtc_time)); | ||
302 | read_alarm(&time); | ||
303 | break; | ||
304 | case RTC_RD_TIME: | ||
305 | memset(&time, 0, sizeof(struct rtc_time)); | ||
306 | read_time(&time); | ||
307 | if (copy_to_user((void __user *)arg, &time, sizeof(struct rtc_time))) | ||
308 | return -EFAULT; | ||
309 | break; | ||
310 | case RTC_SET_TIME: | ||
311 | if (capable(CAP_SYS_TIME) == 0) | ||
312 | return -EACCES; | ||
313 | |||
314 | if (copy_from_user(&time, (struct rtc_time __user *)arg, | ||
315 | sizeof(struct rtc_time))) | ||
316 | return -EFAULT; | ||
317 | |||
318 | set_time(&time); | ||
319 | break; | ||
320 | case RTC_IRQP_READ: | 236 | case RTC_IRQP_READ: |
321 | return put_user(periodic_frequency, (unsigned long __user *)arg); | 237 | return put_user(periodic_frequency, (unsigned long __user *)arg); |
322 | break; | 238 | break; |
@@ -324,8 +240,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from | |||
324 | if (arg > MAX_PERIODIC_RATE) | 240 | if (arg > MAX_PERIODIC_RATE) |
325 | return -EINVAL; | 241 | return -EINVAL; |
326 | 242 | ||
327 | if (from == FUNCTION_RTC_IOCTL && arg > MAX_USER_PERIODIC_RATE && | 243 | if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0) |
328 | capable(CAP_SYS_RESOURCE) == 0) | ||
329 | return -EACCES; | 244 | return -EACCES; |
330 | 245 | ||
331 | periodic_frequency = arg; | 246 | periodic_frequency = arg; |
@@ -361,205 +276,46 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, rtc_callfrom_t from | |||
361 | return 0; | 276 | return 0; |
362 | } | 277 | } |
363 | 278 | ||
364 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
365 | unsigned long arg) | ||
366 | { | ||
367 | return rtc_do_ioctl(cmd, arg, FUNCTION_RTC_IOCTL); | ||
368 | } | ||
369 | |||
370 | static int rtc_open(struct inode *inode, struct file *file) | ||
371 | { | ||
372 | spin_lock_irq(&rtc_lock); | ||
373 | |||
374 | if (rtc_status == RTC_OPEN) { | ||
375 | spin_unlock_irq(&rtc_lock); | ||
376 | return -EBUSY; | ||
377 | } | ||
378 | |||
379 | rtc_status = RTC_OPEN; | ||
380 | rtc_irq_data = 0; | ||
381 | |||
382 | spin_unlock_irq(&rtc_lock); | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int rtc_release(struct inode *inode, struct file *file) | ||
388 | { | ||
389 | if (file->f_flags & FASYNC) | ||
390 | (void)fasync_helper(-1, file, 0, &rtc_async_queue); | ||
391 | |||
392 | spin_lock_irq(&rtc_lock); | ||
393 | |||
394 | rtc1_write(ECMPLREG, 0); | ||
395 | rtc1_write(ECMPMREG, 0); | ||
396 | rtc1_write(ECMPHREG, 0); | ||
397 | rtc1_write(RTCL1LREG, 0); | ||
398 | rtc1_write(RTCL1HREG, 0); | ||
399 | |||
400 | rtc_status = RTC_RELEASE; | ||
401 | |||
402 | spin_unlock_irq(&rtc_lock); | ||
403 | |||
404 | disable_irq(ELAPSEDTIME_IRQ); | ||
405 | disable_irq(RTCLONG1_IRQ); | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | static int rtc_fasync(int fd, struct file *file, int on) | ||
411 | { | ||
412 | return fasync_helper(fd, file, on, &rtc_async_queue); | ||
413 | } | ||
414 | |||
415 | static struct file_operations rtc_fops = { | ||
416 | .owner = THIS_MODULE, | ||
417 | .llseek = no_llseek, | ||
418 | .read = rtc_read, | ||
419 | .poll = rtc_poll, | ||
420 | .ioctl = rtc_ioctl, | ||
421 | .open = rtc_open, | ||
422 | .release = rtc_release, | ||
423 | .fasync = rtc_fasync, | ||
424 | }; | ||
425 | |||
426 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 279 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
427 | { | 280 | { |
428 | spin_lock(&rtc_lock); | 281 | struct platform_device *pdev = (struct platform_device *)dev_id; |
429 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); | 282 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
430 | |||
431 | rtc_irq_data += 0x100; | ||
432 | rtc_irq_data &= ~0xff; | ||
433 | rtc_irq_data |= RTC_AF; | ||
434 | spin_unlock(&rtc_lock); | ||
435 | 283 | ||
436 | spin_lock(&rtc_lock); | 284 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); |
437 | if (rtc_callback) | ||
438 | rtc_callback->func(rtc_callback->private_data); | ||
439 | spin_unlock(&rtc_lock); | ||
440 | |||
441 | wake_up_interruptible(&rtc_wait); | ||
442 | 285 | ||
443 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); | 286 | rtc_update_irq(&rtc->class_dev, 1, RTC_AF); |
444 | 287 | ||
445 | return IRQ_HANDLED; | 288 | return IRQ_HANDLED; |
446 | } | 289 | } |
447 | 290 | ||
448 | static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 291 | static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
449 | { | 292 | { |
293 | struct platform_device *pdev = (struct platform_device *)dev_id; | ||
294 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
450 | unsigned long count = periodic_count; | 295 | unsigned long count = periodic_count; |
451 | 296 | ||
452 | spin_lock(&rtc_lock); | ||
453 | rtc2_write(RTCINTREG, RTCLONG1_INT); | 297 | rtc2_write(RTCINTREG, RTCLONG1_INT); |
454 | 298 | ||
455 | rtc1_write(RTCL1LREG, count); | 299 | rtc1_write(RTCL1LREG, count); |
456 | rtc1_write(RTCL1HREG, count >> 16); | 300 | rtc1_write(RTCL1HREG, count >> 16); |
457 | 301 | ||
458 | rtc_irq_data += 0x100; | 302 | rtc_update_irq(&rtc->class_dev, 1, RTC_PF); |
459 | rtc_irq_data &= ~0xff; | ||
460 | rtc_irq_data |= RTC_PF; | ||
461 | spin_unlock(&rtc_lock); | ||
462 | |||
463 | spin_lock(&rtc_task_lock); | ||
464 | if (rtc_callback) | ||
465 | rtc_callback->func(rtc_callback->private_data); | ||
466 | spin_unlock(&rtc_task_lock); | ||
467 | |||
468 | wake_up_interruptible(&rtc_wait); | ||
469 | |||
470 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); | ||
471 | 303 | ||
472 | return IRQ_HANDLED; | 304 | return IRQ_HANDLED; |
473 | } | 305 | } |
474 | 306 | ||
475 | int rtc_register(rtc_task_t *task) | 307 | static struct rtc_class_ops vr41xx_rtc_ops = { |
476 | { | 308 | .release = vr41xx_rtc_release, |
477 | if (task == NULL || task->func == NULL) | 309 | .ioctl = vr41xx_rtc_ioctl, |
478 | return -EINVAL; | 310 | .read_time = vr41xx_rtc_read_time, |
479 | 311 | .set_time = vr41xx_rtc_set_time, | |
480 | spin_lock_irq(&rtc_lock); | 312 | .read_alarm = vr41xx_rtc_read_alarm, |
481 | if (rtc_status == RTC_OPEN) { | 313 | .set_alarm = vr41xx_rtc_set_alarm, |
482 | spin_unlock_irq(&rtc_lock); | ||
483 | return -EBUSY; | ||
484 | } | ||
485 | |||
486 | spin_lock(&rtc_task_lock); | ||
487 | if (rtc_callback != NULL) { | ||
488 | spin_unlock(&rtc_task_lock); | ||
489 | spin_unlock_irq(&rtc_task_lock); | ||
490 | return -EBUSY; | ||
491 | } | ||
492 | |||
493 | rtc_callback = task; | ||
494 | spin_unlock(&rtc_task_lock); | ||
495 | |||
496 | rtc_status = RTC_OPEN; | ||
497 | |||
498 | spin_unlock_irq(&rtc_lock); | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | EXPORT_SYMBOL_GPL(rtc_register); | ||
504 | |||
505 | int rtc_unregister(rtc_task_t *task) | ||
506 | { | ||
507 | spin_lock_irq(&rtc_task_lock); | ||
508 | if (task == NULL || rtc_callback != task) { | ||
509 | spin_unlock_irq(&rtc_task_lock); | ||
510 | return -ENXIO; | ||
511 | } | ||
512 | |||
513 | spin_lock(&rtc_lock); | ||
514 | |||
515 | rtc1_write(ECMPLREG, 0); | ||
516 | rtc1_write(ECMPMREG, 0); | ||
517 | rtc1_write(ECMPHREG, 0); | ||
518 | rtc1_write(RTCL1LREG, 0); | ||
519 | rtc1_write(RTCL1HREG, 0); | ||
520 | |||
521 | rtc_status = RTC_RELEASE; | ||
522 | |||
523 | spin_unlock(&rtc_lock); | ||
524 | |||
525 | rtc_callback = NULL; | ||
526 | |||
527 | spin_unlock_irq(&rtc_task_lock); | ||
528 | |||
529 | disable_irq(ELAPSEDTIME_IRQ); | ||
530 | disable_irq(RTCLONG1_IRQ); | ||
531 | |||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | EXPORT_SYMBOL_GPL(rtc_unregister); | ||
536 | |||
537 | int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | ||
538 | { | ||
539 | int retval = 0; | ||
540 | |||
541 | spin_lock_irq(&rtc_task_lock); | ||
542 | |||
543 | if (rtc_callback != task) | ||
544 | retval = -ENXIO; | ||
545 | else | ||
546 | rtc_do_ioctl(cmd, arg, FUNCTION_RTC_CONTROL); | ||
547 | |||
548 | spin_unlock_irq(&rtc_task_lock); | ||
549 | |||
550 | return retval; | ||
551 | } | ||
552 | |||
553 | EXPORT_SYMBOL_GPL(rtc_control); | ||
554 | |||
555 | static struct miscdevice rtc_miscdevice = { | ||
556 | .minor = RTC_MINOR, | ||
557 | .name = rtc_name, | ||
558 | .fops = &rtc_fops, | ||
559 | }; | 314 | }; |
560 | 315 | ||
561 | static int __devinit rtc_probe(struct platform_device *pdev) | 316 | static int __devinit rtc_probe(struct platform_device *pdev) |
562 | { | 317 | { |
318 | struct rtc_device *rtc; | ||
563 | unsigned int irq; | 319 | unsigned int irq; |
564 | int retval; | 320 | int retval; |
565 | 321 | ||
@@ -577,13 +333,13 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
577 | return -EBUSY; | 333 | return -EBUSY; |
578 | } | 334 | } |
579 | 335 | ||
580 | retval = misc_register(&rtc_miscdevice); | 336 | rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE); |
581 | if (retval < 0) { | 337 | if (IS_ERR(rtc)) { |
582 | iounmap(rtc1_base); | 338 | iounmap(rtc1_base); |
583 | iounmap(rtc2_base); | 339 | iounmap(rtc2_base); |
584 | rtc1_base = NULL; | 340 | rtc1_base = NULL; |
585 | rtc2_base = NULL; | 341 | rtc2_base = NULL; |
586 | return retval; | 342 | return PTR_ERR(rtc); |
587 | } | 343 | } |
588 | 344 | ||
589 | spin_lock_irq(&rtc_lock); | 345 | spin_lock_irq(&rtc_lock); |
@@ -594,24 +350,20 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
594 | rtc1_write(RTCL1LREG, 0); | 350 | rtc1_write(RTCL1LREG, 0); |
595 | rtc1_write(RTCL1HREG, 0); | 351 | rtc1_write(RTCL1HREG, 0); |
596 | 352 | ||
597 | rtc_status = RTC_RELEASE; | ||
598 | rtc_irq_data = 0; | ||
599 | |||
600 | spin_unlock_irq(&rtc_lock); | 353 | spin_unlock_irq(&rtc_lock); |
601 | 354 | ||
602 | init_waitqueue_head(&rtc_wait); | ||
603 | |||
604 | irq = ELAPSEDTIME_IRQ; | 355 | irq = ELAPSEDTIME_IRQ; |
605 | retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT, | 356 | retval = request_irq(irq, elapsedtime_interrupt, SA_INTERRUPT, |
606 | "elapsed_time", NULL); | 357 | "elapsed_time", pdev); |
607 | if (retval == 0) { | 358 | if (retval == 0) { |
608 | irq = RTCLONG1_IRQ; | 359 | irq = RTCLONG1_IRQ; |
609 | retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT, | 360 | retval = request_irq(irq, rtclong1_interrupt, SA_INTERRUPT, |
610 | "rtclong1", NULL); | 361 | "rtclong1", pdev); |
611 | } | 362 | } |
612 | 363 | ||
613 | if (retval < 0) { | 364 | if (retval < 0) { |
614 | printk(KERN_ERR "rtc: IRQ%d is busy\n", irq); | 365 | printk(KERN_ERR "rtc: IRQ%d is busy\n", irq); |
366 | rtc_device_unregister(rtc); | ||
615 | if (irq == RTCLONG1_IRQ) | 367 | if (irq == RTCLONG1_IRQ) |
616 | free_irq(ELAPSEDTIME_IRQ, NULL); | 368 | free_irq(ELAPSEDTIME_IRQ, NULL); |
617 | iounmap(rtc1_base); | 369 | iounmap(rtc1_base); |
@@ -621,23 +373,25 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
621 | return retval; | 373 | return retval; |
622 | } | 374 | } |
623 | 375 | ||
376 | platform_set_drvdata(pdev, rtc); | ||
377 | |||
624 | disable_irq(ELAPSEDTIME_IRQ); | 378 | disable_irq(ELAPSEDTIME_IRQ); |
625 | disable_irq(RTCLONG1_IRQ); | 379 | disable_irq(RTCLONG1_IRQ); |
626 | 380 | ||
627 | spin_lock_init(&rtc_task_lock); | ||
628 | |||
629 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); | 381 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); |
630 | 382 | ||
631 | return 0; | 383 | return 0; |
632 | } | 384 | } |
633 | 385 | ||
634 | static int __devexit rtc_remove(struct platform_device *dev) | 386 | static int __devexit rtc_remove(struct platform_device *pdev) |
635 | { | 387 | { |
636 | int retval; | 388 | struct rtc_device *rtc; |
637 | 389 | ||
638 | retval = misc_deregister(&rtc_miscdevice); | 390 | rtc = platform_get_drvdata(pdev); |
639 | if (retval < 0) | 391 | if (rtc != NULL) |
640 | return retval; | 392 | rtc_device_unregister(rtc); |
393 | |||
394 | platform_set_drvdata(pdev, NULL); | ||
641 | 395 | ||
642 | free_irq(ELAPSEDTIME_IRQ, NULL); | 396 | free_irq(ELAPSEDTIME_IRQ, NULL); |
643 | free_irq(RTCLONG1_IRQ, NULL); | 397 | free_irq(RTCLONG1_IRQ, NULL); |
@@ -651,7 +405,7 @@ static int __devexit rtc_remove(struct platform_device *dev) | |||
651 | 405 | ||
652 | static struct platform_device *rtc_platform_device; | 406 | static struct platform_device *rtc_platform_device; |
653 | 407 | ||
654 | static struct platform_driver rtc_device_driver = { | 408 | static struct platform_driver rtc_platform_driver = { |
655 | .probe = rtc_probe, | 409 | .probe = rtc_probe, |
656 | .remove = __devexit_p(rtc_remove), | 410 | .remove = __devexit_p(rtc_remove), |
657 | .driver = { | 411 | .driver = { |
@@ -686,7 +440,7 @@ static int __init vr41xx_rtc_init(void) | |||
686 | } | 440 | } |
687 | 441 | ||
688 | rtc_platform_device = platform_device_alloc("RTC", -1); | 442 | rtc_platform_device = platform_device_alloc("RTC", -1); |
689 | if (!rtc_platform_device) | 443 | if (rtc_platform_device == NULL) |
690 | return -ENOMEM; | 444 | return -ENOMEM; |
691 | 445 | ||
692 | retval = platform_device_add_resources(rtc_platform_device, | 446 | retval = platform_device_add_resources(rtc_platform_device, |
@@ -700,7 +454,7 @@ static int __init vr41xx_rtc_init(void) | |||
700 | return retval; | 454 | return retval; |
701 | } | 455 | } |
702 | 456 | ||
703 | retval = platform_driver_register(&rtc_device_driver); | 457 | retval = platform_driver_register(&rtc_platform_driver); |
704 | if (retval < 0) | 458 | if (retval < 0) |
705 | platform_device_unregister(rtc_platform_device); | 459 | platform_device_unregister(rtc_platform_device); |
706 | 460 | ||
@@ -709,7 +463,7 @@ static int __init vr41xx_rtc_init(void) | |||
709 | 463 | ||
710 | static void __exit vr41xx_rtc_exit(void) | 464 | static void __exit vr41xx_rtc_exit(void) |
711 | { | 465 | { |
712 | platform_driver_unregister(&rtc_device_driver); | 466 | platform_driver_unregister(&rtc_platform_driver); |
713 | platform_device_unregister(rtc_platform_device); | 467 | platform_device_unregister(rtc_platform_device); |
714 | } | 468 | } |
715 | 469 | ||
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 621d17afc0d9..788b6d1f8f2f 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | 21 | ||
22 | #define DRV_VERSION "1.0.6" | 22 | #define DRV_VERSION "1.0.7" |
23 | 23 | ||
24 | /* Addresses to scan: none. This chip is located at | 24 | /* Addresses to scan: none. This chip is located at |
25 | * 0x6f and uses a two bytes register addressing. | 25 | * 0x6f and uses a two bytes register addressing. |
@@ -451,8 +451,6 @@ static int x1205_rtc_proc(struct device *dev, struct seq_file *seq) | |||
451 | { | 451 | { |
452 | int err, dtrim, atrim; | 452 | int err, dtrim, atrim; |
453 | 453 | ||
454 | seq_printf(seq, "24hr\t\t: yes\n"); | ||
455 | |||
456 | if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) | 454 | if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0) |
457 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); | 455 | seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim); |
458 | 456 | ||
@@ -473,30 +471,31 @@ static struct rtc_class_ops x1205_rtc_ops = { | |||
473 | static ssize_t x1205_sysfs_show_atrim(struct device *dev, | 471 | static ssize_t x1205_sysfs_show_atrim(struct device *dev, |
474 | struct device_attribute *attr, char *buf) | 472 | struct device_attribute *attr, char *buf) |
475 | { | 473 | { |
476 | int atrim; | 474 | int err, atrim; |
477 | 475 | ||
478 | if (x1205_get_atrim(to_i2c_client(dev), &atrim) == 0) | 476 | err = x1205_get_atrim(to_i2c_client(dev), &atrim); |
479 | return sprintf(buf, "%d.%02d pF\n", | 477 | if (err) |
480 | atrim / 1000, atrim % 1000); | 478 | return err; |
481 | return 0; | 479 | |
480 | return sprintf(buf, "%d.%02d pF\n", atrim / 1000, atrim % 1000); | ||
482 | } | 481 | } |
483 | static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); | 482 | static DEVICE_ATTR(atrim, S_IRUGO, x1205_sysfs_show_atrim, NULL); |
484 | 483 | ||
485 | static ssize_t x1205_sysfs_show_dtrim(struct device *dev, | 484 | static ssize_t x1205_sysfs_show_dtrim(struct device *dev, |
486 | struct device_attribute *attr, char *buf) | 485 | struct device_attribute *attr, char *buf) |
487 | { | 486 | { |
488 | int dtrim; | 487 | int err, dtrim; |
489 | 488 | ||
490 | if (x1205_get_dtrim(to_i2c_client(dev), &dtrim) == 0) | 489 | err = x1205_get_dtrim(to_i2c_client(dev), &dtrim); |
491 | return sprintf(buf, "%d ppm\n", dtrim); | 490 | if (err) |
491 | return err; | ||
492 | 492 | ||
493 | return 0; | 493 | return sprintf(buf, "%d ppm\n", dtrim); |
494 | } | 494 | } |
495 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); | 495 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); |
496 | 496 | ||
497 | static int x1205_attach(struct i2c_adapter *adapter) | 497 | static int x1205_attach(struct i2c_adapter *adapter) |
498 | { | 498 | { |
499 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | ||
500 | return i2c_probe(adapter, &addr_data, x1205_probe); | 499 | return i2c_probe(adapter, &addr_data, x1205_probe); |
501 | } | 500 | } |
502 | 501 | ||
@@ -545,8 +544,6 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | |||
545 | 544 | ||
546 | if (IS_ERR(rtc)) { | 545 | if (IS_ERR(rtc)) { |
547 | err = PTR_ERR(rtc); | 546 | err = PTR_ERR(rtc); |
548 | dev_err(&client->dev, | ||
549 | "unable to register the class device\n"); | ||
550 | goto exit_detach; | 547 | goto exit_detach; |
551 | } | 548 | } |
552 | 549 | ||
@@ -585,8 +582,6 @@ static int x1205_detach(struct i2c_client *client) | |||
585 | int err; | 582 | int err; |
586 | struct rtc_device *rtc = i2c_get_clientdata(client); | 583 | struct rtc_device *rtc = i2c_get_clientdata(client); |
587 | 584 | ||
588 | dev_dbg(&client->dev, "%s\n", __FUNCTION__); | ||
589 | |||
590 | if (rtc) | 585 | if (rtc) |
591 | rtc_device_unregister(rtc); | 586 | rtc_device_unregister(rtc); |
592 | 587 | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 0a9f12c4e911..a3bfebcf31ef 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -1257,25 +1257,28 @@ __dasd_start_head(struct dasd_device * device) | |||
1257 | if (list_empty(&device->ccw_queue)) | 1257 | if (list_empty(&device->ccw_queue)) |
1258 | return; | 1258 | return; |
1259 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1259 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
1260 | /* check FAILFAST */ | 1260 | if (cqr->status != DASD_CQR_QUEUED) |
1261 | return; | ||
1262 | /* Non-temporary stop condition will trigger fail fast */ | ||
1261 | if (device->stopped & ~DASD_STOPPED_PENDING && | 1263 | if (device->stopped & ~DASD_STOPPED_PENDING && |
1262 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && | 1264 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && |
1263 | (!dasd_eer_enabled(device))) { | 1265 | (!dasd_eer_enabled(device))) { |
1264 | cqr->status = DASD_CQR_FAILED; | 1266 | cqr->status = DASD_CQR_FAILED; |
1265 | dasd_schedule_bh(device); | 1267 | dasd_schedule_bh(device); |
1268 | return; | ||
1266 | } | 1269 | } |
1267 | if ((cqr->status == DASD_CQR_QUEUED) && | 1270 | /* Don't try to start requests if device is stopped */ |
1268 | (!device->stopped)) { | 1271 | if (device->stopped) |
1269 | /* try to start the first I/O that can be started */ | 1272 | return; |
1270 | rc = device->discipline->start_IO(cqr); | 1273 | |
1271 | if (rc == 0) | 1274 | rc = device->discipline->start_IO(cqr); |
1272 | dasd_set_timer(device, cqr->expires); | 1275 | if (rc == 0) |
1273 | else if (rc == -EACCES) { | 1276 | dasd_set_timer(device, cqr->expires); |
1274 | dasd_schedule_bh(device); | 1277 | else if (rc == -EACCES) { |
1275 | } else | 1278 | dasd_schedule_bh(device); |
1276 | /* Hmpf, try again in 1/2 sec */ | 1279 | } else |
1277 | dasd_set_timer(device, 50); | 1280 | /* Hmpf, try again in 1/2 sec */ |
1278 | } | 1281 | dasd_set_timer(device, 50); |
1279 | } | 1282 | } |
1280 | 1283 | ||
1281 | /* | 1284 | /* |
@@ -1968,7 +1971,7 @@ int | |||
1968 | dasd_generic_set_offline (struct ccw_device *cdev) | 1971 | dasd_generic_set_offline (struct ccw_device *cdev) |
1969 | { | 1972 | { |
1970 | struct dasd_device *device; | 1973 | struct dasd_device *device; |
1971 | int max_count; | 1974 | int max_count, open_count; |
1972 | 1975 | ||
1973 | device = dasd_device_from_cdev(cdev); | 1976 | device = dasd_device_from_cdev(cdev); |
1974 | if (IS_ERR(device)) | 1977 | if (IS_ERR(device)) |
@@ -1985,10 +1988,16 @@ dasd_generic_set_offline (struct ccw_device *cdev) | |||
1985 | * in the other openers. | 1988 | * in the other openers. |
1986 | */ | 1989 | */ |
1987 | max_count = device->bdev ? 0 : -1; | 1990 | max_count = device->bdev ? 0 : -1; |
1988 | if (atomic_read(&device->open_count) > max_count) { | 1991 | open_count = (int) atomic_read(&device->open_count); |
1989 | printk (KERN_WARNING "Can't offline dasd device with open" | 1992 | if (open_count > max_count) { |
1990 | " count = %i.\n", | 1993 | if (open_count > 0) |
1991 | atomic_read(&device->open_count)); | 1994 | printk (KERN_WARNING "Can't offline dasd device with " |
1995 | "open count = %i.\n", | ||
1996 | open_count); | ||
1997 | else | ||
1998 | printk (KERN_WARNING "%s", | ||
1999 | "Can't offline dasd device due to internal " | ||
2000 | "use\n"); | ||
1992 | clear_bit(DASD_FLAG_OFFLINE, &device->flags); | 2001 | clear_bit(DASD_FLAG_OFFLINE, &device->flags); |
1993 | dasd_put_device(device); | 2002 | dasd_put_device(device); |
1994 | return -EBUSY; | 2003 | return -EBUSY; |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 1aa3c261718a..ad23aede356c 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -294,23 +294,40 @@ out_error: | |||
294 | #endif /* CONFIG_DASD_PROFILE */ | 294 | #endif /* CONFIG_DASD_PROFILE */ |
295 | } | 295 | } |
296 | 296 | ||
297 | /* | ||
298 | * Create dasd proc-fs entries. | ||
299 | * In case creation failed, cleanup and return -ENOENT. | ||
300 | */ | ||
297 | int | 301 | int |
298 | dasd_proc_init(void) | 302 | dasd_proc_init(void) |
299 | { | 303 | { |
300 | dasd_proc_root_entry = proc_mkdir("dasd", &proc_root); | 304 | dasd_proc_root_entry = proc_mkdir("dasd", &proc_root); |
305 | if (!dasd_proc_root_entry) | ||
306 | goto out_nodasd; | ||
301 | dasd_proc_root_entry->owner = THIS_MODULE; | 307 | dasd_proc_root_entry->owner = THIS_MODULE; |
302 | dasd_devices_entry = create_proc_entry("devices", | 308 | dasd_devices_entry = create_proc_entry("devices", |
303 | S_IFREG | S_IRUGO | S_IWUSR, | 309 | S_IFREG | S_IRUGO | S_IWUSR, |
304 | dasd_proc_root_entry); | 310 | dasd_proc_root_entry); |
311 | if (!dasd_devices_entry) | ||
312 | goto out_nodevices; | ||
305 | dasd_devices_entry->proc_fops = &dasd_devices_file_ops; | 313 | dasd_devices_entry->proc_fops = &dasd_devices_file_ops; |
306 | dasd_devices_entry->owner = THIS_MODULE; | 314 | dasd_devices_entry->owner = THIS_MODULE; |
307 | dasd_statistics_entry = create_proc_entry("statistics", | 315 | dasd_statistics_entry = create_proc_entry("statistics", |
308 | S_IFREG | S_IRUGO | S_IWUSR, | 316 | S_IFREG | S_IRUGO | S_IWUSR, |
309 | dasd_proc_root_entry); | 317 | dasd_proc_root_entry); |
318 | if (!dasd_statistics_entry) | ||
319 | goto out_nostatistics; | ||
310 | dasd_statistics_entry->read_proc = dasd_statistics_read; | 320 | dasd_statistics_entry->read_proc = dasd_statistics_read; |
311 | dasd_statistics_entry->write_proc = dasd_statistics_write; | 321 | dasd_statistics_entry->write_proc = dasd_statistics_write; |
312 | dasd_statistics_entry->owner = THIS_MODULE; | 322 | dasd_statistics_entry->owner = THIS_MODULE; |
313 | return 0; | 323 | return 0; |
324 | |||
325 | out_nostatistics: | ||
326 | remove_proc_entry("devices", dasd_proc_root_entry); | ||
327 | out_nodevices: | ||
328 | remove_proc_entry("dasd", &proc_root); | ||
329 | out_nodasd: | ||
330 | return -ENOENT; | ||
314 | } | 331 | } |
315 | 332 | ||
316 | void | 333 | void |
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 6badd8403409..d4d2ff0a9da2 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
@@ -54,7 +54,7 @@ kbd_alloc(void) { | |||
54 | if (!kbd) | 54 | if (!kbd) |
55 | goto out; | 55 | goto out; |
56 | kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); | 56 | kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); |
57 | if (!key_maps) | 57 | if (!kbd->key_maps) |
58 | goto out_kbd; | 58 | goto out_kbd; |
59 | for (i = 0; i < ARRAY_SIZE(key_maps); i++) { | 59 | for (i = 0; i < ARRAY_SIZE(key_maps); i++) { |
60 | if (key_maps[i]) { | 60 | if (key_maps[i]) { |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 5c65cf3e5cc0..b70d92690242 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -432,8 +432,8 @@ tapeblock_ioctl( | |||
432 | ) { | 432 | ) { |
433 | int rc; | 433 | int rc; |
434 | int minor; | 434 | int minor; |
435 | struct gendisk *disk = inode->i_bdev->bd_disk; | 435 | struct gendisk *disk; |
436 | struct tape_device *device = disk->private_data; | 436 | struct tape_device *device; |
437 | 437 | ||
438 | rc = 0; | 438 | rc = 0; |
439 | disk = inode->i_bdev->bd_disk; | 439 | disk = inode->i_bdev->bd_disk; |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 389ee2c0f443..e6e4086d3224 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -210,18 +210,14 @@ tape_state_set(struct tape_device *device, enum tape_state newstate) | |||
210 | return; | 210 | return; |
211 | } | 211 | } |
212 | DBF_EVENT(4, "ts. dev: %x\n", device->first_minor); | 212 | DBF_EVENT(4, "ts. dev: %x\n", device->first_minor); |
213 | if (device->tape_state < TO_SIZE && device->tape_state >= 0) | 213 | DBF_EVENT(4, "old ts:\t\n"); |
214 | str = tape_state_verbose[device->tape_state]; | 214 | if (device->tape_state < TS_SIZE && device->tape_state >=0 ) |
215 | else | ||
216 | str = "UNKNOWN TS"; | ||
217 | DBF_EVENT(4, "old ts: %s\n", str); | ||
218 | if (device->tape_state < TO_SIZE && device->tape_state >=0 ) | ||
219 | str = tape_state_verbose[device->tape_state]; | 215 | str = tape_state_verbose[device->tape_state]; |
220 | else | 216 | else |
221 | str = "UNKNOWN TS"; | 217 | str = "UNKNOWN TS"; |
222 | DBF_EVENT(4, "%s\n", str); | 218 | DBF_EVENT(4, "%s\n", str); |
223 | DBF_EVENT(4, "new ts:\t\n"); | 219 | DBF_EVENT(4, "new ts:\t\n"); |
224 | if (newstate < TO_SIZE && newstate >= 0) | 220 | if (newstate < TS_SIZE && newstate >= 0) |
225 | str = tape_state_verbose[newstate]; | 221 | str = tape_state_verbose[newstate]; |
226 | else | 222 | else |
227 | str = "UNKNOWN TS"; | 223 | str = "UNKNOWN TS"; |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index cb8e2e672b68..0960bef7b199 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -414,11 +414,11 @@ cio_ignore_proc_init (void) | |||
414 | entry = create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR, | 414 | entry = create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR, |
415 | &proc_root); | 415 | &proc_root); |
416 | if (!entry) | 416 | if (!entry) |
417 | return 0; | 417 | return -ENOENT; |
418 | 418 | ||
419 | entry->proc_fops = &cio_ignore_proc_fops; | 419 | entry->proc_fops = &cio_ignore_proc_fops; |
420 | 420 | ||
421 | return 1; | 421 | return 0; |
422 | } | 422 | } |
423 | 423 | ||
424 | __initcall (cio_ignore_proc_init); | 424 | __initcall (cio_ignore_proc_init); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index cbb86fa5f293..5b20d8c9c025 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -67,7 +67,7 @@ cio_debug_init (void) | |||
67 | goto out_unregister; | 67 | goto out_unregister; |
68 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); | 68 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); |
69 | debug_set_level (cio_debug_msg_id, 2); | 69 | debug_set_level (cio_debug_msg_id, 2); |
70 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8); | 70 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 16); |
71 | if (!cio_debug_trace_id) | 71 | if (!cio_debug_trace_id) |
72 | goto out_unregister; | 72 | goto out_unregister; |
73 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); | 73 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); |
diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h index 6af8b27d366b..f88844adae1b 100644 --- a/drivers/s390/cio/cio_debug.h +++ b/drivers/s390/cio/cio_debug.h | |||
@@ -3,6 +3,11 @@ | |||
3 | 3 | ||
4 | #include <asm/debug.h> | 4 | #include <asm/debug.h> |
5 | 5 | ||
6 | /* for use of debug feature */ | ||
7 | extern debug_info_t *cio_debug_msg_id; | ||
8 | extern debug_info_t *cio_debug_trace_id; | ||
9 | extern debug_info_t *cio_debug_crw_id; | ||
10 | |||
6 | #define CIO_TRACE_EVENT(imp, txt) do { \ | 11 | #define CIO_TRACE_EVENT(imp, txt) do { \ |
7 | debug_text_event(cio_debug_trace_id, imp, txt); \ | 12 | debug_text_event(cio_debug_trace_id, imp, txt); \ |
8 | } while (0) | 13 | } while (0) |
@@ -15,18 +20,19 @@ | |||
15 | debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ | 20 | debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ |
16 | } while (0) | 21 | } while (0) |
17 | 22 | ||
18 | #define CIO_HEX_EVENT(imp, args...) do { \ | 23 | static inline void |
19 | debug_event(cio_debug_trace_id, imp, ##args); \ | 24 | CIO_HEX_EVENT(int level, void *data, int length) |
20 | } while (0) | 25 | { |
26 | while (length > 0) { | ||
27 | debug_event(cio_debug_trace_id, level, data, length); | ||
28 | length -= cio_debug_trace_id->buf_size; | ||
29 | data += cio_debug_trace_id->buf_size; | ||
30 | } | ||
31 | } | ||
21 | 32 | ||
22 | #define CIO_DEBUG(printk_level,event_level,msg...) ({ \ | 33 | #define CIO_DEBUG(printk_level,event_level,msg...) ({ \ |
23 | if (cio_show_msg) printk(printk_level msg); \ | 34 | if (cio_show_msg) printk(printk_level msg); \ |
24 | CIO_MSG_EVENT (event_level, msg); \ | 35 | CIO_MSG_EVENT (event_level, msg); \ |
25 | }) | 36 | }) |
26 | 37 | ||
27 | /* for use of debug feature */ | ||
28 | extern debug_info_t *cio_debug_msg_id; | ||
29 | extern debug_info_t *cio_debug_trace_id; | ||
30 | extern debug_info_t *cio_debug_crw_id; | ||
31 | |||
32 | #endif | 38 | #endif |
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 25f678d0780b..e8e41e6eb42a 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -1508,10 +1508,12 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id, | |||
1508 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; | 1508 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; |
1509 | void *buf; | 1509 | void *buf; |
1510 | unsigned int transfer_len; | 1510 | unsigned int transfer_len; |
1511 | unsigned long flags = 0; | ||
1511 | 1512 | ||
1512 | if (cmd->use_sg) { | 1513 | if (cmd->use_sg) { |
1513 | struct scatterlist *sg = | 1514 | struct scatterlist *sg = |
1514 | (struct scatterlist *)cmd->request_buffer; | 1515 | (struct scatterlist *)cmd->request_buffer; |
1516 | local_irq_save(flags); | ||
1515 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | 1517 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; |
1516 | transfer_len = min(sg->length, len); | 1518 | transfer_len = min(sg->length, len); |
1517 | } else { | 1519 | } else { |
@@ -1526,6 +1528,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id, | |||
1526 | 1528 | ||
1527 | sg = (struct scatterlist *)cmd->request_buffer; | 1529 | sg = (struct scatterlist *)cmd->request_buffer; |
1528 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 1530 | kunmap_atomic(buf - sg->offset, KM_IRQ0); |
1531 | local_irq_restore(flags); | ||
1529 | } | 1532 | } |
1530 | } | 1533 | } |
1531 | 1534 | ||
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index ff48066d4c4f..20fc0846e0be 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = { | |||
207 | .name = DRV_NAME, | 207 | .name = DRV_NAME, |
208 | .ioctl = ata_scsi_ioctl, | 208 | .ioctl = ata_scsi_ioctl, |
209 | .queuecommand = ata_scsi_queuecmd, | 209 | .queuecommand = ata_scsi_queuecmd, |
210 | .eh_strategy_handler = ata_scsi_error, | ||
211 | .can_queue = ATA_DEF_QUEUE, | 210 | .can_queue = ATA_DEF_QUEUE, |
212 | .this_id = ATA_SHT_THIS_ID, | 211 | .this_id = ATA_SHT_THIS_ID, |
213 | .sg_tablesize = AHCI_MAX_SG, | 212 | .sg_tablesize = AHCI_MAX_SG, |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 83839706f5e0..62dabf74188e 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -209,7 +209,6 @@ static struct scsi_host_template piix_sht = { | |||
209 | .name = DRV_NAME, | 209 | .name = DRV_NAME, |
210 | .ioctl = ata_scsi_ioctl, | 210 | .ioctl = ata_scsi_ioctl, |
211 | .queuecommand = ata_scsi_queuecmd, | 211 | .queuecommand = ata_scsi_queuecmd, |
212 | .eh_strategy_handler = ata_scsi_error, | ||
213 | .can_queue = ATA_DEF_QUEUE, | 212 | .can_queue = ATA_DEF_QUEUE, |
214 | .this_id = ATA_SHT_THIS_ID, | 213 | .this_id = ATA_SHT_THIS_ID, |
215 | .sg_tablesize = LIBATA_MAX_PRD, | 214 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ef57f253031c..dfcb96f3e60c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -294,18 +294,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
294 | if (sht->unchecked_isa_dma && privsize) | 294 | if (sht->unchecked_isa_dma && privsize) |
295 | gfp_mask |= __GFP_DMA; | 295 | gfp_mask |= __GFP_DMA; |
296 | 296 | ||
297 | /* Check to see if this host has any error handling facilities */ | ||
298 | if (!sht->eh_strategy_handler && !sht->eh_abort_handler && | ||
299 | !sht->eh_device_reset_handler && !sht->eh_bus_reset_handler && | ||
300 | !sht->eh_host_reset_handler) { | ||
301 | printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n" | ||
302 | "ERROR: This is not a safe way to run your " | ||
303 | "SCSI host\n" | ||
304 | "ERROR: The error handling must be added to " | ||
305 | "this driver\n", sht->proc_name); | ||
306 | dump_stack(); | ||
307 | } | ||
308 | |||
309 | shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); | 297 | shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); |
310 | if (!shost) | 298 | if (!shost) |
311 | return NULL; | 299 | return NULL; |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index c9c001490293..5ae7613bc157 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -98,6 +98,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { | |||
98 | * It just needs the eh_timed_out hook. | 98 | * It just needs the eh_timed_out hook. |
99 | */ | 99 | */ |
100 | struct scsi_transport_template ata_scsi_transport_template = { | 100 | struct scsi_transport_template ata_scsi_transport_template = { |
101 | .eh_strategy_handler = ata_scsi_error, | ||
101 | .eh_timed_out = ata_scsi_timed_out, | 102 | .eh_timed_out = ata_scsi_timed_out, |
102 | }; | 103 | }; |
103 | 104 | ||
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 1364b1da9e2a..b9a3c566f833 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c | |||
@@ -143,7 +143,6 @@ static struct scsi_host_template adma_ata_sht = { | |||
143 | .name = DRV_NAME, | 143 | .name = DRV_NAME, |
144 | .ioctl = ata_scsi_ioctl, | 144 | .ioctl = ata_scsi_ioctl, |
145 | .queuecommand = ata_scsi_queuecmd, | 145 | .queuecommand = ata_scsi_queuecmd, |
146 | .eh_strategy_handler = ata_scsi_error, | ||
147 | .can_queue = ATA_DEF_QUEUE, | 146 | .can_queue = ATA_DEF_QUEUE, |
148 | .this_id = ATA_SHT_THIS_ID, | 147 | .this_id = ATA_SHT_THIS_ID, |
149 | .sg_tablesize = LIBATA_MAX_PRD, | 148 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index e9152f850003..4aabc759fcec 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -378,7 +378,6 @@ static struct scsi_host_template mv_sht = { | |||
378 | .name = DRV_NAME, | 378 | .name = DRV_NAME, |
379 | .ioctl = ata_scsi_ioctl, | 379 | .ioctl = ata_scsi_ioctl, |
380 | .queuecommand = ata_scsi_queuecmd, | 380 | .queuecommand = ata_scsi_queuecmd, |
381 | .eh_strategy_handler = ata_scsi_error, | ||
382 | .can_queue = MV_USE_Q_DEPTH, | 381 | .can_queue = MV_USE_Q_DEPTH, |
383 | .this_id = ATA_SHT_THIS_ID, | 382 | .this_id = ATA_SHT_THIS_ID, |
384 | .sg_tablesize = MV_MAX_SG_CT / 2, | 383 | .sg_tablesize = MV_MAX_SG_CT / 2, |
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index c92fbd0989bd..3a70875be8ba 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
@@ -201,7 +201,6 @@ static struct scsi_host_template nv_sht = { | |||
201 | .name = DRV_NAME, | 201 | .name = DRV_NAME, |
202 | .ioctl = ata_scsi_ioctl, | 202 | .ioctl = ata_scsi_ioctl, |
203 | .queuecommand = ata_scsi_queuecmd, | 203 | .queuecommand = ata_scsi_queuecmd, |
204 | .eh_strategy_handler = ata_scsi_error, | ||
205 | .can_queue = ATA_DEF_QUEUE, | 204 | .can_queue = ATA_DEF_QUEUE, |
206 | .this_id = ATA_SHT_THIS_ID, | 205 | .this_id = ATA_SHT_THIS_ID, |
207 | .sg_tablesize = LIBATA_MAX_PRD, | 206 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 000844a4129f..ddbc0c6dd9fe 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -111,7 +111,6 @@ static struct scsi_host_template pdc_ata_sht = { | |||
111 | .name = DRV_NAME, | 111 | .name = DRV_NAME, |
112 | .ioctl = ata_scsi_ioctl, | 112 | .ioctl = ata_scsi_ioctl, |
113 | .queuecommand = ata_scsi_queuecmd, | 113 | .queuecommand = ata_scsi_queuecmd, |
114 | .eh_strategy_handler = ata_scsi_error, | ||
115 | .can_queue = ATA_DEF_QUEUE, | 114 | .can_queue = ATA_DEF_QUEUE, |
116 | .this_id = ATA_SHT_THIS_ID, | 115 | .this_id = ATA_SHT_THIS_ID, |
117 | .sg_tablesize = LIBATA_MAX_PRD, | 116 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 0b5446ada5ca..259c2dec4e21 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -132,7 +132,6 @@ static struct scsi_host_template qs_ata_sht = { | |||
132 | .name = DRV_NAME, | 132 | .name = DRV_NAME, |
133 | .ioctl = ata_scsi_ioctl, | 133 | .ioctl = ata_scsi_ioctl, |
134 | .queuecommand = ata_scsi_queuecmd, | 134 | .queuecommand = ata_scsi_queuecmd, |
135 | .eh_strategy_handler = ata_scsi_error, | ||
136 | .can_queue = ATA_DEF_QUEUE, | 135 | .can_queue = ATA_DEF_QUEUE, |
137 | .this_id = ATA_SHT_THIS_ID, | 136 | .this_id = ATA_SHT_THIS_ID, |
138 | .sg_tablesize = QS_MAX_PRD, | 137 | .sg_tablesize = QS_MAX_PRD, |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index f29c3e733a00..c9333577330e 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -146,7 +146,6 @@ static struct scsi_host_template sil_sht = { | |||
146 | .name = DRV_NAME, | 146 | .name = DRV_NAME, |
147 | .ioctl = ata_scsi_ioctl, | 147 | .ioctl = ata_scsi_ioctl, |
148 | .queuecommand = ata_scsi_queuecmd, | 148 | .queuecommand = ata_scsi_queuecmd, |
149 | .eh_strategy_handler = ata_scsi_error, | ||
150 | .can_queue = ATA_DEF_QUEUE, | 149 | .can_queue = ATA_DEF_QUEUE, |
151 | .this_id = ATA_SHT_THIS_ID, | 150 | .this_id = ATA_SHT_THIS_ID, |
152 | .sg_tablesize = LIBATA_MAX_PRD, | 151 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 646756abb10e..9aa7493ea146 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -281,7 +281,6 @@ static struct scsi_host_template sil24_sht = { | |||
281 | .name = DRV_NAME, | 281 | .name = DRV_NAME, |
282 | .ioctl = ata_scsi_ioctl, | 282 | .ioctl = ata_scsi_ioctl, |
283 | .queuecommand = ata_scsi_queuecmd, | 283 | .queuecommand = ata_scsi_queuecmd, |
284 | .eh_strategy_handler = ata_scsi_error, | ||
285 | .can_queue = ATA_DEF_QUEUE, | 284 | .can_queue = ATA_DEF_QUEUE, |
286 | .this_id = ATA_SHT_THIS_ID, | 285 | .this_id = ATA_SHT_THIS_ID, |
287 | .sg_tablesize = LIBATA_MAX_PRD, | 286 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index eb3cf5b534dc..3097821688dc 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c | |||
@@ -87,7 +87,6 @@ static struct scsi_host_template sis_sht = { | |||
87 | .name = DRV_NAME, | 87 | .name = DRV_NAME, |
88 | .ioctl = ata_scsi_ioctl, | 88 | .ioctl = ata_scsi_ioctl, |
89 | .queuecommand = ata_scsi_queuecmd, | 89 | .queuecommand = ata_scsi_queuecmd, |
90 | .eh_strategy_handler = ata_scsi_error, | ||
91 | .can_queue = ATA_DEF_QUEUE, | 90 | .can_queue = ATA_DEF_QUEUE, |
92 | .this_id = ATA_SHT_THIS_ID, | 91 | .this_id = ATA_SHT_THIS_ID, |
93 | .sg_tablesize = ATA_MAX_PRD, | 92 | .sg_tablesize = ATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index a20bc8154753..e15c693e0539 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -290,7 +290,6 @@ static struct scsi_host_template k2_sata_sht = { | |||
290 | .name = DRV_NAME, | 290 | .name = DRV_NAME, |
291 | .ioctl = ata_scsi_ioctl, | 291 | .ioctl = ata_scsi_ioctl, |
292 | .queuecommand = ata_scsi_queuecmd, | 292 | .queuecommand = ata_scsi_queuecmd, |
293 | .eh_strategy_handler = ata_scsi_error, | ||
294 | .can_queue = ATA_DEF_QUEUE, | 293 | .can_queue = ATA_DEF_QUEUE, |
295 | .this_id = ATA_SHT_THIS_ID, | 294 | .this_id = ATA_SHT_THIS_ID, |
296 | .sg_tablesize = LIBATA_MAX_PRD, | 295 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 801ac3787d5d..a669d0589889 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -182,7 +182,6 @@ static struct scsi_host_template pdc_sata_sht = { | |||
182 | .name = DRV_NAME, | 182 | .name = DRV_NAME, |
183 | .ioctl = ata_scsi_ioctl, | 183 | .ioctl = ata_scsi_ioctl, |
184 | .queuecommand = ata_scsi_queuecmd, | 184 | .queuecommand = ata_scsi_queuecmd, |
185 | .eh_strategy_handler = ata_scsi_error, | ||
186 | .can_queue = ATA_DEF_QUEUE, | 185 | .can_queue = ATA_DEF_QUEUE, |
187 | .this_id = ATA_SHT_THIS_ID, | 186 | .this_id = ATA_SHT_THIS_ID, |
188 | .sg_tablesize = LIBATA_MAX_PRD, | 187 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 513dd78ea6fe..15f81bfc30f0 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c | |||
@@ -81,7 +81,6 @@ static struct scsi_host_template uli_sht = { | |||
81 | .name = DRV_NAME, | 81 | .name = DRV_NAME, |
82 | .ioctl = ata_scsi_ioctl, | 82 | .ioctl = ata_scsi_ioctl, |
83 | .queuecommand = ata_scsi_queuecmd, | 83 | .queuecommand = ata_scsi_queuecmd, |
84 | .eh_strategy_handler = ata_scsi_error, | ||
85 | .can_queue = ATA_DEF_QUEUE, | 84 | .can_queue = ATA_DEF_QUEUE, |
86 | .this_id = ATA_SHT_THIS_ID, | 85 | .this_id = ATA_SHT_THIS_ID, |
87 | .sg_tablesize = LIBATA_MAX_PRD, | 86 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index de4e0eb224bb..17aefab5f42f 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
@@ -94,7 +94,6 @@ static struct scsi_host_template svia_sht = { | |||
94 | .name = DRV_NAME, | 94 | .name = DRV_NAME, |
95 | .ioctl = ata_scsi_ioctl, | 95 | .ioctl = ata_scsi_ioctl, |
96 | .queuecommand = ata_scsi_queuecmd, | 96 | .queuecommand = ata_scsi_queuecmd, |
97 | .eh_strategy_handler = ata_scsi_error, | ||
98 | .can_queue = ATA_DEF_QUEUE, | 97 | .can_queue = ATA_DEF_QUEUE, |
99 | .this_id = ATA_SHT_THIS_ID, | 98 | .this_id = ATA_SHT_THIS_ID, |
100 | .sg_tablesize = LIBATA_MAX_PRD, | 99 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index cecc1f76256b..9646c3932129 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -263,7 +263,6 @@ static struct scsi_host_template vsc_sata_sht = { | |||
263 | .name = DRV_NAME, | 263 | .name = DRV_NAME, |
264 | .ioctl = ata_scsi_ioctl, | 264 | .ioctl = ata_scsi_ioctl, |
265 | .queuecommand = ata_scsi_queuecmd, | 265 | .queuecommand = ata_scsi_queuecmd, |
266 | .eh_strategy_handler = ata_scsi_error, | ||
267 | .can_queue = ATA_DEF_QUEUE, | 266 | .can_queue = ATA_DEF_QUEUE, |
268 | .this_id = ATA_SHT_THIS_ID, | 267 | .this_id = ATA_SHT_THIS_ID, |
269 | .sg_tablesize = LIBATA_MAX_PRD, | 268 | .sg_tablesize = LIBATA_MAX_PRD, |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5f0fdfb2618c..1c75646f9689 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1537,8 +1537,8 @@ int scsi_error_handler(void *data) | |||
1537 | * what we need to do to get it up and online again (if we can). | 1537 | * what we need to do to get it up and online again (if we can). |
1538 | * If we fail, we end up taking the thing offline. | 1538 | * If we fail, we end up taking the thing offline. |
1539 | */ | 1539 | */ |
1540 | if (shost->hostt->eh_strategy_handler) | 1540 | if (shost->transportt->eh_strategy_handler) |
1541 | shost->hostt->eh_strategy_handler(shost); | 1541 | shost->transportt->eh_strategy_handler(shost); |
1542 | else | 1542 | else |
1543 | scsi_unjam_host(shost); | 1543 | scsi_unjam_host(shost); |
1544 | 1544 | ||
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 93449a1a0065..0b49ff78efc1 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/dma-mapping.h> | ||
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
@@ -619,9 +620,9 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
619 | pci_set_master(pdev); | 620 | pci_set_master(pdev); |
620 | 621 | ||
621 | #ifdef USE_64BIT_DMA | 622 | #ifdef USE_64BIT_DMA |
622 | ret = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); | 623 | ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK); |
623 | if (!ret) { | 624 | if (!ret) { |
624 | ret = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); | 625 | ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); |
625 | if (ret < 0) { | 626 | if (ret < 0) { |
626 | printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " | 627 | printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " |
627 | "for consistent allocations\n", | 628 | "for consistent allocations\n", |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 495db5755df9..5cf2b80add7a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard | 28 | 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard |
29 | 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes | 29 | 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes |
30 | wants to send >2000 bytes. | 30 | wants to send >2000 bytes. |
31 | 2006-04-10 v0.4.2 fixed two array overrun errors :-/ | ||
31 | 32 | ||
32 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> | 33 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> |
33 | 34 | ||
@@ -582,14 +583,14 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
582 | portdata = usb_get_serial_port_data(port); | 583 | portdata = usb_get_serial_port_data(port); |
583 | 584 | ||
584 | /* Do indat endpoints first */ | 585 | /* Do indat endpoints first */ |
585 | for (j = 0; j <= N_IN_URB; ++j) { | 586 | for (j = 0; j < N_IN_URB; ++j) { |
586 | portdata->in_urbs[j] = option_setup_urb (serial, | 587 | portdata->in_urbs[j] = option_setup_urb (serial, |
587 | port->bulk_in_endpointAddress, USB_DIR_IN, port, | 588 | port->bulk_in_endpointAddress, USB_DIR_IN, port, |
588 | portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); | 589 | portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); |
589 | } | 590 | } |
590 | 591 | ||
591 | /* outdat endpoints */ | 592 | /* outdat endpoints */ |
592 | for (j = 0; j <= N_OUT_URB; ++j) { | 593 | for (j = 0; j < N_OUT_URB; ++j) { |
593 | portdata->out_urbs[j] = option_setup_urb (serial, | 594 | portdata->out_urbs[j] = option_setup_urb (serial, |
594 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, | 595 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, |
595 | portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); | 596 | portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index f87c0171f4ec..9060e7137441 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -961,7 +961,7 @@ config FB_ATY128 | |||
961 | 961 | ||
962 | config FB_ATY | 962 | config FB_ATY |
963 | tristate "ATI Mach64 display support" if PCI || ATARI | 963 | tristate "ATI Mach64 display support" if PCI || ATARI |
964 | depends on FB | 964 | depends on FB && !SPARC32 |
965 | select FB_CFB_FILLRECT | 965 | select FB_CFB_FILLRECT |
966 | select FB_CFB_COPYAREA | 966 | select FB_CFB_COPYAREA |
967 | select FB_CFB_IMAGEBLIT | 967 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index b39e72d5413b..d9d7d3c4cae2 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -3400,7 +3400,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi | |||
3400 | struct atyfb_par *par; | 3400 | struct atyfb_par *par; |
3401 | int i, rc = -ENOMEM; | 3401 | int i, rc = -ENOMEM; |
3402 | 3402 | ||
3403 | for (i = ARRAY_SIZE(aty_chips); i >= 0; i--) | 3403 | for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) |
3404 | if (pdev->device == aty_chips[i].pci_id) | 3404 | if (pdev->device == aty_chips[i].pci_id) |
3405 | break; | 3405 | break; |
3406 | 3406 | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 944855b3e4af..8d8eadb64853 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -435,6 +435,11 @@ int fb_prepare_logo(struct fb_info *info, int rotate) | |||
435 | depth = info->var.green.length; | 435 | depth = info->var.green.length; |
436 | } | 436 | } |
437 | 437 | ||
438 | if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { | ||
439 | /* assume console colormap */ | ||
440 | depth = 4; | ||
441 | } | ||
442 | |||
438 | if (depth >= 8) { | 443 | if (depth >= 8) { |
439 | switch (info->fix.visual) { | 444 | switch (info->fix.visual) { |
440 | case FB_VISUAL_TRUECOLOR: | 445 | case FB_VISUAL_TRUECOLOR: |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 8982e540214c..b0b9acfdd430 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -57,7 +57,7 @@ static unsigned short *pmi_base = NULL; | |||
57 | static void (*pmi_start)(void); | 57 | static void (*pmi_start)(void); |
58 | static void (*pmi_pal)(void); | 58 | static void (*pmi_pal)(void); |
59 | static int depth; | 59 | static int depth; |
60 | 60 | static int vga_compat; | |
61 | /* --------------------------------------------------------------------- */ | 61 | /* --------------------------------------------------------------------- */ |
62 | 62 | ||
63 | static int vesafb_pan_display(struct fb_var_screeninfo *var, | 63 | static int vesafb_pan_display(struct fb_var_screeninfo *var, |
@@ -83,9 +83,10 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, | |||
83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, | 83 | static void vesa_setpalette(int regno, unsigned red, unsigned green, |
84 | unsigned blue) | 84 | unsigned blue) |
85 | { | 85 | { |
86 | int shift = 16 - depth; | ||
87 | |||
86 | #ifdef __i386__ | 88 | #ifdef __i386__ |
87 | struct { u_char blue, green, red, pad; } entry; | 89 | struct { u_char blue, green, red, pad; } entry; |
88 | int shift = 16 - depth; | ||
89 | 90 | ||
90 | if (pmi_setpal) { | 91 | if (pmi_setpal) { |
91 | entry.red = red >> shift; | 92 | entry.red = red >> shift; |
@@ -101,14 +102,20 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, | |||
101 | "d" (regno), /* EDX */ | 102 | "d" (regno), /* EDX */ |
102 | "D" (&entry), /* EDI */ | 103 | "D" (&entry), /* EDI */ |
103 | "S" (&pmi_pal)); /* ESI */ | 104 | "S" (&pmi_pal)); /* ESI */ |
104 | } else { | 105 | return; |
105 | /* without protected mode interface, try VGA registers... */ | 106 | } |
107 | #endif | ||
108 | |||
109 | /* | ||
110 | * without protected mode interface and if VGA compatible, | ||
111 | * try VGA registers... | ||
112 | */ | ||
113 | if (vga_compat) { | ||
106 | outb_p(regno, dac_reg); | 114 | outb_p(regno, dac_reg); |
107 | outb_p(red >> shift, dac_val); | 115 | outb_p(red >> shift, dac_val); |
108 | outb_p(green >> shift, dac_val); | 116 | outb_p(green >> shift, dac_val); |
109 | outb_p(blue >> shift, dac_val); | 117 | outb_p(blue >> shift, dac_val); |
110 | } | 118 | } |
111 | #endif | ||
112 | } | 119 | } |
113 | 120 | ||
114 | static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, | 121 | static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, |
@@ -214,6 +221,7 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
214 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) | 221 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
215 | return -ENODEV; | 222 | return -ENODEV; |
216 | 223 | ||
224 | vga_compat = (screen_info.capabilities & 2) ? 0 : 1; | ||
217 | vesafb_fix.smem_start = screen_info.lfb_base; | 225 | vesafb_fix.smem_start = screen_info.lfb_base; |
218 | vesafb_defined.bits_per_pixel = screen_info.lfb_depth; | 226 | vesafb_defined.bits_per_pixel = screen_info.lfb_depth; |
219 | if (15 == vesafb_defined.bits_per_pixel) | 227 | if (15 == vesafb_defined.bits_per_pixel) |
@@ -318,6 +326,12 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
318 | } | 326 | } |
319 | } | 327 | } |
320 | 328 | ||
329 | if (vesafb_defined.bits_per_pixel == 8 && !pmi_setpal && !vga_compat) { | ||
330 | printk(KERN_WARNING "vesafb: hardware palette is unchangeable,\n" | ||
331 | " colors may be incorrect\n"); | ||
332 | vesafb_fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; | ||
333 | } | ||
334 | |||
321 | vesafb_defined.xres_virtual = vesafb_defined.xres; | 335 | vesafb_defined.xres_virtual = vesafb_defined.xres; |
322 | vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length; | 336 | vesafb_defined.yres_virtual = vesafb_fix.smem_len / vesafb_fix.line_length; |
323 | if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) { | 337 | if (ypan && vesafb_defined.yres_virtual > vesafb_defined.yres) { |
@@ -354,7 +368,8 @@ static int __init vesafb_probe(struct platform_device *dev) | |||
354 | printk(KERN_INFO "vesafb: %s: " | 368 | printk(KERN_INFO "vesafb: %s: " |
355 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", | 369 | "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", |
356 | (vesafb_defined.bits_per_pixel > 8) ? | 370 | (vesafb_defined.bits_per_pixel > 8) ? |
357 | "Truecolor" : "Pseudocolor", | 371 | "Truecolor" : (vga_compat || pmi_setpal) ? |
372 | "Pseudocolor" : "Static Pseudocolor", | ||
358 | screen_info.rsvd_size, | 373 | screen_info.rsvd_size, |
359 | screen_info.red_size, | 374 | screen_info.red_size, |
360 | screen_info.green_size, | 375 | screen_info.green_size, |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index b0a0ae509c00..61c599b4a1e3 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -127,12 +127,13 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
127 | 127 | ||
128 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { | 128 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { |
129 | dprintk(DEBUG_ERROR, "problem initiating session\n"); | 129 | dprintk(DEBUG_ERROR, "problem initiating session\n"); |
130 | kfree(v9ses); | 130 | sb = ERR_PTR(newfid); |
131 | return ERR_PTR(newfid); | 131 | goto out_free_session; |
132 | } | 132 | } |
133 | 133 | ||
134 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 134 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); |
135 | 135 | if (IS_ERR(sb)) | |
136 | goto out_close_session; | ||
136 | v9fs_fill_super(sb, v9ses, flags); | 137 | v9fs_fill_super(sb, v9ses, flags); |
137 | 138 | ||
138 | inode = v9fs_get_inode(sb, S_IFDIR | mode); | 139 | inode = v9fs_get_inode(sb, S_IFDIR | mode); |
@@ -185,6 +186,12 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
185 | 186 | ||
186 | return sb; | 187 | return sb; |
187 | 188 | ||
189 | out_close_session: | ||
190 | v9fs_session_close(v9ses); | ||
191 | out_free_session: | ||
192 | kfree(v9ses); | ||
193 | return sb; | ||
194 | |||
188 | put_back_sb: | 195 | put_back_sb: |
189 | /* deactivate_super calls v9fs_kill_super which will frees the rest */ | 196 | /* deactivate_super calls v9fs_kill_super which will frees the rest */ |
190 | up_write(&sb->s_umount); | 197 | up_write(&sb->s_umount); |
diff --git a/fs/Kconfig b/fs/Kconfig index e207be68d4ca..2524629dc835 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -799,6 +799,7 @@ config PROC_KCORE | |||
799 | config PROC_VMCORE | 799 | config PROC_VMCORE |
800 | bool "/proc/vmcore support (EXPERIMENTAL)" | 800 | bool "/proc/vmcore support (EXPERIMENTAL)" |
801 | depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP | 801 | depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP |
802 | default y | ||
802 | help | 803 | help |
803 | Exports the dump image of crashed kernel in ELF format. | 804 | Exports the dump image of crashed kernel in ELF format. |
804 | 805 | ||
@@ -861,7 +862,7 @@ config RAMFS | |||
861 | 862 | ||
862 | config CONFIGFS_FS | 863 | config CONFIGFS_FS |
863 | tristate "Userspace-driven configuration filesystem (EXPERIMENTAL)" | 864 | tristate "Userspace-driven configuration filesystem (EXPERIMENTAL)" |
864 | depends on EXPERIMENTAL | 865 | depends on SYSFS && EXPERIMENTAL |
865 | help | 866 | help |
866 | configfs is a ram-based filesystem that provides the converse | 867 | configfs is a ram-based filesystem that provides the converse |
867 | of sysfs's functionality. Where sysfs is a filesystem-based | 868 | of sysfs's functionality. Where sysfs is a filesystem-based |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 8ed9b06a9828..5638c8f9362f 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -504,7 +504,7 @@ static int populate_groups(struct config_group *group) | |||
504 | int ret = 0; | 504 | int ret = 0; |
505 | int i; | 505 | int i; |
506 | 506 | ||
507 | if (group && group->default_groups) { | 507 | if (group->default_groups) { |
508 | /* FYI, we're faking mkdir here | 508 | /* FYI, we're faking mkdir here |
509 | * I'm not sure we need this semaphore, as we're called | 509 | * I'm not sure we need this semaphore, as we're called |
510 | * from our parent's mkdir. That holds our parent's | 510 | * from our parent's mkdir. That holds our parent's |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 242fe1a66ce5..1b4491cdd115 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -599,7 +599,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) | |||
599 | switch (op) { | 599 | switch (op) { |
600 | case EPOLL_CTL_ADD: | 600 | case EPOLL_CTL_ADD: |
601 | if (!epi) { | 601 | if (!epi) { |
602 | epds.events |= POLLERR | POLLHUP | POLLRDHUP; | 602 | epds.events |= POLLERR | POLLHUP; |
603 | 603 | ||
604 | error = ep_insert(ep, &epds, tfile, fd); | 604 | error = ep_insert(ep, &epds, tfile, fd); |
605 | } else | 605 | } else |
@@ -613,7 +613,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event) | |||
613 | break; | 613 | break; |
614 | case EPOLL_CTL_MOD: | 614 | case EPOLL_CTL_MOD: |
615 | if (epi) { | 615 | if (epi) { |
616 | epds.events |= POLLERR | POLLHUP | POLLRDHUP; | 616 | epds.events |= POLLERR | POLLHUP; |
617 | error = ep_modify(ep, epi, &epds); | 617 | error = ep_modify(ep, epi, &epds); |
618 | } else | 618 | } else |
619 | error = -ENOENT; | 619 | error = -ENOENT; |
@@ -678,6 +678,18 @@ static int de_thread(struct task_struct *tsk) | |||
678 | while (leader->exit_state != EXIT_ZOMBIE) | 678 | while (leader->exit_state != EXIT_ZOMBIE) |
679 | yield(); | 679 | yield(); |
680 | 680 | ||
681 | /* | ||
682 | * The only record we have of the real-time age of a | ||
683 | * process, regardless of execs it's done, is start_time. | ||
684 | * All the past CPU time is accumulated in signal_struct | ||
685 | * from sister threads now dead. But in this non-leader | ||
686 | * exec, nothing survives from the original leader thread, | ||
687 | * whose birth marks the true age of this process now. | ||
688 | * When we take on its identity by switching to its PID, we | ||
689 | * also take its birthdate (always earlier than our own). | ||
690 | */ | ||
691 | current->start_time = leader->start_time; | ||
692 | |||
681 | spin_lock(&leader->proc_lock); | 693 | spin_lock(&leader->proc_lock); |
682 | spin_lock(¤t->proc_lock); | 694 | spin_lock(¤t->proc_lock); |
683 | proc_dentry1 = proc_pid_unhash(current); | 695 | proc_dentry1 = proc_pid_unhash(current); |
@@ -723,7 +735,12 @@ static int de_thread(struct task_struct *tsk) | |||
723 | current->parent = current->real_parent = leader->real_parent; | 735 | current->parent = current->real_parent = leader->real_parent; |
724 | leader->parent = leader->real_parent = child_reaper; | 736 | leader->parent = leader->real_parent = child_reaper; |
725 | current->group_leader = current; | 737 | current->group_leader = current; |
726 | leader->group_leader = leader; | 738 | leader->group_leader = current; |
739 | |||
740 | /* Reduce leader to a thread */ | ||
741 | detach_pid(leader, PIDTYPE_PGID); | ||
742 | detach_pid(leader, PIDTYPE_SID); | ||
743 | list_del_init(&leader->tasks); | ||
727 | 744 | ||
728 | add_parent(current); | 745 | add_parent(current); |
729 | add_parent(leader); | 746 | add_parent(leader); |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 1041dab6de2f..14f5f6ea3e72 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -974,6 +974,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
974 | if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { | 974 | if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { |
975 | ext3_warning(sb, __FUNCTION__, | 975 | ext3_warning(sb, __FUNCTION__, |
976 | "multiple resizers run on filesystem!"); | 976 | "multiple resizers run on filesystem!"); |
977 | unlock_super(sb); | ||
977 | err = -EBUSY; | 978 | err = -EBUSY; |
978 | goto exit_put; | 979 | goto exit_put; |
979 | } | 980 | } |
@@ -15,30 +15,35 @@ | |||
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/pipe_fs_i.h> | 16 | #include <linux/pipe_fs_i.h> |
17 | 17 | ||
18 | static void wait_for_partner(struct inode* inode, unsigned int* cnt) | 18 | static void wait_for_partner(struct inode* inode, unsigned int *cnt) |
19 | { | 19 | { |
20 | int cur = *cnt; | 20 | int cur = *cnt; |
21 | while(cur == *cnt) { | 21 | |
22 | pipe_wait(inode); | 22 | while (cur == *cnt) { |
23 | if(signal_pending(current)) | 23 | pipe_wait(inode->i_pipe); |
24 | if (signal_pending(current)) | ||
24 | break; | 25 | break; |
25 | } | 26 | } |
26 | } | 27 | } |
27 | 28 | ||
28 | static void wake_up_partner(struct inode* inode) | 29 | static void wake_up_partner(struct inode* inode) |
29 | { | 30 | { |
30 | wake_up_interruptible(PIPE_WAIT(*inode)); | 31 | wake_up_interruptible(&inode->i_pipe->wait); |
31 | } | 32 | } |
32 | 33 | ||
33 | static int fifo_open(struct inode *inode, struct file *filp) | 34 | static int fifo_open(struct inode *inode, struct file *filp) |
34 | { | 35 | { |
36 | struct pipe_inode_info *pipe; | ||
35 | int ret; | 37 | int ret; |
36 | 38 | ||
37 | mutex_lock(PIPE_MUTEX(*inode)); | 39 | mutex_lock(&inode->i_mutex); |
38 | if (!inode->i_pipe) { | 40 | pipe = inode->i_pipe; |
41 | if (!pipe) { | ||
39 | ret = -ENOMEM; | 42 | ret = -ENOMEM; |
40 | if(!pipe_new(inode)) | 43 | pipe = alloc_pipe_info(inode); |
44 | if (!pipe) | ||
41 | goto err_nocleanup; | 45 | goto err_nocleanup; |
46 | inode->i_pipe = pipe; | ||
42 | } | 47 | } |
43 | filp->f_version = 0; | 48 | filp->f_version = 0; |
44 | 49 | ||
@@ -53,18 +58,18 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
53 | * opened, even when there is no process writing the FIFO. | 58 | * opened, even when there is no process writing the FIFO. |
54 | */ | 59 | */ |
55 | filp->f_op = &read_fifo_fops; | 60 | filp->f_op = &read_fifo_fops; |
56 | PIPE_RCOUNTER(*inode)++; | 61 | pipe->r_counter++; |
57 | if (PIPE_READERS(*inode)++ == 0) | 62 | if (pipe->readers++ == 0) |
58 | wake_up_partner(inode); | 63 | wake_up_partner(inode); |
59 | 64 | ||
60 | if (!PIPE_WRITERS(*inode)) { | 65 | if (!pipe->writers) { |
61 | if ((filp->f_flags & O_NONBLOCK)) { | 66 | if ((filp->f_flags & O_NONBLOCK)) { |
62 | /* suppress POLLHUP until we have | 67 | /* suppress POLLHUP until we have |
63 | * seen a writer */ | 68 | * seen a writer */ |
64 | filp->f_version = PIPE_WCOUNTER(*inode); | 69 | filp->f_version = pipe->w_counter; |
65 | } else | 70 | } else |
66 | { | 71 | { |
67 | wait_for_partner(inode, &PIPE_WCOUNTER(*inode)); | 72 | wait_for_partner(inode, &pipe->w_counter); |
68 | if(signal_pending(current)) | 73 | if(signal_pending(current)) |
69 | goto err_rd; | 74 | goto err_rd; |
70 | } | 75 | } |
@@ -78,16 +83,16 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
78 | * errno=ENXIO when there is no process reading the FIFO. | 83 | * errno=ENXIO when there is no process reading the FIFO. |
79 | */ | 84 | */ |
80 | ret = -ENXIO; | 85 | ret = -ENXIO; |
81 | if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) | 86 | if ((filp->f_flags & O_NONBLOCK) && !pipe->readers) |
82 | goto err; | 87 | goto err; |
83 | 88 | ||
84 | filp->f_op = &write_fifo_fops; | 89 | filp->f_op = &write_fifo_fops; |
85 | PIPE_WCOUNTER(*inode)++; | 90 | pipe->w_counter++; |
86 | if (!PIPE_WRITERS(*inode)++) | 91 | if (!pipe->writers++) |
87 | wake_up_partner(inode); | 92 | wake_up_partner(inode); |
88 | 93 | ||
89 | if (!PIPE_READERS(*inode)) { | 94 | if (!pipe->readers) { |
90 | wait_for_partner(inode, &PIPE_RCOUNTER(*inode)); | 95 | wait_for_partner(inode, &pipe->r_counter); |
91 | if (signal_pending(current)) | 96 | if (signal_pending(current)) |
92 | goto err_wr; | 97 | goto err_wr; |
93 | } | 98 | } |
@@ -102,11 +107,11 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
102 | */ | 107 | */ |
103 | filp->f_op = &rdwr_fifo_fops; | 108 | filp->f_op = &rdwr_fifo_fops; |
104 | 109 | ||
105 | PIPE_READERS(*inode)++; | 110 | pipe->readers++; |
106 | PIPE_WRITERS(*inode)++; | 111 | pipe->writers++; |
107 | PIPE_RCOUNTER(*inode)++; | 112 | pipe->r_counter++; |
108 | PIPE_WCOUNTER(*inode)++; | 113 | pipe->w_counter++; |
109 | if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1) | 114 | if (pipe->readers == 1 || pipe->writers == 1) |
110 | wake_up_partner(inode); | 115 | wake_up_partner(inode); |
111 | break; | 116 | break; |
112 | 117 | ||
@@ -116,27 +121,27 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
116 | } | 121 | } |
117 | 122 | ||
118 | /* Ok! */ | 123 | /* Ok! */ |
119 | mutex_unlock(PIPE_MUTEX(*inode)); | 124 | mutex_unlock(&inode->i_mutex); |
120 | return 0; | 125 | return 0; |
121 | 126 | ||
122 | err_rd: | 127 | err_rd: |
123 | if (!--PIPE_READERS(*inode)) | 128 | if (!--pipe->readers) |
124 | wake_up_interruptible(PIPE_WAIT(*inode)); | 129 | wake_up_interruptible(&pipe->wait); |
125 | ret = -ERESTARTSYS; | 130 | ret = -ERESTARTSYS; |
126 | goto err; | 131 | goto err; |
127 | 132 | ||
128 | err_wr: | 133 | err_wr: |
129 | if (!--PIPE_WRITERS(*inode)) | 134 | if (!--pipe->writers) |
130 | wake_up_interruptible(PIPE_WAIT(*inode)); | 135 | wake_up_interruptible(&pipe->wait); |
131 | ret = -ERESTARTSYS; | 136 | ret = -ERESTARTSYS; |
132 | goto err; | 137 | goto err; |
133 | 138 | ||
134 | err: | 139 | err: |
135 | if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) | 140 | if (!pipe->readers && !pipe->writers) |
136 | free_pipe_info(inode); | 141 | free_pipe_info(inode); |
137 | 142 | ||
138 | err_nocleanup: | 143 | err_nocleanup: |
139 | mutex_unlock(PIPE_MUTEX(*inode)); | 144 | mutex_unlock(&inode->i_mutex); |
140 | return ret; | 145 | return ret; |
141 | } | 146 | } |
142 | 147 | ||
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 23d1f52eb1b8..6c740f860665 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -23,13 +23,11 @@ static kmem_cache_t *fuse_req_cachep; | |||
23 | 23 | ||
24 | static struct fuse_conn *fuse_get_conn(struct file *file) | 24 | static struct fuse_conn *fuse_get_conn(struct file *file) |
25 | { | 25 | { |
26 | struct fuse_conn *fc; | 26 | /* |
27 | spin_lock(&fuse_lock); | 27 | * Lockless access is OK, because file->private data is set |
28 | fc = file->private_data; | 28 | * once during mount and is valid until the file is released. |
29 | if (fc && !fc->connected) | 29 | */ |
30 | fc = NULL; | 30 | return file->private_data; |
31 | spin_unlock(&fuse_lock); | ||
32 | return fc; | ||
33 | } | 31 | } |
34 | 32 | ||
35 | static void fuse_request_init(struct fuse_req *req) | 33 | static void fuse_request_init(struct fuse_req *req) |
@@ -74,10 +72,8 @@ static void restore_sigs(sigset_t *oldset) | |||
74 | */ | 72 | */ |
75 | void fuse_reset_request(struct fuse_req *req) | 73 | void fuse_reset_request(struct fuse_req *req) |
76 | { | 74 | { |
77 | int preallocated = req->preallocated; | ||
78 | BUG_ON(atomic_read(&req->count) != 1); | 75 | BUG_ON(atomic_read(&req->count) != 1); |
79 | fuse_request_init(req); | 76 | fuse_request_init(req); |
80 | req->preallocated = preallocated; | ||
81 | } | 77 | } |
82 | 78 | ||
83 | static void __fuse_get_request(struct fuse_req *req) | 79 | static void __fuse_get_request(struct fuse_req *req) |
@@ -92,80 +88,52 @@ static void __fuse_put_request(struct fuse_req *req) | |||
92 | atomic_dec(&req->count); | 88 | atomic_dec(&req->count); |
93 | } | 89 | } |
94 | 90 | ||
95 | static struct fuse_req *do_get_request(struct fuse_conn *fc) | 91 | struct fuse_req *fuse_get_req(struct fuse_conn *fc) |
96 | { | 92 | { |
97 | struct fuse_req *req; | 93 | struct fuse_req *req; |
98 | |||
99 | spin_lock(&fuse_lock); | ||
100 | BUG_ON(list_empty(&fc->unused_list)); | ||
101 | req = list_entry(fc->unused_list.next, struct fuse_req, list); | ||
102 | list_del_init(&req->list); | ||
103 | spin_unlock(&fuse_lock); | ||
104 | fuse_request_init(req); | ||
105 | req->preallocated = 1; | ||
106 | req->in.h.uid = current->fsuid; | ||
107 | req->in.h.gid = current->fsgid; | ||
108 | req->in.h.pid = current->pid; | ||
109 | return req; | ||
110 | } | ||
111 | |||
112 | /* This can return NULL, but only in case it's interrupted by a SIGKILL */ | ||
113 | struct fuse_req *fuse_get_request(struct fuse_conn *fc) | ||
114 | { | ||
115 | int intr; | ||
116 | sigset_t oldset; | 94 | sigset_t oldset; |
95 | int err; | ||
117 | 96 | ||
118 | atomic_inc(&fc->num_waiting); | ||
119 | block_sigs(&oldset); | 97 | block_sigs(&oldset); |
120 | intr = down_interruptible(&fc->outstanding_sem); | 98 | err = wait_event_interruptible(fc->blocked_waitq, !fc->blocked); |
121 | restore_sigs(&oldset); | 99 | restore_sigs(&oldset); |
122 | if (intr) { | 100 | if (err) |
123 | atomic_dec(&fc->num_waiting); | 101 | return ERR_PTR(-EINTR); |
124 | return NULL; | ||
125 | } | ||
126 | return do_get_request(fc); | ||
127 | } | ||
128 | 102 | ||
129 | /* Must be called with fuse_lock held */ | 103 | req = fuse_request_alloc(); |
130 | static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) | 104 | if (!req) |
131 | { | 105 | return ERR_PTR(-ENOMEM); |
132 | if (req->preallocated) { | ||
133 | atomic_dec(&fc->num_waiting); | ||
134 | list_add(&req->list, &fc->unused_list); | ||
135 | } else | ||
136 | fuse_request_free(req); | ||
137 | 106 | ||
138 | /* If we are in debt decrease that first */ | 107 | atomic_inc(&fc->num_waiting); |
139 | if (fc->outstanding_debt) | 108 | fuse_request_init(req); |
140 | fc->outstanding_debt--; | 109 | req->in.h.uid = current->fsuid; |
141 | else | 110 | req->in.h.gid = current->fsgid; |
142 | up(&fc->outstanding_sem); | 111 | req->in.h.pid = current->pid; |
112 | return req; | ||
143 | } | 113 | } |
144 | 114 | ||
145 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | 115 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) |
146 | { | 116 | { |
147 | if (atomic_dec_and_test(&req->count)) { | 117 | if (atomic_dec_and_test(&req->count)) { |
148 | spin_lock(&fuse_lock); | 118 | atomic_dec(&fc->num_waiting); |
149 | fuse_putback_request(fc, req); | 119 | fuse_request_free(req); |
150 | spin_unlock(&fuse_lock); | ||
151 | } | 120 | } |
152 | } | 121 | } |
153 | 122 | ||
154 | static void fuse_put_request_locked(struct fuse_conn *fc, struct fuse_req *req) | 123 | void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req) |
155 | { | ||
156 | if (atomic_dec_and_test(&req->count)) | ||
157 | fuse_putback_request(fc, req); | ||
158 | } | ||
159 | |||
160 | void fuse_release_background(struct fuse_req *req) | ||
161 | { | 124 | { |
162 | iput(req->inode); | 125 | iput(req->inode); |
163 | iput(req->inode2); | 126 | iput(req->inode2); |
164 | if (req->file) | 127 | if (req->file) |
165 | fput(req->file); | 128 | fput(req->file); |
166 | spin_lock(&fuse_lock); | 129 | spin_lock(&fc->lock); |
167 | list_del(&req->bg_entry); | 130 | list_del(&req->bg_entry); |
168 | spin_unlock(&fuse_lock); | 131 | if (fc->num_background == FUSE_MAX_BACKGROUND) { |
132 | fc->blocked = 0; | ||
133 | wake_up_all(&fc->blocked_waitq); | ||
134 | } | ||
135 | fc->num_background--; | ||
136 | spin_unlock(&fc->lock); | ||
169 | } | 137 | } |
170 | 138 | ||
171 | /* | 139 | /* |
@@ -184,23 +152,23 @@ void fuse_release_background(struct fuse_req *req) | |||
184 | * interrupted and put in the background, it will return with an error | 152 | * interrupted and put in the background, it will return with an error |
185 | * and hence never be reset and reused. | 153 | * and hence never be reset and reused. |
186 | * | 154 | * |
187 | * Called with fuse_lock, unlocks it | 155 | * Called with fc->lock, unlocks it |
188 | */ | 156 | */ |
189 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) | 157 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
190 | { | 158 | { |
191 | list_del(&req->list); | 159 | list_del(&req->list); |
192 | req->state = FUSE_REQ_FINISHED; | 160 | req->state = FUSE_REQ_FINISHED; |
193 | if (!req->background) { | 161 | if (!req->background) { |
162 | spin_unlock(&fc->lock); | ||
194 | wake_up(&req->waitq); | 163 | wake_up(&req->waitq); |
195 | fuse_put_request_locked(fc, req); | 164 | fuse_put_request(fc, req); |
196 | spin_unlock(&fuse_lock); | ||
197 | } else { | 165 | } else { |
198 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | 166 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
199 | req->end = NULL; | 167 | req->end = NULL; |
200 | spin_unlock(&fuse_lock); | 168 | spin_unlock(&fc->lock); |
201 | down_read(&fc->sbput_sem); | 169 | down_read(&fc->sbput_sem); |
202 | if (fc->mounted) | 170 | if (fc->mounted) |
203 | fuse_release_background(req); | 171 | fuse_release_background(fc, req); |
204 | up_read(&fc->sbput_sem); | 172 | up_read(&fc->sbput_sem); |
205 | if (end) | 173 | if (end) |
206 | end(fc, req); | 174 | end(fc, req); |
@@ -242,6 +210,9 @@ static void background_request(struct fuse_conn *fc, struct fuse_req *req) | |||
242 | { | 210 | { |
243 | req->background = 1; | 211 | req->background = 1; |
244 | list_add(&req->bg_entry, &fc->background); | 212 | list_add(&req->bg_entry, &fc->background); |
213 | fc->num_background++; | ||
214 | if (fc->num_background == FUSE_MAX_BACKGROUND) | ||
215 | fc->blocked = 1; | ||
245 | if (req->inode) | 216 | if (req->inode) |
246 | req->inode = igrab(req->inode); | 217 | req->inode = igrab(req->inode); |
247 | if (req->inode2) | 218 | if (req->inode2) |
@@ -250,16 +221,16 @@ static void background_request(struct fuse_conn *fc, struct fuse_req *req) | |||
250 | get_file(req->file); | 221 | get_file(req->file); |
251 | } | 222 | } |
252 | 223 | ||
253 | /* Called with fuse_lock held. Releases, and then reacquires it. */ | 224 | /* Called with fc->lock held. Releases, and then reacquires it. */ |
254 | static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | 225 | static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) |
255 | { | 226 | { |
256 | sigset_t oldset; | 227 | sigset_t oldset; |
257 | 228 | ||
258 | spin_unlock(&fuse_lock); | 229 | spin_unlock(&fc->lock); |
259 | block_sigs(&oldset); | 230 | block_sigs(&oldset); |
260 | wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED); | 231 | wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED); |
261 | restore_sigs(&oldset); | 232 | restore_sigs(&oldset); |
262 | spin_lock(&fuse_lock); | 233 | spin_lock(&fc->lock); |
263 | if (req->state == FUSE_REQ_FINISHED && !req->interrupted) | 234 | if (req->state == FUSE_REQ_FINISHED && !req->interrupted) |
264 | return; | 235 | return; |
265 | 236 | ||
@@ -273,9 +244,9 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | |||
273 | locked state, there mustn't be any filesystem | 244 | locked state, there mustn't be any filesystem |
274 | operation (e.g. page fault), since that could lead | 245 | operation (e.g. page fault), since that could lead |
275 | to deadlock */ | 246 | to deadlock */ |
276 | spin_unlock(&fuse_lock); | 247 | spin_unlock(&fc->lock); |
277 | wait_event(req->waitq, !req->locked); | 248 | wait_event(req->waitq, !req->locked); |
278 | spin_lock(&fuse_lock); | 249 | spin_lock(&fc->lock); |
279 | } | 250 | } |
280 | if (req->state == FUSE_REQ_PENDING) { | 251 | if (req->state == FUSE_REQ_PENDING) { |
281 | list_del(&req->list); | 252 | list_del(&req->list); |
@@ -304,19 +275,10 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | |||
304 | req->in.h.unique = fc->reqctr; | 275 | req->in.h.unique = fc->reqctr; |
305 | req->in.h.len = sizeof(struct fuse_in_header) + | 276 | req->in.h.len = sizeof(struct fuse_in_header) + |
306 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); | 277 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); |
307 | if (!req->preallocated) { | ||
308 | /* If request is not preallocated (either FORGET or | ||
309 | RELEASE), then still decrease outstanding_sem, so | ||
310 | user can't open infinite number of files while not | ||
311 | processing the RELEASE requests. However for | ||
312 | efficiency do it without blocking, so if down() | ||
313 | would block, just increase the debt instead */ | ||
314 | if (down_trylock(&fc->outstanding_sem)) | ||
315 | fc->outstanding_debt++; | ||
316 | } | ||
317 | list_add_tail(&req->list, &fc->pending); | 278 | list_add_tail(&req->list, &fc->pending); |
318 | req->state = FUSE_REQ_PENDING; | 279 | req->state = FUSE_REQ_PENDING; |
319 | wake_up(&fc->waitq); | 280 | wake_up(&fc->waitq); |
281 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
320 | } | 282 | } |
321 | 283 | ||
322 | /* | 284 | /* |
@@ -325,7 +287,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | |||
325 | void request_send(struct fuse_conn *fc, struct fuse_req *req) | 287 | void request_send(struct fuse_conn *fc, struct fuse_req *req) |
326 | { | 288 | { |
327 | req->isreply = 1; | 289 | req->isreply = 1; |
328 | spin_lock(&fuse_lock); | 290 | spin_lock(&fc->lock); |
329 | if (!fc->connected) | 291 | if (!fc->connected) |
330 | req->out.h.error = -ENOTCONN; | 292 | req->out.h.error = -ENOTCONN; |
331 | else if (fc->conn_error) | 293 | else if (fc->conn_error) |
@@ -338,15 +300,16 @@ void request_send(struct fuse_conn *fc, struct fuse_req *req) | |||
338 | 300 | ||
339 | request_wait_answer(fc, req); | 301 | request_wait_answer(fc, req); |
340 | } | 302 | } |
341 | spin_unlock(&fuse_lock); | 303 | spin_unlock(&fc->lock); |
342 | } | 304 | } |
343 | 305 | ||
344 | static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) | 306 | static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) |
345 | { | 307 | { |
346 | spin_lock(&fuse_lock); | 308 | spin_lock(&fc->lock); |
309 | background_request(fc, req); | ||
347 | if (fc->connected) { | 310 | if (fc->connected) { |
348 | queue_request(fc, req); | 311 | queue_request(fc, req); |
349 | spin_unlock(&fuse_lock); | 312 | spin_unlock(&fc->lock); |
350 | } else { | 313 | } else { |
351 | req->out.h.error = -ENOTCONN; | 314 | req->out.h.error = -ENOTCONN; |
352 | request_end(fc, req); | 315 | request_end(fc, req); |
@@ -362,9 +325,6 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) | |||
362 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req) | 325 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req) |
363 | { | 326 | { |
364 | req->isreply = 1; | 327 | req->isreply = 1; |
365 | spin_lock(&fuse_lock); | ||
366 | background_request(fc, req); | ||
367 | spin_unlock(&fuse_lock); | ||
368 | request_send_nowait(fc, req); | 328 | request_send_nowait(fc, req); |
369 | } | 329 | } |
370 | 330 | ||
@@ -373,16 +333,16 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req) | |||
373 | * anything that could cause a page-fault. If the request was already | 333 | * anything that could cause a page-fault. If the request was already |
374 | * interrupted bail out. | 334 | * interrupted bail out. |
375 | */ | 335 | */ |
376 | static int lock_request(struct fuse_req *req) | 336 | static int lock_request(struct fuse_conn *fc, struct fuse_req *req) |
377 | { | 337 | { |
378 | int err = 0; | 338 | int err = 0; |
379 | if (req) { | 339 | if (req) { |
380 | spin_lock(&fuse_lock); | 340 | spin_lock(&fc->lock); |
381 | if (req->interrupted) | 341 | if (req->interrupted) |
382 | err = -ENOENT; | 342 | err = -ENOENT; |
383 | else | 343 | else |
384 | req->locked = 1; | 344 | req->locked = 1; |
385 | spin_unlock(&fuse_lock); | 345 | spin_unlock(&fc->lock); |
386 | } | 346 | } |
387 | return err; | 347 | return err; |
388 | } | 348 | } |
@@ -392,18 +352,19 @@ static int lock_request(struct fuse_req *req) | |||
392 | * requester thread is currently waiting for it to be unlocked, so | 352 | * requester thread is currently waiting for it to be unlocked, so |
393 | * wake it up. | 353 | * wake it up. |
394 | */ | 354 | */ |
395 | static void unlock_request(struct fuse_req *req) | 355 | static void unlock_request(struct fuse_conn *fc, struct fuse_req *req) |
396 | { | 356 | { |
397 | if (req) { | 357 | if (req) { |
398 | spin_lock(&fuse_lock); | 358 | spin_lock(&fc->lock); |
399 | req->locked = 0; | 359 | req->locked = 0; |
400 | if (req->interrupted) | 360 | if (req->interrupted) |
401 | wake_up(&req->waitq); | 361 | wake_up(&req->waitq); |
402 | spin_unlock(&fuse_lock); | 362 | spin_unlock(&fc->lock); |
403 | } | 363 | } |
404 | } | 364 | } |
405 | 365 | ||
406 | struct fuse_copy_state { | 366 | struct fuse_copy_state { |
367 | struct fuse_conn *fc; | ||
407 | int write; | 368 | int write; |
408 | struct fuse_req *req; | 369 | struct fuse_req *req; |
409 | const struct iovec *iov; | 370 | const struct iovec *iov; |
@@ -416,11 +377,12 @@ struct fuse_copy_state { | |||
416 | unsigned len; | 377 | unsigned len; |
417 | }; | 378 | }; |
418 | 379 | ||
419 | static void fuse_copy_init(struct fuse_copy_state *cs, int write, | 380 | static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, |
420 | struct fuse_req *req, const struct iovec *iov, | 381 | int write, struct fuse_req *req, |
421 | unsigned long nr_segs) | 382 | const struct iovec *iov, unsigned long nr_segs) |
422 | { | 383 | { |
423 | memset(cs, 0, sizeof(*cs)); | 384 | memset(cs, 0, sizeof(*cs)); |
385 | cs->fc = fc; | ||
424 | cs->write = write; | 386 | cs->write = write; |
425 | cs->req = req; | 387 | cs->req = req; |
426 | cs->iov = iov; | 388 | cs->iov = iov; |
@@ -450,7 +412,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
450 | unsigned long offset; | 412 | unsigned long offset; |
451 | int err; | 413 | int err; |
452 | 414 | ||
453 | unlock_request(cs->req); | 415 | unlock_request(cs->fc, cs->req); |
454 | fuse_copy_finish(cs); | 416 | fuse_copy_finish(cs); |
455 | if (!cs->seglen) { | 417 | if (!cs->seglen) { |
456 | BUG_ON(!cs->nr_segs); | 418 | BUG_ON(!cs->nr_segs); |
@@ -473,7 +435,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
473 | cs->seglen -= cs->len; | 435 | cs->seglen -= cs->len; |
474 | cs->addr += cs->len; | 436 | cs->addr += cs->len; |
475 | 437 | ||
476 | return lock_request(cs->req); | 438 | return lock_request(cs->fc, cs->req); |
477 | } | 439 | } |
478 | 440 | ||
479 | /* Do as much copy to/from userspace buffer as we can */ | 441 | /* Do as much copy to/from userspace buffer as we can */ |
@@ -585,9 +547,9 @@ static void request_wait(struct fuse_conn *fc) | |||
585 | if (signal_pending(current)) | 547 | if (signal_pending(current)) |
586 | break; | 548 | break; |
587 | 549 | ||
588 | spin_unlock(&fuse_lock); | 550 | spin_unlock(&fc->lock); |
589 | schedule(); | 551 | schedule(); |
590 | spin_lock(&fuse_lock); | 552 | spin_lock(&fc->lock); |
591 | } | 553 | } |
592 | set_current_state(TASK_RUNNING); | 554 | set_current_state(TASK_RUNNING); |
593 | remove_wait_queue(&fc->waitq, &wait); | 555 | remove_wait_queue(&fc->waitq, &wait); |
@@ -606,18 +568,21 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, | |||
606 | unsigned long nr_segs, loff_t *off) | 568 | unsigned long nr_segs, loff_t *off) |
607 | { | 569 | { |
608 | int err; | 570 | int err; |
609 | struct fuse_conn *fc; | ||
610 | struct fuse_req *req; | 571 | struct fuse_req *req; |
611 | struct fuse_in *in; | 572 | struct fuse_in *in; |
612 | struct fuse_copy_state cs; | 573 | struct fuse_copy_state cs; |
613 | unsigned reqsize; | 574 | unsigned reqsize; |
575 | struct fuse_conn *fc = fuse_get_conn(file); | ||
576 | if (!fc) | ||
577 | return -EPERM; | ||
614 | 578 | ||
615 | restart: | 579 | restart: |
616 | spin_lock(&fuse_lock); | 580 | spin_lock(&fc->lock); |
617 | fc = file->private_data; | 581 | err = -EAGAIN; |
618 | err = -EPERM; | 582 | if ((file->f_flags & O_NONBLOCK) && fc->connected && |
619 | if (!fc) | 583 | list_empty(&fc->pending)) |
620 | goto err_unlock; | 584 | goto err_unlock; |
585 | |||
621 | request_wait(fc); | 586 | request_wait(fc); |
622 | err = -ENODEV; | 587 | err = -ENODEV; |
623 | if (!fc->connected) | 588 | if (!fc->connected) |
@@ -641,14 +606,14 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, | |||
641 | request_end(fc, req); | 606 | request_end(fc, req); |
642 | goto restart; | 607 | goto restart; |
643 | } | 608 | } |
644 | spin_unlock(&fuse_lock); | 609 | spin_unlock(&fc->lock); |
645 | fuse_copy_init(&cs, 1, req, iov, nr_segs); | 610 | fuse_copy_init(&cs, fc, 1, req, iov, nr_segs); |
646 | err = fuse_copy_one(&cs, &in->h, sizeof(in->h)); | 611 | err = fuse_copy_one(&cs, &in->h, sizeof(in->h)); |
647 | if (!err) | 612 | if (!err) |
648 | err = fuse_copy_args(&cs, in->numargs, in->argpages, | 613 | err = fuse_copy_args(&cs, in->numargs, in->argpages, |
649 | (struct fuse_arg *) in->args, 0); | 614 | (struct fuse_arg *) in->args, 0); |
650 | fuse_copy_finish(&cs); | 615 | fuse_copy_finish(&cs); |
651 | spin_lock(&fuse_lock); | 616 | spin_lock(&fc->lock); |
652 | req->locked = 0; | 617 | req->locked = 0; |
653 | if (!err && req->interrupted) | 618 | if (!err && req->interrupted) |
654 | err = -ENOENT; | 619 | err = -ENOENT; |
@@ -663,12 +628,12 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, | |||
663 | else { | 628 | else { |
664 | req->state = FUSE_REQ_SENT; | 629 | req->state = FUSE_REQ_SENT; |
665 | list_move_tail(&req->list, &fc->processing); | 630 | list_move_tail(&req->list, &fc->processing); |
666 | spin_unlock(&fuse_lock); | 631 | spin_unlock(&fc->lock); |
667 | } | 632 | } |
668 | return reqsize; | 633 | return reqsize; |
669 | 634 | ||
670 | err_unlock: | 635 | err_unlock: |
671 | spin_unlock(&fuse_lock); | 636 | spin_unlock(&fc->lock); |
672 | return err; | 637 | return err; |
673 | } | 638 | } |
674 | 639 | ||
@@ -735,9 +700,9 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, | |||
735 | struct fuse_copy_state cs; | 700 | struct fuse_copy_state cs; |
736 | struct fuse_conn *fc = fuse_get_conn(file); | 701 | struct fuse_conn *fc = fuse_get_conn(file); |
737 | if (!fc) | 702 | if (!fc) |
738 | return -ENODEV; | 703 | return -EPERM; |
739 | 704 | ||
740 | fuse_copy_init(&cs, 0, NULL, iov, nr_segs); | 705 | fuse_copy_init(&cs, fc, 0, NULL, iov, nr_segs); |
741 | if (nbytes < sizeof(struct fuse_out_header)) | 706 | if (nbytes < sizeof(struct fuse_out_header)) |
742 | return -EINVAL; | 707 | return -EINVAL; |
743 | 708 | ||
@@ -749,7 +714,7 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, | |||
749 | oh.len != nbytes) | 714 | oh.len != nbytes) |
750 | goto err_finish; | 715 | goto err_finish; |
751 | 716 | ||
752 | spin_lock(&fuse_lock); | 717 | spin_lock(&fc->lock); |
753 | err = -ENOENT; | 718 | err = -ENOENT; |
754 | if (!fc->connected) | 719 | if (!fc->connected) |
755 | goto err_unlock; | 720 | goto err_unlock; |
@@ -760,9 +725,9 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, | |||
760 | goto err_unlock; | 725 | goto err_unlock; |
761 | 726 | ||
762 | if (req->interrupted) { | 727 | if (req->interrupted) { |
763 | spin_unlock(&fuse_lock); | 728 | spin_unlock(&fc->lock); |
764 | fuse_copy_finish(&cs); | 729 | fuse_copy_finish(&cs); |
765 | spin_lock(&fuse_lock); | 730 | spin_lock(&fc->lock); |
766 | request_end(fc, req); | 731 | request_end(fc, req); |
767 | return -ENOENT; | 732 | return -ENOENT; |
768 | } | 733 | } |
@@ -770,12 +735,12 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, | |||
770 | req->out.h = oh; | 735 | req->out.h = oh; |
771 | req->locked = 1; | 736 | req->locked = 1; |
772 | cs.req = req; | 737 | cs.req = req; |
773 | spin_unlock(&fuse_lock); | 738 | spin_unlock(&fc->lock); |
774 | 739 | ||
775 | err = copy_out_args(&cs, &req->out, nbytes); | 740 | err = copy_out_args(&cs, &req->out, nbytes); |
776 | fuse_copy_finish(&cs); | 741 | fuse_copy_finish(&cs); |
777 | 742 | ||
778 | spin_lock(&fuse_lock); | 743 | spin_lock(&fc->lock); |
779 | req->locked = 0; | 744 | req->locked = 0; |
780 | if (!err) { | 745 | if (!err) { |
781 | if (req->interrupted) | 746 | if (req->interrupted) |
@@ -787,7 +752,7 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, | |||
787 | return err ? err : nbytes; | 752 | return err ? err : nbytes; |
788 | 753 | ||
789 | err_unlock: | 754 | err_unlock: |
790 | spin_unlock(&fuse_lock); | 755 | spin_unlock(&fc->lock); |
791 | err_finish: | 756 | err_finish: |
792 | fuse_copy_finish(&cs); | 757 | fuse_copy_finish(&cs); |
793 | return err; | 758 | return err; |
@@ -804,18 +769,19 @@ static ssize_t fuse_dev_write(struct file *file, const char __user *buf, | |||
804 | 769 | ||
805 | static unsigned fuse_dev_poll(struct file *file, poll_table *wait) | 770 | static unsigned fuse_dev_poll(struct file *file, poll_table *wait) |
806 | { | 771 | { |
807 | struct fuse_conn *fc = fuse_get_conn(file); | ||
808 | unsigned mask = POLLOUT | POLLWRNORM; | 772 | unsigned mask = POLLOUT | POLLWRNORM; |
809 | 773 | struct fuse_conn *fc = fuse_get_conn(file); | |
810 | if (!fc) | 774 | if (!fc) |
811 | return -ENODEV; | 775 | return POLLERR; |
812 | 776 | ||
813 | poll_wait(file, &fc->waitq, wait); | 777 | poll_wait(file, &fc->waitq, wait); |
814 | 778 | ||
815 | spin_lock(&fuse_lock); | 779 | spin_lock(&fc->lock); |
816 | if (!list_empty(&fc->pending)) | 780 | if (!fc->connected) |
817 | mask |= POLLIN | POLLRDNORM; | 781 | mask = POLLERR; |
818 | spin_unlock(&fuse_lock); | 782 | else if (!list_empty(&fc->pending)) |
783 | mask |= POLLIN | POLLRDNORM; | ||
784 | spin_unlock(&fc->lock); | ||
819 | 785 | ||
820 | return mask; | 786 | return mask; |
821 | } | 787 | } |
@@ -823,7 +789,7 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait) | |||
823 | /* | 789 | /* |
824 | * Abort all requests on the given list (pending or processing) | 790 | * Abort all requests on the given list (pending or processing) |
825 | * | 791 | * |
826 | * This function releases and reacquires fuse_lock | 792 | * This function releases and reacquires fc->lock |
827 | */ | 793 | */ |
828 | static void end_requests(struct fuse_conn *fc, struct list_head *head) | 794 | static void end_requests(struct fuse_conn *fc, struct list_head *head) |
829 | { | 795 | { |
@@ -832,7 +798,7 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head) | |||
832 | req = list_entry(head->next, struct fuse_req, list); | 798 | req = list_entry(head->next, struct fuse_req, list); |
833 | req->out.h.error = -ECONNABORTED; | 799 | req->out.h.error = -ECONNABORTED; |
834 | request_end(fc, req); | 800 | request_end(fc, req); |
835 | spin_lock(&fuse_lock); | 801 | spin_lock(&fc->lock); |
836 | } | 802 | } |
837 | } | 803 | } |
838 | 804 | ||
@@ -863,10 +829,10 @@ static void end_io_requests(struct fuse_conn *fc) | |||
863 | req->end = NULL; | 829 | req->end = NULL; |
864 | /* The end function will consume this reference */ | 830 | /* The end function will consume this reference */ |
865 | __fuse_get_request(req); | 831 | __fuse_get_request(req); |
866 | spin_unlock(&fuse_lock); | 832 | spin_unlock(&fc->lock); |
867 | wait_event(req->waitq, !req->locked); | 833 | wait_event(req->waitq, !req->locked); |
868 | end(fc, req); | 834 | end(fc, req); |
869 | spin_lock(&fuse_lock); | 835 | spin_lock(&fc->lock); |
870 | } | 836 | } |
871 | } | 837 | } |
872 | } | 838 | } |
@@ -893,35 +859,44 @@ static void end_io_requests(struct fuse_conn *fc) | |||
893 | */ | 859 | */ |
894 | void fuse_abort_conn(struct fuse_conn *fc) | 860 | void fuse_abort_conn(struct fuse_conn *fc) |
895 | { | 861 | { |
896 | spin_lock(&fuse_lock); | 862 | spin_lock(&fc->lock); |
897 | if (fc->connected) { | 863 | if (fc->connected) { |
898 | fc->connected = 0; | 864 | fc->connected = 0; |
899 | end_io_requests(fc); | 865 | end_io_requests(fc); |
900 | end_requests(fc, &fc->pending); | 866 | end_requests(fc, &fc->pending); |
901 | end_requests(fc, &fc->processing); | 867 | end_requests(fc, &fc->processing); |
902 | wake_up_all(&fc->waitq); | 868 | wake_up_all(&fc->waitq); |
869 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
903 | } | 870 | } |
904 | spin_unlock(&fuse_lock); | 871 | spin_unlock(&fc->lock); |
905 | } | 872 | } |
906 | 873 | ||
907 | static int fuse_dev_release(struct inode *inode, struct file *file) | 874 | static int fuse_dev_release(struct inode *inode, struct file *file) |
908 | { | 875 | { |
909 | struct fuse_conn *fc; | 876 | struct fuse_conn *fc = fuse_get_conn(file); |
910 | |||
911 | spin_lock(&fuse_lock); | ||
912 | fc = file->private_data; | ||
913 | if (fc) { | 877 | if (fc) { |
878 | spin_lock(&fc->lock); | ||
914 | fc->connected = 0; | 879 | fc->connected = 0; |
915 | end_requests(fc, &fc->pending); | 880 | end_requests(fc, &fc->pending); |
916 | end_requests(fc, &fc->processing); | 881 | end_requests(fc, &fc->processing); |
917 | } | 882 | spin_unlock(&fc->lock); |
918 | spin_unlock(&fuse_lock); | 883 | fasync_helper(-1, file, 0, &fc->fasync); |
919 | if (fc) | ||
920 | kobject_put(&fc->kobj); | 884 | kobject_put(&fc->kobj); |
885 | } | ||
921 | 886 | ||
922 | return 0; | 887 | return 0; |
923 | } | 888 | } |
924 | 889 | ||
890 | static int fuse_dev_fasync(int fd, struct file *file, int on) | ||
891 | { | ||
892 | struct fuse_conn *fc = fuse_get_conn(file); | ||
893 | if (!fc) | ||
894 | return -EPERM; | ||
895 | |||
896 | /* No locking - fasync_helper does its own locking */ | ||
897 | return fasync_helper(fd, file, on, &fc->fasync); | ||
898 | } | ||
899 | |||
925 | const struct file_operations fuse_dev_operations = { | 900 | const struct file_operations fuse_dev_operations = { |
926 | .owner = THIS_MODULE, | 901 | .owner = THIS_MODULE, |
927 | .llseek = no_llseek, | 902 | .llseek = no_llseek, |
@@ -931,6 +906,7 @@ const struct file_operations fuse_dev_operations = { | |||
931 | .writev = fuse_dev_writev, | 906 | .writev = fuse_dev_writev, |
932 | .poll = fuse_dev_poll, | 907 | .poll = fuse_dev_poll, |
933 | .release = fuse_dev_release, | 908 | .release = fuse_dev_release, |
909 | .fasync = fuse_dev_fasync, | ||
934 | }; | 910 | }; |
935 | 911 | ||
936 | static struct miscdevice fuse_miscdevice = { | 912 | static struct miscdevice fuse_miscdevice = { |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 256355b80256..8d7546e832e8 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -117,8 +117,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
117 | return 0; | 117 | return 0; |
118 | 118 | ||
119 | fc = get_fuse_conn(inode); | 119 | fc = get_fuse_conn(inode); |
120 | req = fuse_get_request(fc); | 120 | req = fuse_get_req(fc); |
121 | if (!req) | 121 | if (IS_ERR(req)) |
122 | return 0; | 122 | return 0; |
123 | 123 | ||
124 | fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg); | 124 | fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg); |
@@ -188,9 +188,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
188 | if (entry->d_name.len > FUSE_NAME_MAX) | 188 | if (entry->d_name.len > FUSE_NAME_MAX) |
189 | return ERR_PTR(-ENAMETOOLONG); | 189 | return ERR_PTR(-ENAMETOOLONG); |
190 | 190 | ||
191 | req = fuse_get_request(fc); | 191 | req = fuse_get_req(fc); |
192 | if (!req) | 192 | if (IS_ERR(req)) |
193 | return ERR_PTR(-EINTR); | 193 | return ERR_PTR(PTR_ERR(req)); |
194 | 194 | ||
195 | fuse_lookup_init(req, dir, entry, &outarg); | 195 | fuse_lookup_init(req, dir, entry, &outarg); |
196 | request_send(fc, req); | 196 | request_send(fc, req); |
@@ -244,15 +244,14 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
244 | struct file *file; | 244 | struct file *file; |
245 | int flags = nd->intent.open.flags - 1; | 245 | int flags = nd->intent.open.flags - 1; |
246 | 246 | ||
247 | err = -ENOSYS; | ||
248 | if (fc->no_create) | 247 | if (fc->no_create) |
249 | goto out; | 248 | return -ENOSYS; |
250 | 249 | ||
251 | err = -EINTR; | 250 | req = fuse_get_req(fc); |
252 | req = fuse_get_request(fc); | 251 | if (IS_ERR(req)) |
253 | if (!req) | 252 | return PTR_ERR(req); |
254 | goto out; | ||
255 | 253 | ||
254 | err = -ENOMEM; | ||
256 | ff = fuse_file_alloc(); | 255 | ff = fuse_file_alloc(); |
257 | if (!ff) | 256 | if (!ff) |
258 | goto out_put_request; | 257 | goto out_put_request; |
@@ -314,7 +313,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
314 | fuse_file_free(ff); | 313 | fuse_file_free(ff); |
315 | out_put_request: | 314 | out_put_request: |
316 | fuse_put_request(fc, req); | 315 | fuse_put_request(fc, req); |
317 | out: | ||
318 | return err; | 316 | return err; |
319 | } | 317 | } |
320 | 318 | ||
@@ -375,9 +373,9 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode, | |||
375 | { | 373 | { |
376 | struct fuse_mknod_in inarg; | 374 | struct fuse_mknod_in inarg; |
377 | struct fuse_conn *fc = get_fuse_conn(dir); | 375 | struct fuse_conn *fc = get_fuse_conn(dir); |
378 | struct fuse_req *req = fuse_get_request(fc); | 376 | struct fuse_req *req = fuse_get_req(fc); |
379 | if (!req) | 377 | if (IS_ERR(req)) |
380 | return -EINTR; | 378 | return PTR_ERR(req); |
381 | 379 | ||
382 | memset(&inarg, 0, sizeof(inarg)); | 380 | memset(&inarg, 0, sizeof(inarg)); |
383 | inarg.mode = mode; | 381 | inarg.mode = mode; |
@@ -407,9 +405,9 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode) | |||
407 | { | 405 | { |
408 | struct fuse_mkdir_in inarg; | 406 | struct fuse_mkdir_in inarg; |
409 | struct fuse_conn *fc = get_fuse_conn(dir); | 407 | struct fuse_conn *fc = get_fuse_conn(dir); |
410 | struct fuse_req *req = fuse_get_request(fc); | 408 | struct fuse_req *req = fuse_get_req(fc); |
411 | if (!req) | 409 | if (IS_ERR(req)) |
412 | return -EINTR; | 410 | return PTR_ERR(req); |
413 | 411 | ||
414 | memset(&inarg, 0, sizeof(inarg)); | 412 | memset(&inarg, 0, sizeof(inarg)); |
415 | inarg.mode = mode; | 413 | inarg.mode = mode; |
@@ -427,9 +425,9 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry, | |||
427 | { | 425 | { |
428 | struct fuse_conn *fc = get_fuse_conn(dir); | 426 | struct fuse_conn *fc = get_fuse_conn(dir); |
429 | unsigned len = strlen(link) + 1; | 427 | unsigned len = strlen(link) + 1; |
430 | struct fuse_req *req = fuse_get_request(fc); | 428 | struct fuse_req *req = fuse_get_req(fc); |
431 | if (!req) | 429 | if (IS_ERR(req)) |
432 | return -EINTR; | 430 | return PTR_ERR(req); |
433 | 431 | ||
434 | req->in.h.opcode = FUSE_SYMLINK; | 432 | req->in.h.opcode = FUSE_SYMLINK; |
435 | req->in.numargs = 2; | 433 | req->in.numargs = 2; |
@@ -444,9 +442,9 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) | |||
444 | { | 442 | { |
445 | int err; | 443 | int err; |
446 | struct fuse_conn *fc = get_fuse_conn(dir); | 444 | struct fuse_conn *fc = get_fuse_conn(dir); |
447 | struct fuse_req *req = fuse_get_request(fc); | 445 | struct fuse_req *req = fuse_get_req(fc); |
448 | if (!req) | 446 | if (IS_ERR(req)) |
449 | return -EINTR; | 447 | return PTR_ERR(req); |
450 | 448 | ||
451 | req->in.h.opcode = FUSE_UNLINK; | 449 | req->in.h.opcode = FUSE_UNLINK; |
452 | req->in.h.nodeid = get_node_id(dir); | 450 | req->in.h.nodeid = get_node_id(dir); |
@@ -476,9 +474,9 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
476 | { | 474 | { |
477 | int err; | 475 | int err; |
478 | struct fuse_conn *fc = get_fuse_conn(dir); | 476 | struct fuse_conn *fc = get_fuse_conn(dir); |
479 | struct fuse_req *req = fuse_get_request(fc); | 477 | struct fuse_req *req = fuse_get_req(fc); |
480 | if (!req) | 478 | if (IS_ERR(req)) |
481 | return -EINTR; | 479 | return PTR_ERR(req); |
482 | 480 | ||
483 | req->in.h.opcode = FUSE_RMDIR; | 481 | req->in.h.opcode = FUSE_RMDIR; |
484 | req->in.h.nodeid = get_node_id(dir); | 482 | req->in.h.nodeid = get_node_id(dir); |
@@ -504,9 +502,9 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
504 | int err; | 502 | int err; |
505 | struct fuse_rename_in inarg; | 503 | struct fuse_rename_in inarg; |
506 | struct fuse_conn *fc = get_fuse_conn(olddir); | 504 | struct fuse_conn *fc = get_fuse_conn(olddir); |
507 | struct fuse_req *req = fuse_get_request(fc); | 505 | struct fuse_req *req = fuse_get_req(fc); |
508 | if (!req) | 506 | if (IS_ERR(req)) |
509 | return -EINTR; | 507 | return PTR_ERR(req); |
510 | 508 | ||
511 | memset(&inarg, 0, sizeof(inarg)); | 509 | memset(&inarg, 0, sizeof(inarg)); |
512 | inarg.newdir = get_node_id(newdir); | 510 | inarg.newdir = get_node_id(newdir); |
@@ -553,9 +551,9 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, | |||
553 | struct fuse_link_in inarg; | 551 | struct fuse_link_in inarg; |
554 | struct inode *inode = entry->d_inode; | 552 | struct inode *inode = entry->d_inode; |
555 | struct fuse_conn *fc = get_fuse_conn(inode); | 553 | struct fuse_conn *fc = get_fuse_conn(inode); |
556 | struct fuse_req *req = fuse_get_request(fc); | 554 | struct fuse_req *req = fuse_get_req(fc); |
557 | if (!req) | 555 | if (IS_ERR(req)) |
558 | return -EINTR; | 556 | return PTR_ERR(req); |
559 | 557 | ||
560 | memset(&inarg, 0, sizeof(inarg)); | 558 | memset(&inarg, 0, sizeof(inarg)); |
561 | inarg.oldnodeid = get_node_id(inode); | 559 | inarg.oldnodeid = get_node_id(inode); |
@@ -583,9 +581,9 @@ int fuse_do_getattr(struct inode *inode) | |||
583 | int err; | 581 | int err; |
584 | struct fuse_attr_out arg; | 582 | struct fuse_attr_out arg; |
585 | struct fuse_conn *fc = get_fuse_conn(inode); | 583 | struct fuse_conn *fc = get_fuse_conn(inode); |
586 | struct fuse_req *req = fuse_get_request(fc); | 584 | struct fuse_req *req = fuse_get_req(fc); |
587 | if (!req) | 585 | if (IS_ERR(req)) |
588 | return -EINTR; | 586 | return PTR_ERR(req); |
589 | 587 | ||
590 | req->in.h.opcode = FUSE_GETATTR; | 588 | req->in.h.opcode = FUSE_GETATTR; |
591 | req->in.h.nodeid = get_node_id(inode); | 589 | req->in.h.nodeid = get_node_id(inode); |
@@ -673,9 +671,9 @@ static int fuse_access(struct inode *inode, int mask) | |||
673 | if (fc->no_access) | 671 | if (fc->no_access) |
674 | return 0; | 672 | return 0; |
675 | 673 | ||
676 | req = fuse_get_request(fc); | 674 | req = fuse_get_req(fc); |
677 | if (!req) | 675 | if (IS_ERR(req)) |
678 | return -EINTR; | 676 | return PTR_ERR(req); |
679 | 677 | ||
680 | memset(&inarg, 0, sizeof(inarg)); | 678 | memset(&inarg, 0, sizeof(inarg)); |
681 | inarg.mask = mask; | 679 | inarg.mask = mask; |
@@ -780,9 +778,9 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
780 | if (is_bad_inode(inode)) | 778 | if (is_bad_inode(inode)) |
781 | return -EIO; | 779 | return -EIO; |
782 | 780 | ||
783 | req = fuse_get_request(fc); | 781 | req = fuse_get_req(fc); |
784 | if (!req) | 782 | if (IS_ERR(req)) |
785 | return -EINTR; | 783 | return PTR_ERR(req); |
786 | 784 | ||
787 | page = alloc_page(GFP_KERNEL); | 785 | page = alloc_page(GFP_KERNEL); |
788 | if (!page) { | 786 | if (!page) { |
@@ -809,11 +807,11 @@ static char *read_link(struct dentry *dentry) | |||
809 | { | 807 | { |
810 | struct inode *inode = dentry->d_inode; | 808 | struct inode *inode = dentry->d_inode; |
811 | struct fuse_conn *fc = get_fuse_conn(inode); | 809 | struct fuse_conn *fc = get_fuse_conn(inode); |
812 | struct fuse_req *req = fuse_get_request(fc); | 810 | struct fuse_req *req = fuse_get_req(fc); |
813 | char *link; | 811 | char *link; |
814 | 812 | ||
815 | if (!req) | 813 | if (IS_ERR(req)) |
816 | return ERR_PTR(-EINTR); | 814 | return ERR_PTR(PTR_ERR(req)); |
817 | 815 | ||
818 | link = (char *) __get_free_page(GFP_KERNEL); | 816 | link = (char *) __get_free_page(GFP_KERNEL); |
819 | if (!link) { | 817 | if (!link) { |
@@ -933,9 +931,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
933 | } | 931 | } |
934 | } | 932 | } |
935 | 933 | ||
936 | req = fuse_get_request(fc); | 934 | req = fuse_get_req(fc); |
937 | if (!req) | 935 | if (IS_ERR(req)) |
938 | return -EINTR; | 936 | return PTR_ERR(req); |
939 | 937 | ||
940 | memset(&inarg, 0, sizeof(inarg)); | 938 | memset(&inarg, 0, sizeof(inarg)); |
941 | iattr_to_fattr(attr, &inarg); | 939 | iattr_to_fattr(attr, &inarg); |
@@ -995,9 +993,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name, | |||
995 | if (fc->no_setxattr) | 993 | if (fc->no_setxattr) |
996 | return -EOPNOTSUPP; | 994 | return -EOPNOTSUPP; |
997 | 995 | ||
998 | req = fuse_get_request(fc); | 996 | req = fuse_get_req(fc); |
999 | if (!req) | 997 | if (IS_ERR(req)) |
1000 | return -EINTR; | 998 | return PTR_ERR(req); |
1001 | 999 | ||
1002 | memset(&inarg, 0, sizeof(inarg)); | 1000 | memset(&inarg, 0, sizeof(inarg)); |
1003 | inarg.size = size; | 1001 | inarg.size = size; |
@@ -1035,9 +1033,9 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name, | |||
1035 | if (fc->no_getxattr) | 1033 | if (fc->no_getxattr) |
1036 | return -EOPNOTSUPP; | 1034 | return -EOPNOTSUPP; |
1037 | 1035 | ||
1038 | req = fuse_get_request(fc); | 1036 | req = fuse_get_req(fc); |
1039 | if (!req) | 1037 | if (IS_ERR(req)) |
1040 | return -EINTR; | 1038 | return PTR_ERR(req); |
1041 | 1039 | ||
1042 | memset(&inarg, 0, sizeof(inarg)); | 1040 | memset(&inarg, 0, sizeof(inarg)); |
1043 | inarg.size = size; | 1041 | inarg.size = size; |
@@ -1085,9 +1083,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) | |||
1085 | if (fc->no_listxattr) | 1083 | if (fc->no_listxattr) |
1086 | return -EOPNOTSUPP; | 1084 | return -EOPNOTSUPP; |
1087 | 1085 | ||
1088 | req = fuse_get_request(fc); | 1086 | req = fuse_get_req(fc); |
1089 | if (!req) | 1087 | if (IS_ERR(req)) |
1090 | return -EINTR; | 1088 | return PTR_ERR(req); |
1091 | 1089 | ||
1092 | memset(&inarg, 0, sizeof(inarg)); | 1090 | memset(&inarg, 0, sizeof(inarg)); |
1093 | inarg.size = size; | 1091 | inarg.size = size; |
@@ -1131,9 +1129,9 @@ static int fuse_removexattr(struct dentry *entry, const char *name) | |||
1131 | if (fc->no_removexattr) | 1129 | if (fc->no_removexattr) |
1132 | return -EOPNOTSUPP; | 1130 | return -EOPNOTSUPP; |
1133 | 1131 | ||
1134 | req = fuse_get_request(fc); | 1132 | req = fuse_get_req(fc); |
1135 | if (!req) | 1133 | if (IS_ERR(req)) |
1136 | return -EINTR; | 1134 | return PTR_ERR(req); |
1137 | 1135 | ||
1138 | req->in.h.opcode = FUSE_REMOVEXATTR; | 1136 | req->in.h.opcode = FUSE_REMOVEXATTR; |
1139 | req->in.h.nodeid = get_node_id(inode); | 1137 | req->in.h.nodeid = get_node_id(inode); |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 975f2697e866..e4f041a11bb5 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -22,9 +22,9 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, | |||
22 | struct fuse_req *req; | 22 | struct fuse_req *req; |
23 | int err; | 23 | int err; |
24 | 24 | ||
25 | req = fuse_get_request(fc); | 25 | req = fuse_get_req(fc); |
26 | if (!req) | 26 | if (IS_ERR(req)) |
27 | return -EINTR; | 27 | return PTR_ERR(req); |
28 | 28 | ||
29 | memset(&inarg, 0, sizeof(inarg)); | 29 | memset(&inarg, 0, sizeof(inarg)); |
30 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); | 30 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); |
@@ -184,9 +184,9 @@ static int fuse_flush(struct file *file) | |||
184 | if (fc->no_flush) | 184 | if (fc->no_flush) |
185 | return 0; | 185 | return 0; |
186 | 186 | ||
187 | req = fuse_get_request(fc); | 187 | req = fuse_get_req(fc); |
188 | if (!req) | 188 | if (IS_ERR(req)) |
189 | return -EINTR; | 189 | return PTR_ERR(req); |
190 | 190 | ||
191 | memset(&inarg, 0, sizeof(inarg)); | 191 | memset(&inarg, 0, sizeof(inarg)); |
192 | inarg.fh = ff->fh; | 192 | inarg.fh = ff->fh; |
@@ -223,9 +223,9 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, | |||
223 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) | 223 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) |
224 | return 0; | 224 | return 0; |
225 | 225 | ||
226 | req = fuse_get_request(fc); | 226 | req = fuse_get_req(fc); |
227 | if (!req) | 227 | if (IS_ERR(req)) |
228 | return -EINTR; | 228 | return PTR_ERR(req); |
229 | 229 | ||
230 | memset(&inarg, 0, sizeof(inarg)); | 230 | memset(&inarg, 0, sizeof(inarg)); |
231 | inarg.fh = ff->fh; | 231 | inarg.fh = ff->fh; |
@@ -297,9 +297,9 @@ static int fuse_readpage(struct file *file, struct page *page) | |||
297 | if (is_bad_inode(inode)) | 297 | if (is_bad_inode(inode)) |
298 | goto out; | 298 | goto out; |
299 | 299 | ||
300 | err = -EINTR; | 300 | req = fuse_get_req(fc); |
301 | req = fuse_get_request(fc); | 301 | err = PTR_ERR(req); |
302 | if (!req) | 302 | if (IS_ERR(req)) |
303 | goto out; | 303 | goto out; |
304 | 304 | ||
305 | req->out.page_zeroing = 1; | 305 | req->out.page_zeroing = 1; |
@@ -368,10 +368,10 @@ static int fuse_readpages_fill(void *_data, struct page *page) | |||
368 | (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || | 368 | (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || |
369 | req->pages[req->num_pages - 1]->index + 1 != page->index)) { | 369 | req->pages[req->num_pages - 1]->index + 1 != page->index)) { |
370 | fuse_send_readpages(req, data->file, inode); | 370 | fuse_send_readpages(req, data->file, inode); |
371 | data->req = req = fuse_get_request(fc); | 371 | data->req = req = fuse_get_req(fc); |
372 | if (!req) { | 372 | if (IS_ERR(req)) { |
373 | unlock_page(page); | 373 | unlock_page(page); |
374 | return -EINTR; | 374 | return PTR_ERR(req); |
375 | } | 375 | } |
376 | } | 376 | } |
377 | req->pages[req->num_pages] = page; | 377 | req->pages[req->num_pages] = page; |
@@ -392,13 +392,17 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
392 | 392 | ||
393 | data.file = file; | 393 | data.file = file; |
394 | data.inode = inode; | 394 | data.inode = inode; |
395 | data.req = fuse_get_request(fc); | 395 | data.req = fuse_get_req(fc); |
396 | if (!data.req) | 396 | if (IS_ERR(data.req)) |
397 | return -EINTR; | 397 | return PTR_ERR(data.req); |
398 | 398 | ||
399 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); | 399 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); |
400 | if (!err) | 400 | if (!err) { |
401 | fuse_send_readpages(data.req, file, inode); | 401 | if (data.req->num_pages) |
402 | fuse_send_readpages(data.req, file, inode); | ||
403 | else | ||
404 | fuse_put_request(fc, data.req); | ||
405 | } | ||
402 | return err; | 406 | return err; |
403 | } | 407 | } |
404 | 408 | ||
@@ -451,9 +455,9 @@ static int fuse_commit_write(struct file *file, struct page *page, | |||
451 | if (is_bad_inode(inode)) | 455 | if (is_bad_inode(inode)) |
452 | return -EIO; | 456 | return -EIO; |
453 | 457 | ||
454 | req = fuse_get_request(fc); | 458 | req = fuse_get_req(fc); |
455 | if (!req) | 459 | if (IS_ERR(req)) |
456 | return -EINTR; | 460 | return PTR_ERR(req); |
457 | 461 | ||
458 | req->num_pages = 1; | 462 | req->num_pages = 1; |
459 | req->pages[0] = page; | 463 | req->pages[0] = page; |
@@ -528,9 +532,9 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | |||
528 | if (is_bad_inode(inode)) | 532 | if (is_bad_inode(inode)) |
529 | return -EIO; | 533 | return -EIO; |
530 | 534 | ||
531 | req = fuse_get_request(fc); | 535 | req = fuse_get_req(fc); |
532 | if (!req) | 536 | if (IS_ERR(req)) |
533 | return -EINTR; | 537 | return PTR_ERR(req); |
534 | 538 | ||
535 | while (count) { | 539 | while (count) { |
536 | size_t nres; | 540 | size_t nres; |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index a16a04fcf41e..19c7185a7546 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -18,8 +18,8 @@ | |||
18 | /** Max number of pages that can be used in a single read request */ | 18 | /** Max number of pages that can be used in a single read request */ |
19 | #define FUSE_MAX_PAGES_PER_REQ 32 | 19 | #define FUSE_MAX_PAGES_PER_REQ 32 |
20 | 20 | ||
21 | /** If more requests are outstanding, then the operation will block */ | 21 | /** Maximum number of outstanding background requests */ |
22 | #define FUSE_MAX_OUTSTANDING 10 | 22 | #define FUSE_MAX_BACKGROUND 10 |
23 | 23 | ||
24 | /** It could be as large as PATH_MAX, but would that have any uses? */ | 24 | /** It could be as large as PATH_MAX, but would that have any uses? */ |
25 | #define FUSE_NAME_MAX 1024 | 25 | #define FUSE_NAME_MAX 1024 |
@@ -131,8 +131,8 @@ struct fuse_conn; | |||
131 | * A request to the client | 131 | * A request to the client |
132 | */ | 132 | */ |
133 | struct fuse_req { | 133 | struct fuse_req { |
134 | /** This can be on either unused_list, pending processing or | 134 | /** This can be on either pending processing or io lists in |
135 | io lists in fuse_conn */ | 135 | fuse_conn */ |
136 | struct list_head list; | 136 | struct list_head list; |
137 | 137 | ||
138 | /** Entry on the background list */ | 138 | /** Entry on the background list */ |
@@ -144,15 +144,12 @@ struct fuse_req { | |||
144 | /* | 144 | /* |
145 | * The following bitfields are either set once before the | 145 | * The following bitfields are either set once before the |
146 | * request is queued or setting/clearing them is protected by | 146 | * request is queued or setting/clearing them is protected by |
147 | * fuse_lock | 147 | * fuse_conn->lock |
148 | */ | 148 | */ |
149 | 149 | ||
150 | /** True if the request has reply */ | 150 | /** True if the request has reply */ |
151 | unsigned isreply:1; | 151 | unsigned isreply:1; |
152 | 152 | ||
153 | /** The request is preallocated */ | ||
154 | unsigned preallocated:1; | ||
155 | |||
156 | /** The request was interrupted */ | 153 | /** The request was interrupted */ |
157 | unsigned interrupted:1; | 154 | unsigned interrupted:1; |
158 | 155 | ||
@@ -213,6 +210,9 @@ struct fuse_req { | |||
213 | * unmounted. | 210 | * unmounted. |
214 | */ | 211 | */ |
215 | struct fuse_conn { | 212 | struct fuse_conn { |
213 | /** Lock protecting accessess to members of this structure */ | ||
214 | spinlock_t lock; | ||
215 | |||
216 | /** The user id for this mount */ | 216 | /** The user id for this mount */ |
217 | uid_t user_id; | 217 | uid_t user_id; |
218 | 218 | ||
@@ -244,19 +244,20 @@ struct fuse_conn { | |||
244 | interrupted request) */ | 244 | interrupted request) */ |
245 | struct list_head background; | 245 | struct list_head background; |
246 | 246 | ||
247 | /** Controls the maximum number of outstanding requests */ | 247 | /** Number of requests currently in the background */ |
248 | struct semaphore outstanding_sem; | 248 | unsigned num_background; |
249 | |||
250 | /** Flag indicating if connection is blocked. This will be | ||
251 | the case before the INIT reply is received, and if there | ||
252 | are too many outstading backgrounds requests */ | ||
253 | int blocked; | ||
249 | 254 | ||
250 | /** This counts the number of outstanding requests if | 255 | /** waitq for blocked connection */ |
251 | outstanding_sem would go negative */ | 256 | wait_queue_head_t blocked_waitq; |
252 | unsigned outstanding_debt; | ||
253 | 257 | ||
254 | /** RW semaphore for exclusion with fuse_put_super() */ | 258 | /** RW semaphore for exclusion with fuse_put_super() */ |
255 | struct rw_semaphore sbput_sem; | 259 | struct rw_semaphore sbput_sem; |
256 | 260 | ||
257 | /** The list of unused requests */ | ||
258 | struct list_head unused_list; | ||
259 | |||
260 | /** The next unique request id */ | 261 | /** The next unique request id */ |
261 | u64 reqctr; | 262 | u64 reqctr; |
262 | 263 | ||
@@ -318,6 +319,9 @@ struct fuse_conn { | |||
318 | 319 | ||
319 | /** kobject */ | 320 | /** kobject */ |
320 | struct kobject kobj; | 321 | struct kobject kobj; |
322 | |||
323 | /** O_ASYNC requests */ | ||
324 | struct fasync_struct *fasync; | ||
321 | }; | 325 | }; |
322 | 326 | ||
323 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) | 327 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) |
@@ -349,21 +353,6 @@ static inline u64 get_node_id(struct inode *inode) | |||
349 | extern const struct file_operations fuse_dev_operations; | 353 | extern const struct file_operations fuse_dev_operations; |
350 | 354 | ||
351 | /** | 355 | /** |
352 | * This is the single global spinlock which protects FUSE's structures | ||
353 | * | ||
354 | * The following data is protected by this lock: | ||
355 | * | ||
356 | * - the private_data field of the device file | ||
357 | * - the s_fs_info field of the super block | ||
358 | * - unused_list, pending, processing lists in fuse_conn | ||
359 | * - background list in fuse_conn | ||
360 | * - the unique request ID counter reqctr in fuse_conn | ||
361 | * - the sb (super_block) field in fuse_conn | ||
362 | * - the file (device file) field in fuse_conn | ||
363 | */ | ||
364 | extern spinlock_t fuse_lock; | ||
365 | |||
366 | /** | ||
367 | * Get a filled in inode | 356 | * Get a filled in inode |
368 | */ | 357 | */ |
369 | struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, | 358 | struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, |
@@ -461,11 +450,11 @@ void fuse_reset_request(struct fuse_req *req); | |||
461 | /** | 450 | /** |
462 | * Reserve a preallocated request | 451 | * Reserve a preallocated request |
463 | */ | 452 | */ |
464 | struct fuse_req *fuse_get_request(struct fuse_conn *fc); | 453 | struct fuse_req *fuse_get_req(struct fuse_conn *fc); |
465 | 454 | ||
466 | /** | 455 | /** |
467 | * Decrement reference count of a request. If count goes to zero put | 456 | * Decrement reference count of a request. If count goes to zero free |
468 | * on unused list (preallocated) or free request (not preallocated). | 457 | * the request. |
469 | */ | 458 | */ |
470 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); | 459 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); |
471 | 460 | ||
@@ -487,7 +476,7 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req); | |||
487 | /** | 476 | /** |
488 | * Release inodes and file associated with background request | 477 | * Release inodes and file associated with background request |
489 | */ | 478 | */ |
490 | void fuse_release_background(struct fuse_req *req); | 479 | void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req); |
491 | 480 | ||
492 | /* Abort all requests */ | 481 | /* Abort all requests */ |
493 | void fuse_abort_conn(struct fuse_conn *fc); | 482 | void fuse_abort_conn(struct fuse_conn *fc); |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 879e6fba9480..fd34037b0588 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | FUSE: Filesystem in Userspace | 2 | FUSE: Filesystem in Userspace |
3 | Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu> | 3 | Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
4 | 4 | ||
5 | This program can be distributed under the terms of the GNU GPL. | 5 | This program can be distributed under the terms of the GNU GPL. |
6 | See the file COPYING. | 6 | See the file COPYING. |
@@ -22,7 +22,6 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |||
22 | MODULE_DESCRIPTION("Filesystem in Userspace"); | 22 | MODULE_DESCRIPTION("Filesystem in Userspace"); |
23 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
24 | 24 | ||
25 | spinlock_t fuse_lock; | ||
26 | static kmem_cache_t *fuse_inode_cachep; | 25 | static kmem_cache_t *fuse_inode_cachep; |
27 | static struct subsystem connections_subsys; | 26 | static struct subsystem connections_subsys; |
28 | 27 | ||
@@ -207,15 +206,17 @@ static void fuse_put_super(struct super_block *sb) | |||
207 | 206 | ||
208 | down_write(&fc->sbput_sem); | 207 | down_write(&fc->sbput_sem); |
209 | while (!list_empty(&fc->background)) | 208 | while (!list_empty(&fc->background)) |
210 | fuse_release_background(list_entry(fc->background.next, | 209 | fuse_release_background(fc, |
210 | list_entry(fc->background.next, | ||
211 | struct fuse_req, bg_entry)); | 211 | struct fuse_req, bg_entry)); |
212 | 212 | ||
213 | spin_lock(&fuse_lock); | 213 | spin_lock(&fc->lock); |
214 | fc->mounted = 0; | 214 | fc->mounted = 0; |
215 | fc->connected = 0; | 215 | fc->connected = 0; |
216 | spin_unlock(&fuse_lock); | 216 | spin_unlock(&fc->lock); |
217 | up_write(&fc->sbput_sem); | 217 | up_write(&fc->sbput_sem); |
218 | /* Flush all readers on this fs */ | 218 | /* Flush all readers on this fs */ |
219 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
219 | wake_up_all(&fc->waitq); | 220 | wake_up_all(&fc->waitq); |
220 | kobject_del(&fc->kobj); | 221 | kobject_del(&fc->kobj); |
221 | kobject_put(&fc->kobj); | 222 | kobject_put(&fc->kobj); |
@@ -242,9 +243,9 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf) | |||
242 | struct fuse_statfs_out outarg; | 243 | struct fuse_statfs_out outarg; |
243 | int err; | 244 | int err; |
244 | 245 | ||
245 | req = fuse_get_request(fc); | 246 | req = fuse_get_req(fc); |
246 | if (!req) | 247 | if (IS_ERR(req)) |
247 | return -EINTR; | 248 | return PTR_ERR(req); |
248 | 249 | ||
249 | memset(&outarg, 0, sizeof(outarg)); | 250 | memset(&outarg, 0, sizeof(outarg)); |
250 | req->in.numargs = 0; | 251 | req->in.numargs = 0; |
@@ -369,15 +370,7 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
369 | 370 | ||
370 | static void fuse_conn_release(struct kobject *kobj) | 371 | static void fuse_conn_release(struct kobject *kobj) |
371 | { | 372 | { |
372 | struct fuse_conn *fc = get_fuse_conn_kobj(kobj); | 373 | kfree(get_fuse_conn_kobj(kobj)); |
373 | |||
374 | while (!list_empty(&fc->unused_list)) { | ||
375 | struct fuse_req *req; | ||
376 | req = list_entry(fc->unused_list.next, struct fuse_req, list); | ||
377 | list_del(&req->list); | ||
378 | fuse_request_free(req); | ||
379 | } | ||
380 | kfree(fc); | ||
381 | } | 374 | } |
382 | 375 | ||
383 | static struct fuse_conn *new_conn(void) | 376 | static struct fuse_conn *new_conn(void) |
@@ -386,64 +379,25 @@ static struct fuse_conn *new_conn(void) | |||
386 | 379 | ||
387 | fc = kzalloc(sizeof(*fc), GFP_KERNEL); | 380 | fc = kzalloc(sizeof(*fc), GFP_KERNEL); |
388 | if (fc) { | 381 | if (fc) { |
389 | int i; | 382 | spin_lock_init(&fc->lock); |
390 | init_waitqueue_head(&fc->waitq); | 383 | init_waitqueue_head(&fc->waitq); |
384 | init_waitqueue_head(&fc->blocked_waitq); | ||
391 | INIT_LIST_HEAD(&fc->pending); | 385 | INIT_LIST_HEAD(&fc->pending); |
392 | INIT_LIST_HEAD(&fc->processing); | 386 | INIT_LIST_HEAD(&fc->processing); |
393 | INIT_LIST_HEAD(&fc->io); | 387 | INIT_LIST_HEAD(&fc->io); |
394 | INIT_LIST_HEAD(&fc->unused_list); | ||
395 | INIT_LIST_HEAD(&fc->background); | 388 | INIT_LIST_HEAD(&fc->background); |
396 | sema_init(&fc->outstanding_sem, 1); /* One for INIT */ | ||
397 | init_rwsem(&fc->sbput_sem); | 389 | init_rwsem(&fc->sbput_sem); |
398 | kobj_set_kset_s(fc, connections_subsys); | 390 | kobj_set_kset_s(fc, connections_subsys); |
399 | kobject_init(&fc->kobj); | 391 | kobject_init(&fc->kobj); |
400 | atomic_set(&fc->num_waiting, 0); | 392 | atomic_set(&fc->num_waiting, 0); |
401 | for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) { | ||
402 | struct fuse_req *req = fuse_request_alloc(); | ||
403 | if (!req) { | ||
404 | kobject_put(&fc->kobj); | ||
405 | return NULL; | ||
406 | } | ||
407 | list_add(&req->list, &fc->unused_list); | ||
408 | } | ||
409 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | 393 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; |
410 | fc->bdi.unplug_io_fn = default_unplug_io_fn; | 394 | fc->bdi.unplug_io_fn = default_unplug_io_fn; |
411 | fc->reqctr = 0; | 395 | fc->reqctr = 0; |
396 | fc->blocked = 1; | ||
412 | } | 397 | } |
413 | return fc; | 398 | return fc; |
414 | } | 399 | } |
415 | 400 | ||
416 | static struct fuse_conn *get_conn(struct file *file, struct super_block *sb) | ||
417 | { | ||
418 | struct fuse_conn *fc; | ||
419 | int err; | ||
420 | |||
421 | err = -EINVAL; | ||
422 | if (file->f_op != &fuse_dev_operations) | ||
423 | goto out_err; | ||
424 | |||
425 | err = -ENOMEM; | ||
426 | fc = new_conn(); | ||
427 | if (!fc) | ||
428 | goto out_err; | ||
429 | |||
430 | spin_lock(&fuse_lock); | ||
431 | err = -EINVAL; | ||
432 | if (file->private_data) | ||
433 | goto out_unlock; | ||
434 | |||
435 | kobject_get(&fc->kobj); | ||
436 | file->private_data = fc; | ||
437 | spin_unlock(&fuse_lock); | ||
438 | return fc; | ||
439 | |||
440 | out_unlock: | ||
441 | spin_unlock(&fuse_lock); | ||
442 | kobject_put(&fc->kobj); | ||
443 | out_err: | ||
444 | return ERR_PTR(err); | ||
445 | } | ||
446 | |||
447 | static struct inode *get_root_inode(struct super_block *sb, unsigned mode) | 401 | static struct inode *get_root_inode(struct super_block *sb, unsigned mode) |
448 | { | 402 | { |
449 | struct fuse_attr attr; | 403 | struct fuse_attr attr; |
@@ -467,7 +421,6 @@ static struct super_operations fuse_super_operations = { | |||
467 | 421 | ||
468 | static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | 422 | static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) |
469 | { | 423 | { |
470 | int i; | ||
471 | struct fuse_init_out *arg = &req->misc.init_out; | 424 | struct fuse_init_out *arg = &req->misc.init_out; |
472 | 425 | ||
473 | if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) | 426 | if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) |
@@ -486,22 +439,13 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
486 | fc->minor = arg->minor; | 439 | fc->minor = arg->minor; |
487 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | 440 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
488 | } | 441 | } |
489 | |||
490 | /* After INIT reply is received other requests can go | ||
491 | out. So do (FUSE_MAX_OUTSTANDING - 1) number of | ||
492 | up()s on outstanding_sem. The last up() is done in | ||
493 | fuse_putback_request() */ | ||
494 | for (i = 1; i < FUSE_MAX_OUTSTANDING; i++) | ||
495 | up(&fc->outstanding_sem); | ||
496 | |||
497 | fuse_put_request(fc, req); | 442 | fuse_put_request(fc, req); |
443 | fc->blocked = 0; | ||
444 | wake_up_all(&fc->blocked_waitq); | ||
498 | } | 445 | } |
499 | 446 | ||
500 | static void fuse_send_init(struct fuse_conn *fc) | 447 | static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) |
501 | { | 448 | { |
502 | /* This is called from fuse_read_super() so there's guaranteed | ||
503 | to be exactly one request available */ | ||
504 | struct fuse_req *req = fuse_get_request(fc); | ||
505 | struct fuse_init_in *arg = &req->misc.init_in; | 449 | struct fuse_init_in *arg = &req->misc.init_in; |
506 | 450 | ||
507 | arg->major = FUSE_KERNEL_VERSION; | 451 | arg->major = FUSE_KERNEL_VERSION; |
@@ -525,12 +469,9 @@ static void fuse_send_init(struct fuse_conn *fc) | |||
525 | 469 | ||
526 | static unsigned long long conn_id(void) | 470 | static unsigned long long conn_id(void) |
527 | { | 471 | { |
472 | /* BKL is held for ->get_sb() */ | ||
528 | static unsigned long long ctr = 1; | 473 | static unsigned long long ctr = 1; |
529 | unsigned long long val; | 474 | return ctr++; |
530 | spin_lock(&fuse_lock); | ||
531 | val = ctr++; | ||
532 | spin_unlock(&fuse_lock); | ||
533 | return val; | ||
534 | } | 475 | } |
535 | 476 | ||
536 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) | 477 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) |
@@ -540,6 +481,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
540 | struct fuse_mount_data d; | 481 | struct fuse_mount_data d; |
541 | struct file *file; | 482 | struct file *file; |
542 | struct dentry *root_dentry; | 483 | struct dentry *root_dentry; |
484 | struct fuse_req *init_req; | ||
543 | int err; | 485 | int err; |
544 | 486 | ||
545 | if (!parse_fuse_opt((char *) data, &d)) | 487 | if (!parse_fuse_opt((char *) data, &d)) |
@@ -555,10 +497,17 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
555 | if (!file) | 497 | if (!file) |
556 | return -EINVAL; | 498 | return -EINVAL; |
557 | 499 | ||
558 | fc = get_conn(file, sb); | 500 | if (file->f_op != &fuse_dev_operations) |
559 | fput(file); | 501 | return -EINVAL; |
560 | if (IS_ERR(fc)) | 502 | |
561 | return PTR_ERR(fc); | 503 | /* Setting file->private_data can't race with other mount() |
504 | instances, since BKL is held for ->get_sb() */ | ||
505 | if (file->private_data) | ||
506 | return -EINVAL; | ||
507 | |||
508 | fc = new_conn(); | ||
509 | if (!fc) | ||
510 | return -ENOMEM; | ||
562 | 511 | ||
563 | fc->flags = d.flags; | 512 | fc->flags = d.flags; |
564 | fc->user_id = d.user_id; | 513 | fc->user_id = d.user_id; |
@@ -579,27 +528,40 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
579 | goto err; | 528 | goto err; |
580 | } | 529 | } |
581 | 530 | ||
531 | init_req = fuse_request_alloc(); | ||
532 | if (!init_req) | ||
533 | goto err_put_root; | ||
534 | |||
582 | err = kobject_set_name(&fc->kobj, "%llu", conn_id()); | 535 | err = kobject_set_name(&fc->kobj, "%llu", conn_id()); |
583 | if (err) | 536 | if (err) |
584 | goto err_put_root; | 537 | goto err_free_req; |
585 | 538 | ||
586 | err = kobject_add(&fc->kobj); | 539 | err = kobject_add(&fc->kobj); |
587 | if (err) | 540 | if (err) |
588 | goto err_put_root; | 541 | goto err_free_req; |
589 | 542 | ||
590 | sb->s_root = root_dentry; | 543 | sb->s_root = root_dentry; |
591 | spin_lock(&fuse_lock); | ||
592 | fc->mounted = 1; | 544 | fc->mounted = 1; |
593 | fc->connected = 1; | 545 | fc->connected = 1; |
594 | spin_unlock(&fuse_lock); | 546 | kobject_get(&fc->kobj); |
547 | file->private_data = fc; | ||
548 | /* | ||
549 | * atomic_dec_and_test() in fput() provides the necessary | ||
550 | * memory barrier for file->private_data to be visible on all | ||
551 | * CPUs after this | ||
552 | */ | ||
553 | fput(file); | ||
595 | 554 | ||
596 | fuse_send_init(fc); | 555 | fuse_send_init(fc, init_req); |
597 | 556 | ||
598 | return 0; | 557 | return 0; |
599 | 558 | ||
559 | err_free_req: | ||
560 | fuse_request_free(init_req); | ||
600 | err_put_root: | 561 | err_put_root: |
601 | dput(root_dentry); | 562 | dput(root_dentry); |
602 | err: | 563 | err: |
564 | fput(file); | ||
603 | kobject_put(&fc->kobj); | 565 | kobject_put(&fc->kobj); |
604 | return err; | 566 | return err; |
605 | } | 567 | } |
@@ -753,7 +715,6 @@ static int __init fuse_init(void) | |||
753 | printk("fuse init (API version %i.%i)\n", | 715 | printk("fuse init (API version %i.%i)\n", |
754 | FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); | 716 | FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); |
755 | 717 | ||
756 | spin_lock_init(&fuse_lock); | ||
757 | res = fuse_fs_init(); | 718 | res = fuse_fs_init(); |
758 | if (res) | 719 | if (res) |
759 | goto err; | 720 | goto err; |
diff --git a/fs/inotify.c b/fs/inotify.c index 367c487c014b..1f50302849c5 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -538,7 +538,7 @@ void inotify_d_instantiate(struct dentry *entry, struct inode *inode) | |||
538 | WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED); | 538 | WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED); |
539 | spin_lock(&entry->d_lock); | 539 | spin_lock(&entry->d_lock); |
540 | parent = entry->d_parent; | 540 | parent = entry->d_parent; |
541 | if (inotify_inode_watched(parent->d_inode)) | 541 | if (parent->d_inode && inotify_inode_watched(parent->d_inode)) |
542 | entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; | 542 | entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; |
543 | spin_unlock(&entry->d_lock); | 543 | spin_unlock(&entry->d_lock); |
544 | } | 544 | } |
diff --git a/fs/namespace.c b/fs/namespace.c index bf478addb852..2c5f1f80bdc2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -899,11 +899,13 @@ static int do_change_type(struct nameidata *nd, int flag) | |||
899 | /* | 899 | /* |
900 | * do loopback mount. | 900 | * do loopback mount. |
901 | */ | 901 | */ |
902 | static int do_loopback(struct nameidata *nd, char *old_name, int recurse) | 902 | static int do_loopback(struct nameidata *nd, char *old_name, unsigned long flags, int mnt_flags) |
903 | { | 903 | { |
904 | struct nameidata old_nd; | 904 | struct nameidata old_nd; |
905 | struct vfsmount *mnt = NULL; | 905 | struct vfsmount *mnt = NULL; |
906 | int recurse = flags & MS_REC; | ||
906 | int err = mount_is_safe(nd); | 907 | int err = mount_is_safe(nd); |
908 | |||
907 | if (err) | 909 | if (err) |
908 | return err; | 910 | return err; |
909 | if (!old_name || !*old_name) | 911 | if (!old_name || !*old_name) |
@@ -937,6 +939,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse) | |||
937 | spin_unlock(&vfsmount_lock); | 939 | spin_unlock(&vfsmount_lock); |
938 | release_mounts(&umount_list); | 940 | release_mounts(&umount_list); |
939 | } | 941 | } |
942 | mnt->mnt_flags = mnt_flags; | ||
940 | 943 | ||
941 | out: | 944 | out: |
942 | up_write(&namespace_sem); | 945 | up_write(&namespace_sem); |
@@ -1350,7 +1353,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1350 | retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, | 1353 | retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, |
1351 | data_page); | 1354 | data_page); |
1352 | else if (flags & MS_BIND) | 1355 | else if (flags & MS_BIND) |
1353 | retval = do_loopback(&nd, dev_name, flags & MS_REC); | 1356 | retval = do_loopback(&nd, dev_name, flags, mnt_flags); |
1354 | else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) | 1357 | else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) |
1355 | retval = do_change_type(&nd, flags); | 1358 | retval = do_change_type(&nd, flags); |
1356 | else if (flags & MS_MOVE) | 1359 | else if (flags & MS_MOVE) |
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index cfe9ce881613..6e92b0fe5323 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c | |||
@@ -14,46 +14,46 @@ | |||
14 | 14 | ||
15 | int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | 15 | int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) |
16 | { | 16 | { |
17 | struct svc_cred *cred = &rqstp->rq_cred; | 17 | struct svc_cred cred = rqstp->rq_cred; |
18 | int i; | 18 | int i; |
19 | int ret; | 19 | int ret; |
20 | 20 | ||
21 | if (exp->ex_flags & NFSEXP_ALLSQUASH) { | 21 | if (exp->ex_flags & NFSEXP_ALLSQUASH) { |
22 | cred->cr_uid = exp->ex_anon_uid; | 22 | cred.cr_uid = exp->ex_anon_uid; |
23 | cred->cr_gid = exp->ex_anon_gid; | 23 | cred.cr_gid = exp->ex_anon_gid; |
24 | put_group_info(cred->cr_group_info); | 24 | cred.cr_group_info = groups_alloc(0); |
25 | cred->cr_group_info = groups_alloc(0); | ||
26 | } else if (exp->ex_flags & NFSEXP_ROOTSQUASH) { | 25 | } else if (exp->ex_flags & NFSEXP_ROOTSQUASH) { |
27 | struct group_info *gi; | 26 | struct group_info *gi; |
28 | if (!cred->cr_uid) | 27 | if (!cred.cr_uid) |
29 | cred->cr_uid = exp->ex_anon_uid; | 28 | cred.cr_uid = exp->ex_anon_uid; |
30 | if (!cred->cr_gid) | 29 | if (!cred.cr_gid) |
31 | cred->cr_gid = exp->ex_anon_gid; | 30 | cred.cr_gid = exp->ex_anon_gid; |
32 | gi = groups_alloc(cred->cr_group_info->ngroups); | 31 | gi = groups_alloc(cred.cr_group_info->ngroups); |
33 | if (gi) | 32 | if (gi) |
34 | for (i = 0; i < cred->cr_group_info->ngroups; i++) { | 33 | for (i = 0; i < cred.cr_group_info->ngroups; i++) { |
35 | if (!GROUP_AT(cred->cr_group_info, i)) | 34 | if (!GROUP_AT(cred.cr_group_info, i)) |
36 | GROUP_AT(gi, i) = exp->ex_anon_gid; | 35 | GROUP_AT(gi, i) = exp->ex_anon_gid; |
37 | else | 36 | else |
38 | GROUP_AT(gi, i) = GROUP_AT(cred->cr_group_info, i); | 37 | GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i); |
39 | } | 38 | } |
40 | put_group_info(cred->cr_group_info); | 39 | cred.cr_group_info = gi; |
41 | cred->cr_group_info = gi; | 40 | } else |
42 | } | 41 | get_group_info(cred.cr_group_info); |
43 | 42 | ||
44 | if (cred->cr_uid != (uid_t) -1) | 43 | if (cred.cr_uid != (uid_t) -1) |
45 | current->fsuid = cred->cr_uid; | 44 | current->fsuid = cred.cr_uid; |
46 | else | 45 | else |
47 | current->fsuid = exp->ex_anon_uid; | 46 | current->fsuid = exp->ex_anon_uid; |
48 | if (cred->cr_gid != (gid_t) -1) | 47 | if (cred.cr_gid != (gid_t) -1) |
49 | current->fsgid = cred->cr_gid; | 48 | current->fsgid = cred.cr_gid; |
50 | else | 49 | else |
51 | current->fsgid = exp->ex_anon_gid; | 50 | current->fsgid = exp->ex_anon_gid; |
52 | 51 | ||
53 | if (!cred->cr_group_info) | 52 | if (!cred.cr_group_info) |
54 | return -ENOMEM; | 53 | return -ENOMEM; |
55 | ret = set_current_groups(cred->cr_group_info); | 54 | ret = set_current_groups(cred.cr_group_info); |
56 | if ((cred->cr_uid)) { | 55 | put_group_info(cred.cr_group_info); |
56 | if ((cred.cr_uid)) { | ||
57 | cap_t(current->cap_effective) &= ~CAP_NFSD_MASK; | 57 | cap_t(current->cap_effective) &= ~CAP_NFSD_MASK; |
58 | } else { | 58 | } else { |
59 | cap_t(current->cap_effective) |= (CAP_NFSD_MASK & | 59 | cap_t(current->cap_effective) |= (CAP_NFSD_MASK & |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index c340be0a3f59..4e0578121d9a 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -422,7 +422,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
422 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) | 422 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) |
423 | goto out; | 423 | goto out; |
424 | err = path_lookup(buf, 0, &nd); | 424 | err = path_lookup(buf, 0, &nd); |
425 | if (err) goto out; | 425 | if (err) goto out_no_path; |
426 | 426 | ||
427 | exp.h.flags = 0; | 427 | exp.h.flags = 0; |
428 | exp.ex_client = dom; | 428 | exp.ex_client = dom; |
@@ -475,6 +475,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
475 | out: | 475 | out: |
476 | if (nd.dentry) | 476 | if (nd.dentry) |
477 | path_release(&nd); | 477 | path_release(&nd); |
478 | out_no_path: | ||
478 | if (dom) | 479 | if (dom) |
479 | auth_domain_put(dom); | 480 | auth_domain_put(dom); |
480 | kfree(buf); | 481 | kfree(buf); |
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 6d2dfed1de08..f61142afea44 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
@@ -682,7 +682,7 @@ static struct svc_procedure nfsd_procedures3[22] = { | |||
682 | PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, ST+FH+pAT+pAT), | 682 | PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, ST+FH+pAT+pAT), |
683 | PROC(access, access, access, fhandle, RC_NOCACHE, ST+pAT+1), | 683 | PROC(access, access, access, fhandle, RC_NOCACHE, ST+pAT+1), |
684 | PROC(readlink, readlink, readlink, fhandle, RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4), | 684 | PROC(readlink, readlink, readlink, fhandle, RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4), |
685 | PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE), | 685 | PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE/4), |
686 | PROC(write, write, write, fhandle, RC_REPLBUFF, ST+WC+4), | 686 | PROC(write, write, write, fhandle, RC_REPLBUFF, ST+WC+4), |
687 | PROC(create, create, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), | 687 | PROC(create, create, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), |
688 | PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), | 688 | PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), |
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 7391f4aabedb..edb107e61b91 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -710,9 +710,9 @@ calculate_posix_ace_count(struct nfs4_acl *n4acl) | |||
710 | /* Also, the remaining entries are for named users and | 710 | /* Also, the remaining entries are for named users and |
711 | * groups, and come in threes (mask, allow, deny): */ | 711 | * groups, and come in threes (mask, allow, deny): */ |
712 | if (n4acl->naces < 7) | 712 | if (n4acl->naces < 7) |
713 | return -1; | 713 | return -EINVAL; |
714 | if ((n4acl->naces - 7) % 3) | 714 | if ((n4acl->naces - 7) % 3) |
715 | return -1; | 715 | return -EINVAL; |
716 | return 4 + (n4acl->naces - 7)/3; | 716 | return 4 + (n4acl->naces - 7)/3; |
717 | } | 717 | } |
718 | } | 718 | } |
@@ -790,7 +790,7 @@ nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl) | |||
790 | continue; | 790 | continue; |
791 | 791 | ||
792 | error = nfs4_acl_add_ace(dacl, ace->type, ace->flag, | 792 | error = nfs4_acl_add_ace(dacl, ace->type, ace->flag, |
793 | ace->access_mask, ace->whotype, ace->who) == -1; | 793 | ace->access_mask, ace->whotype, ace->who); |
794 | if (error < 0) | 794 | if (error < 0) |
795 | goto out; | 795 | goto out; |
796 | 796 | ||
@@ -866,7 +866,7 @@ nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, | |||
866 | struct nfs4_ace *ace; | 866 | struct nfs4_ace *ace; |
867 | 867 | ||
868 | if ((ace = kmalloc(sizeof(*ace), GFP_KERNEL)) == NULL) | 868 | if ((ace = kmalloc(sizeof(*ace), GFP_KERNEL)) == NULL) |
869 | return -1; | 869 | return -ENOMEM; |
870 | 870 | ||
871 | ace->type = type; | 871 | ace->type = type; |
872 | ace->flag = flag; | 872 | ace->flag = flag; |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index c872bd07fc10..dbaf3f93f328 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -441,8 +441,9 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
441 | goto out_clnt; | 441 | goto out_clnt; |
442 | } | 442 | } |
443 | 443 | ||
444 | /* the task holds a reference to the nfs4_client struct */ | ||
445 | cb->cb_client = clnt; | 444 | cb->cb_client = clnt; |
445 | |||
446 | /* the task holds a reference to the nfs4_client struct */ | ||
446 | atomic_inc(&clp->cl_count); | 447 | atomic_inc(&clp->cl_count); |
447 | 448 | ||
448 | msg.rpc_cred = nfsd4_lookupcred(clp,0); | 449 | msg.rpc_cred = nfsd4_lookupcred(clp,0); |
@@ -460,13 +461,12 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
460 | out_rpciod: | 461 | out_rpciod: |
461 | atomic_dec(&clp->cl_count); | 462 | atomic_dec(&clp->cl_count); |
462 | rpciod_down(); | 463 | rpciod_down(); |
464 | cb->cb_client = NULL; | ||
463 | out_clnt: | 465 | out_clnt: |
464 | rpc_shutdown_client(clnt); | 466 | rpc_shutdown_client(clnt); |
465 | goto out_err; | ||
466 | out_err: | 467 | out_err: |
467 | dprintk("NFSD: warning: no callback path to client %.*s\n", | 468 | dprintk("NFSD: warning: no callback path to client %.*s\n", |
468 | (int)clp->cl_name.len, clp->cl_name.data); | 469 | (int)clp->cl_name.len, clp->cl_name.data); |
469 | cb->cb_client = NULL; | ||
470 | } | 470 | } |
471 | 471 | ||
472 | static void | 472 | static void |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 6d63f1d9e5f5..b0e095ea0c03 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -288,8 +288,6 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) | |||
288 | fh_put(current_fh); | 288 | fh_put(current_fh); |
289 | status = exp_pseudoroot(rqstp->rq_client, current_fh, | 289 | status = exp_pseudoroot(rqstp->rq_client, current_fh, |
290 | &rqstp->rq_chandle); | 290 | &rqstp->rq_chandle); |
291 | if (!status) | ||
292 | status = nfserrno(nfsd_setuser(rqstp, current_fh->fh_export)); | ||
293 | return status; | 291 | return status; |
294 | } | 292 | } |
295 | 293 | ||
@@ -975,7 +973,7 @@ struct nfsd4_voidargs { int dummy; }; | |||
975 | */ | 973 | */ |
976 | static struct svc_procedure nfsd_procedures4[2] = { | 974 | static struct svc_procedure nfsd_procedures4[2] = { |
977 | PROC(null, void, void, void, RC_NOCACHE, 1), | 975 | PROC(null, void, void, void, RC_NOCACHE, 1), |
978 | PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE) | 976 | PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE/4) |
979 | }; | 977 | }; |
980 | 978 | ||
981 | struct svc_version nfsd_version4 = { | 979 | struct svc_version nfsd_version4 = { |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 47ec112b266c..96c7578cbe1e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -147,6 +147,42 @@ get_nfs4_file(struct nfs4_file *fi) | |||
147 | kref_get(&fi->fi_ref); | 147 | kref_get(&fi->fi_ref); |
148 | } | 148 | } |
149 | 149 | ||
150 | static int num_delegations; | ||
151 | |||
152 | /* | ||
153 | * Open owner state (share locks) | ||
154 | */ | ||
155 | |||
156 | /* hash tables for nfs4_stateowner */ | ||
157 | #define OWNER_HASH_BITS 8 | ||
158 | #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS) | ||
159 | #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1) | ||
160 | |||
161 | #define ownerid_hashval(id) \ | ||
162 | ((id) & OWNER_HASH_MASK) | ||
163 | #define ownerstr_hashval(clientid, ownername) \ | ||
164 | (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK) | ||
165 | |||
166 | static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE]; | ||
167 | static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; | ||
168 | |||
169 | /* hash table for nfs4_file */ | ||
170 | #define FILE_HASH_BITS 8 | ||
171 | #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) | ||
172 | #define FILE_HASH_MASK (FILE_HASH_SIZE - 1) | ||
173 | /* hash table for (open)nfs4_stateid */ | ||
174 | #define STATEID_HASH_BITS 10 | ||
175 | #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) | ||
176 | #define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1) | ||
177 | |||
178 | #define file_hashval(x) \ | ||
179 | hash_ptr(x, FILE_HASH_BITS) | ||
180 | #define stateid_hashval(owner_id, file_id) \ | ||
181 | (((owner_id) + (file_id)) & STATEID_HASH_MASK) | ||
182 | |||
183 | static struct list_head file_hashtbl[FILE_HASH_SIZE]; | ||
184 | static struct list_head stateid_hashtbl[STATEID_HASH_SIZE]; | ||
185 | |||
150 | static struct nfs4_delegation * | 186 | static struct nfs4_delegation * |
151 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type) | 187 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type) |
152 | { | 188 | { |
@@ -155,9 +191,12 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f | |||
155 | struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback; | 191 | struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback; |
156 | 192 | ||
157 | dprintk("NFSD alloc_init_deleg\n"); | 193 | dprintk("NFSD alloc_init_deleg\n"); |
194 | if (num_delegations > STATEID_HASH_SIZE * 4) | ||
195 | return NULL; | ||
158 | dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL); | 196 | dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL); |
159 | if (dp == NULL) | 197 | if (dp == NULL) |
160 | return dp; | 198 | return dp; |
199 | num_delegations++; | ||
161 | INIT_LIST_HEAD(&dp->dl_perfile); | 200 | INIT_LIST_HEAD(&dp->dl_perfile); |
162 | INIT_LIST_HEAD(&dp->dl_perclnt); | 201 | INIT_LIST_HEAD(&dp->dl_perclnt); |
163 | INIT_LIST_HEAD(&dp->dl_recall_lru); | 202 | INIT_LIST_HEAD(&dp->dl_recall_lru); |
@@ -192,6 +231,7 @@ nfs4_put_delegation(struct nfs4_delegation *dp) | |||
192 | dprintk("NFSD: freeing dp %p\n",dp); | 231 | dprintk("NFSD: freeing dp %p\n",dp); |
193 | put_nfs4_file(dp->dl_file); | 232 | put_nfs4_file(dp->dl_file); |
194 | kmem_cache_free(deleg_slab, dp); | 233 | kmem_cache_free(deleg_slab, dp); |
234 | num_delegations--; | ||
195 | } | 235 | } |
196 | } | 236 | } |
197 | 237 | ||
@@ -330,22 +370,29 @@ put_nfs4_client(struct nfs4_client *clp) | |||
330 | } | 370 | } |
331 | 371 | ||
332 | static void | 372 | static void |
373 | shutdown_callback_client(struct nfs4_client *clp) | ||
374 | { | ||
375 | struct rpc_clnt *clnt = clp->cl_callback.cb_client; | ||
376 | |||
377 | /* shutdown rpc client, ending any outstanding recall rpcs */ | ||
378 | if (clnt) { | ||
379 | clp->cl_callback.cb_client = NULL; | ||
380 | rpc_shutdown_client(clnt); | ||
381 | rpciod_down(); | ||
382 | } | ||
383 | } | ||
384 | |||
385 | static void | ||
333 | expire_client(struct nfs4_client *clp) | 386 | expire_client(struct nfs4_client *clp) |
334 | { | 387 | { |
335 | struct nfs4_stateowner *sop; | 388 | struct nfs4_stateowner *sop; |
336 | struct nfs4_delegation *dp; | 389 | struct nfs4_delegation *dp; |
337 | struct nfs4_callback *cb = &clp->cl_callback; | ||
338 | struct rpc_clnt *clnt = clp->cl_callback.cb_client; | ||
339 | struct list_head reaplist; | 390 | struct list_head reaplist; |
340 | 391 | ||
341 | dprintk("NFSD: expire_client cl_count %d\n", | 392 | dprintk("NFSD: expire_client cl_count %d\n", |
342 | atomic_read(&clp->cl_count)); | 393 | atomic_read(&clp->cl_count)); |
343 | 394 | ||
344 | /* shutdown rpc client, ending any outstanding recall rpcs */ | 395 | shutdown_callback_client(clp); |
345 | if (atomic_read(&cb->cb_set) == 1 && clnt) { | ||
346 | rpc_shutdown_client(clnt); | ||
347 | clnt = clp->cl_callback.cb_client = NULL; | ||
348 | } | ||
349 | 396 | ||
350 | INIT_LIST_HEAD(&reaplist); | 397 | INIT_LIST_HEAD(&reaplist); |
351 | spin_lock(&recall_lock); | 398 | spin_lock(&recall_lock); |
@@ -936,40 +983,6 @@ out: | |||
936 | return status; | 983 | return status; |
937 | } | 984 | } |
938 | 985 | ||
939 | /* | ||
940 | * Open owner state (share locks) | ||
941 | */ | ||
942 | |||
943 | /* hash tables for nfs4_stateowner */ | ||
944 | #define OWNER_HASH_BITS 8 | ||
945 | #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS) | ||
946 | #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1) | ||
947 | |||
948 | #define ownerid_hashval(id) \ | ||
949 | ((id) & OWNER_HASH_MASK) | ||
950 | #define ownerstr_hashval(clientid, ownername) \ | ||
951 | (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK) | ||
952 | |||
953 | static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE]; | ||
954 | static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; | ||
955 | |||
956 | /* hash table for nfs4_file */ | ||
957 | #define FILE_HASH_BITS 8 | ||
958 | #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) | ||
959 | #define FILE_HASH_MASK (FILE_HASH_SIZE - 1) | ||
960 | /* hash table for (open)nfs4_stateid */ | ||
961 | #define STATEID_HASH_BITS 10 | ||
962 | #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) | ||
963 | #define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1) | ||
964 | |||
965 | #define file_hashval(x) \ | ||
966 | hash_ptr(x, FILE_HASH_BITS) | ||
967 | #define stateid_hashval(owner_id, file_id) \ | ||
968 | (((owner_id) + (file_id)) & STATEID_HASH_MASK) | ||
969 | |||
970 | static struct list_head file_hashtbl[FILE_HASH_SIZE]; | ||
971 | static struct list_head stateid_hashtbl[STATEID_HASH_SIZE]; | ||
972 | |||
973 | /* OPEN Share state helper functions */ | 986 | /* OPEN Share state helper functions */ |
974 | static inline struct nfs4_file * | 987 | static inline struct nfs4_file * |
975 | alloc_init_file(struct inode *ino) | 988 | alloc_init_file(struct inode *ino) |
@@ -1186,8 +1199,7 @@ move_to_close_lru(struct nfs4_stateowner *sop) | |||
1186 | { | 1199 | { |
1187 | dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); | 1200 | dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); |
1188 | 1201 | ||
1189 | unhash_stateowner(sop); | 1202 | list_move_tail(&sop->so_close_lru, &close_lru); |
1190 | list_add_tail(&sop->so_close_lru, &close_lru); | ||
1191 | sop->so_time = get_seconds(); | 1203 | sop->so_time = get_seconds(); |
1192 | } | 1204 | } |
1193 | 1205 | ||
@@ -1916,8 +1928,7 @@ nfs4_laundromat(void) | |||
1916 | } | 1928 | } |
1917 | dprintk("NFSD: purging unused open stateowner (so_id %d)\n", | 1929 | dprintk("NFSD: purging unused open stateowner (so_id %d)\n", |
1918 | sop->so_id); | 1930 | sop->so_id); |
1919 | list_del(&sop->so_close_lru); | 1931 | release_stateowner(sop); |
1920 | nfs4_put_stateowner(sop); | ||
1921 | } | 1932 | } |
1922 | if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) | 1933 | if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) |
1923 | clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; | 1934 | clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; |
@@ -2495,36 +2506,27 @@ nfs4_transform_lock_offset(struct file_lock *lock) | |||
2495 | lock->fl_end = OFFSET_MAX; | 2506 | lock->fl_end = OFFSET_MAX; |
2496 | } | 2507 | } |
2497 | 2508 | ||
2498 | static int | 2509 | /* Hack!: For now, we're defining this just so we can use a pointer to it |
2499 | nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval) | 2510 | * as a unique cookie to identify our (NFSv4's) posix locks. */ |
2500 | { | 2511 | static struct lock_manager_operations nfsd_posix_mng_ops = { |
2501 | struct nfs4_stateowner *local = NULL; | 2512 | }; |
2502 | int status = 0; | ||
2503 | |||
2504 | if (hashval >= LOCK_HASH_SIZE) | ||
2505 | goto out; | ||
2506 | list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) { | ||
2507 | if (local == sop) { | ||
2508 | status = 1; | ||
2509 | goto out; | ||
2510 | } | ||
2511 | } | ||
2512 | out: | ||
2513 | return status; | ||
2514 | } | ||
2515 | |||
2516 | 2513 | ||
2517 | static inline void | 2514 | static inline void |
2518 | nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) | 2515 | nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) |
2519 | { | 2516 | { |
2520 | struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner; | 2517 | struct nfs4_stateowner *sop; |
2521 | unsigned int hval = lockownerid_hashval(sop->so_id); | 2518 | unsigned int hval; |
2522 | 2519 | ||
2523 | deny->ld_sop = NULL; | 2520 | if (fl->fl_lmops == &nfsd_posix_mng_ops) { |
2524 | if (nfs4_verify_lock_stateowner(sop, hval)) { | 2521 | sop = (struct nfs4_stateowner *) fl->fl_owner; |
2522 | hval = lockownerid_hashval(sop->so_id); | ||
2525 | kref_get(&sop->so_ref); | 2523 | kref_get(&sop->so_ref); |
2526 | deny->ld_sop = sop; | 2524 | deny->ld_sop = sop; |
2527 | deny->ld_clientid = sop->so_client->cl_clientid; | 2525 | deny->ld_clientid = sop->so_client->cl_clientid; |
2526 | } else { | ||
2527 | deny->ld_sop = NULL; | ||
2528 | deny->ld_clientid.cl_boot = 0; | ||
2529 | deny->ld_clientid.cl_id = 0; | ||
2528 | } | 2530 | } |
2529 | deny->ld_start = fl->fl_start; | 2531 | deny->ld_start = fl->fl_start; |
2530 | deny->ld_length = ~(u64)0; | 2532 | deny->ld_length = ~(u64)0; |
@@ -2736,6 +2738,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2736 | file_lock.fl_pid = current->tgid; | 2738 | file_lock.fl_pid = current->tgid; |
2737 | file_lock.fl_file = filp; | 2739 | file_lock.fl_file = filp; |
2738 | file_lock.fl_flags = FL_POSIX; | 2740 | file_lock.fl_flags = FL_POSIX; |
2741 | file_lock.fl_lmops = &nfsd_posix_mng_ops; | ||
2739 | 2742 | ||
2740 | file_lock.fl_start = lock->lk_offset; | 2743 | file_lock.fl_start = lock->lk_offset; |
2741 | if ((lock->lk_length == ~(u64)0) || | 2744 | if ((lock->lk_length == ~(u64)0) || |
@@ -2841,6 +2844,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2841 | file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner; | 2844 | file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner; |
2842 | file_lock.fl_pid = current->tgid; | 2845 | file_lock.fl_pid = current->tgid; |
2843 | file_lock.fl_flags = FL_POSIX; | 2846 | file_lock.fl_flags = FL_POSIX; |
2847 | file_lock.fl_lmops = &nfsd_posix_mng_ops; | ||
2844 | 2848 | ||
2845 | file_lock.fl_start = lockt->lt_offset; | 2849 | file_lock.fl_start = lockt->lt_offset; |
2846 | if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length)) | 2850 | if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length)) |
@@ -2900,6 +2904,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2900 | file_lock.fl_pid = current->tgid; | 2904 | file_lock.fl_pid = current->tgid; |
2901 | file_lock.fl_file = filp; | 2905 | file_lock.fl_file = filp; |
2902 | file_lock.fl_flags = FL_POSIX; | 2906 | file_lock.fl_flags = FL_POSIX; |
2907 | file_lock.fl_lmops = &nfsd_posix_mng_ops; | ||
2903 | file_lock.fl_start = locku->lu_offset; | 2908 | file_lock.fl_start = locku->lu_offset; |
2904 | 2909 | ||
2905 | if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length)) | 2910 | if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length)) |
@@ -3211,15 +3216,8 @@ __nfs4_state_shutdown(void) | |||
3211 | int i; | 3216 | int i; |
3212 | struct nfs4_client *clp = NULL; | 3217 | struct nfs4_client *clp = NULL; |
3213 | struct nfs4_delegation *dp = NULL; | 3218 | struct nfs4_delegation *dp = NULL; |
3214 | struct nfs4_stateowner *sop = NULL; | ||
3215 | struct list_head *pos, *next, reaplist; | 3219 | struct list_head *pos, *next, reaplist; |
3216 | 3220 | ||
3217 | list_for_each_safe(pos, next, &close_lru) { | ||
3218 | sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); | ||
3219 | list_del(&sop->so_close_lru); | ||
3220 | nfs4_put_stateowner(sop); | ||
3221 | } | ||
3222 | |||
3223 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | 3221 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { |
3224 | while (!list_empty(&conf_id_hashtbl[i])) { | 3222 | while (!list_empty(&conf_id_hashtbl[i])) { |
3225 | clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); | 3223 | clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); |
@@ -3244,8 +3242,6 @@ __nfs4_state_shutdown(void) | |||
3244 | } | 3242 | } |
3245 | 3243 | ||
3246 | cancel_delayed_work(&laundromat_work); | 3244 | cancel_delayed_work(&laundromat_work); |
3247 | flush_workqueue(laundry_wq); | ||
3248 | destroy_workqueue(laundry_wq); | ||
3249 | nfsd4_shutdown_recdir(); | 3245 | nfsd4_shutdown_recdir(); |
3250 | nfs4_init = 0; | 3246 | nfs4_init = 0; |
3251 | } | 3247 | } |
@@ -3253,6 +3249,8 @@ __nfs4_state_shutdown(void) | |||
3253 | void | 3249 | void |
3254 | nfs4_state_shutdown(void) | 3250 | nfs4_state_shutdown(void) |
3255 | { | 3251 | { |
3252 | cancel_rearming_delayed_workqueue(laundry_wq, &laundromat_work); | ||
3253 | destroy_workqueue(laundry_wq); | ||
3256 | nfs4_lock_state(); | 3254 | nfs4_lock_state(); |
3257 | nfs4_release_reclaim(); | 3255 | nfs4_release_reclaim(); |
3258 | __nfs4_state_shutdown(); | 3256 | __nfs4_state_shutdown(); |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 03857fd81126..de3998f15f10 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -299,11 +299,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
299 | buf, dummy32, &ace.who); | 299 | buf, dummy32, &ace.who); |
300 | if (status) | 300 | if (status) |
301 | goto out_nfserr; | 301 | goto out_nfserr; |
302 | if (nfs4_acl_add_ace(*acl, ace.type, ace.flag, | 302 | status = nfs4_acl_add_ace(*acl, ace.type, ace.flag, |
303 | ace.access_mask, ace.whotype, ace.who) != 0) { | 303 | ace.access_mask, ace.whotype, ace.who); |
304 | status = -ENOMEM; | 304 | if (status) |
305 | goto out_nfserr; | 305 | goto out_nfserr; |
306 | } | ||
307 | } | 306 | } |
308 | } else | 307 | } else |
309 | *acl = NULL; | 308 | *acl = NULL; |
@@ -2085,27 +2084,20 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
2085 | WRITE32(eof); | 2084 | WRITE32(eof); |
2086 | WRITE32(maxcount); | 2085 | WRITE32(maxcount); |
2087 | ADJUST_ARGS(); | 2086 | ADJUST_ARGS(); |
2088 | resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; | 2087 | resp->xbuf->head[0].iov_len = (char*)p |
2089 | 2088 | - (char*)resp->xbuf->head[0].iov_base; | |
2090 | resp->xbuf->page_len = maxcount; | 2089 | resp->xbuf->page_len = maxcount; |
2091 | 2090 | ||
2092 | /* read zero bytes -> don't set up tail */ | 2091 | /* Use rest of head for padding and remaining ops: */ |
2093 | if(!maxcount) | 2092 | resp->rqstp->rq_restailpage = 0; |
2094 | return 0; | 2093 | resp->xbuf->tail[0].iov_base = p; |
2095 | |||
2096 | /* set up page for remaining responses */ | ||
2097 | svc_take_page(resp->rqstp); | ||
2098 | resp->xbuf->tail[0].iov_base = | ||
2099 | page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
2100 | resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1; | ||
2101 | resp->xbuf->tail[0].iov_len = 0; | 2094 | resp->xbuf->tail[0].iov_len = 0; |
2102 | resp->p = resp->xbuf->tail[0].iov_base; | ||
2103 | resp->end = resp->p + PAGE_SIZE/4; | ||
2104 | |||
2105 | if (maxcount&3) { | 2095 | if (maxcount&3) { |
2106 | *(resp->p)++ = 0; | 2096 | RESERVE_SPACE(4); |
2097 | WRITE32(0); | ||
2107 | resp->xbuf->tail[0].iov_base += maxcount&3; | 2098 | resp->xbuf->tail[0].iov_base += maxcount&3; |
2108 | resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); | 2099 | resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); |
2100 | ADJUST_ARGS(); | ||
2109 | } | 2101 | } |
2110 | return 0; | 2102 | return 0; |
2111 | } | 2103 | } |
@@ -2142,21 +2134,20 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r | |||
2142 | 2134 | ||
2143 | WRITE32(maxcount); | 2135 | WRITE32(maxcount); |
2144 | ADJUST_ARGS(); | 2136 | ADJUST_ARGS(); |
2145 | resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; | 2137 | resp->xbuf->head[0].iov_len = (char*)p |
2138 | - (char*)resp->xbuf->head[0].iov_base; | ||
2139 | resp->xbuf->page_len = maxcount; | ||
2146 | 2140 | ||
2147 | svc_take_page(resp->rqstp); | 2141 | /* Use rest of head for padding and remaining ops: */ |
2148 | resp->xbuf->tail[0].iov_base = | 2142 | resp->rqstp->rq_restailpage = 0; |
2149 | page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | 2143 | resp->xbuf->tail[0].iov_base = p; |
2150 | resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1; | ||
2151 | resp->xbuf->tail[0].iov_len = 0; | 2144 | resp->xbuf->tail[0].iov_len = 0; |
2152 | resp->p = resp->xbuf->tail[0].iov_base; | ||
2153 | resp->end = resp->p + PAGE_SIZE/4; | ||
2154 | |||
2155 | resp->xbuf->page_len = maxcount; | ||
2156 | if (maxcount&3) { | 2145 | if (maxcount&3) { |
2157 | *(resp->p)++ = 0; | 2146 | RESERVE_SPACE(4); |
2147 | WRITE32(0); | ||
2158 | resp->xbuf->tail[0].iov_base += maxcount&3; | 2148 | resp->xbuf->tail[0].iov_base += maxcount&3; |
2159 | resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); | 2149 | resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); |
2150 | ADJUST_ARGS(); | ||
2160 | } | 2151 | } |
2161 | return 0; | 2152 | return 0; |
2162 | } | 2153 | } |
@@ -2166,7 +2157,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
2166 | { | 2157 | { |
2167 | int maxcount; | 2158 | int maxcount; |
2168 | loff_t offset; | 2159 | loff_t offset; |
2169 | u32 *page, *savep; | 2160 | u32 *page, *savep, *tailbase; |
2170 | ENCODE_HEAD; | 2161 | ENCODE_HEAD; |
2171 | 2162 | ||
2172 | if (nfserr) | 2163 | if (nfserr) |
@@ -2182,6 +2173,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
2182 | WRITE32(0); | 2173 | WRITE32(0); |
2183 | ADJUST_ARGS(); | 2174 | ADJUST_ARGS(); |
2184 | resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; | 2175 | resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; |
2176 | tailbase = p; | ||
2185 | 2177 | ||
2186 | maxcount = PAGE_SIZE; | 2178 | maxcount = PAGE_SIZE; |
2187 | if (maxcount > readdir->rd_maxcount) | 2179 | if (maxcount > readdir->rd_maxcount) |
@@ -2226,14 +2218,12 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
2226 | *p++ = htonl(readdir->common.err == nfserr_eof); | 2218 | *p++ = htonl(readdir->common.err == nfserr_eof); |
2227 | resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | 2219 | resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); |
2228 | 2220 | ||
2229 | /* allocate a page for the tail */ | 2221 | /* Use rest of head for padding and remaining ops: */ |
2230 | svc_take_page(resp->rqstp); | 2222 | resp->rqstp->rq_restailpage = 0; |
2231 | resp->xbuf->tail[0].iov_base = | 2223 | resp->xbuf->tail[0].iov_base = tailbase; |
2232 | page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
2233 | resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1; | ||
2234 | resp->xbuf->tail[0].iov_len = 0; | 2224 | resp->xbuf->tail[0].iov_len = 0; |
2235 | resp->p = resp->xbuf->tail[0].iov_base; | 2225 | resp->p = resp->xbuf->tail[0].iov_base; |
2236 | resp->end = resp->p + PAGE_SIZE/4; | 2226 | resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4; |
2237 | 2227 | ||
2238 | return 0; | 2228 | return 0; |
2239 | err_no_verf: | 2229 | err_no_verf: |
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 3e6b75cd90fd..06cd0db0f32b 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c | |||
@@ -553,7 +553,7 @@ static struct svc_procedure nfsd_procedures2[18] = { | |||
553 | PROC(none, void, void, none, RC_NOCACHE, ST), | 553 | PROC(none, void, void, none, RC_NOCACHE, ST), |
554 | PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), | 554 | PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), |
555 | PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), | 555 | PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), |
556 | PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE), | 556 | PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4), |
557 | PROC(none, void, void, none, RC_NOCACHE, ST), | 557 | PROC(none, void, void, none, RC_NOCACHE, ST), |
558 | PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), | 558 | PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), |
559 | PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), | 559 | PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 31018333dc38..6aa92d0e6876 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -371,7 +371,6 @@ out_nfserr: | |||
371 | static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) | 371 | static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) |
372 | { | 372 | { |
373 | ssize_t buflen; | 373 | ssize_t buflen; |
374 | int error; | ||
375 | 374 | ||
376 | buflen = vfs_getxattr(dentry, key, NULL, 0); | 375 | buflen = vfs_getxattr(dentry, key, NULL, 0); |
377 | if (buflen <= 0) | 376 | if (buflen <= 0) |
@@ -381,10 +380,7 @@ static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) | |||
381 | if (!*buf) | 380 | if (!*buf) |
382 | return -ENOMEM; | 381 | return -ENOMEM; |
383 | 382 | ||
384 | error = vfs_getxattr(dentry, key, *buf, buflen); | 383 | return vfs_getxattr(dentry, key, *buf, buflen); |
385 | if (error < 0) | ||
386 | return error; | ||
387 | return buflen; | ||
388 | } | 384 | } |
389 | #endif | 385 | #endif |
390 | 386 | ||
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index bff0f0d06867..21f38accd039 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -153,6 +153,7 @@ struct o2hb_region { | |||
153 | struct o2hb_bio_wait_ctxt { | 153 | struct o2hb_bio_wait_ctxt { |
154 | atomic_t wc_num_reqs; | 154 | atomic_t wc_num_reqs; |
155 | struct completion wc_io_complete; | 155 | struct completion wc_io_complete; |
156 | int wc_error; | ||
156 | }; | 157 | }; |
157 | 158 | ||
158 | static void o2hb_write_timeout(void *arg) | 159 | static void o2hb_write_timeout(void *arg) |
@@ -186,6 +187,7 @@ static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc, | |||
186 | { | 187 | { |
187 | atomic_set(&wc->wc_num_reqs, num_ios); | 188 | atomic_set(&wc->wc_num_reqs, num_ios); |
188 | init_completion(&wc->wc_io_complete); | 189 | init_completion(&wc->wc_io_complete); |
190 | wc->wc_error = 0; | ||
189 | } | 191 | } |
190 | 192 | ||
191 | /* Used in error paths too */ | 193 | /* Used in error paths too */ |
@@ -218,8 +220,10 @@ static int o2hb_bio_end_io(struct bio *bio, | |||
218 | { | 220 | { |
219 | struct o2hb_bio_wait_ctxt *wc = bio->bi_private; | 221 | struct o2hb_bio_wait_ctxt *wc = bio->bi_private; |
220 | 222 | ||
221 | if (error) | 223 | if (error) { |
222 | mlog(ML_ERROR, "IO Error %d\n", error); | 224 | mlog(ML_ERROR, "IO Error %d\n", error); |
225 | wc->wc_error = error; | ||
226 | } | ||
223 | 227 | ||
224 | if (bio->bi_size) | 228 | if (bio->bi_size) |
225 | return 1; | 229 | return 1; |
@@ -390,6 +394,8 @@ static int o2hb_read_slots(struct o2hb_region *reg, | |||
390 | 394 | ||
391 | bail_and_wait: | 395 | bail_and_wait: |
392 | o2hb_wait_on_io(reg, &wc); | 396 | o2hb_wait_on_io(reg, &wc); |
397 | if (wc.wc_error && !status) | ||
398 | status = wc.wc_error; | ||
393 | 399 | ||
394 | if (bios) { | 400 | if (bios) { |
395 | for(i = 0; i < num_bios; i++) | 401 | for(i = 0; i < num_bios; i++) |
@@ -790,20 +796,24 @@ static int o2hb_highest_node(unsigned long *nodes, | |||
790 | return highest; | 796 | return highest; |
791 | } | 797 | } |
792 | 798 | ||
793 | static void o2hb_do_disk_heartbeat(struct o2hb_region *reg) | 799 | static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) |
794 | { | 800 | { |
795 | int i, ret, highest_node, change = 0; | 801 | int i, ret, highest_node, change = 0; |
796 | unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)]; | 802 | unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
797 | struct bio *write_bio; | 803 | struct bio *write_bio; |
798 | struct o2hb_bio_wait_ctxt write_wc; | 804 | struct o2hb_bio_wait_ctxt write_wc; |
799 | 805 | ||
800 | if (o2nm_configured_node_map(configured_nodes, sizeof(configured_nodes))) | 806 | ret = o2nm_configured_node_map(configured_nodes, |
801 | return; | 807 | sizeof(configured_nodes)); |
808 | if (ret) { | ||
809 | mlog_errno(ret); | ||
810 | return ret; | ||
811 | } | ||
802 | 812 | ||
803 | highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES); | 813 | highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES); |
804 | if (highest_node >= O2NM_MAX_NODES) { | 814 | if (highest_node >= O2NM_MAX_NODES) { |
805 | mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n"); | 815 | mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n"); |
806 | return; | 816 | return -EINVAL; |
807 | } | 817 | } |
808 | 818 | ||
809 | /* No sense in reading the slots of nodes that don't exist | 819 | /* No sense in reading the slots of nodes that don't exist |
@@ -813,7 +823,7 @@ static void o2hb_do_disk_heartbeat(struct o2hb_region *reg) | |||
813 | ret = o2hb_read_slots(reg, highest_node + 1); | 823 | ret = o2hb_read_slots(reg, highest_node + 1); |
814 | if (ret < 0) { | 824 | if (ret < 0) { |
815 | mlog_errno(ret); | 825 | mlog_errno(ret); |
816 | return; | 826 | return ret; |
817 | } | 827 | } |
818 | 828 | ||
819 | /* With an up to date view of the slots, we can check that no | 829 | /* With an up to date view of the slots, we can check that no |
@@ -831,7 +841,7 @@ static void o2hb_do_disk_heartbeat(struct o2hb_region *reg) | |||
831 | ret = o2hb_issue_node_write(reg, &write_bio, &write_wc); | 841 | ret = o2hb_issue_node_write(reg, &write_bio, &write_wc); |
832 | if (ret < 0) { | 842 | if (ret < 0) { |
833 | mlog_errno(ret); | 843 | mlog_errno(ret); |
834 | return; | 844 | return ret; |
835 | } | 845 | } |
836 | 846 | ||
837 | i = -1; | 847 | i = -1; |
@@ -847,6 +857,15 @@ static void o2hb_do_disk_heartbeat(struct o2hb_region *reg) | |||
847 | */ | 857 | */ |
848 | o2hb_wait_on_io(reg, &write_wc); | 858 | o2hb_wait_on_io(reg, &write_wc); |
849 | bio_put(write_bio); | 859 | bio_put(write_bio); |
860 | if (write_wc.wc_error) { | ||
861 | /* Do not re-arm the write timeout on I/O error - we | ||
862 | * can't be sure that the new block ever made it to | ||
863 | * disk */ | ||
864 | mlog(ML_ERROR, "Write error %d on device \"%s\"\n", | ||
865 | write_wc.wc_error, reg->hr_dev_name); | ||
866 | return write_wc.wc_error; | ||
867 | } | ||
868 | |||
850 | o2hb_arm_write_timeout(reg); | 869 | o2hb_arm_write_timeout(reg); |
851 | 870 | ||
852 | /* let the person who launched us know when things are steady */ | 871 | /* let the person who launched us know when things are steady */ |
@@ -854,6 +873,8 @@ static void o2hb_do_disk_heartbeat(struct o2hb_region *reg) | |||
854 | if (atomic_dec_and_test(®->hr_steady_iterations)) | 873 | if (atomic_dec_and_test(®->hr_steady_iterations)) |
855 | wake_up(&o2hb_steady_queue); | 874 | wake_up(&o2hb_steady_queue); |
856 | } | 875 | } |
876 | |||
877 | return 0; | ||
857 | } | 878 | } |
858 | 879 | ||
859 | /* Subtract b from a, storing the result in a. a *must* have a larger | 880 | /* Subtract b from a, storing the result in a. a *must* have a larger |
@@ -913,7 +934,10 @@ static int o2hb_thread(void *data) | |||
913 | * likely to time itself out. */ | 934 | * likely to time itself out. */ |
914 | do_gettimeofday(&before_hb); | 935 | do_gettimeofday(&before_hb); |
915 | 936 | ||
916 | o2hb_do_disk_heartbeat(reg); | 937 | i = 0; |
938 | do { | ||
939 | ret = o2hb_do_disk_heartbeat(reg); | ||
940 | } while (ret && ++i < 2); | ||
917 | 941 | ||
918 | do_gettimeofday(&after_hb); | 942 | do_gettimeofday(&after_hb); |
919 | elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); | 943 | elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); |
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c index c3764f4744ee..74ca4e5f9765 100644 --- a/fs/ocfs2/dlm/userdlm.c +++ b/fs/ocfs2/dlm/userdlm.c | |||
@@ -139,6 +139,10 @@ static void user_ast(void *opaque) | |||
139 | return; | 139 | return; |
140 | } | 140 | } |
141 | 141 | ||
142 | mlog_bug_on_msg(lockres->l_requested == LKM_IVMODE, | ||
143 | "Lockres %s, requested ivmode. flags 0x%x\n", | ||
144 | lockres->l_name, lockres->l_flags); | ||
145 | |||
142 | /* we're downconverting. */ | 146 | /* we're downconverting. */ |
143 | if (lockres->l_requested < lockres->l_level) { | 147 | if (lockres->l_requested < lockres->l_level) { |
144 | if (lockres->l_requested <= | 148 | if (lockres->l_requested <= |
@@ -229,23 +233,42 @@ static void user_unlock_ast(void *opaque, enum dlm_status status) | |||
229 | 233 | ||
230 | mlog(0, "UNLOCK AST called on lock %s\n", lockres->l_name); | 234 | mlog(0, "UNLOCK AST called on lock %s\n", lockres->l_name); |
231 | 235 | ||
232 | if (status != DLM_NORMAL) | 236 | if (status != DLM_NORMAL && status != DLM_CANCELGRANT) |
233 | mlog(ML_ERROR, "Dlm returns status %d\n", status); | 237 | mlog(ML_ERROR, "Dlm returns status %d\n", status); |
234 | 238 | ||
235 | spin_lock(&lockres->l_lock); | 239 | spin_lock(&lockres->l_lock); |
236 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) | 240 | /* The teardown flag gets set early during the unlock process, |
241 | * so test the cancel flag to make sure that this ast isn't | ||
242 | * for a concurrent cancel. */ | ||
243 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN | ||
244 | && !(lockres->l_flags & USER_LOCK_IN_CANCEL)) { | ||
237 | lockres->l_level = LKM_IVMODE; | 245 | lockres->l_level = LKM_IVMODE; |
238 | else { | 246 | } else if (status == DLM_CANCELGRANT) { |
247 | mlog(0, "Lock %s, cancel fails, flags 0x%x\n", | ||
248 | lockres->l_name, lockres->l_flags); | ||
249 | /* We tried to cancel a convert request, but it was | ||
250 | * already granted. Don't clear the busy flag - the | ||
251 | * ast should've done this already. */ | ||
252 | BUG_ON(!(lockres->l_flags & USER_LOCK_IN_CANCEL)); | ||
253 | lockres->l_flags &= ~USER_LOCK_IN_CANCEL; | ||
254 | goto out_noclear; | ||
255 | } else { | ||
256 | BUG_ON(!(lockres->l_flags & USER_LOCK_IN_CANCEL)); | ||
257 | /* Cancel succeeded, we want to re-queue */ | ||
258 | mlog(0, "Lock %s, cancel succeeds, flags 0x%x\n", | ||
259 | lockres->l_name, lockres->l_flags); | ||
239 | lockres->l_requested = LKM_IVMODE; /* cancel an | 260 | lockres->l_requested = LKM_IVMODE; /* cancel an |
240 | * upconvert | 261 | * upconvert |
241 | * request. */ | 262 | * request. */ |
242 | lockres->l_flags &= ~USER_LOCK_IN_CANCEL; | 263 | lockres->l_flags &= ~USER_LOCK_IN_CANCEL; |
243 | /* we want the unblock thread to look at it again | 264 | /* we want the unblock thread to look at it again |
244 | * now. */ | 265 | * now. */ |
245 | __user_dlm_queue_lockres(lockres); | 266 | if (lockres->l_flags & USER_LOCK_BLOCKED) |
267 | __user_dlm_queue_lockres(lockres); | ||
246 | } | 268 | } |
247 | 269 | ||
248 | lockres->l_flags &= ~USER_LOCK_BUSY; | 270 | lockres->l_flags &= ~USER_LOCK_BUSY; |
271 | out_noclear: | ||
249 | spin_unlock(&lockres->l_lock); | 272 | spin_unlock(&lockres->l_lock); |
250 | 273 | ||
251 | wake_up(&lockres->l_event); | 274 | wake_up(&lockres->l_event); |
@@ -268,13 +291,26 @@ static void user_dlm_unblock_lock(void *opaque) | |||
268 | 291 | ||
269 | spin_lock(&lockres->l_lock); | 292 | spin_lock(&lockres->l_lock); |
270 | 293 | ||
271 | BUG_ON(!(lockres->l_flags & USER_LOCK_BLOCKED)); | 294 | mlog_bug_on_msg(!(lockres->l_flags & USER_LOCK_QUEUED), |
272 | BUG_ON(!(lockres->l_flags & USER_LOCK_QUEUED)); | 295 | "Lockres %s, flags 0x%x\n", |
296 | lockres->l_name, lockres->l_flags); | ||
273 | 297 | ||
274 | /* notice that we don't clear USER_LOCK_BLOCKED here. That's | 298 | /* notice that we don't clear USER_LOCK_BLOCKED here. If it's |
275 | * for user_ast to do. */ | 299 | * set, we want user_ast clear it. */ |
276 | lockres->l_flags &= ~USER_LOCK_QUEUED; | 300 | lockres->l_flags &= ~USER_LOCK_QUEUED; |
277 | 301 | ||
302 | /* It's valid to get here and no longer be blocked - if we get | ||
303 | * several basts in a row, we might be queued by the first | ||
304 | * one, the unblock thread might run and clear the queued | ||
305 | * flag, and finally we might get another bast which re-queues | ||
306 | * us before our ast for the downconvert is called. */ | ||
307 | if (!(lockres->l_flags & USER_LOCK_BLOCKED)) { | ||
308 | mlog(0, "Lockres %s, flags 0x%x: queued but not blocking\n", | ||
309 | lockres->l_name, lockres->l_flags); | ||
310 | spin_unlock(&lockres->l_lock); | ||
311 | goto drop_ref; | ||
312 | } | ||
313 | |||
278 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { | 314 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { |
279 | mlog(0, "lock is in teardown so we do nothing\n"); | 315 | mlog(0, "lock is in teardown so we do nothing\n"); |
280 | spin_unlock(&lockres->l_lock); | 316 | spin_unlock(&lockres->l_lock); |
@@ -282,7 +318,9 @@ static void user_dlm_unblock_lock(void *opaque) | |||
282 | } | 318 | } |
283 | 319 | ||
284 | if (lockres->l_flags & USER_LOCK_BUSY) { | 320 | if (lockres->l_flags & USER_LOCK_BUSY) { |
285 | mlog(0, "BUSY flag detected...\n"); | 321 | mlog(0, "Cancel lock %s, flags 0x%x\n", |
322 | lockres->l_name, lockres->l_flags); | ||
323 | |||
286 | if (lockres->l_flags & USER_LOCK_IN_CANCEL) { | 324 | if (lockres->l_flags & USER_LOCK_IN_CANCEL) { |
287 | spin_unlock(&lockres->l_lock); | 325 | spin_unlock(&lockres->l_lock); |
288 | goto drop_ref; | 326 | goto drop_ref; |
@@ -296,14 +334,7 @@ static void user_dlm_unblock_lock(void *opaque) | |||
296 | LKM_CANCEL, | 334 | LKM_CANCEL, |
297 | user_unlock_ast, | 335 | user_unlock_ast, |
298 | lockres); | 336 | lockres); |
299 | if (status == DLM_CANCELGRANT) { | 337 | if (status != DLM_NORMAL) |
300 | /* If we got this, then the ast was fired | ||
301 | * before we could cancel. We cleanup our | ||
302 | * state, and restart the function. */ | ||
303 | spin_lock(&lockres->l_lock); | ||
304 | lockres->l_flags &= ~USER_LOCK_IN_CANCEL; | ||
305 | spin_unlock(&lockres->l_lock); | ||
306 | } else if (status != DLM_NORMAL) | ||
307 | user_log_dlm_error("dlmunlock", status, lockres); | 338 | user_log_dlm_error("dlmunlock", status, lockres); |
308 | goto drop_ref; | 339 | goto drop_ref; |
309 | } | 340 | } |
@@ -581,6 +612,14 @@ int user_dlm_destroy_lock(struct user_lock_res *lockres) | |||
581 | mlog(0, "asked to destroy %s\n", lockres->l_name); | 612 | mlog(0, "asked to destroy %s\n", lockres->l_name); |
582 | 613 | ||
583 | spin_lock(&lockres->l_lock); | 614 | spin_lock(&lockres->l_lock); |
615 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { | ||
616 | mlog(0, "Lock is already torn down\n"); | ||
617 | spin_unlock(&lockres->l_lock); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | lockres->l_flags |= USER_LOCK_IN_TEARDOWN; | ||
622 | |||
584 | while (lockres->l_flags & USER_LOCK_BUSY) { | 623 | while (lockres->l_flags & USER_LOCK_BUSY) { |
585 | spin_unlock(&lockres->l_lock); | 624 | spin_unlock(&lockres->l_lock); |
586 | 625 | ||
@@ -606,7 +645,6 @@ int user_dlm_destroy_lock(struct user_lock_res *lockres) | |||
606 | 645 | ||
607 | lockres->l_flags &= ~USER_LOCK_ATTACHED; | 646 | lockres->l_flags &= ~USER_LOCK_ATTACHED; |
608 | lockres->l_flags |= USER_LOCK_BUSY; | 647 | lockres->l_flags |= USER_LOCK_BUSY; |
609 | lockres->l_flags |= USER_LOCK_IN_TEARDOWN; | ||
610 | spin_unlock(&lockres->l_lock); | 648 | spin_unlock(&lockres->l_lock); |
611 | 649 | ||
612 | mlog(0, "unlocking lockres %s\n", lockres->l_name); | 650 | mlog(0, "unlocking lockres %s\n", lockres->l_name); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 34e903a6a46b..581eb451a41a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -260,6 +260,17 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
260 | if (new_i_size == le64_to_cpu(fe->i_size)) | 260 | if (new_i_size == le64_to_cpu(fe->i_size)) |
261 | goto bail; | 261 | goto bail; |
262 | 262 | ||
263 | /* This forces other nodes to sync and drop their pages. Do | ||
264 | * this even if we have a truncate without allocation change - | ||
265 | * ocfs2 cluster sizes can be much greater than page size, so | ||
266 | * we have to truncate them anyway. */ | ||
267 | status = ocfs2_data_lock(inode, 1); | ||
268 | if (status < 0) { | ||
269 | mlog_errno(status); | ||
270 | goto bail; | ||
271 | } | ||
272 | ocfs2_data_unlock(inode, 1); | ||
273 | |||
263 | if (le32_to_cpu(fe->i_clusters) == | 274 | if (le32_to_cpu(fe->i_clusters) == |
264 | ocfs2_clusters_for_bytes(osb->sb, new_i_size)) { | 275 | ocfs2_clusters_for_bytes(osb->sb, new_i_size)) { |
265 | mlog(0, "fe->i_clusters = %u, so we do a simple truncate\n", | 276 | mlog(0, "fe->i_clusters = %u, so we do a simple truncate\n", |
@@ -272,14 +283,6 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
272 | goto bail; | 283 | goto bail; |
273 | } | 284 | } |
274 | 285 | ||
275 | /* This forces other nodes to sync and drop their pages */ | ||
276 | status = ocfs2_data_lock(inode, 1); | ||
277 | if (status < 0) { | ||
278 | mlog_errno(status); | ||
279 | goto bail; | ||
280 | } | ||
281 | ocfs2_data_unlock(inode, 1); | ||
282 | |||
283 | /* alright, we're going to need to do a full blown alloc size | 286 | /* alright, we're going to need to do a full blown alloc size |
284 | * change. Orphan the inode so that recovery can complete the | 287 | * change. Orphan the inode so that recovery can complete the |
285 | * truncate if necessary. This does the task of marking | 288 | * truncate if necessary. This does the task of marking |
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | /* Drop the inode semaphore and wait for a pipe event, atomically */ | 38 | /* Drop the inode semaphore and wait for a pipe event, atomically */ |
39 | void pipe_wait(struct inode * inode) | 39 | void pipe_wait(struct pipe_inode_info *pipe) |
40 | { | 40 | { |
41 | DEFINE_WAIT(wait); | 41 | DEFINE_WAIT(wait); |
42 | 42 | ||
@@ -44,11 +44,14 @@ void pipe_wait(struct inode * inode) | |||
44 | * Pipes are system-local resources, so sleeping on them | 44 | * Pipes are system-local resources, so sleeping on them |
45 | * is considered a noninteractive wait: | 45 | * is considered a noninteractive wait: |
46 | */ | 46 | */ |
47 | prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); | 47 | prepare_to_wait(&pipe->wait, &wait, |
48 | mutex_unlock(PIPE_MUTEX(*inode)); | 48 | TASK_INTERRUPTIBLE | TASK_NONINTERACTIVE); |
49 | if (pipe->inode) | ||
50 | mutex_unlock(&pipe->inode->i_mutex); | ||
49 | schedule(); | 51 | schedule(); |
50 | finish_wait(PIPE_WAIT(*inode), &wait); | 52 | finish_wait(&pipe->wait, &wait); |
51 | mutex_lock(PIPE_MUTEX(*inode)); | 53 | if (pipe->inode) |
54 | mutex_lock(&pipe->inode->i_mutex); | ||
52 | } | 55 | } |
53 | 56 | ||
54 | static int | 57 | static int |
@@ -91,7 +94,8 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len) | |||
91 | return 0; | 94 | return 0; |
92 | } | 95 | } |
93 | 96 | ||
94 | static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buffer *buf) | 97 | static void anon_pipe_buf_release(struct pipe_inode_info *pipe, |
98 | struct pipe_buffer *buf) | ||
95 | { | 99 | { |
96 | struct page *page = buf->page; | 100 | struct page *page = buf->page; |
97 | 101 | ||
@@ -100,30 +104,27 @@ static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buff | |||
100 | /* | 104 | /* |
101 | * If nobody else uses this page, and we don't already have a | 105 | * If nobody else uses this page, and we don't already have a |
102 | * temporary page, let's keep track of it as a one-deep | 106 | * temporary page, let's keep track of it as a one-deep |
103 | * allocation cache | 107 | * allocation cache. (Otherwise just release our reference to it) |
104 | */ | 108 | */ |
105 | if (page_count(page) == 1 && !info->tmp_page) { | 109 | if (page_count(page) == 1 && !pipe->tmp_page) |
106 | info->tmp_page = page; | 110 | pipe->tmp_page = page; |
107 | return; | 111 | else |
108 | } | 112 | page_cache_release(page); |
109 | |||
110 | /* | ||
111 | * Otherwise just release our reference to it | ||
112 | */ | ||
113 | page_cache_release(page); | ||
114 | } | 113 | } |
115 | 114 | ||
116 | static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf) | 115 | static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, |
116 | struct pipe_buffer *buf) | ||
117 | { | 117 | { |
118 | return kmap(buf->page); | 118 | return kmap(buf->page); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer *buf) | 121 | static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, |
122 | struct pipe_buffer *buf) | ||
122 | { | 123 | { |
123 | kunmap(buf->page); | 124 | kunmap(buf->page); |
124 | } | 125 | } |
125 | 126 | ||
126 | static int anon_pipe_buf_steal(struct pipe_inode_info *info, | 127 | static int anon_pipe_buf_steal(struct pipe_inode_info *pipe, |
127 | struct pipe_buffer *buf) | 128 | struct pipe_buffer *buf) |
128 | { | 129 | { |
129 | buf->flags |= PIPE_BUF_FLAG_STOLEN; | 130 | buf->flags |= PIPE_BUF_FLAG_STOLEN; |
@@ -143,7 +144,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
143 | unsigned long nr_segs, loff_t *ppos) | 144 | unsigned long nr_segs, loff_t *ppos) |
144 | { | 145 | { |
145 | struct inode *inode = filp->f_dentry->d_inode; | 146 | struct inode *inode = filp->f_dentry->d_inode; |
146 | struct pipe_inode_info *info; | 147 | struct pipe_inode_info *pipe; |
147 | int do_wakeup; | 148 | int do_wakeup; |
148 | ssize_t ret; | 149 | ssize_t ret; |
149 | struct iovec *iov = (struct iovec *)_iov; | 150 | struct iovec *iov = (struct iovec *)_iov; |
@@ -156,13 +157,13 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
156 | 157 | ||
157 | do_wakeup = 0; | 158 | do_wakeup = 0; |
158 | ret = 0; | 159 | ret = 0; |
159 | mutex_lock(PIPE_MUTEX(*inode)); | 160 | mutex_lock(&inode->i_mutex); |
160 | info = inode->i_pipe; | 161 | pipe = inode->i_pipe; |
161 | for (;;) { | 162 | for (;;) { |
162 | int bufs = info->nrbufs; | 163 | int bufs = pipe->nrbufs; |
163 | if (bufs) { | 164 | if (bufs) { |
164 | int curbuf = info->curbuf; | 165 | int curbuf = pipe->curbuf; |
165 | struct pipe_buffer *buf = info->bufs + curbuf; | 166 | struct pipe_buffer *buf = pipe->bufs + curbuf; |
166 | struct pipe_buf_operations *ops = buf->ops; | 167 | struct pipe_buf_operations *ops = buf->ops; |
167 | void *addr; | 168 | void *addr; |
168 | size_t chars = buf->len; | 169 | size_t chars = buf->len; |
@@ -171,16 +172,17 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
171 | if (chars > total_len) | 172 | if (chars > total_len) |
172 | chars = total_len; | 173 | chars = total_len; |
173 | 174 | ||
174 | addr = ops->map(filp, info, buf); | 175 | addr = ops->map(filp, pipe, buf); |
175 | if (IS_ERR(addr)) { | 176 | if (IS_ERR(addr)) { |
176 | if (!ret) | 177 | if (!ret) |
177 | ret = PTR_ERR(addr); | 178 | ret = PTR_ERR(addr); |
178 | break; | 179 | break; |
179 | } | 180 | } |
180 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); | 181 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); |
181 | ops->unmap(info, buf); | 182 | ops->unmap(pipe, buf); |
182 | if (unlikely(error)) { | 183 | if (unlikely(error)) { |
183 | if (!ret) ret = -EFAULT; | 184 | if (!ret) |
185 | ret = -EFAULT; | ||
184 | break; | 186 | break; |
185 | } | 187 | } |
186 | ret += chars; | 188 | ret += chars; |
@@ -188,10 +190,10 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
188 | buf->len -= chars; | 190 | buf->len -= chars; |
189 | if (!buf->len) { | 191 | if (!buf->len) { |
190 | buf->ops = NULL; | 192 | buf->ops = NULL; |
191 | ops->release(info, buf); | 193 | ops->release(pipe, buf); |
192 | curbuf = (curbuf + 1) & (PIPE_BUFFERS-1); | 194 | curbuf = (curbuf + 1) & (PIPE_BUFFERS-1); |
193 | info->curbuf = curbuf; | 195 | pipe->curbuf = curbuf; |
194 | info->nrbufs = --bufs; | 196 | pipe->nrbufs = --bufs; |
195 | do_wakeup = 1; | 197 | do_wakeup = 1; |
196 | } | 198 | } |
197 | total_len -= chars; | 199 | total_len -= chars; |
@@ -200,9 +202,9 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
200 | } | 202 | } |
201 | if (bufs) /* More to do? */ | 203 | if (bufs) /* More to do? */ |
202 | continue; | 204 | continue; |
203 | if (!PIPE_WRITERS(*inode)) | 205 | if (!pipe->writers) |
204 | break; | 206 | break; |
205 | if (!PIPE_WAITING_WRITERS(*inode)) { | 207 | if (!pipe->waiting_writers) { |
206 | /* syscall merging: Usually we must not sleep | 208 | /* syscall merging: Usually we must not sleep |
207 | * if O_NONBLOCK is set, or if we got some data. | 209 | * if O_NONBLOCK is set, or if we got some data. |
208 | * But if a writer sleeps in kernel space, then | 210 | * But if a writer sleeps in kernel space, then |
@@ -216,20 +218,22 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
216 | } | 218 | } |
217 | } | 219 | } |
218 | if (signal_pending(current)) { | 220 | if (signal_pending(current)) { |
219 | if (!ret) ret = -ERESTARTSYS; | 221 | if (!ret) |
222 | ret = -ERESTARTSYS; | ||
220 | break; | 223 | break; |
221 | } | 224 | } |
222 | if (do_wakeup) { | 225 | if (do_wakeup) { |
223 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 226 | wake_up_interruptible_sync(&pipe->wait); |
224 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 227 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
225 | } | 228 | } |
226 | pipe_wait(inode); | 229 | pipe_wait(pipe); |
227 | } | 230 | } |
228 | mutex_unlock(PIPE_MUTEX(*inode)); | 231 | mutex_unlock(&inode->i_mutex); |
229 | /* Signal writers asynchronously that there is more room. */ | 232 | |
233 | /* Signal writers asynchronously that there is more room. */ | ||
230 | if (do_wakeup) { | 234 | if (do_wakeup) { |
231 | wake_up_interruptible(PIPE_WAIT(*inode)); | 235 | wake_up_interruptible(&pipe->wait); |
232 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 236 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
233 | } | 237 | } |
234 | if (ret > 0) | 238 | if (ret > 0) |
235 | file_accessed(filp); | 239 | file_accessed(filp); |
@@ -240,6 +244,7 @@ static ssize_t | |||
240 | pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | 244 | pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) |
241 | { | 245 | { |
242 | struct iovec iov = { .iov_base = buf, .iov_len = count }; | 246 | struct iovec iov = { .iov_base = buf, .iov_len = count }; |
247 | |||
243 | return pipe_readv(filp, &iov, 1, ppos); | 248 | return pipe_readv(filp, &iov, 1, ppos); |
244 | } | 249 | } |
245 | 250 | ||
@@ -248,7 +253,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
248 | unsigned long nr_segs, loff_t *ppos) | 253 | unsigned long nr_segs, loff_t *ppos) |
249 | { | 254 | { |
250 | struct inode *inode = filp->f_dentry->d_inode; | 255 | struct inode *inode = filp->f_dentry->d_inode; |
251 | struct pipe_inode_info *info; | 256 | struct pipe_inode_info *pipe; |
252 | ssize_t ret; | 257 | ssize_t ret; |
253 | int do_wakeup; | 258 | int do_wakeup; |
254 | struct iovec *iov = (struct iovec *)_iov; | 259 | struct iovec *iov = (struct iovec *)_iov; |
@@ -262,10 +267,10 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
262 | 267 | ||
263 | do_wakeup = 0; | 268 | do_wakeup = 0; |
264 | ret = 0; | 269 | ret = 0; |
265 | mutex_lock(PIPE_MUTEX(*inode)); | 270 | mutex_lock(&inode->i_mutex); |
266 | info = inode->i_pipe; | 271 | pipe = inode->i_pipe; |
267 | 272 | ||
268 | if (!PIPE_READERS(*inode)) { | 273 | if (!pipe->readers) { |
269 | send_sig(SIGPIPE, current, 0); | 274 | send_sig(SIGPIPE, current, 0); |
270 | ret = -EPIPE; | 275 | ret = -EPIPE; |
271 | goto out; | 276 | goto out; |
@@ -273,23 +278,25 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
273 | 278 | ||
274 | /* We try to merge small writes */ | 279 | /* We try to merge small writes */ |
275 | chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ | 280 | chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ |
276 | if (info->nrbufs && chars != 0) { | 281 | if (pipe->nrbufs && chars != 0) { |
277 | int lastbuf = (info->curbuf + info->nrbufs - 1) & (PIPE_BUFFERS-1); | 282 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & |
278 | struct pipe_buffer *buf = info->bufs + lastbuf; | 283 | (PIPE_BUFFERS-1); |
284 | struct pipe_buffer *buf = pipe->bufs + lastbuf; | ||
279 | struct pipe_buf_operations *ops = buf->ops; | 285 | struct pipe_buf_operations *ops = buf->ops; |
280 | int offset = buf->offset + buf->len; | 286 | int offset = buf->offset + buf->len; |
287 | |||
281 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { | 288 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { |
282 | void *addr; | 289 | void *addr; |
283 | int error; | 290 | int error; |
284 | 291 | ||
285 | addr = ops->map(filp, info, buf); | 292 | addr = ops->map(filp, pipe, buf); |
286 | if (IS_ERR(addr)) { | 293 | if (IS_ERR(addr)) { |
287 | error = PTR_ERR(addr); | 294 | error = PTR_ERR(addr); |
288 | goto out; | 295 | goto out; |
289 | } | 296 | } |
290 | error = pipe_iov_copy_from_user(offset + addr, iov, | 297 | error = pipe_iov_copy_from_user(offset + addr, iov, |
291 | chars); | 298 | chars); |
292 | ops->unmap(info, buf); | 299 | ops->unmap(pipe, buf); |
293 | ret = error; | 300 | ret = error; |
294 | do_wakeup = 1; | 301 | do_wakeup = 1; |
295 | if (error) | 302 | if (error) |
@@ -304,16 +311,18 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
304 | 311 | ||
305 | for (;;) { | 312 | for (;;) { |
306 | int bufs; | 313 | int bufs; |
307 | if (!PIPE_READERS(*inode)) { | 314 | |
315 | if (!pipe->readers) { | ||
308 | send_sig(SIGPIPE, current, 0); | 316 | send_sig(SIGPIPE, current, 0); |
309 | if (!ret) ret = -EPIPE; | 317 | if (!ret) |
318 | ret = -EPIPE; | ||
310 | break; | 319 | break; |
311 | } | 320 | } |
312 | bufs = info->nrbufs; | 321 | bufs = pipe->nrbufs; |
313 | if (bufs < PIPE_BUFFERS) { | 322 | if (bufs < PIPE_BUFFERS) { |
314 | int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS-1); | 323 | int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS-1); |
315 | struct pipe_buffer *buf = info->bufs + newbuf; | 324 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
316 | struct page *page = info->tmp_page; | 325 | struct page *page = pipe->tmp_page; |
317 | int error; | 326 | int error; |
318 | 327 | ||
319 | if (!page) { | 328 | if (!page) { |
@@ -322,9 +331,9 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
322 | ret = ret ? : -ENOMEM; | 331 | ret = ret ? : -ENOMEM; |
323 | break; | 332 | break; |
324 | } | 333 | } |
325 | info->tmp_page = page; | 334 | pipe->tmp_page = page; |
326 | } | 335 | } |
327 | /* Always wakeup, even if the copy fails. Otherwise | 336 | /* Always wake up, even if the copy fails. Otherwise |
328 | * we lock up (O_NONBLOCK-)readers that sleep due to | 337 | * we lock up (O_NONBLOCK-)readers that sleep due to |
329 | * syscall merging. | 338 | * syscall merging. |
330 | * FIXME! Is this really true? | 339 | * FIXME! Is this really true? |
@@ -337,7 +346,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
337 | error = pipe_iov_copy_from_user(kmap(page), iov, chars); | 346 | error = pipe_iov_copy_from_user(kmap(page), iov, chars); |
338 | kunmap(page); | 347 | kunmap(page); |
339 | if (unlikely(error)) { | 348 | if (unlikely(error)) { |
340 | if (!ret) ret = -EFAULT; | 349 | if (!ret) |
350 | ret = -EFAULT; | ||
341 | break; | 351 | break; |
342 | } | 352 | } |
343 | ret += chars; | 353 | ret += chars; |
@@ -347,8 +357,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
347 | buf->ops = &anon_pipe_buf_ops; | 357 | buf->ops = &anon_pipe_buf_ops; |
348 | buf->offset = 0; | 358 | buf->offset = 0; |
349 | buf->len = chars; | 359 | buf->len = chars; |
350 | info->nrbufs = ++bufs; | 360 | pipe->nrbufs = ++bufs; |
351 | info->tmp_page = NULL; | 361 | pipe->tmp_page = NULL; |
352 | 362 | ||
353 | total_len -= chars; | 363 | total_len -= chars; |
354 | if (!total_len) | 364 | if (!total_len) |
@@ -357,27 +367,29 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
357 | if (bufs < PIPE_BUFFERS) | 367 | if (bufs < PIPE_BUFFERS) |
358 | continue; | 368 | continue; |
359 | if (filp->f_flags & O_NONBLOCK) { | 369 | if (filp->f_flags & O_NONBLOCK) { |
360 | if (!ret) ret = -EAGAIN; | 370 | if (!ret) |
371 | ret = -EAGAIN; | ||
361 | break; | 372 | break; |
362 | } | 373 | } |
363 | if (signal_pending(current)) { | 374 | if (signal_pending(current)) { |
364 | if (!ret) ret = -ERESTARTSYS; | 375 | if (!ret) |
376 | ret = -ERESTARTSYS; | ||
365 | break; | 377 | break; |
366 | } | 378 | } |
367 | if (do_wakeup) { | 379 | if (do_wakeup) { |
368 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 380 | wake_up_interruptible_sync(&pipe->wait); |
369 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 381 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
370 | do_wakeup = 0; | 382 | do_wakeup = 0; |
371 | } | 383 | } |
372 | PIPE_WAITING_WRITERS(*inode)++; | 384 | pipe->waiting_writers++; |
373 | pipe_wait(inode); | 385 | pipe_wait(pipe); |
374 | PIPE_WAITING_WRITERS(*inode)--; | 386 | pipe->waiting_writers--; |
375 | } | 387 | } |
376 | out: | 388 | out: |
377 | mutex_unlock(PIPE_MUTEX(*inode)); | 389 | mutex_unlock(&inode->i_mutex); |
378 | if (do_wakeup) { | 390 | if (do_wakeup) { |
379 | wake_up_interruptible(PIPE_WAIT(*inode)); | 391 | wake_up_interruptible(&pipe->wait); |
380 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 392 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
381 | } | 393 | } |
382 | if (ret > 0) | 394 | if (ret > 0) |
383 | file_update_time(filp); | 395 | file_update_time(filp); |
@@ -389,6 +401,7 @@ pipe_write(struct file *filp, const char __user *buf, | |||
389 | size_t count, loff_t *ppos) | 401 | size_t count, loff_t *ppos) |
390 | { | 402 | { |
391 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; | 403 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; |
404 | |||
392 | return pipe_writev(filp, &iov, 1, ppos); | 405 | return pipe_writev(filp, &iov, 1, ppos); |
393 | } | 406 | } |
394 | 407 | ||
@@ -399,7 +412,8 @@ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | |||
399 | } | 412 | } |
400 | 413 | ||
401 | static ssize_t | 414 | static ssize_t |
402 | bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) | 415 | bad_pipe_w(struct file *filp, const char __user *buf, size_t count, |
416 | loff_t *ppos) | ||
403 | { | 417 | { |
404 | return -EBADF; | 418 | return -EBADF; |
405 | } | 419 | } |
@@ -409,21 +423,22 @@ pipe_ioctl(struct inode *pino, struct file *filp, | |||
409 | unsigned int cmd, unsigned long arg) | 423 | unsigned int cmd, unsigned long arg) |
410 | { | 424 | { |
411 | struct inode *inode = filp->f_dentry->d_inode; | 425 | struct inode *inode = filp->f_dentry->d_inode; |
412 | struct pipe_inode_info *info; | 426 | struct pipe_inode_info *pipe; |
413 | int count, buf, nrbufs; | 427 | int count, buf, nrbufs; |
414 | 428 | ||
415 | switch (cmd) { | 429 | switch (cmd) { |
416 | case FIONREAD: | 430 | case FIONREAD: |
417 | mutex_lock(PIPE_MUTEX(*inode)); | 431 | mutex_lock(&inode->i_mutex); |
418 | info = inode->i_pipe; | 432 | pipe = inode->i_pipe; |
419 | count = 0; | 433 | count = 0; |
420 | buf = info->curbuf; | 434 | buf = pipe->curbuf; |
421 | nrbufs = info->nrbufs; | 435 | nrbufs = pipe->nrbufs; |
422 | while (--nrbufs >= 0) { | 436 | while (--nrbufs >= 0) { |
423 | count += info->bufs[buf].len; | 437 | count += pipe->bufs[buf].len; |
424 | buf = (buf+1) & (PIPE_BUFFERS-1); | 438 | buf = (buf+1) & (PIPE_BUFFERS-1); |
425 | } | 439 | } |
426 | mutex_unlock(PIPE_MUTEX(*inode)); | 440 | mutex_unlock(&inode->i_mutex); |
441 | |||
427 | return put_user(count, (int __user *)arg); | 442 | return put_user(count, (int __user *)arg); |
428 | default: | 443 | default: |
429 | return -EINVAL; | 444 | return -EINVAL; |
@@ -436,17 +451,17 @@ pipe_poll(struct file *filp, poll_table *wait) | |||
436 | { | 451 | { |
437 | unsigned int mask; | 452 | unsigned int mask; |
438 | struct inode *inode = filp->f_dentry->d_inode; | 453 | struct inode *inode = filp->f_dentry->d_inode; |
439 | struct pipe_inode_info *info = inode->i_pipe; | 454 | struct pipe_inode_info *pipe = inode->i_pipe; |
440 | int nrbufs; | 455 | int nrbufs; |
441 | 456 | ||
442 | poll_wait(filp, PIPE_WAIT(*inode), wait); | 457 | poll_wait(filp, &pipe->wait, wait); |
443 | 458 | ||
444 | /* Reading only -- no need for acquiring the semaphore. */ | 459 | /* Reading only -- no need for acquiring the semaphore. */ |
445 | nrbufs = info->nrbufs; | 460 | nrbufs = pipe->nrbufs; |
446 | mask = 0; | 461 | mask = 0; |
447 | if (filp->f_mode & FMODE_READ) { | 462 | if (filp->f_mode & FMODE_READ) { |
448 | mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0; | 463 | mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0; |
449 | if (!PIPE_WRITERS(*inode) && filp->f_version != PIPE_WCOUNTER(*inode)) | 464 | if (!pipe->writers && filp->f_version != pipe->w_counter) |
450 | mask |= POLLHUP; | 465 | mask |= POLLHUP; |
451 | } | 466 | } |
452 | 467 | ||
@@ -456,7 +471,7 @@ pipe_poll(struct file *filp, poll_table *wait) | |||
456 | * Most Unices do not set POLLERR for FIFOs but on Linux they | 471 | * Most Unices do not set POLLERR for FIFOs but on Linux they |
457 | * behave exactly like pipes for poll(). | 472 | * behave exactly like pipes for poll(). |
458 | */ | 473 | */ |
459 | if (!PIPE_READERS(*inode)) | 474 | if (!pipe->readers) |
460 | mask |= POLLERR; | 475 | mask |= POLLERR; |
461 | } | 476 | } |
462 | 477 | ||
@@ -466,17 +481,21 @@ pipe_poll(struct file *filp, poll_table *wait) | |||
466 | static int | 481 | static int |
467 | pipe_release(struct inode *inode, int decr, int decw) | 482 | pipe_release(struct inode *inode, int decr, int decw) |
468 | { | 483 | { |
469 | mutex_lock(PIPE_MUTEX(*inode)); | 484 | struct pipe_inode_info *pipe; |
470 | PIPE_READERS(*inode) -= decr; | 485 | |
471 | PIPE_WRITERS(*inode) -= decw; | 486 | mutex_lock(&inode->i_mutex); |
472 | if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) { | 487 | pipe = inode->i_pipe; |
488 | pipe->readers -= decr; | ||
489 | pipe->writers -= decw; | ||
490 | |||
491 | if (!pipe->readers && !pipe->writers) { | ||
473 | free_pipe_info(inode); | 492 | free_pipe_info(inode); |
474 | } else { | 493 | } else { |
475 | wake_up_interruptible(PIPE_WAIT(*inode)); | 494 | wake_up_interruptible(&pipe->wait); |
476 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 495 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
477 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 496 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
478 | } | 497 | } |
479 | mutex_unlock(PIPE_MUTEX(*inode)); | 498 | mutex_unlock(&inode->i_mutex); |
480 | 499 | ||
481 | return 0; | 500 | return 0; |
482 | } | 501 | } |
@@ -487,9 +506,9 @@ pipe_read_fasync(int fd, struct file *filp, int on) | |||
487 | struct inode *inode = filp->f_dentry->d_inode; | 506 | struct inode *inode = filp->f_dentry->d_inode; |
488 | int retval; | 507 | int retval; |
489 | 508 | ||
490 | mutex_lock(PIPE_MUTEX(*inode)); | 509 | mutex_lock(&inode->i_mutex); |
491 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode)); | 510 | retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); |
492 | mutex_unlock(PIPE_MUTEX(*inode)); | 511 | mutex_unlock(&inode->i_mutex); |
493 | 512 | ||
494 | if (retval < 0) | 513 | if (retval < 0) |
495 | return retval; | 514 | return retval; |
@@ -504,9 +523,9 @@ pipe_write_fasync(int fd, struct file *filp, int on) | |||
504 | struct inode *inode = filp->f_dentry->d_inode; | 523 | struct inode *inode = filp->f_dentry->d_inode; |
505 | int retval; | 524 | int retval; |
506 | 525 | ||
507 | mutex_lock(PIPE_MUTEX(*inode)); | 526 | mutex_lock(&inode->i_mutex); |
508 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode)); | 527 | retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); |
509 | mutex_unlock(PIPE_MUTEX(*inode)); | 528 | mutex_unlock(&inode->i_mutex); |
510 | 529 | ||
511 | if (retval < 0) | 530 | if (retval < 0) |
512 | return retval; | 531 | return retval; |
@@ -519,16 +538,17 @@ static int | |||
519 | pipe_rdwr_fasync(int fd, struct file *filp, int on) | 538 | pipe_rdwr_fasync(int fd, struct file *filp, int on) |
520 | { | 539 | { |
521 | struct inode *inode = filp->f_dentry->d_inode; | 540 | struct inode *inode = filp->f_dentry->d_inode; |
541 | struct pipe_inode_info *pipe = inode->i_pipe; | ||
522 | int retval; | 542 | int retval; |
523 | 543 | ||
524 | mutex_lock(PIPE_MUTEX(*inode)); | 544 | mutex_lock(&inode->i_mutex); |
525 | 545 | ||
526 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode)); | 546 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); |
527 | 547 | ||
528 | if (retval >= 0) | 548 | if (retval >= 0) |
529 | retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode)); | 549 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); |
530 | 550 | ||
531 | mutex_unlock(PIPE_MUTEX(*inode)); | 551 | mutex_unlock(&inode->i_mutex); |
532 | 552 | ||
533 | if (retval < 0) | 553 | if (retval < 0) |
534 | return retval; | 554 | return retval; |
@@ -567,9 +587,9 @@ pipe_read_open(struct inode *inode, struct file *filp) | |||
567 | { | 587 | { |
568 | /* We could have perhaps used atomic_t, but this and friends | 588 | /* We could have perhaps used atomic_t, but this and friends |
569 | below are the only places. So it doesn't seem worthwhile. */ | 589 | below are the only places. So it doesn't seem worthwhile. */ |
570 | mutex_lock(PIPE_MUTEX(*inode)); | 590 | mutex_lock(&inode->i_mutex); |
571 | PIPE_READERS(*inode)++; | 591 | inode->i_pipe->readers++; |
572 | mutex_unlock(PIPE_MUTEX(*inode)); | 592 | mutex_unlock(&inode->i_mutex); |
573 | 593 | ||
574 | return 0; | 594 | return 0; |
575 | } | 595 | } |
@@ -577,9 +597,9 @@ pipe_read_open(struct inode *inode, struct file *filp) | |||
577 | static int | 597 | static int |
578 | pipe_write_open(struct inode *inode, struct file *filp) | 598 | pipe_write_open(struct inode *inode, struct file *filp) |
579 | { | 599 | { |
580 | mutex_lock(PIPE_MUTEX(*inode)); | 600 | mutex_lock(&inode->i_mutex); |
581 | PIPE_WRITERS(*inode)++; | 601 | inode->i_pipe->writers++; |
582 | mutex_unlock(PIPE_MUTEX(*inode)); | 602 | mutex_unlock(&inode->i_mutex); |
583 | 603 | ||
584 | return 0; | 604 | return 0; |
585 | } | 605 | } |
@@ -587,12 +607,12 @@ pipe_write_open(struct inode *inode, struct file *filp) | |||
587 | static int | 607 | static int |
588 | pipe_rdwr_open(struct inode *inode, struct file *filp) | 608 | pipe_rdwr_open(struct inode *inode, struct file *filp) |
589 | { | 609 | { |
590 | mutex_lock(PIPE_MUTEX(*inode)); | 610 | mutex_lock(&inode->i_mutex); |
591 | if (filp->f_mode & FMODE_READ) | 611 | if (filp->f_mode & FMODE_READ) |
592 | PIPE_READERS(*inode)++; | 612 | inode->i_pipe->readers++; |
593 | if (filp->f_mode & FMODE_WRITE) | 613 | if (filp->f_mode & FMODE_WRITE) |
594 | PIPE_WRITERS(*inode)++; | 614 | inode->i_pipe->writers++; |
595 | mutex_unlock(PIPE_MUTEX(*inode)); | 615 | mutex_unlock(&inode->i_mutex); |
596 | 616 | ||
597 | return 0; | 617 | return 0; |
598 | } | 618 | } |
@@ -675,37 +695,38 @@ static struct file_operations rdwr_pipe_fops = { | |||
675 | .fasync = pipe_rdwr_fasync, | 695 | .fasync = pipe_rdwr_fasync, |
676 | }; | 696 | }; |
677 | 697 | ||
678 | void free_pipe_info(struct inode *inode) | 698 | struct pipe_inode_info * alloc_pipe_info(struct inode *inode) |
699 | { | ||
700 | struct pipe_inode_info *pipe; | ||
701 | |||
702 | pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); | ||
703 | if (pipe) { | ||
704 | init_waitqueue_head(&pipe->wait); | ||
705 | pipe->r_counter = pipe->w_counter = 1; | ||
706 | pipe->inode = inode; | ||
707 | } | ||
708 | |||
709 | return pipe; | ||
710 | } | ||
711 | |||
712 | void __free_pipe_info(struct pipe_inode_info *pipe) | ||
679 | { | 713 | { |
680 | int i; | 714 | int i; |
681 | struct pipe_inode_info *info = inode->i_pipe; | ||
682 | 715 | ||
683 | inode->i_pipe = NULL; | ||
684 | for (i = 0; i < PIPE_BUFFERS; i++) { | 716 | for (i = 0; i < PIPE_BUFFERS; i++) { |
685 | struct pipe_buffer *buf = info->bufs + i; | 717 | struct pipe_buffer *buf = pipe->bufs + i; |
686 | if (buf->ops) | 718 | if (buf->ops) |
687 | buf->ops->release(info, buf); | 719 | buf->ops->release(pipe, buf); |
688 | } | 720 | } |
689 | if (info->tmp_page) | 721 | if (pipe->tmp_page) |
690 | __free_page(info->tmp_page); | 722 | __free_page(pipe->tmp_page); |
691 | kfree(info); | 723 | kfree(pipe); |
692 | } | 724 | } |
693 | 725 | ||
694 | struct inode* pipe_new(struct inode* inode) | 726 | void free_pipe_info(struct inode *inode) |
695 | { | 727 | { |
696 | struct pipe_inode_info *info; | 728 | __free_pipe_info(inode->i_pipe); |
697 | 729 | inode->i_pipe = NULL; | |
698 | info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); | ||
699 | if (!info) | ||
700 | goto fail_page; | ||
701 | inode->i_pipe = info; | ||
702 | |||
703 | init_waitqueue_head(PIPE_WAIT(*inode)); | ||
704 | PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1; | ||
705 | |||
706 | return inode; | ||
707 | fail_page: | ||
708 | return NULL; | ||
709 | } | 730 | } |
710 | 731 | ||
711 | static struct vfsmount *pipe_mnt __read_mostly; | 732 | static struct vfsmount *pipe_mnt __read_mostly; |
@@ -713,6 +734,7 @@ static int pipefs_delete_dentry(struct dentry *dentry) | |||
713 | { | 734 | { |
714 | return 1; | 735 | return 1; |
715 | } | 736 | } |
737 | |||
716 | static struct dentry_operations pipefs_dentry_operations = { | 738 | static struct dentry_operations pipefs_dentry_operations = { |
717 | .d_delete = pipefs_delete_dentry, | 739 | .d_delete = pipefs_delete_dentry, |
718 | }; | 740 | }; |
@@ -720,13 +742,17 @@ static struct dentry_operations pipefs_dentry_operations = { | |||
720 | static struct inode * get_pipe_inode(void) | 742 | static struct inode * get_pipe_inode(void) |
721 | { | 743 | { |
722 | struct inode *inode = new_inode(pipe_mnt->mnt_sb); | 744 | struct inode *inode = new_inode(pipe_mnt->mnt_sb); |
745 | struct pipe_inode_info *pipe; | ||
723 | 746 | ||
724 | if (!inode) | 747 | if (!inode) |
725 | goto fail_inode; | 748 | goto fail_inode; |
726 | 749 | ||
727 | if(!pipe_new(inode)) | 750 | pipe = alloc_pipe_info(inode); |
751 | if (!pipe) | ||
728 | goto fail_iput; | 752 | goto fail_iput; |
729 | PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; | 753 | inode->i_pipe = pipe; |
754 | |||
755 | pipe->readers = pipe->writers = 1; | ||
730 | inode->i_fop = &rdwr_pipe_fops; | 756 | inode->i_fop = &rdwr_pipe_fops; |
731 | 757 | ||
732 | /* | 758 | /* |
@@ -741,10 +767,12 @@ static struct inode * get_pipe_inode(void) | |||
741 | inode->i_gid = current->fsgid; | 767 | inode->i_gid = current->fsgid; |
742 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 768 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
743 | inode->i_blksize = PAGE_SIZE; | 769 | inode->i_blksize = PAGE_SIZE; |
770 | |||
744 | return inode; | 771 | return inode; |
745 | 772 | ||
746 | fail_iput: | 773 | fail_iput: |
747 | iput(inode); | 774 | iput(inode); |
775 | |||
748 | fail_inode: | 776 | fail_inode: |
749 | return NULL; | 777 | return NULL; |
750 | } | 778 | } |
@@ -757,7 +785,7 @@ int do_pipe(int *fd) | |||
757 | struct inode * inode; | 785 | struct inode * inode; |
758 | struct file *f1, *f2; | 786 | struct file *f1, *f2; |
759 | int error; | 787 | int error; |
760 | int i,j; | 788 | int i, j; |
761 | 789 | ||
762 | error = -ENFILE; | 790 | error = -ENFILE; |
763 | f1 = get_empty_filp(); | 791 | f1 = get_empty_filp(); |
@@ -790,6 +818,7 @@ int do_pipe(int *fd) | |||
790 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 818 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
791 | if (!dentry) | 819 | if (!dentry) |
792 | goto close_f12_inode_i_j; | 820 | goto close_f12_inode_i_j; |
821 | |||
793 | dentry->d_op = &pipefs_dentry_operations; | 822 | dentry->d_op = &pipefs_dentry_operations; |
794 | d_add(dentry, inode); | 823 | d_add(dentry, inode); |
795 | f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); | 824 | f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); |
@@ -813,6 +842,7 @@ int do_pipe(int *fd) | |||
813 | fd_install(j, f2); | 842 | fd_install(j, f2); |
814 | fd[0] = i; | 843 | fd[0] = i; |
815 | fd[1] = j; | 844 | fd[1] = j; |
845 | |||
816 | return 0; | 846 | return 0; |
817 | 847 | ||
818 | close_f12_inode_i_j: | 848 | close_f12_inode_i_j: |
@@ -837,8 +867,9 @@ no_files: | |||
837 | * d_name - pipe: will go nicely and kill the special-casing in procfs. | 867 | * d_name - pipe: will go nicely and kill the special-casing in procfs. |
838 | */ | 868 | */ |
839 | 869 | ||
840 | static struct super_block *pipefs_get_sb(struct file_system_type *fs_type, | 870 | static struct super_block * |
841 | int flags, const char *dev_name, void *data) | 871 | pipefs_get_sb(struct file_system_type *fs_type, int flags, |
872 | const char *dev_name, void *data) | ||
842 | { | 873 | { |
843 | return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); | 874 | return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); |
844 | } | 875 | } |
@@ -852,6 +883,7 @@ static struct file_system_type pipe_fs_type = { | |||
852 | static int __init init_pipe_fs(void) | 883 | static int __init init_pipe_fs(void) |
853 | { | 884 | { |
854 | int err = register_filesystem(&pipe_fs_type); | 885 | int err = register_filesystem(&pipe_fs_type); |
886 | |||
855 | if (!err) { | 887 | if (!err) { |
856 | pipe_mnt = kern_mount(&pipe_fs_type); | 888 | pipe_mnt = kern_mount(&pipe_fs_type); |
857 | if (IS_ERR(pipe_mnt)) { | 889 | if (IS_ERR(pipe_mnt)) { |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 7efa73d44c9a..20d4b2237fce 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -103,8 +103,8 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, | |||
103 | size_t buflen, loff_t *fpos) | 103 | size_t buflen, loff_t *fpos) |
104 | { | 104 | { |
105 | ssize_t acc = 0, tmp; | 105 | ssize_t acc = 0, tmp; |
106 | size_t tsz, nr_bytes; | 106 | size_t tsz; |
107 | u64 start; | 107 | u64 start, nr_bytes; |
108 | struct vmcore *curr_m = NULL; | 108 | struct vmcore *curr_m = NULL; |
109 | 109 | ||
110 | if (buflen == 0 || *fpos >= vmcore_size) | 110 | if (buflen == 0 || *fpos >= vmcore_size) |
diff --git a/fs/read_write.c b/fs/read_write.c index 6256ca81a718..5bc0e9234f9d 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -202,7 +202,7 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count | |||
202 | goto Einval; | 202 | goto Einval; |
203 | 203 | ||
204 | inode = file->f_dentry->d_inode; | 204 | inode = file->f_dentry->d_inode; |
205 | if (inode->i_flock && MANDATORY_LOCK(inode)) { | 205 | if (unlikely(inode->i_flock && MANDATORY_LOCK(inode))) { |
206 | int retval = locks_mandatory_area( | 206 | int retval = locks_mandatory_area( |
207 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, | 207 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, |
208 | inode, file, pos, count); | 208 | inode, file, pos, count); |
diff --git a/fs/select.c b/fs/select.c index 071660fa7b01..a8109baa5e46 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -310,8 +310,9 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
310 | fd_set __user *exp, s64 *timeout) | 310 | fd_set __user *exp, s64 *timeout) |
311 | { | 311 | { |
312 | fd_set_bits fds; | 312 | fd_set_bits fds; |
313 | char *bits; | 313 | void *bits; |
314 | int ret, size, max_fdset; | 314 | int ret, max_fdset; |
315 | unsigned int size; | ||
315 | struct fdtable *fdt; | 316 | struct fdtable *fdt; |
316 | /* Allocate small arguments on the stack to save memory and be faster */ | 317 | /* Allocate small arguments on the stack to save memory and be faster */ |
317 | long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; | 318 | long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; |
@@ -333,20 +334,21 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
333 | * since we used fdset we need to allocate memory in units of | 334 | * since we used fdset we need to allocate memory in units of |
334 | * long-words. | 335 | * long-words. |
335 | */ | 336 | */ |
336 | ret = -ENOMEM; | ||
337 | size = FDS_BYTES(n); | 337 | size = FDS_BYTES(n); |
338 | if (6*size < SELECT_STACK_ALLOC) | 338 | bits = stack_fds; |
339 | bits = stack_fds; | 339 | if (size > sizeof(stack_fds) / 6) { |
340 | else | 340 | /* Not enough space in on-stack array; must use kmalloc */ |
341 | ret = -ENOMEM; | ||
341 | bits = kmalloc(6 * size, GFP_KERNEL); | 342 | bits = kmalloc(6 * size, GFP_KERNEL); |
342 | if (!bits) | 343 | if (!bits) |
343 | goto out_nofds; | 344 | goto out_nofds; |
344 | fds.in = (unsigned long *) bits; | 345 | } |
345 | fds.out = (unsigned long *) (bits + size); | 346 | fds.in = bits; |
346 | fds.ex = (unsigned long *) (bits + 2*size); | 347 | fds.out = bits + size; |
347 | fds.res_in = (unsigned long *) (bits + 3*size); | 348 | fds.ex = bits + 2*size; |
348 | fds.res_out = (unsigned long *) (bits + 4*size); | 349 | fds.res_in = bits + 3*size; |
349 | fds.res_ex = (unsigned long *) (bits + 5*size); | 350 | fds.res_out = bits + 4*size; |
351 | fds.res_ex = bits + 5*size; | ||
350 | 352 | ||
351 | if ((ret = get_fd_set(n, inp, fds.in)) || | 353 | if ((ret = get_fd_set(n, inp, fds.in)) || |
352 | (ret = get_fd_set(n, outp, fds.out)) || | 354 | (ret = get_fd_set(n, outp, fds.out)) || |
diff --git a/fs/splice.c b/fs/splice.c index bfa42a277bb8..e50a460239dd 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -9,11 +9,12 @@ | |||
9 | * that transfers data buffers to or from a pipe buffer. | 9 | * that transfers data buffers to or from a pipe buffer. |
10 | * | 10 | * |
11 | * Named by Larry McVoy, original implementation from Linus, extended by | 11 | * Named by Larry McVoy, original implementation from Linus, extended by |
12 | * Jens to support splicing to files and fixing the initial implementation | 12 | * Jens to support splicing to files, network, direct splicing, etc and |
13 | * bugs. | 13 | * fixing lots of bugs. |
14 | * | 14 | * |
15 | * Copyright (C) 2005 Jens Axboe <axboe@suse.de> | 15 | * Copyright (C) 2005-2006 Jens Axboe <axboe@suse.de> |
16 | * Copyright (C) 2005 Linus Torvalds <torvalds@osdl.org> | 16 | * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org> |
17 | * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu> | ||
17 | * | 18 | * |
18 | */ | 19 | */ |
19 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
@@ -84,26 +85,43 @@ static void *page_cache_pipe_buf_map(struct file *file, | |||
84 | struct pipe_buffer *buf) | 85 | struct pipe_buffer *buf) |
85 | { | 86 | { |
86 | struct page *page = buf->page; | 87 | struct page *page = buf->page; |
87 | 88 | int err; | |
88 | lock_page(page); | ||
89 | 89 | ||
90 | if (!PageUptodate(page)) { | 90 | if (!PageUptodate(page)) { |
91 | unlock_page(page); | 91 | lock_page(page); |
92 | return ERR_PTR(-EIO); | 92 | |
93 | } | 93 | /* |
94 | * Page got truncated/unhashed. This will cause a 0-byte | ||
95 | * splice, if this is the first page. | ||
96 | */ | ||
97 | if (!page->mapping) { | ||
98 | err = -ENODATA; | ||
99 | goto error; | ||
100 | } | ||
94 | 101 | ||
95 | if (!page->mapping) { | 102 | /* |
103 | * Uh oh, read-error from disk. | ||
104 | */ | ||
105 | if (!PageUptodate(page)) { | ||
106 | err = -EIO; | ||
107 | goto error; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Page is ok afterall, fall through to mapping. | ||
112 | */ | ||
96 | unlock_page(page); | 113 | unlock_page(page); |
97 | return ERR_PTR(-ENODATA); | ||
98 | } | 114 | } |
99 | 115 | ||
100 | return kmap(buf->page); | 116 | return kmap(page); |
117 | error: | ||
118 | unlock_page(page); | ||
119 | return ERR_PTR(err); | ||
101 | } | 120 | } |
102 | 121 | ||
103 | static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, | 122 | static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, |
104 | struct pipe_buffer *buf) | 123 | struct pipe_buffer *buf) |
105 | { | 124 | { |
106 | unlock_page(buf->page); | ||
107 | kunmap(buf->page); | 125 | kunmap(buf->page); |
108 | } | 126 | } |
109 | 127 | ||
@@ -119,34 +137,30 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = { | |||
119 | * Pipe output worker. This sets up our pipe format with the page cache | 137 | * Pipe output worker. This sets up our pipe format with the page cache |
120 | * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). | 138 | * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). |
121 | */ | 139 | */ |
122 | static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | 140 | static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, |
123 | int nr_pages, unsigned long offset, | 141 | int nr_pages, unsigned long offset, |
124 | unsigned long len, unsigned int flags) | 142 | unsigned long len, unsigned int flags) |
125 | { | 143 | { |
126 | struct pipe_inode_info *info; | ||
127 | int ret, do_wakeup, i; | 144 | int ret, do_wakeup, i; |
128 | 145 | ||
129 | ret = 0; | 146 | ret = 0; |
130 | do_wakeup = 0; | 147 | do_wakeup = 0; |
131 | i = 0; | 148 | i = 0; |
132 | 149 | ||
133 | mutex_lock(PIPE_MUTEX(*inode)); | 150 | if (pipe->inode) |
151 | mutex_lock(&pipe->inode->i_mutex); | ||
134 | 152 | ||
135 | info = inode->i_pipe; | ||
136 | for (;;) { | 153 | for (;;) { |
137 | int bufs; | 154 | if (!pipe->readers) { |
138 | |||
139 | if (!PIPE_READERS(*inode)) { | ||
140 | send_sig(SIGPIPE, current, 0); | 155 | send_sig(SIGPIPE, current, 0); |
141 | if (!ret) | 156 | if (!ret) |
142 | ret = -EPIPE; | 157 | ret = -EPIPE; |
143 | break; | 158 | break; |
144 | } | 159 | } |
145 | 160 | ||
146 | bufs = info->nrbufs; | 161 | if (pipe->nrbufs < PIPE_BUFFERS) { |
147 | if (bufs < PIPE_BUFFERS) { | 162 | int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); |
148 | int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS - 1); | 163 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
149 | struct pipe_buffer *buf = info->bufs + newbuf; | ||
150 | struct page *page = pages[i++]; | 164 | struct page *page = pages[i++]; |
151 | unsigned long this_len; | 165 | unsigned long this_len; |
152 | 166 | ||
@@ -158,8 +172,9 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
158 | buf->offset = offset; | 172 | buf->offset = offset; |
159 | buf->len = this_len; | 173 | buf->len = this_len; |
160 | buf->ops = &page_cache_pipe_buf_ops; | 174 | buf->ops = &page_cache_pipe_buf_ops; |
161 | info->nrbufs = ++bufs; | 175 | pipe->nrbufs++; |
162 | do_wakeup = 1; | 176 | if (pipe->inode) |
177 | do_wakeup = 1; | ||
163 | 178 | ||
164 | ret += this_len; | 179 | ret += this_len; |
165 | len -= this_len; | 180 | len -= this_len; |
@@ -168,7 +183,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
168 | break; | 183 | break; |
169 | if (!len) | 184 | if (!len) |
170 | break; | 185 | break; |
171 | if (bufs < PIPE_BUFFERS) | 186 | if (pipe->nrbufs < PIPE_BUFFERS) |
172 | continue; | 187 | continue; |
173 | 188 | ||
174 | break; | 189 | break; |
@@ -187,22 +202,26 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
187 | } | 202 | } |
188 | 203 | ||
189 | if (do_wakeup) { | 204 | if (do_wakeup) { |
190 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 205 | smp_mb(); |
191 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, | 206 | if (waitqueue_active(&pipe->wait)) |
192 | POLL_IN); | 207 | wake_up_interruptible_sync(&pipe->wait); |
208 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | ||
193 | do_wakeup = 0; | 209 | do_wakeup = 0; |
194 | } | 210 | } |
195 | 211 | ||
196 | PIPE_WAITING_WRITERS(*inode)++; | 212 | pipe->waiting_writers++; |
197 | pipe_wait(inode); | 213 | pipe_wait(pipe); |
198 | PIPE_WAITING_WRITERS(*inode)--; | 214 | pipe->waiting_writers--; |
199 | } | 215 | } |
200 | 216 | ||
201 | mutex_unlock(PIPE_MUTEX(*inode)); | 217 | if (pipe->inode) |
218 | mutex_unlock(&pipe->inode->i_mutex); | ||
202 | 219 | ||
203 | if (do_wakeup) { | 220 | if (do_wakeup) { |
204 | wake_up_interruptible(PIPE_WAIT(*inode)); | 221 | smp_mb(); |
205 | kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); | 222 | if (waitqueue_active(&pipe->wait)) |
223 | wake_up_interruptible(&pipe->wait); | ||
224 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | ||
206 | } | 225 | } |
207 | 226 | ||
208 | while (i < nr_pages) | 227 | while (i < nr_pages) |
@@ -211,15 +230,16 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, | |||
211 | return ret; | 230 | return ret; |
212 | } | 231 | } |
213 | 232 | ||
214 | static int __generic_file_splice_read(struct file *in, struct inode *pipe, | 233 | static int |
215 | size_t len, unsigned int flags) | 234 | __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, |
235 | size_t len, unsigned int flags) | ||
216 | { | 236 | { |
217 | struct address_space *mapping = in->f_mapping; | 237 | struct address_space *mapping = in->f_mapping; |
218 | unsigned int offset, nr_pages; | 238 | unsigned int offset, nr_pages; |
219 | struct page *pages[PIPE_BUFFERS], *shadow[PIPE_BUFFERS]; | 239 | struct page *pages[PIPE_BUFFERS]; |
220 | struct page *page; | 240 | struct page *page; |
221 | pgoff_t index, pidx; | 241 | pgoff_t index; |
222 | int i, j; | 242 | int i, error; |
223 | 243 | ||
224 | index = in->f_pos >> PAGE_CACHE_SHIFT; | 244 | index = in->f_pos >> PAGE_CACHE_SHIFT; |
225 | offset = in->f_pos & ~PAGE_CACHE_MASK; | 245 | offset = in->f_pos & ~PAGE_CACHE_MASK; |
@@ -229,78 +249,94 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, | |||
229 | nr_pages = PIPE_BUFFERS; | 249 | nr_pages = PIPE_BUFFERS; |
230 | 250 | ||
231 | /* | 251 | /* |
232 | * initiate read-ahead on this page range | 252 | * Initiate read-ahead on this page range. however, don't call into |
233 | */ | 253 | * read-ahead if this is a non-zero offset (we are likely doing small |
234 | do_page_cache_readahead(mapping, in, index, nr_pages); | 254 | * chunk splice and the page is already there) for a single page. |
235 | |||
236 | /* | ||
237 | * Get as many pages from the page cache as possible.. | ||
238 | * Start IO on the page cache entries we create (we | ||
239 | * can assume that any pre-existing ones we find have | ||
240 | * already had IO started on them). | ||
241 | */ | 255 | */ |
242 | i = find_get_pages(mapping, index, nr_pages, pages); | 256 | if (!offset || nr_pages > 1) |
257 | do_page_cache_readahead(mapping, in, index, nr_pages); | ||
243 | 258 | ||
244 | /* | 259 | /* |
245 | * common case - we found all pages and they are contiguous, | 260 | * Now fill in the holes: |
246 | * kick them off | ||
247 | */ | 261 | */ |
248 | if (i && (pages[i - 1]->index == index + i - 1)) | 262 | error = 0; |
249 | goto splice_them; | 263 | for (i = 0; i < nr_pages; i++, index++) { |
264 | find_page: | ||
265 | /* | ||
266 | * lookup the page for this index | ||
267 | */ | ||
268 | page = find_get_page(mapping, index); | ||
269 | if (!page) { | ||
270 | /* | ||
271 | * If in nonblock mode then dont block on | ||
272 | * readpage (we've kicked readahead so there | ||
273 | * will be asynchronous progress): | ||
274 | */ | ||
275 | if (flags & SPLICE_F_NONBLOCK) | ||
276 | break; | ||
250 | 277 | ||
251 | /* | 278 | /* |
252 | * fill shadow[] with pages at the right locations, so we only | 279 | * page didn't exist, allocate one |
253 | * have to fill holes | 280 | */ |
254 | */ | 281 | page = page_cache_alloc_cold(mapping); |
255 | memset(shadow, 0, nr_pages * sizeof(struct page *)); | 282 | if (!page) |
256 | for (j = 0; j < i; j++) | 283 | break; |
257 | shadow[pages[j]->index - index] = pages[j]; | ||
258 | 284 | ||
259 | /* | 285 | error = add_to_page_cache_lru(page, mapping, index, |
260 | * now fill in the holes | 286 | mapping_gfp_mask(mapping)); |
261 | */ | 287 | if (unlikely(error)) { |
262 | for (i = 0, pidx = index; i < nr_pages; pidx++, i++) { | 288 | page_cache_release(page); |
263 | int error; | 289 | break; |
290 | } | ||
264 | 291 | ||
265 | if (shadow[i]) | 292 | goto readpage; |
266 | continue; | 293 | } |
267 | 294 | ||
268 | /* | 295 | /* |
269 | * no page there, look one up / create it | 296 | * If the page isn't uptodate, we may need to start io on it |
270 | */ | 297 | */ |
271 | page = find_or_create_page(mapping, pidx, | 298 | if (!PageUptodate(page)) { |
272 | mapping_gfp_mask(mapping)); | 299 | lock_page(page); |
273 | if (!page) | 300 | |
274 | break; | 301 | /* |
302 | * page was truncated, stop here. if this isn't the | ||
303 | * first page, we'll just complete what we already | ||
304 | * added | ||
305 | */ | ||
306 | if (!page->mapping) { | ||
307 | unlock_page(page); | ||
308 | page_cache_release(page); | ||
309 | break; | ||
310 | } | ||
311 | /* | ||
312 | * page was already under io and is now done, great | ||
313 | */ | ||
314 | if (PageUptodate(page)) { | ||
315 | unlock_page(page); | ||
316 | goto fill_it; | ||
317 | } | ||
275 | 318 | ||
276 | if (PageUptodate(page)) | 319 | readpage: |
277 | unlock_page(page); | 320 | /* |
278 | else { | 321 | * need to read in the page |
322 | */ | ||
279 | error = mapping->a_ops->readpage(in, page); | 323 | error = mapping->a_ops->readpage(in, page); |
280 | 324 | ||
281 | if (unlikely(error)) { | 325 | if (unlikely(error)) { |
282 | page_cache_release(page); | 326 | page_cache_release(page); |
327 | if (error == AOP_TRUNCATED_PAGE) | ||
328 | goto find_page; | ||
283 | break; | 329 | break; |
284 | } | 330 | } |
285 | } | 331 | } |
286 | shadow[i] = page; | 332 | fill_it: |
333 | pages[i] = page; | ||
287 | } | 334 | } |
288 | 335 | ||
289 | if (!i) { | 336 | if (i) |
290 | for (i = 0; i < nr_pages; i++) { | 337 | return move_to_pipe(pipe, pages, i, offset, len, flags); |
291 | if (shadow[i]) | ||
292 | page_cache_release(shadow[i]); | ||
293 | } | ||
294 | return 0; | ||
295 | } | ||
296 | 338 | ||
297 | memcpy(pages, shadow, i * sizeof(struct page *)); | 339 | return error; |
298 | |||
299 | /* | ||
300 | * Now we splice them into the pipe.. | ||
301 | */ | ||
302 | splice_them: | ||
303 | return move_to_pipe(pipe, pages, i, offset, len, flags); | ||
304 | } | 340 | } |
305 | 341 | ||
306 | /** | 342 | /** |
@@ -311,9 +347,8 @@ splice_them: | |||
311 | * @flags: splice modifier flags | 347 | * @flags: splice modifier flags |
312 | * | 348 | * |
313 | * Will read pages from given file and fill them into a pipe. | 349 | * Will read pages from given file and fill them into a pipe. |
314 | * | ||
315 | */ | 350 | */ |
316 | ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, | 351 | ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, |
317 | size_t len, unsigned int flags) | 352 | size_t len, unsigned int flags) |
318 | { | 353 | { |
319 | ssize_t spliced; | 354 | ssize_t spliced; |
@@ -321,6 +356,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, | |||
321 | 356 | ||
322 | ret = 0; | 357 | ret = 0; |
323 | spliced = 0; | 358 | spliced = 0; |
359 | |||
324 | while (len) { | 360 | while (len) { |
325 | ret = __generic_file_splice_read(in, pipe, len, flags); | 361 | ret = __generic_file_splice_read(in, pipe, len, flags); |
326 | 362 | ||
@@ -360,10 +396,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *info, | |||
360 | int more; | 396 | int more; |
361 | 397 | ||
362 | /* | 398 | /* |
363 | * sub-optimal, but we are limited by the pipe ->map. we don't | 399 | * Sub-optimal, but we are limited by the pipe ->map. We don't |
364 | * need a kmap'ed buffer here, we just want to make sure we | 400 | * need a kmap'ed buffer here, we just want to make sure we |
365 | * have the page pinned if the pipe page originates from the | 401 | * have the page pinned if the pipe page originates from the |
366 | * page cache | 402 | * page cache. |
367 | */ | 403 | */ |
368 | ptr = buf->ops->map(file, info, buf); | 404 | ptr = buf->ops->map(file, info, buf); |
369 | if (IS_ERR(ptr)) | 405 | if (IS_ERR(ptr)) |
@@ -414,7 +450,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
414 | int ret; | 450 | int ret; |
415 | 451 | ||
416 | /* | 452 | /* |
417 | * after this, page will be locked and unmapped | 453 | * make sure the data in this buffer is uptodate |
418 | */ | 454 | */ |
419 | src = buf->ops->map(file, info, buf); | 455 | src = buf->ops->map(file, info, buf); |
420 | if (IS_ERR(src)) | 456 | if (IS_ERR(src)) |
@@ -424,7 +460,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
424 | offset = sd->pos & ~PAGE_CACHE_MASK; | 460 | offset = sd->pos & ~PAGE_CACHE_MASK; |
425 | 461 | ||
426 | /* | 462 | /* |
427 | * reuse buf page, if SPLICE_F_MOVE is set | 463 | * Reuse buf page, if SPLICE_F_MOVE is set. |
428 | */ | 464 | */ |
429 | if (sd->flags & SPLICE_F_MOVE) { | 465 | if (sd->flags & SPLICE_F_MOVE) { |
430 | /* | 466 | /* |
@@ -434,6 +470,9 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
434 | if (buf->ops->steal(info, buf)) | 470 | if (buf->ops->steal(info, buf)) |
435 | goto find_page; | 471 | goto find_page; |
436 | 472 | ||
473 | /* | ||
474 | * this will also set the page locked | ||
475 | */ | ||
437 | page = buf->page; | 476 | page = buf->page; |
438 | if (add_to_page_cache(page, mapping, index, gfp_mask)) | 477 | if (add_to_page_cache(page, mapping, index, gfp_mask)) |
439 | goto find_page; | 478 | goto find_page; |
@@ -445,7 +484,7 @@ find_page: | |||
445 | ret = -ENOMEM; | 484 | ret = -ENOMEM; |
446 | page = find_or_create_page(mapping, index, gfp_mask); | 485 | page = find_or_create_page(mapping, index, gfp_mask); |
447 | if (!page) | 486 | if (!page) |
448 | goto out; | 487 | goto out_nomem; |
449 | 488 | ||
450 | /* | 489 | /* |
451 | * If the page is uptodate, it is also locked. If it isn't | 490 | * If the page is uptodate, it is also locked. If it isn't |
@@ -462,7 +501,7 @@ find_page: | |||
462 | 501 | ||
463 | if (!PageUptodate(page)) { | 502 | if (!PageUptodate(page)) { |
464 | /* | 503 | /* |
465 | * page got invalidated, repeat | 504 | * Page got invalidated, repeat. |
466 | */ | 505 | */ |
467 | if (!page->mapping) { | 506 | if (!page->mapping) { |
468 | unlock_page(page); | 507 | unlock_page(page); |
@@ -501,12 +540,14 @@ find_page: | |||
501 | } else if (ret) | 540 | } else if (ret) |
502 | goto out; | 541 | goto out; |
503 | 542 | ||
543 | mark_page_accessed(page); | ||
504 | balance_dirty_pages_ratelimited(mapping); | 544 | balance_dirty_pages_ratelimited(mapping); |
505 | out: | 545 | out: |
506 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { | 546 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { |
507 | page_cache_release(page); | 547 | page_cache_release(page); |
508 | unlock_page(page); | 548 | unlock_page(page); |
509 | } | 549 | } |
550 | out_nomem: | ||
510 | buf->ops->unmap(info, buf); | 551 | buf->ops->unmap(info, buf); |
511 | return ret; | 552 | return ret; |
512 | } | 553 | } |
@@ -519,11 +560,10 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, | |||
519 | * key here is the 'actor' worker passed in that actually moves the data | 560 | * key here is the 'actor' worker passed in that actually moves the data |
520 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. | 561 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
521 | */ | 562 | */ |
522 | static ssize_t move_from_pipe(struct inode *inode, struct file *out, | 563 | static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, |
523 | size_t len, unsigned int flags, | 564 | size_t len, unsigned int flags, |
524 | splice_actor *actor) | 565 | splice_actor *actor) |
525 | { | 566 | { |
526 | struct pipe_inode_info *info; | ||
527 | int ret, do_wakeup, err; | 567 | int ret, do_wakeup, err; |
528 | struct splice_desc sd; | 568 | struct splice_desc sd; |
529 | 569 | ||
@@ -535,22 +575,19 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
535 | sd.file = out; | 575 | sd.file = out; |
536 | sd.pos = out->f_pos; | 576 | sd.pos = out->f_pos; |
537 | 577 | ||
538 | mutex_lock(PIPE_MUTEX(*inode)); | 578 | if (pipe->inode) |
579 | mutex_lock(&pipe->inode->i_mutex); | ||
539 | 580 | ||
540 | info = inode->i_pipe; | ||
541 | for (;;) { | 581 | for (;;) { |
542 | int bufs = info->nrbufs; | 582 | if (pipe->nrbufs) { |
543 | 583 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | |
544 | if (bufs) { | ||
545 | int curbuf = info->curbuf; | ||
546 | struct pipe_buffer *buf = info->bufs + curbuf; | ||
547 | struct pipe_buf_operations *ops = buf->ops; | 584 | struct pipe_buf_operations *ops = buf->ops; |
548 | 585 | ||
549 | sd.len = buf->len; | 586 | sd.len = buf->len; |
550 | if (sd.len > sd.total_len) | 587 | if (sd.len > sd.total_len) |
551 | sd.len = sd.total_len; | 588 | sd.len = sd.total_len; |
552 | 589 | ||
553 | err = actor(info, buf, &sd); | 590 | err = actor(pipe, buf, &sd); |
554 | if (err) { | 591 | if (err) { |
555 | if (!ret && err != -ENODATA) | 592 | if (!ret && err != -ENODATA) |
556 | ret = err; | 593 | ret = err; |
@@ -561,13 +598,14 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
561 | ret += sd.len; | 598 | ret += sd.len; |
562 | buf->offset += sd.len; | 599 | buf->offset += sd.len; |
563 | buf->len -= sd.len; | 600 | buf->len -= sd.len; |
601 | |||
564 | if (!buf->len) { | 602 | if (!buf->len) { |
565 | buf->ops = NULL; | 603 | buf->ops = NULL; |
566 | ops->release(info, buf); | 604 | ops->release(pipe, buf); |
567 | curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1); | 605 | pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); |
568 | info->curbuf = curbuf; | 606 | pipe->nrbufs--; |
569 | info->nrbufs = --bufs; | 607 | if (pipe->inode) |
570 | do_wakeup = 1; | 608 | do_wakeup = 1; |
571 | } | 609 | } |
572 | 610 | ||
573 | sd.pos += sd.len; | 611 | sd.pos += sd.len; |
@@ -576,11 +614,11 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
576 | break; | 614 | break; |
577 | } | 615 | } |
578 | 616 | ||
579 | if (bufs) | 617 | if (pipe->nrbufs) |
580 | continue; | 618 | continue; |
581 | if (!PIPE_WRITERS(*inode)) | 619 | if (!pipe->writers) |
582 | break; | 620 | break; |
583 | if (!PIPE_WAITING_WRITERS(*inode)) { | 621 | if (!pipe->waiting_writers) { |
584 | if (ret) | 622 | if (ret) |
585 | break; | 623 | break; |
586 | } | 624 | } |
@@ -598,31 +636,34 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
598 | } | 636 | } |
599 | 637 | ||
600 | if (do_wakeup) { | 638 | if (do_wakeup) { |
601 | wake_up_interruptible_sync(PIPE_WAIT(*inode)); | 639 | smp_mb(); |
602 | kill_fasync(PIPE_FASYNC_WRITERS(*inode),SIGIO,POLL_OUT); | 640 | if (waitqueue_active(&pipe->wait)) |
641 | wake_up_interruptible_sync(&pipe->wait); | ||
642 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | ||
603 | do_wakeup = 0; | 643 | do_wakeup = 0; |
604 | } | 644 | } |
605 | 645 | ||
606 | pipe_wait(inode); | 646 | pipe_wait(pipe); |
607 | } | 647 | } |
608 | 648 | ||
609 | mutex_unlock(PIPE_MUTEX(*inode)); | 649 | if (pipe->inode) |
650 | mutex_unlock(&pipe->inode->i_mutex); | ||
610 | 651 | ||
611 | if (do_wakeup) { | 652 | if (do_wakeup) { |
612 | wake_up_interruptible(PIPE_WAIT(*inode)); | 653 | smp_mb(); |
613 | kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); | 654 | if (waitqueue_active(&pipe->wait)) |
655 | wake_up_interruptible(&pipe->wait); | ||
656 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | ||
614 | } | 657 | } |
615 | 658 | ||
616 | mutex_lock(&out->f_mapping->host->i_mutex); | ||
617 | out->f_pos = sd.pos; | 659 | out->f_pos = sd.pos; |
618 | mutex_unlock(&out->f_mapping->host->i_mutex); | ||
619 | return ret; | 660 | return ret; |
620 | 661 | ||
621 | } | 662 | } |
622 | 663 | ||
623 | /** | 664 | /** |
624 | * generic_file_splice_write - splice data from a pipe to a file | 665 | * generic_file_splice_write - splice data from a pipe to a file |
625 | * @inode: pipe inode | 666 | * @pipe: pipe info |
626 | * @out: file to write to | 667 | * @out: file to write to |
627 | * @len: number of bytes to splice | 668 | * @len: number of bytes to splice |
628 | * @flags: splice modifier flags | 669 | * @flags: splice modifier flags |
@@ -631,14 +672,17 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, | |||
631 | * the given pipe inode to the given file. | 672 | * the given pipe inode to the given file. |
632 | * | 673 | * |
633 | */ | 674 | */ |
634 | ssize_t generic_file_splice_write(struct inode *inode, struct file *out, | 675 | ssize_t |
635 | size_t len, unsigned int flags) | 676 | generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, |
677 | size_t len, unsigned int flags) | ||
636 | { | 678 | { |
637 | struct address_space *mapping = out->f_mapping; | 679 | struct address_space *mapping = out->f_mapping; |
638 | ssize_t ret = move_from_pipe(inode, out, len, flags, pipe_to_file); | 680 | ssize_t ret; |
681 | |||
682 | ret = move_from_pipe(pipe, out, len, flags, pipe_to_file); | ||
639 | 683 | ||
640 | /* | 684 | /* |
641 | * if file or inode is SYNC and we actually wrote some data, sync it | 685 | * If file or inode is SYNC and we actually wrote some data, sync it. |
642 | */ | 686 | */ |
643 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host)) | 687 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host)) |
644 | && ret > 0) { | 688 | && ret > 0) { |
@@ -647,7 +691,7 @@ ssize_t generic_file_splice_write(struct inode *inode, struct file *out, | |||
647 | 691 | ||
648 | mutex_lock(&inode->i_mutex); | 692 | mutex_lock(&inode->i_mutex); |
649 | err = generic_osync_inode(mapping->host, mapping, | 693 | err = generic_osync_inode(mapping->host, mapping, |
650 | OSYNC_METADATA|OSYNC_DATA); | 694 | OSYNC_METADATA|OSYNC_DATA); |
651 | mutex_unlock(&inode->i_mutex); | 695 | mutex_unlock(&inode->i_mutex); |
652 | 696 | ||
653 | if (err) | 697 | if (err) |
@@ -670,10 +714,10 @@ EXPORT_SYMBOL(generic_file_splice_write); | |||
670 | * is involved. | 714 | * is involved. |
671 | * | 715 | * |
672 | */ | 716 | */ |
673 | ssize_t generic_splice_sendpage(struct inode *inode, struct file *out, | 717 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, |
674 | size_t len, unsigned int flags) | 718 | size_t len, unsigned int flags) |
675 | { | 719 | { |
676 | return move_from_pipe(inode, out, len, flags, pipe_to_sendpage); | 720 | return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage); |
677 | } | 721 | } |
678 | 722 | ||
679 | EXPORT_SYMBOL(generic_splice_sendpage); | 723 | EXPORT_SYMBOL(generic_splice_sendpage); |
@@ -681,19 +725,20 @@ EXPORT_SYMBOL(generic_splice_sendpage); | |||
681 | /* | 725 | /* |
682 | * Attempt to initiate a splice from pipe to file. | 726 | * Attempt to initiate a splice from pipe to file. |
683 | */ | 727 | */ |
684 | static long do_splice_from(struct inode *pipe, struct file *out, size_t len, | 728 | static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, |
685 | unsigned int flags) | 729 | size_t len, unsigned int flags) |
686 | { | 730 | { |
687 | loff_t pos; | 731 | loff_t pos; |
688 | int ret; | 732 | int ret; |
689 | 733 | ||
690 | if (!out->f_op || !out->f_op->splice_write) | 734 | if (unlikely(!out->f_op || !out->f_op->splice_write)) |
691 | return -EINVAL; | 735 | return -EINVAL; |
692 | 736 | ||
693 | if (!(out->f_mode & FMODE_WRITE)) | 737 | if (unlikely(!(out->f_mode & FMODE_WRITE))) |
694 | return -EBADF; | 738 | return -EBADF; |
695 | 739 | ||
696 | pos = out->f_pos; | 740 | pos = out->f_pos; |
741 | |||
697 | ret = rw_verify_area(WRITE, out, &pos, len); | 742 | ret = rw_verify_area(WRITE, out, &pos, len); |
698 | if (unlikely(ret < 0)) | 743 | if (unlikely(ret < 0)) |
699 | return ret; | 744 | return ret; |
@@ -704,19 +749,20 @@ static long do_splice_from(struct inode *pipe, struct file *out, size_t len, | |||
704 | /* | 749 | /* |
705 | * Attempt to initiate a splice from a file to a pipe. | 750 | * Attempt to initiate a splice from a file to a pipe. |
706 | */ | 751 | */ |
707 | static long do_splice_to(struct file *in, struct inode *pipe, size_t len, | 752 | static long do_splice_to(struct file *in, struct pipe_inode_info *pipe, |
708 | unsigned int flags) | 753 | size_t len, unsigned int flags) |
709 | { | 754 | { |
710 | loff_t pos, isize, left; | 755 | loff_t pos, isize, left; |
711 | int ret; | 756 | int ret; |
712 | 757 | ||
713 | if (!in->f_op || !in->f_op->splice_read) | 758 | if (unlikely(!in->f_op || !in->f_op->splice_read)) |
714 | return -EINVAL; | 759 | return -EINVAL; |
715 | 760 | ||
716 | if (!(in->f_mode & FMODE_READ)) | 761 | if (unlikely(!(in->f_mode & FMODE_READ))) |
717 | return -EBADF; | 762 | return -EBADF; |
718 | 763 | ||
719 | pos = in->f_pos; | 764 | pos = in->f_pos; |
765 | |||
720 | ret = rw_verify_area(READ, in, &pos, len); | 766 | ret = rw_verify_area(READ, in, &pos, len); |
721 | if (unlikely(ret < 0)) | 767 | if (unlikely(ret < 0)) |
722 | return ret; | 768 | return ret; |
@@ -726,32 +772,168 @@ static long do_splice_to(struct file *in, struct inode *pipe, size_t len, | |||
726 | return 0; | 772 | return 0; |
727 | 773 | ||
728 | left = isize - in->f_pos; | 774 | left = isize - in->f_pos; |
729 | if (left < len) | 775 | if (unlikely(left < len)) |
730 | len = left; | 776 | len = left; |
731 | 777 | ||
732 | return in->f_op->splice_read(in, pipe, len, flags); | 778 | return in->f_op->splice_read(in, pipe, len, flags); |
733 | } | 779 | } |
734 | 780 | ||
781 | long do_splice_direct(struct file *in, struct file *out, size_t len, | ||
782 | unsigned int flags) | ||
783 | { | ||
784 | struct pipe_inode_info *pipe; | ||
785 | long ret, bytes; | ||
786 | umode_t i_mode; | ||
787 | int i; | ||
788 | |||
789 | /* | ||
790 | * We require the input being a regular file, as we don't want to | ||
791 | * randomly drop data for eg socket -> socket splicing. Use the | ||
792 | * piped splicing for that! | ||
793 | */ | ||
794 | i_mode = in->f_dentry->d_inode->i_mode; | ||
795 | if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode))) | ||
796 | return -EINVAL; | ||
797 | |||
798 | /* | ||
799 | * neither in nor out is a pipe, setup an internal pipe attached to | ||
800 | * 'out' and transfer the wanted data from 'in' to 'out' through that | ||
801 | */ | ||
802 | pipe = current->splice_pipe; | ||
803 | if (unlikely(!pipe)) { | ||
804 | pipe = alloc_pipe_info(NULL); | ||
805 | if (!pipe) | ||
806 | return -ENOMEM; | ||
807 | |||
808 | /* | ||
809 | * We don't have an immediate reader, but we'll read the stuff | ||
810 | * out of the pipe right after the move_to_pipe(). So set | ||
811 | * PIPE_READERS appropriately. | ||
812 | */ | ||
813 | pipe->readers = 1; | ||
814 | |||
815 | current->splice_pipe = pipe; | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * Do the splice. | ||
820 | */ | ||
821 | ret = 0; | ||
822 | bytes = 0; | ||
823 | |||
824 | while (len) { | ||
825 | size_t read_len, max_read_len; | ||
826 | |||
827 | /* | ||
828 | * Do at most PIPE_BUFFERS pages worth of transfer: | ||
829 | */ | ||
830 | max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); | ||
831 | |||
832 | ret = do_splice_to(in, pipe, max_read_len, flags); | ||
833 | if (unlikely(ret < 0)) | ||
834 | goto out_release; | ||
835 | |||
836 | read_len = ret; | ||
837 | |||
838 | /* | ||
839 | * NOTE: nonblocking mode only applies to the input. We | ||
840 | * must not do the output in nonblocking mode as then we | ||
841 | * could get stuck data in the internal pipe: | ||
842 | */ | ||
843 | ret = do_splice_from(pipe, out, read_len, | ||
844 | flags & ~SPLICE_F_NONBLOCK); | ||
845 | if (unlikely(ret < 0)) | ||
846 | goto out_release; | ||
847 | |||
848 | bytes += ret; | ||
849 | len -= ret; | ||
850 | |||
851 | /* | ||
852 | * In nonblocking mode, if we got back a short read then | ||
853 | * that was due to either an IO error or due to the | ||
854 | * pagecache entry not being there. In the IO error case | ||
855 | * the _next_ splice attempt will produce a clean IO error | ||
856 | * return value (not a short read), so in both cases it's | ||
857 | * correct to break out of the loop here: | ||
858 | */ | ||
859 | if ((flags & SPLICE_F_NONBLOCK) && (read_len < max_read_len)) | ||
860 | break; | ||
861 | } | ||
862 | |||
863 | pipe->nrbufs = pipe->curbuf = 0; | ||
864 | |||
865 | return bytes; | ||
866 | |||
867 | out_release: | ||
868 | /* | ||
869 | * If we did an incomplete transfer we must release | ||
870 | * the pipe buffers in question: | ||
871 | */ | ||
872 | for (i = 0; i < PIPE_BUFFERS; i++) { | ||
873 | struct pipe_buffer *buf = pipe->bufs + i; | ||
874 | |||
875 | if (buf->ops) { | ||
876 | buf->ops->release(pipe, buf); | ||
877 | buf->ops = NULL; | ||
878 | } | ||
879 | } | ||
880 | pipe->nrbufs = pipe->curbuf = 0; | ||
881 | |||
882 | /* | ||
883 | * If we transferred some data, return the number of bytes: | ||
884 | */ | ||
885 | if (bytes > 0) | ||
886 | return bytes; | ||
887 | |||
888 | return ret; | ||
889 | } | ||
890 | |||
891 | EXPORT_SYMBOL(do_splice_direct); | ||
892 | |||
735 | /* | 893 | /* |
736 | * Determine where to splice to/from. | 894 | * Determine where to splice to/from. |
737 | */ | 895 | */ |
738 | static long do_splice(struct file *in, struct file *out, size_t len, | 896 | static long do_splice(struct file *in, loff_t __user *off_in, |
739 | unsigned int flags) | 897 | struct file *out, loff_t __user *off_out, |
898 | size_t len, unsigned int flags) | ||
740 | { | 899 | { |
741 | struct inode *pipe; | 900 | struct pipe_inode_info *pipe; |
901 | |||
902 | pipe = in->f_dentry->d_inode->i_pipe; | ||
903 | if (pipe) { | ||
904 | if (off_in) | ||
905 | return -ESPIPE; | ||
906 | if (off_out) { | ||
907 | if (out->f_op->llseek == no_llseek) | ||
908 | return -EINVAL; | ||
909 | if (copy_from_user(&out->f_pos, off_out, | ||
910 | sizeof(loff_t))) | ||
911 | return -EFAULT; | ||
912 | } | ||
742 | 913 | ||
743 | pipe = in->f_dentry->d_inode; | ||
744 | if (pipe->i_pipe) | ||
745 | return do_splice_from(pipe, out, len, flags); | 914 | return do_splice_from(pipe, out, len, flags); |
915 | } | ||
916 | |||
917 | pipe = out->f_dentry->d_inode->i_pipe; | ||
918 | if (pipe) { | ||
919 | if (off_out) | ||
920 | return -ESPIPE; | ||
921 | if (off_in) { | ||
922 | if (in->f_op->llseek == no_llseek) | ||
923 | return -EINVAL; | ||
924 | if (copy_from_user(&in->f_pos, off_in, sizeof(loff_t))) | ||
925 | return -EFAULT; | ||
926 | } | ||
746 | 927 | ||
747 | pipe = out->f_dentry->d_inode; | ||
748 | if (pipe->i_pipe) | ||
749 | return do_splice_to(in, pipe, len, flags); | 928 | return do_splice_to(in, pipe, len, flags); |
929 | } | ||
750 | 930 | ||
751 | return -EINVAL; | 931 | return -EINVAL; |
752 | } | 932 | } |
753 | 933 | ||
754 | asmlinkage long sys_splice(int fdin, int fdout, size_t len, unsigned int flags) | 934 | asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, |
935 | int fd_out, loff_t __user *off_out, | ||
936 | size_t len, unsigned int flags) | ||
755 | { | 937 | { |
756 | long error; | 938 | long error; |
757 | struct file *in, *out; | 939 | struct file *in, *out; |
@@ -761,13 +943,15 @@ asmlinkage long sys_splice(int fdin, int fdout, size_t len, unsigned int flags) | |||
761 | return 0; | 943 | return 0; |
762 | 944 | ||
763 | error = -EBADF; | 945 | error = -EBADF; |
764 | in = fget_light(fdin, &fput_in); | 946 | in = fget_light(fd_in, &fput_in); |
765 | if (in) { | 947 | if (in) { |
766 | if (in->f_mode & FMODE_READ) { | 948 | if (in->f_mode & FMODE_READ) { |
767 | out = fget_light(fdout, &fput_out); | 949 | out = fget_light(fd_out, &fput_out); |
768 | if (out) { | 950 | if (out) { |
769 | if (out->f_mode & FMODE_WRITE) | 951 | if (out->f_mode & FMODE_WRITE) |
770 | error = do_splice(in, out, len, flags); | 952 | error = do_splice(in, off_in, |
953 | out, off_out, | ||
954 | len, flags); | ||
771 | fput_light(out, fput_out); | 955 | fput_light(out, fput_out); |
772 | } | 956 | } |
773 | } | 957 | } |
@@ -61,7 +61,7 @@ | |||
61 | * will be available after a crash. | 61 | * will be available after a crash. |
62 | */ | 62 | */ |
63 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | 63 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, |
64 | int flags) | 64 | unsigned int flags) |
65 | { | 65 | { |
66 | int ret; | 66 | int ret; |
67 | struct file *file; | 67 | struct file *file; |
@@ -126,7 +126,7 @@ out: | |||
126 | * `endbyte' is inclusive | 126 | * `endbyte' is inclusive |
127 | */ | 127 | */ |
128 | int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte, | 128 | int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte, |
129 | int flags) | 129 | unsigned int flags) |
130 | { | 130 | { |
131 | int ret; | 131 | int ret; |
132 | struct address_space *mapping; | 132 | struct address_space *mapping; |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 6cbbd165c60d..4d191ef39b67 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -870,12 +870,14 @@ xfs_page_state_convert( | |||
870 | pgoff_t end_index, last_index, tlast; | 870 | pgoff_t end_index, last_index, tlast; |
871 | ssize_t size, len; | 871 | ssize_t size, len; |
872 | int flags, err, iomap_valid = 0, uptodate = 1; | 872 | int flags, err, iomap_valid = 0, uptodate = 1; |
873 | int page_dirty, count = 0, trylock_flag = 0; | 873 | int page_dirty, count = 0; |
874 | int trylock = 0; | ||
874 | int all_bh = unmapped; | 875 | int all_bh = unmapped; |
875 | 876 | ||
876 | /* wait for other IO threads? */ | 877 | if (startio) { |
877 | if (startio && (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking)) | 878 | if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking) |
878 | trylock_flag |= BMAPI_TRYLOCK; | 879 | trylock |= BMAPI_TRYLOCK; |
880 | } | ||
879 | 881 | ||
880 | /* Is this page beyond the end of the file? */ | 882 | /* Is this page beyond the end of the file? */ |
881 | offset = i_size_read(inode); | 883 | offset = i_size_read(inode); |
@@ -956,15 +958,13 @@ xfs_page_state_convert( | |||
956 | 958 | ||
957 | if (buffer_unwritten(bh)) { | 959 | if (buffer_unwritten(bh)) { |
958 | type = IOMAP_UNWRITTEN; | 960 | type = IOMAP_UNWRITTEN; |
959 | flags = BMAPI_WRITE|BMAPI_IGNSTATE; | 961 | flags = BMAPI_WRITE | BMAPI_IGNSTATE; |
960 | } else if (buffer_delay(bh)) { | 962 | } else if (buffer_delay(bh)) { |
961 | type = IOMAP_DELAY; | 963 | type = IOMAP_DELAY; |
962 | flags = BMAPI_ALLOCATE; | 964 | flags = BMAPI_ALLOCATE | trylock; |
963 | if (!startio) | ||
964 | flags |= trylock_flag; | ||
965 | } else { | 965 | } else { |
966 | type = IOMAP_NEW; | 966 | type = IOMAP_NEW; |
967 | flags = BMAPI_WRITE|BMAPI_MMAP; | 967 | flags = BMAPI_WRITE | BMAPI_MMAP; |
968 | } | 968 | } |
969 | 969 | ||
970 | if (!iomap_valid) { | 970 | if (!iomap_valid) { |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 9fb0312665ca..26fed0756f01 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -182,7 +182,7 @@ free_address( | |||
182 | { | 182 | { |
183 | a_list_t *aentry; | 183 | a_list_t *aentry; |
184 | 184 | ||
185 | aentry = kmalloc(sizeof(a_list_t), GFP_ATOMIC & ~__GFP_HIGH); | 185 | aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); |
186 | if (likely(aentry)) { | 186 | if (likely(aentry)) { |
187 | spin_lock(&as_lock); | 187 | spin_lock(&as_lock); |
188 | aentry->next = as_free_head; | 188 | aentry->next = as_free_head; |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index ae4c4754ed31..269721af02f3 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -252,7 +252,7 @@ xfs_file_sendfile_invis( | |||
252 | STATIC ssize_t | 252 | STATIC ssize_t |
253 | xfs_file_splice_read( | 253 | xfs_file_splice_read( |
254 | struct file *infilp, | 254 | struct file *infilp, |
255 | struct inode *pipe, | 255 | struct pipe_inode_info *pipe, |
256 | size_t len, | 256 | size_t len, |
257 | unsigned int flags) | 257 | unsigned int flags) |
258 | { | 258 | { |
@@ -266,7 +266,7 @@ xfs_file_splice_read( | |||
266 | STATIC ssize_t | 266 | STATIC ssize_t |
267 | xfs_file_splice_read_invis( | 267 | xfs_file_splice_read_invis( |
268 | struct file *infilp, | 268 | struct file *infilp, |
269 | struct inode *pipe, | 269 | struct pipe_inode_info *pipe, |
270 | size_t len, | 270 | size_t len, |
271 | unsigned int flags) | 271 | unsigned int flags) |
272 | { | 272 | { |
@@ -279,7 +279,7 @@ xfs_file_splice_read_invis( | |||
279 | 279 | ||
280 | STATIC ssize_t | 280 | STATIC ssize_t |
281 | xfs_file_splice_write( | 281 | xfs_file_splice_write( |
282 | struct inode *pipe, | 282 | struct pipe_inode_info *pipe, |
283 | struct file *outfilp, | 283 | struct file *outfilp, |
284 | size_t len, | 284 | size_t len, |
285 | unsigned int flags) | 285 | unsigned int flags) |
@@ -293,7 +293,7 @@ xfs_file_splice_write( | |||
293 | 293 | ||
294 | STATIC ssize_t | 294 | STATIC ssize_t |
295 | xfs_file_splice_write_invis( | 295 | xfs_file_splice_write_invis( |
296 | struct inode *pipe, | 296 | struct pipe_inode_info *pipe, |
297 | struct file *outfilp, | 297 | struct file *outfilp, |
298 | size_t len, | 298 | size_t len, |
299 | unsigned int flags) | 299 | unsigned int flags) |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 149237304fb6..2e2e275c786f 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -673,8 +673,7 @@ xfs_vn_setattr( | |||
673 | if (ia_valid & ATTR_ATIME) { | 673 | if (ia_valid & ATTR_ATIME) { |
674 | vattr.va_mask |= XFS_AT_ATIME; | 674 | vattr.va_mask |= XFS_AT_ATIME; |
675 | vattr.va_atime = attr->ia_atime; | 675 | vattr.va_atime = attr->ia_atime; |
676 | if (ia_valid & ATTR_ATIME_SET) | 676 | inode->i_atime = attr->ia_atime; |
677 | inode->i_atime = attr->ia_atime; | ||
678 | } | 677 | } |
679 | if (ia_valid & ATTR_MTIME) { | 678 | if (ia_valid & ATTR_MTIME) { |
680 | vattr.va_mask |= XFS_AT_MTIME; | 679 | vattr.va_mask |= XFS_AT_MTIME; |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 90cd314acbaa..74a52937f208 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -338,7 +338,7 @@ ssize_t | |||
338 | xfs_splice_read( | 338 | xfs_splice_read( |
339 | bhv_desc_t *bdp, | 339 | bhv_desc_t *bdp, |
340 | struct file *infilp, | 340 | struct file *infilp, |
341 | struct inode *pipe, | 341 | struct pipe_inode_info *pipe, |
342 | size_t count, | 342 | size_t count, |
343 | int flags, | 343 | int flags, |
344 | int ioflags, | 344 | int ioflags, |
@@ -380,7 +380,7 @@ xfs_splice_read( | |||
380 | ssize_t | 380 | ssize_t |
381 | xfs_splice_write( | 381 | xfs_splice_write( |
382 | bhv_desc_t *bdp, | 382 | bhv_desc_t *bdp, |
383 | struct inode *pipe, | 383 | struct pipe_inode_info *pipe, |
384 | struct file *outfilp, | 384 | struct file *outfilp, |
385 | size_t count, | 385 | size_t count, |
386 | int flags, | 386 | int flags, |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index eaa5659713fb..55c689a86ad2 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h | |||
@@ -94,9 +94,9 @@ extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, | |||
94 | loff_t *, int, size_t, read_actor_t, | 94 | loff_t *, int, size_t, read_actor_t, |
95 | void *, struct cred *); | 95 | void *, struct cred *); |
96 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, | 96 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, |
97 | struct inode *, size_t, int, int, | 97 | struct pipe_inode_info *, size_t, int, int, |
98 | struct cred *); | 98 | struct cred *); |
99 | extern ssize_t xfs_splice_write(struct bhv_desc *, struct inode *, | 99 | extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *, |
100 | struct file *, size_t, int, int, | 100 | struct file *, size_t, int, int, |
101 | struct cred *); | 101 | struct cred *); |
102 | 102 | ||
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 6f1c79a28f8b..88b09f186289 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -174,9 +174,9 @@ typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, | |||
174 | loff_t *, int, size_t, read_actor_t, | 174 | loff_t *, int, size_t, read_actor_t, |
175 | void *, struct cred *); | 175 | void *, struct cred *); |
176 | typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, | 176 | typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, |
177 | struct inode *, size_t, int, int, | 177 | struct pipe_inode_info *, size_t, int, int, |
178 | struct cred *); | 178 | struct cred *); |
179 | typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct inode *, | 179 | typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *, |
180 | struct file *, size_t, int, int, | 180 | struct file *, size_t, int, int, |
181 | struct cred *); | 181 | struct cred *); |
182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, | 182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 4eeb856183b1..deddbd03c166 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -158,9 +158,10 @@ xfs_ialloc_ag_alloc( | |||
158 | */ | 158 | */ |
159 | agi = XFS_BUF_TO_AGI(agbp); | 159 | agi = XFS_BUF_TO_AGI(agbp); |
160 | newino = be32_to_cpu(agi->agi_newino); | 160 | newino = be32_to_cpu(agi->agi_newino); |
161 | if(likely(newino != NULLAGINO)) { | 161 | args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + |
162 | args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + | 162 | XFS_IALLOC_BLOCKS(args.mp); |
163 | XFS_IALLOC_BLOCKS(args.mp); | 163 | if (likely(newino != NULLAGINO && |
164 | (args.agbno < be32_to_cpu(agi->agi_length)))) { | ||
164 | args.fsbno = XFS_AGB_TO_FSB(args.mp, | 165 | args.fsbno = XFS_AGB_TO_FSB(args.mp, |
165 | be32_to_cpu(agi->agi_seqno), args.agbno); | 166 | be32_to_cpu(agi->agi_seqno), args.agbno); |
166 | args.type = XFS_ALLOCTYPE_THIS_BNO; | 167 | args.type = XFS_ALLOCTYPE_THIS_BNO; |
@@ -182,8 +183,8 @@ xfs_ialloc_ag_alloc( | |||
182 | * Set the alignment for the allocation. | 183 | * Set the alignment for the allocation. |
183 | * If stripe alignment is turned on then align at stripe unit | 184 | * If stripe alignment is turned on then align at stripe unit |
184 | * boundary. | 185 | * boundary. |
185 | * If the cluster size is smaller than a filesystem block | 186 | * If the cluster size is smaller than a filesystem block |
186 | * then we're doing I/O for inodes in filesystem block size | 187 | * then we're doing I/O for inodes in filesystem block size |
187 | * pieces, so don't need alignment anyway. | 188 | * pieces, so don't need alignment anyway. |
188 | */ | 189 | */ |
189 | isaligned = 0; | 190 | isaligned = 0; |
@@ -192,7 +193,7 @@ xfs_ialloc_ag_alloc( | |||
192 | args.alignment = args.mp->m_dalign; | 193 | args.alignment = args.mp->m_dalign; |
193 | isaligned = 1; | 194 | isaligned = 1; |
194 | } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && | 195 | } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && |
195 | args.mp->m_sb.sb_inoalignmt >= | 196 | args.mp->m_sb.sb_inoalignmt >= |
196 | XFS_B_TO_FSBT(args.mp, | 197 | XFS_B_TO_FSBT(args.mp, |
197 | XFS_INODE_CLUSTER_SIZE(args.mp))) | 198 | XFS_INODE_CLUSTER_SIZE(args.mp))) |
198 | args.alignment = args.mp->m_sb.sb_inoalignmt; | 199 | args.alignment = args.mp->m_sb.sb_inoalignmt; |
@@ -220,7 +221,7 @@ xfs_ialloc_ag_alloc( | |||
220 | if ((error = xfs_alloc_vextent(&args))) | 221 | if ((error = xfs_alloc_vextent(&args))) |
221 | return error; | 222 | return error; |
222 | } | 223 | } |
223 | 224 | ||
224 | /* | 225 | /* |
225 | * If stripe alignment is turned on, then try again with cluster | 226 | * If stripe alignment is turned on, then try again with cluster |
226 | * alignment. | 227 | * alignment. |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index bb33113eef9f..b53854325266 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -421,7 +421,10 @@ finish_inode: | |||
421 | ip->i_chash = chlnew; | 421 | ip->i_chash = chlnew; |
422 | chlnew->chl_ip = ip; | 422 | chlnew->chl_ip = ip; |
423 | chlnew->chl_blkno = ip->i_blkno; | 423 | chlnew->chl_blkno = ip->i_blkno; |
424 | if (ch->ch_list) | ||
425 | ch->ch_list->chl_prev = chlnew; | ||
424 | chlnew->chl_next = ch->ch_list; | 426 | chlnew->chl_next = ch->ch_list; |
427 | chlnew->chl_prev = NULL; | ||
425 | ch->ch_list = chlnew; | 428 | ch->ch_list = chlnew; |
426 | chlnew = NULL; | 429 | chlnew = NULL; |
427 | } | 430 | } |
@@ -723,23 +726,15 @@ xfs_iextract( | |||
723 | ASSERT(ip->i_cnext == ip && ip->i_cprev == ip); | 726 | ASSERT(ip->i_cnext == ip && ip->i_cprev == ip); |
724 | ASSERT(ip->i_chash != NULL); | 727 | ASSERT(ip->i_chash != NULL); |
725 | chm=NULL; | 728 | chm=NULL; |
726 | for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) { | 729 | chl = ip->i_chash; |
727 | if (chl->chl_blkno == ip->i_blkno) { | 730 | if (chl->chl_prev) |
728 | if (chm == NULL) { | 731 | chl->chl_prev->chl_next = chl->chl_next; |
729 | /* first item on the list */ | 732 | else |
730 | ch->ch_list = chl->chl_next; | 733 | ch->ch_list = chl->chl_next; |
731 | } else { | 734 | if (chl->chl_next) |
732 | chm->chl_next = chl->chl_next; | 735 | chl->chl_next->chl_prev = chl->chl_prev; |
733 | } | 736 | kmem_zone_free(xfs_chashlist_zone, chl); |
734 | kmem_zone_free(xfs_chashlist_zone, chl); | 737 | } else { |
735 | break; | ||
736 | } else { | ||
737 | ASSERT(chl->chl_ip != ip); | ||
738 | chm = chl; | ||
739 | } | ||
740 | } | ||
741 | ASSERT_ALWAYS(chl != NULL); | ||
742 | } else { | ||
743 | /* delete one inode from a non-empty list */ | 738 | /* delete one inode from a non-empty list */ |
744 | iq = ip->i_cnext; | 739 | iq = ip->i_cnext; |
745 | iq->i_cprev = ip->i_cprev; | 740 | iq->i_cprev = ip->i_cprev; |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 48146bdc6bdd..94b60dd03801 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2732,16 +2732,29 @@ xfs_iunpin( | |||
2732 | ASSERT(atomic_read(&ip->i_pincount) > 0); | 2732 | ASSERT(atomic_read(&ip->i_pincount) > 0); |
2733 | 2733 | ||
2734 | if (atomic_dec_and_test(&ip->i_pincount)) { | 2734 | if (atomic_dec_and_test(&ip->i_pincount)) { |
2735 | vnode_t *vp = XFS_ITOV_NULL(ip); | 2735 | /* |
2736 | * If the inode is currently being reclaimed, the | ||
2737 | * linux inode _and_ the xfs vnode may have been | ||
2738 | * freed so we cannot reference either of them safely. | ||
2739 | * Hence we should not try to do anything to them | ||
2740 | * if the xfs inode is currently in the reclaim | ||
2741 | * path. | ||
2742 | * | ||
2743 | * However, we still need to issue the unpin wakeup | ||
2744 | * call as the inode reclaim may be blocked waiting for | ||
2745 | * the inode to become unpinned. | ||
2746 | */ | ||
2747 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { | ||
2748 | vnode_t *vp = XFS_ITOV_NULL(ip); | ||
2736 | 2749 | ||
2737 | /* make sync come back and flush this inode */ | 2750 | /* make sync come back and flush this inode */ |
2738 | if (vp) { | 2751 | if (vp) { |
2739 | struct inode *inode = vn_to_inode(vp); | 2752 | struct inode *inode = vn_to_inode(vp); |
2740 | 2753 | ||
2741 | if (!(inode->i_state & I_NEW)) | 2754 | if (!(inode->i_state & I_NEW)) |
2742 | mark_inode_dirty_sync(inode); | 2755 | mark_inode_dirty_sync(inode); |
2756 | } | ||
2743 | } | 2757 | } |
2744 | |||
2745 | wake_up(&ip->i_ipin_wait); | 2758 | wake_up(&ip->i_ipin_wait); |
2746 | } | 2759 | } |
2747 | } | 2760 | } |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 39ef9c36ea55..3b544db1790b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -189,6 +189,7 @@ typedef struct xfs_ihash { | |||
189 | */ | 189 | */ |
190 | typedef struct xfs_chashlist { | 190 | typedef struct xfs_chashlist { |
191 | struct xfs_chashlist *chl_next; | 191 | struct xfs_chashlist *chl_next; |
192 | struct xfs_chashlist *chl_prev; | ||
192 | struct xfs_inode *chl_ip; | 193 | struct xfs_inode *chl_ip; |
193 | xfs_daddr_t chl_blkno; /* starting block number of | 194 | xfs_daddr_t chl_blkno; /* starting block number of |
194 | * the cluster */ | 195 | * the cluster */ |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 049fabb7f7e0..c0b1c2906880 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -270,7 +270,7 @@ xfs_mount_validate_sb( | |||
270 | (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) || | 270 | (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) || |
271 | (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || | 271 | (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || |
272 | (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || | 272 | (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || |
273 | (sbp->sb_imax_pct > 100 || sbp->sb_imax_pct < 1))) { | 273 | (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */))) { |
274 | xfs_fs_mount_cmn_err(flags, "SB sanity check 1 failed"); | 274 | xfs_fs_mount_cmn_err(flags, "SB sanity check 1 failed"); |
275 | return XFS_ERROR(EFSCORRUPTED); | 275 | return XFS_ERROR(EFSCORRUPTED); |
276 | } | 276 | } |
diff --git a/include/asm-alpha/numnodes.h b/include/asm-alpha/numnodes.h deleted file mode 100644 index cd425827e4f3..000000000000 --- a/include/asm-alpha/numnodes.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _ASM_MAX_NUMNODES_H | ||
2 | #define _ASM_MAX_NUMNODES_H | ||
3 | |||
4 | /* Max 128 Nodes - Marvel */ | ||
5 | #define NODES_SHIFT 7 | ||
6 | |||
7 | #endif /* _ASM_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-arm/arch-cl7500/hardware.h b/include/asm-arm/arch-cl7500/hardware.h index 2339b764f69f..1adfd18e6154 100644 --- a/include/asm-arm/arch-cl7500/hardware.h +++ b/include/asm-arm/arch-cl7500/hardware.h | |||
@@ -53,16 +53,12 @@ | |||
53 | #define SCREEN_END 0xdfc00000 | 53 | #define SCREEN_END 0xdfc00000 |
54 | #define SCREEN_BASE 0xdf800000 | 54 | #define SCREEN_BASE 0xdf800000 |
55 | 55 | ||
56 | #define FLUSH_BASE 0xdf000000 | ||
57 | |||
58 | #define VIDC_BASE (void __iomem *)0xe0400000 | 56 | #define VIDC_BASE (void __iomem *)0xe0400000 |
59 | #define IOMD_BASE IOMEM(0xe0200000) | 57 | #define IOMD_BASE IOMEM(0xe0200000) |
60 | #define IOC_BASE IOMEM(0xe0200000) | 58 | #define IOC_BASE IOMEM(0xe0200000) |
61 | #define FLOPPYDMA_BASE IOMEM(0xe002a000) | 59 | #define FLOPPYDMA_BASE IOMEM(0xe002a000) |
62 | #define PCIO_BASE IOMEM(0xe0010000) | 60 | #define PCIO_BASE IOMEM(0xe0010000) |
63 | 61 | ||
64 | #define FLUSH_BASE_PHYS 0x00000000 /* ROM */ | ||
65 | |||
66 | #define vidc_writel(val) __raw_writel(val, VIDC_BASE) | 62 | #define vidc_writel(val) __raw_writel(val, VIDC_BASE) |
67 | 63 | ||
68 | /* in/out bias for the ISA slot region */ | 64 | /* in/out bias for the ISA slot region */ |
diff --git a/include/asm-arm/arch-cl7500/memory.h b/include/asm-arm/arch-cl7500/memory.h index 34f40a6cec30..3178140e24ca 100644 --- a/include/asm-arm/arch-cl7500/memory.h +++ b/include/asm-arm/arch-cl7500/memory.h | |||
@@ -26,4 +26,10 @@ | |||
26 | #define __virt_to_bus(x) __virt_to_phys(x) | 26 | #define __virt_to_bus(x) __virt_to_phys(x) |
27 | #define __bus_to_virt(x) __phys_to_virt(x) | 27 | #define __bus_to_virt(x) __phys_to_virt(x) |
28 | 28 | ||
29 | /* | ||
30 | * Cache flushing area - ROM | ||
31 | */ | ||
32 | #define FLUSH_BASE_PHYS 0x00000000 | ||
33 | #define FLUSH_BASE 0xdf000000 | ||
34 | |||
29 | #endif | 35 | #endif |
diff --git a/include/asm-arm/arch-ebsa110/debug-macro.S b/include/asm-arm/arch-ebsa110/debug-macro.S index f61cadabe0ec..9213bfe4831d 100644 --- a/include/asm-arm/arch-ebsa110/debug-macro.S +++ b/include/asm-arm/arch-ebsa110/debug-macro.S | |||
@@ -18,4 +18,4 @@ | |||
18 | 18 | ||
19 | #define UART_SHIFT 2 | 19 | #define UART_SHIFT 2 |
20 | #define FLOW_CONTROL | 20 | #define FLOW_CONTROL |
21 | #include <asm/hardware/debug-8250.h> | 21 | #include <asm/hardware/debug-8250.S> |
diff --git a/include/asm-arm/arch-ebsa110/hardware.h b/include/asm-arm/arch-ebsa110/hardware.h index 4e41c2358f4e..3ce864def41e 100644 --- a/include/asm-arm/arch-ebsa110/hardware.h +++ b/include/asm-arm/arch-ebsa110/hardware.h | |||
@@ -57,9 +57,6 @@ | |||
57 | /* | 57 | /* |
58 | * RAM definitions | 58 | * RAM definitions |
59 | */ | 59 | */ |
60 | #define FLUSH_BASE_PHYS 0x40000000 | ||
61 | #define FLUSH_BASE 0xdf000000 | ||
62 | |||
63 | #define UNCACHEABLE_ADDR 0xff000000 /* IRQ_STAT */ | 60 | #define UNCACHEABLE_ADDR 0xff000000 /* IRQ_STAT */ |
64 | 61 | ||
65 | #endif | 62 | #endif |
diff --git a/include/asm-arm/arch-ebsa110/memory.h b/include/asm-arm/arch-ebsa110/memory.h index 02f144520c10..c7c500e176d0 100644 --- a/include/asm-arm/arch-ebsa110/memory.h +++ b/include/asm-arm/arch-ebsa110/memory.h | |||
@@ -28,4 +28,10 @@ | |||
28 | #define __virt_to_bus(x) (x) | 28 | #define __virt_to_bus(x) (x) |
29 | #define __bus_to_virt(x) (x) | 29 | #define __bus_to_virt(x) (x) |
30 | 30 | ||
31 | /* | ||
32 | * Cache flushing area - SRAM | ||
33 | */ | ||
34 | #define FLUSH_BASE_PHYS 0x40000000 | ||
35 | #define FLUSH_BASE 0xdf000000 | ||
36 | |||
31 | #endif | 37 | #endif |
diff --git a/include/asm-arm/arch-ebsa110/uncompress.h b/include/asm-arm/arch-ebsa110/uncompress.h index 66b19c7fd908..ae5b775eb0b7 100644 --- a/include/asm-arm/arch-ebsa110/uncompress.h +++ b/include/asm-arm/arch-ebsa110/uncompress.h | |||
@@ -10,7 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/serial_reg.h> | 11 | #include <linux/serial_reg.h> |
12 | 12 | ||
13 | #define SERIAL_BASE ((unsigned char *)0xfe000be0) | 13 | #define SERIAL_BASE ((unsigned char *)0xf0000be0) |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * This does not append a newline | 16 | * This does not append a newline |
diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h index 2ef2200f108c..ec51fe92483b 100644 --- a/include/asm-arm/arch-ebsa285/hardware.h +++ b/include/asm-arm/arch-ebsa285/hardware.h | |||
@@ -48,9 +48,6 @@ | |||
48 | #define PCICFG0_SIZE 0x01000000 | 48 | #define PCICFG0_SIZE 0x01000000 |
49 | #define PCICFG0_BASE 0xfa000000 | 49 | #define PCICFG0_BASE 0xfa000000 |
50 | 50 | ||
51 | #define FLUSH_SIZE 0x00100000 | ||
52 | #define FLUSH_BASE 0xf9000000 | ||
53 | |||
54 | #define PCIMEM_SIZE 0x01000000 | 51 | #define PCIMEM_SIZE 0x01000000 |
55 | #define PCIMEM_BASE 0xf0000000 | 52 | #define PCIMEM_BASE 0xf0000000 |
56 | 53 | ||
@@ -61,9 +58,6 @@ | |||
61 | #define PCIMEM_SIZE 0x80000000 | 58 | #define PCIMEM_SIZE 0x80000000 |
62 | #define PCIMEM_BASE 0x80000000 | 59 | #define PCIMEM_BASE 0x80000000 |
63 | 60 | ||
64 | #define FLUSH_SIZE 0x00100000 | ||
65 | #define FLUSH_BASE 0x7e000000 | ||
66 | |||
67 | #define WFLUSH_SIZE 0x01000000 | 61 | #define WFLUSH_SIZE 0x01000000 |
68 | #define WFLUSH_BASE 0x7d000000 | 62 | #define WFLUSH_BASE 0x7d000000 |
69 | 63 | ||
@@ -94,7 +88,6 @@ | |||
94 | #define XBUS_SWITCH_J17_11 ((*XBUS_SWITCH) & (1 << 5)) | 88 | #define XBUS_SWITCH_J17_11 ((*XBUS_SWITCH) & (1 << 5)) |
95 | #define XBUS_SWITCH_J17_9 ((*XBUS_SWITCH) & (1 << 6)) | 89 | #define XBUS_SWITCH_J17_9 ((*XBUS_SWITCH) & (1 << 6)) |
96 | 90 | ||
97 | #define FLUSH_BASE_PHYS 0x50000000 | ||
98 | #define UNCACHEABLE_ADDR (ARMCSR_BASE + 0x108) | 91 | #define UNCACHEABLE_ADDR (ARMCSR_BASE + 0x108) |
99 | 92 | ||
100 | 93 | ||
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h index 09e335cd687d..99181ffc7e27 100644 --- a/include/asm-arm/arch-ebsa285/memory.h +++ b/include/asm-arm/arch-ebsa285/memory.h | |||
@@ -49,12 +49,22 @@ extern unsigned long __bus_to_virt(unsigned long); | |||
49 | #define TASK_SIZE UL(0xbf000000) | 49 | #define TASK_SIZE UL(0xbf000000) |
50 | #define PAGE_OFFSET UL(0xc0000000) | 50 | #define PAGE_OFFSET UL(0xc0000000) |
51 | 51 | ||
52 | /* | ||
53 | * Cache flushing area. | ||
54 | */ | ||
55 | #define FLUSH_BASE 0xf9000000 | ||
56 | |||
52 | #elif defined(CONFIG_ARCH_CO285) | 57 | #elif defined(CONFIG_ARCH_CO285) |
53 | 58 | ||
54 | /* Task size and page offset at 1.5GB */ | 59 | /* Task size and page offset at 1.5GB */ |
55 | #define TASK_SIZE UL(0x5f000000) | 60 | #define TASK_SIZE UL(0x5f000000) |
56 | #define PAGE_OFFSET UL(0x60000000) | 61 | #define PAGE_OFFSET UL(0x60000000) |
57 | 62 | ||
63 | /* | ||
64 | * Cache flushing area. | ||
65 | */ | ||
66 | #define FLUSH_BASE 0x7e000000 | ||
67 | |||
58 | #else | 68 | #else |
59 | 69 | ||
60 | #error "Undefined footbridge architecture" | 70 | #error "Undefined footbridge architecture" |
@@ -72,4 +82,6 @@ extern unsigned long __bus_to_virt(unsigned long); | |||
72 | */ | 82 | */ |
73 | #define TASK_UNMAPPED_BASE ((TASK_SIZE + 0x01000000) / 3) | 83 | #define TASK_UNMAPPED_BASE ((TASK_SIZE + 0x01000000) / 3) |
74 | 84 | ||
85 | #define FLUSH_BASE_PHYS 0x50000000 | ||
86 | |||
75 | #endif | 87 | #endif |
diff --git a/include/asm-arm/arch-ixp23xx/debug-macro.S b/include/asm-arm/arch-ixp23xx/debug-macro.S index eb99fd69fd24..2b25e640247d 100644 --- a/include/asm-arm/arch-ixp23xx/debug-macro.S +++ b/include/asm-arm/arch-ixp23xx/debug-macro.S | |||
@@ -17,6 +17,9 @@ | |||
17 | tst \rx, #1 @ mmu enabled? | 17 | tst \rx, #1 @ mmu enabled? |
18 | ldreq \rx, =IXP23XX_PERIPHERAL_PHYS @ physical | 18 | ldreq \rx, =IXP23XX_PERIPHERAL_PHYS @ physical |
19 | ldrne \rx, =IXP23XX_PERIPHERAL_VIRT @ virtual | 19 | ldrne \rx, =IXP23XX_PERIPHERAL_VIRT @ virtual |
20 | #ifdef __ARMEB__ | ||
21 | orr \rx, \rx, #0x00000003 | ||
22 | #endif | ||
20 | .endm | 23 | .endm |
21 | 24 | ||
22 | #define UART_SHIFT 2 | 25 | #define UART_SHIFT 2 |
diff --git a/include/asm-arm/arch-l7200/hardware.h b/include/asm-arm/arch-l7200/hardware.h index b755079befab..2ab43f3a4a8d 100644 --- a/include/asm-arm/arch-l7200/hardware.h +++ b/include/asm-arm/arch-l7200/hardware.h | |||
@@ -52,9 +52,6 @@ | |||
52 | #define ISA_SIZE 0x20000000 | 52 | #define ISA_SIZE 0x20000000 |
53 | #define ISA_BASE 0xe0000000 | 53 | #define ISA_BASE 0xe0000000 |
54 | 54 | ||
55 | #define FLUSH_BASE_PHYS 0x40000000 /* ROM */ | ||
56 | #define FLUSH_BASE 0xdf000000 | ||
57 | |||
58 | #define PCIO_BASE IO_BASE | 55 | #define PCIO_BASE IO_BASE |
59 | 56 | ||
60 | #endif | 57 | #endif |
diff --git a/include/asm-arm/arch-l7200/memory.h b/include/asm-arm/arch-l7200/memory.h index 9e50a171f78a..402df637e740 100644 --- a/include/asm-arm/arch-l7200/memory.h +++ b/include/asm-arm/arch-l7200/memory.h | |||
@@ -20,4 +20,10 @@ | |||
20 | #define __virt_to_bus(x) __virt_to_phys(x) | 20 | #define __virt_to_bus(x) __virt_to_phys(x) |
21 | #define __bus_to_virt(x) __phys_to_virt(x) | 21 | #define __bus_to_virt(x) __phys_to_virt(x) |
22 | 22 | ||
23 | /* | ||
24 | * Cache flushing area - ROM | ||
25 | */ | ||
26 | #define FLUSH_BASE_PHYS 0x40000000 | ||
27 | #define FLUSH_BASE 0xdf000000 | ||
28 | |||
23 | #endif | 29 | #endif |
diff --git a/include/asm-arm/arch-lh7a40x/memory.h b/include/asm-arm/arch-lh7a40x/memory.h index c92bcb837629..9f1a58cbf407 100644 --- a/include/asm-arm/arch-lh7a40x/memory.h +++ b/include/asm-arm/arch-lh7a40x/memory.h | |||
@@ -31,8 +31,6 @@ | |||
31 | 31 | ||
32 | #ifdef CONFIG_DISCONTIGMEM | 32 | #ifdef CONFIG_DISCONTIGMEM |
33 | 33 | ||
34 | #define NODES_SHIFT 4 /* Up to 16 nodes */ | ||
35 | |||
36 | /* | 34 | /* |
37 | * Given a kernel address, find the home node of the underlying memory. | 35 | * Given a kernel address, find the home node of the underlying memory. |
38 | */ | 36 | */ |
diff --git a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h index 9d7f87375aa7..7480f4e8d974 100644 --- a/include/asm-arm/arch-rpc/hardware.h +++ b/include/asm-arm/arch-rpc/hardware.h | |||
@@ -46,7 +46,6 @@ | |||
46 | #define SCREEN_END 0xdfc00000 | 46 | #define SCREEN_END 0xdfc00000 |
47 | #define SCREEN_BASE 0xdf800000 | 47 | #define SCREEN_BASE 0xdf800000 |
48 | 48 | ||
49 | #define FLUSH_BASE 0xdf000000 | ||
50 | #define UNCACHEABLE_ADDR 0xdf010000 | 49 | #define UNCACHEABLE_ADDR 0xdf010000 |
51 | 50 | ||
52 | /* | 51 | /* |
@@ -59,8 +58,6 @@ | |||
59 | #define PCIO_BASE IOMEM(0xe0010000) | 58 | #define PCIO_BASE IOMEM(0xe0010000) |
60 | #define FLOPPYDMA_BASE IOMEM(0xe002a000) | 59 | #define FLOPPYDMA_BASE IOMEM(0xe002a000) |
61 | 60 | ||
62 | #define FLUSH_BASE_PHYS 0x00000000 /* ROM */ | ||
63 | |||
64 | #define vidc_writel(val) __raw_writel(val, VIDC_BASE) | 61 | #define vidc_writel(val) __raw_writel(val, VIDC_BASE) |
65 | 62 | ||
66 | #define IO_EC_EASI_BASE 0x81400000 | 63 | #define IO_EC_EASI_BASE 0x81400000 |
diff --git a/include/asm-arm/arch-rpc/memory.h b/include/asm-arm/arch-rpc/memory.h index 0592cb3f0c74..303c424ce673 100644 --- a/include/asm-arm/arch-rpc/memory.h +++ b/include/asm-arm/arch-rpc/memory.h | |||
@@ -30,4 +30,10 @@ | |||
30 | #define __virt_to_bus(x) __virt_to_phys(x) | 30 | #define __virt_to_bus(x) __virt_to_phys(x) |
31 | #define __bus_to_virt(x) __phys_to_virt(x) | 31 | #define __bus_to_virt(x) __phys_to_virt(x) |
32 | 32 | ||
33 | /* | ||
34 | * Cache flushing area - ROM | ||
35 | */ | ||
36 | #define FLUSH_BASE_PHYS 0x00000000 | ||
37 | #define FLUSH_BASE 0xdf000000 | ||
38 | |||
33 | #endif | 39 | #endif |
diff --git a/include/asm-arm/arch-s3c2410/leds-gpio.h b/include/asm-arm/arch-s3c2410/leds-gpio.h new file mode 100644 index 000000000000..f07ed040622b --- /dev/null +++ b/include/asm-arm/arch-s3c2410/leds-gpio.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* linux/include/asm-arm/arch-s3c2410/leds-gpio.h | ||
2 | * | ||
3 | * (c) 2006 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX - LEDs GPIO connector | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_ARCH_LEDSGPIO_H | ||
15 | #define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h" | ||
16 | |||
17 | #define S3C24XX_LEDF_ACTLOW (1<<0) /* LED is on when GPIO low */ | ||
18 | #define S3C24XX_LEDF_TRISTATE (1<<1) /* tristate to turn off */ | ||
19 | |||
20 | struct s3c24xx_led_platdata { | ||
21 | unsigned int gpio; | ||
22 | unsigned int flags; | ||
23 | |||
24 | char *name; | ||
25 | char *def_trigger; | ||
26 | }; | ||
27 | |||
28 | #endif /* __ASM_ARCH_LEDSGPIO_H */ | ||
diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h index 28711aaa4968..ee008a5484f3 100644 --- a/include/asm-arm/arch-sa1100/hardware.h +++ b/include/asm-arm/arch-sa1100/hardware.h | |||
@@ -14,10 +14,6 @@ | |||
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
16 | 16 | ||
17 | /* Flushing areas */ | ||
18 | #define FLUSH_BASE_PHYS 0xe0000000 /* SA1100 zero bank */ | ||
19 | #define FLUSH_BASE 0xf5000000 | ||
20 | #define FLUSH_BASE_MINICACHE 0xf5800000 | ||
21 | #define UNCACHEABLE_ADDR 0xfa050000 | 17 | #define UNCACHEABLE_ADDR 0xfa050000 |
22 | 18 | ||
23 | 19 | ||
diff --git a/include/asm-arm/arch-sa1100/memory.h b/include/asm-arm/arch-sa1100/memory.h index 018a9f0e3986..a29fac1387ca 100644 --- a/include/asm-arm/arch-sa1100/memory.h +++ b/include/asm-arm/arch-sa1100/memory.h | |||
@@ -91,4 +91,11 @@ void sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes); | |||
91 | 91 | ||
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | /* | ||
95 | * Cache flushing area - SA1100 zero bank | ||
96 | */ | ||
97 | #define FLUSH_BASE_PHYS 0xe0000000 | ||
98 | #define FLUSH_BASE 0xf5000000 | ||
99 | #define FLUSH_BASE_MINICACHE 0xf5100000 | ||
100 | |||
94 | #endif | 101 | #endif |
diff --git a/include/asm-arm/arch-shark/hardware.h b/include/asm-arm/arch-shark/hardware.h index 4d35f8c154c3..ecba45260898 100644 --- a/include/asm-arm/arch-shark/hardware.h +++ b/include/asm-arm/arch-shark/hardware.h | |||
@@ -17,11 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | #define IO_BASE 0xe0000000 | 18 | #define IO_BASE 0xe0000000 |
19 | 19 | ||
20 | /* | ||
21 | * RAM definitions | ||
22 | */ | ||
23 | #define FLUSH_BASE_PHYS 0x80000000 | ||
24 | |||
25 | #else | 20 | #else |
26 | 21 | ||
27 | #define IO_BASE 0 | 22 | #define IO_BASE 0 |
@@ -33,7 +28,6 @@ | |||
33 | #define ROMCARD_SIZE 0x08000000 | 28 | #define ROMCARD_SIZE 0x08000000 |
34 | #define ROMCARD_START 0x10000000 | 29 | #define ROMCARD_START 0x10000000 |
35 | 30 | ||
36 | #define FLUSH_BASE 0xdf000000 | ||
37 | #define PCIO_BASE 0xe0000000 | 31 | #define PCIO_BASE 0xe0000000 |
38 | 32 | ||
39 | 33 | ||
diff --git a/include/asm-arm/arch-shark/memory.h b/include/asm-arm/arch-shark/memory.h index 95a29b4bc5d0..6968d6103ea0 100644 --- a/include/asm-arm/arch-shark/memory.h +++ b/include/asm-arm/arch-shark/memory.h | |||
@@ -39,4 +39,10 @@ static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsig | |||
39 | #define __virt_to_bus(x) __virt_to_phys(x) | 39 | #define __virt_to_bus(x) __virt_to_phys(x) |
40 | #define __bus_to_virt(x) __phys_to_virt(x) | 40 | #define __bus_to_virt(x) __phys_to_virt(x) |
41 | 41 | ||
42 | /* | ||
43 | * Cache flushing area | ||
44 | */ | ||
45 | #define FLUSH_BASE_PHYS 0x80000000 | ||
46 | #define FLUSH_BASE 0xdf000000 | ||
47 | |||
42 | #endif | 48 | #endif |
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h index 6246bf83627d..52bae088a185 100644 --- a/include/asm-arm/fpstate.h +++ b/include/asm-arm/fpstate.h | |||
@@ -26,7 +26,9 @@ | |||
26 | 26 | ||
27 | struct vfp_hard_struct { | 27 | struct vfp_hard_struct { |
28 | __u64 fpregs[16]; | 28 | __u64 fpregs[16]; |
29 | #if __LINUX_ARM_ARCH__ < 6 | ||
29 | __u32 fpmx_state; | 30 | __u32 fpmx_state; |
31 | #endif | ||
30 | __u32 fpexc; | 32 | __u32 fpexc; |
31 | __u32 fpscr; | 33 | __u32 fpscr; |
32 | /* | 34 | /* |
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h index 2b3cf69b3ed9..209289407595 100644 --- a/include/asm-arm/memory.h +++ b/include/asm-arm/memory.h | |||
@@ -172,10 +172,10 @@ static inline __deprecated void *bus_to_virt(unsigned long x) | |||
172 | * virt_addr_valid(k) indicates whether a virtual address is valid | 172 | * virt_addr_valid(k) indicates whether a virtual address is valid |
173 | */ | 173 | */ |
174 | #ifndef CONFIG_DISCONTIGMEM | 174 | #ifndef CONFIG_DISCONTIGMEM |
175 | #define ARCH_PFN_OFFSET (PHYS_PFN_OFFSET) | 175 | #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET |
176 | #define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) | 176 | #define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) |
177 | 177 | ||
178 | #define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) | 178 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) |
179 | #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) | 179 | #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) |
180 | 180 | ||
181 | #define PHYS_TO_NID(addr) (0) | 181 | #define PHYS_TO_NID(addr) (0) |
@@ -187,8 +187,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x) | |||
187 | * around in memory. | 187 | * around in memory. |
188 | */ | 188 | */ |
189 | #include <linux/numa.h> | 189 | #include <linux/numa.h> |
190 | #define arch_pfn_to_nid(pfn) (PFN_TO_NID(pfn)) | 190 | #define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) |
191 | #define arch_local_page_offset(pfn, nid) (LOCAL_MAP_NR((pfn) << PAGE_OFFSET)) | 191 | #define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) |
192 | 192 | ||
193 | #define pfn_valid(pfn) \ | 193 | #define pfn_valid(pfn) \ |
194 | ({ \ | 194 | ({ \ |
diff --git a/include/asm-arm/numnodes.h b/include/asm-arm/numnodes.h deleted file mode 100644 index 8df36818ebc9..000000000000 --- a/include/asm-arm/numnodes.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* | ||
2 | * linux/include/asm-arm/numnodes.h | ||
3 | * | ||
4 | * Copyright (C) 2002 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /* This declaration for the size of the NUMA (CONFIG_DISCONTIGMEM) | ||
12 | * memory node table is the default. | ||
13 | * | ||
14 | * A good place to override this value is include/asm/arch/memory.h. | ||
15 | */ | ||
16 | |||
17 | #ifndef __ASM_ARM_NUMNODES_H | ||
18 | #define __ASM_ARM_NUMNODES_H | ||
19 | |||
20 | #include <asm/memory.h> | ||
21 | |||
22 | #ifndef NODES_SHIFT | ||
23 | # define NODES_SHIFT 2 /* Normally, Max 4 Nodes */ | ||
24 | #endif | ||
25 | |||
26 | #endif | ||
diff --git a/include/asm-arm/vfpmacros.h b/include/asm-arm/vfpmacros.h index 15bd6e74c9cf..27fe028b4e72 100644 --- a/include/asm-arm/vfpmacros.h +++ b/include/asm-arm/vfpmacros.h | |||
@@ -16,10 +16,18 @@ | |||
16 | 16 | ||
17 | @ read all the working registers back into the VFP | 17 | @ read all the working registers back into the VFP |
18 | .macro VFPFLDMIA, base | 18 | .macro VFPFLDMIA, base |
19 | #if __LINUX_ARM_ARCH__ < 6 | ||
19 | LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15} | 20 | LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15} |
21 | #else | ||
22 | LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15} | ||
23 | #endif | ||
20 | .endm | 24 | .endm |
21 | 25 | ||
22 | @ write all the working registers out of the VFP | 26 | @ write all the working registers out of the VFP |
23 | .macro VFPFSTMIA, base | 27 | .macro VFPFSTMIA, base |
28 | #if __LINUX_ARM_ARCH__ < 6 | ||
24 | STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15} | 29 | STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15} |
30 | #else | ||
31 | STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15} | ||
32 | #endif | ||
25 | .endm | 33 | .endm |
diff --git a/include/asm-cris/system.h b/include/asm-cris/system.h index 1d63c2aa8ec2..b1c593b6dbff 100644 --- a/include/asm-cris/system.h +++ b/include/asm-cris/system.h | |||
@@ -8,7 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | extern struct task_struct *resume(struct task_struct *prev, struct task_struct *next, int); | 10 | extern struct task_struct *resume(struct task_struct *prev, struct task_struct *next, int); |
11 | #define prepare_to_switch() do { } while(0) | ||
12 | #define switch_to(prev,next,last) last = resume(prev,next, \ | 11 | #define switch_to(prev,next,last) last = resume(prev,next, \ |
13 | (int)&((struct task_struct *)0)->thread) | 12 | (int)&((struct task_struct *)0)->thread) |
14 | 13 | ||
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index 2627bbdf8a11..bb2dfe480213 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h | |||
@@ -288,7 +288,7 @@ | |||
288 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 288 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
289 | #define __NR_mq_notify (__NR_mq_open+4) | 289 | #define __NR_mq_notify (__NR_mq_open+4) |
290 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 290 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
291 | #define __NR_sys_kexec_load 283 | 291 | #define __NR_kexec_load 283 |
292 | #define __NR_waitid 284 | 292 | #define __NR_waitid 284 |
293 | /* #define __NR_sys_setaltroot 285 */ | 293 | /* #define __NR_sys_setaltroot 285 */ |
294 | #define __NR_add_key 286 | 294 | #define __NR_add_key 286 |
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index f72ff0c4dc0b..1734ed91bcdc 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h | |||
@@ -18,8 +18,6 @@ | |||
18 | 18 | ||
19 | struct thread_struct; | 19 | struct thread_struct; |
20 | 20 | ||
21 | #define prepare_to_switch() do { } while(0) | ||
22 | |||
23 | /* | 21 | /* |
24 | * switch_to(prev, next) should switch from task `prev' to `next' | 22 | * switch_to(prev, next) should switch from task `prev' to `next' |
25 | * `prev' will never be the same as `next'. | 23 | * `prev' will never be the same as `next'. |
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index 322531caa484..2662a3e12dc4 100644 --- a/include/asm-frv/unistd.h +++ b/include/asm-frv/unistd.h | |||
@@ -289,7 +289,7 @@ | |||
289 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 289 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
290 | #define __NR_mq_notify (__NR_mq_open+4) | 290 | #define __NR_mq_notify (__NR_mq_open+4) |
291 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 291 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
292 | #define __NR_sys_kexec_load 283 | 292 | #define __NR_kexec_load 283 |
293 | #define __NR_waitid 284 | 293 | #define __NR_waitid 284 |
294 | /* #define __NR_sys_setaltroot 285 */ | 294 | /* #define __NR_sys_setaltroot 285 */ |
295 | #define __NR_add_key 286 | 295 | #define __NR_add_key 286 |
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h index dfe96c7121cf..8e81cf665e75 100644 --- a/include/asm-h8300/system.h +++ b/include/asm-h8300/system.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #include <linux/config.h> /* get configuration macros */ | 4 | #include <linux/config.h> /* get configuration macros */ |
5 | #include <linux/linkage.h> | 5 | #include <linux/linkage.h> |
6 | 6 | ||
7 | #define prepare_to_switch() do { } while(0) | ||
8 | |||
9 | /* | 7 | /* |
10 | * switch_to(n) should switch tasks to task ptr, first checking that | 8 | * switch_to(n) should switch tasks to task ptr, first checking that |
11 | * ptr isn't the current task, in which case it does nothing. This | 9 | * ptr isn't the current task, in which case it does nothing. This |
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h index 56a4a5686c88..adb05159379b 100644 --- a/include/asm-h8300/unistd.h +++ b/include/asm-h8300/unistd.h | |||
@@ -285,7 +285,7 @@ | |||
285 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 285 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
286 | #define __NR_mq_notify (__NR_mq_open+4) | 286 | #define __NR_mq_notify (__NR_mq_open+4) |
287 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 287 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
288 | #define __NR_sys_kexec_load 283 | 288 | #define __NR_kexec_load 283 |
289 | #define __NR_waitid 284 | 289 | #define __NR_waitid 284 |
290 | /* #define __NR_sys_setaltroot 285 */ | 290 | /* #define __NR_sys_setaltroot 285 */ |
291 | #define __NR_add_key 286 | 291 | #define __NR_add_key 286 |
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index ff9ac8d19eb2..288233fd77d7 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h | |||
@@ -139,6 +139,8 @@ void switch_ipi_to_APIC_timer(void *cpumask); | |||
139 | 139 | ||
140 | extern int timer_over_8254; | 140 | extern int timer_over_8254; |
141 | 141 | ||
142 | extern int modern_apic(void); | ||
143 | |||
142 | #else /* !CONFIG_X86_LOCAL_APIC */ | 144 | #else /* !CONFIG_X86_LOCAL_APIC */ |
143 | static inline void lapic_shutdown(void) { } | 145 | static inline void lapic_shutdown(void) { } |
144 | 146 | ||
diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h index edf65be21a92..ca82acb8cb1f 100644 --- a/include/asm-i386/e820.h +++ b/include/asm-i386/e820.h | |||
@@ -35,6 +35,10 @@ struct e820map { | |||
35 | }; | 35 | }; |
36 | 36 | ||
37 | extern struct e820map e820; | 37 | extern struct e820map e820; |
38 | |||
39 | extern int e820_all_mapped(unsigned long start, unsigned long end, | ||
40 | unsigned type); | ||
41 | |||
38 | #endif/*!__ASSEMBLY__*/ | 42 | #endif/*!__ASSEMBLY__*/ |
39 | 43 | ||
40 | #endif/*__E820_HEADER*/ | 44 | #endif/*__E820_HEADER*/ |
diff --git a/include/asm-i386/hpet.h b/include/asm-i386/hpet.h index 16ef9f996e3f..7f1a8a6ee32f 100644 --- a/include/asm-i386/hpet.h +++ b/include/asm-i386/hpet.h | |||
@@ -89,6 +89,7 @@ | |||
89 | * then 32 bit HPET counter wrapsaround in less than 0.5 sec. | 89 | * then 32 bit HPET counter wrapsaround in less than 0.5 sec. |
90 | */ | 90 | */ |
91 | #define HPET_MIN_PERIOD (100000UL) | 91 | #define HPET_MIN_PERIOD (100000UL) |
92 | #define HPET_TICK_RATE (HZ * 100000UL) | ||
92 | 93 | ||
93 | extern unsigned long hpet_tick; /* hpet clks count per tick */ | 94 | extern unsigned long hpet_tick; /* hpet clks count per tick */ |
94 | extern unsigned long hpet_address; /* hpet memory map physical address */ | 95 | extern unsigned long hpet_address; /* hpet memory map physical address */ |
diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index 62113d3bfdc2..770bf6da8c3d 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h | |||
@@ -18,7 +18,6 @@ extern void find_smp_config (void); | |||
18 | extern void get_smp_config (void); | 18 | extern void get_smp_config (void); |
19 | extern int nr_ioapics; | 19 | extern int nr_ioapics; |
20 | extern int apic_version [MAX_APICS]; | 20 | extern int apic_version [MAX_APICS]; |
21 | extern int mp_bus_id_to_type [MAX_MP_BUSSES]; | ||
22 | extern int mp_irq_entries; | 21 | extern int mp_irq_entries; |
23 | extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; | 22 | extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; |
24 | extern int mpc_default_type; | 23 | extern int mpc_default_type; |
diff --git a/include/asm-i386/numnodes.h b/include/asm-i386/numnodes.h deleted file mode 100644 index a61f38c8176f..000000000000 --- a/include/asm-i386/numnodes.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | #ifndef _ASM_MAX_NUMNODES_H | ||
2 | #define _ASM_MAX_NUMNODES_H | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | |||
6 | #ifdef CONFIG_X86_NUMAQ | ||
7 | |||
8 | /* Max 16 Nodes */ | ||
9 | #define NODES_SHIFT 4 | ||
10 | |||
11 | #elif defined(CONFIG_ACPI_SRAT) | ||
12 | |||
13 | /* Max 8 Nodes */ | ||
14 | #define NODES_SHIFT 3 | ||
15 | |||
16 | #endif /* CONFIG_X86_NUMAQ */ | ||
17 | |||
18 | #endif /* _ASM_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 2e7f3e257fdd..6a8dd83c350f 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h | |||
@@ -288,7 +288,7 @@ | |||
288 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 288 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
289 | #define __NR_mq_notify (__NR_mq_open+4) | 289 | #define __NR_mq_notify (__NR_mq_open+4) |
290 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 290 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
291 | #define __NR_sys_kexec_load 283 | 291 | #define __NR_kexec_load 283 |
292 | #define __NR_waitid 284 | 292 | #define __NR_waitid 284 |
293 | /* #define __NR_sys_setaltroot 285 */ | 293 | /* #define __NR_sys_setaltroot 285 */ |
294 | #define __NR_add_key 286 | 294 | #define __NR_add_key 286 |
@@ -318,8 +318,8 @@ | |||
318 | #define __NR_unshare 310 | 318 | #define __NR_unshare 310 |
319 | #define __NR_set_robust_list 311 | 319 | #define __NR_set_robust_list 311 |
320 | #define __NR_get_robust_list 312 | 320 | #define __NR_get_robust_list 312 |
321 | #define __NR_sys_splice 313 | 321 | #define __NR_splice 313 |
322 | #define __NR_sys_sync_file_range 314 | 322 | #define __NR_sync_file_range 314 |
323 | 323 | ||
324 | #define NR_syscalls 315 | 324 | #define NR_syscalls 315 |
325 | 325 | ||
diff --git a/include/asm-ia64/acpi-ext.h b/include/asm-ia64/acpi-ext.h index 56d2ddc97b30..734d137dda6e 100644 --- a/include/asm-ia64/acpi-ext.h +++ b/include/asm-ia64/acpi-ext.h | |||
@@ -1,12 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * ia64/platform/hp/common/hp_acpi.h | 2 | * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P. |
3 | * Alex Williamson <alex.williamson@hp.com> | ||
4 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
3 | * | 5 | * |
4 | * Copyright (C) 2003 Hewlett-Packard | 6 | * This program is free software; you can redistribute it and/or modify |
5 | * Copyright (C) Alex Williamson | 7 | * it under the terms of the GNU General Public License version 2 as |
6 | * Copyright (C) Bjorn Helgaas | 8 | * published by the Free Software Foundation. |
7 | * | 9 | * |
8 | * Vendor specific extensions to ACPI. | 10 | * Vendor specific extensions to ACPI. |
9 | */ | 11 | */ |
12 | |||
10 | #ifndef _ASM_IA64_ACPI_EXT_H | 13 | #ifndef _ASM_IA64_ACPI_EXT_H |
11 | #define _ASM_IA64_ACPI_EXT_H | 14 | #define _ASM_IA64_ACPI_EXT_H |
12 | 15 | ||
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h index 218c458ab60c..c195a9ad1255 100644 --- a/include/asm-ia64/kdebug.h +++ b/include/asm-ia64/kdebug.h | |||
@@ -58,6 +58,8 @@ enum die_val { | |||
58 | DIE_MCA_RENDZVOUS_ENTER, | 58 | DIE_MCA_RENDZVOUS_ENTER, |
59 | DIE_MCA_RENDZVOUS_PROCESS, | 59 | DIE_MCA_RENDZVOUS_PROCESS, |
60 | DIE_MCA_RENDZVOUS_LEAVE, | 60 | DIE_MCA_RENDZVOUS_LEAVE, |
61 | DIE_MCA_NEW_TIMEOUT, | ||
62 | DIE_INIT_ENTER, | ||
61 | DIE_INIT_MONARCH_ENTER, | 63 | DIE_INIT_MONARCH_ENTER, |
62 | DIE_INIT_MONARCH_PROCESS, | 64 | DIE_INIT_MONARCH_PROCESS, |
63 | DIE_INIT_MONARCH_LEAVE, | 65 | DIE_INIT_MONARCH_LEAVE, |
diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h index bfbbb8da79c7..9c5389b7e623 100644 --- a/include/asm-ia64/mca.h +++ b/include/asm-ia64/mca.h | |||
@@ -148,6 +148,11 @@ extern int ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *) | |||
148 | extern void ia64_unreg_MCA_extension(void); | 148 | extern void ia64_unreg_MCA_extension(void); |
149 | extern u64 ia64_get_rnat(u64 *); | 149 | extern u64 ia64_get_rnat(u64 *); |
150 | 150 | ||
151 | struct ia64_mca_notify_die { | ||
152 | struct ia64_sal_os_state *sos; | ||
153 | int *monarch_cpu; | ||
154 | }; | ||
155 | |||
151 | #else /* __ASSEMBLY__ */ | 156 | #else /* __ASSEMBLY__ */ |
152 | 157 | ||
153 | #define IA64_MCA_CORRECTED 0x0 /* Error has been corrected by OS_MCA */ | 158 | #define IA64_MCA_CORRECTED 0x0 /* Error has been corrected by OS_MCA */ |
diff --git a/include/asm-ia64/mutex.h b/include/asm-ia64/mutex.h index 5a3224f6af38..bed73a643a56 100644 --- a/include/asm-ia64/mutex.h +++ b/include/asm-ia64/mutex.h | |||
@@ -84,7 +84,7 @@ __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) | |||
84 | static inline int | 84 | static inline int |
85 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | 85 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) |
86 | { | 86 | { |
87 | if (likely(cmpxchg_acq(count, 1, 0)) == 1) | 87 | if (cmpxchg_acq(count, 1, 0) == 1) |
88 | return 1; | 88 | return 1; |
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
diff --git a/include/asm-ia64/numnodes.h b/include/asm-ia64/numnodes.h deleted file mode 100644 index e9d356f549d9..000000000000 --- a/include/asm-ia64/numnodes.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | #ifndef _ASM_MAX_NUMNODES_H | ||
2 | #define _ASM_MAX_NUMNODES_H | ||
3 | |||
4 | #ifdef CONFIG_IA64_DIG | ||
5 | /* Max 8 Nodes */ | ||
6 | # define NODES_SHIFT 3 | ||
7 | #elif defined(CONFIG_IA64_HP_ZX1) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB) | ||
8 | /* Max 32 Nodes */ | ||
9 | # define NODES_SHIFT 5 | ||
10 | #elif defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) | ||
11 | # if CONFIG_IA64_NR_NODES == 256 | ||
12 | # define NODES_SHIFT 8 | ||
13 | # elif CONFIG_IA64_NR_NODES <= 512 | ||
14 | # define NODES_SHIFT 9 | ||
15 | # elif CONFIG_IA64_NR_NODES <= 1024 | ||
16 | # define NODES_SHIFT 10 | ||
17 | # endif | ||
18 | #endif | ||
19 | |||
20 | #endif /* _ASM_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index 36070c1014d8..1c749acca021 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h | |||
@@ -286,12 +286,15 @@ | |||
286 | /* 1294, 1295 reserved for pselect/ppoll */ | 286 | /* 1294, 1295 reserved for pselect/ppoll */ |
287 | #define __NR_unshare 1296 | 287 | #define __NR_unshare 1296 |
288 | #define __NR_splice 1297 | 288 | #define __NR_splice 1297 |
289 | #define __NR_set_robust_list 1298 | ||
290 | #define __NR_get_robust_list 1299 | ||
291 | #define __NR_sync_file_range 1300 | ||
289 | 292 | ||
290 | #ifdef __KERNEL__ | 293 | #ifdef __KERNEL__ |
291 | 294 | ||
292 | #include <linux/config.h> | 295 | #include <linux/config.h> |
293 | 296 | ||
294 | #define NR_syscalls 274 /* length of syscall table */ | 297 | #define NR_syscalls 277 /* length of syscall table */ |
295 | 298 | ||
296 | #define __ARCH_WANT_SYS_RT_SIGACTION | 299 | #define __ARCH_WANT_SYS_RT_SIGACTION |
297 | 300 | ||
diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h index bc3349ffc505..091177cda223 100644 --- a/include/asm-ia64/vga.h +++ b/include/asm-ia64/vga.h | |||
@@ -17,7 +17,7 @@ | |||
17 | extern unsigned long vga_console_iobase; | 17 | extern unsigned long vga_console_iobase; |
18 | extern unsigned long vga_console_membase; | 18 | extern unsigned long vga_console_membase; |
19 | 19 | ||
20 | #define VGA_MAP_MEM(x) ((unsigned long) ioremap(vga_console_membase + (x), 0)) | 20 | #define VGA_MAP_MEM(x) ((unsigned long) ioremap_nocache(vga_console_membase + (x), 0)) |
21 | 21 | ||
22 | #define vga_readb(x) (*(x)) | 22 | #define vga_readb(x) (*(x)) |
23 | #define vga_writeb(x,y) (*(y) = (x)) | 23 | #define vga_writeb(x,y) (*(y) = (x)) |
diff --git a/include/asm-m32r/numnodes.h b/include/asm-m32r/numnodes.h deleted file mode 100644 index 479a39d49f83..000000000000 --- a/include/asm-m32r/numnodes.h +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | #ifndef _ASM_NUMNODES_H_ | ||
2 | #define _ASM_NUMNODES_H_ | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | |||
6 | #ifdef CONFIG_DISCONTIGMEM | ||
7 | |||
8 | #if defined(CONFIG_CHIP_M32700) | ||
9 | #define NODES_SHIFT 1 /* Max 2 Nodes */ | ||
10 | #endif /* CONFIG_CHIP_M32700 */ | ||
11 | |||
12 | #endif /* CONFIG_DISCONTIGMEM */ | ||
13 | |||
14 | #endif /* _ASM_NUMNODES_H_ */ | ||
15 | |||
diff --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h index 7885b7df84a2..1184293e5712 100644 --- a/include/asm-m32r/smp.h +++ b/include/asm-m32r/smp.h | |||
@@ -67,7 +67,8 @@ extern volatile int cpu_2_physid[NR_CPUS]; | |||
67 | #define raw_smp_processor_id() (current_thread_info()->cpu) | 67 | #define raw_smp_processor_id() (current_thread_info()->cpu) |
68 | 68 | ||
69 | extern cpumask_t cpu_callout_map; | 69 | extern cpumask_t cpu_callout_map; |
70 | #define cpu_possible_map cpu_callout_map | 70 | extern cpumask_t cpu_possible_map; |
71 | extern cpumask_t cpu_present_map; | ||
71 | 72 | ||
72 | static __inline__ int hard_smp_processor_id(void) | 73 | static __inline__ int hard_smp_processor_id(void) |
73 | { | 74 | { |
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h index d6a2c613be68..c5ab5da56d21 100644 --- a/include/asm-m32r/system.h +++ b/include/asm-m32r/system.h | |||
@@ -22,10 +22,6 @@ | |||
22 | * `next' and `prev' should be struct task_struct, but it isn't always defined | 22 | * `next' and `prev' should be struct task_struct, but it isn't always defined |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifndef CONFIG_SMP | ||
26 | #define prepare_to_switch() do { } while(0) | ||
27 | #endif /* not CONFIG_SMP */ | ||
28 | |||
29 | #define switch_to(prev, next, last) do { \ | 25 | #define switch_to(prev, next, last) do { \ |
30 | register unsigned long arg0 __asm__ ("r0") = (unsigned long)prev; \ | 26 | register unsigned long arg0 __asm__ ("r0") = (unsigned long)prev; \ |
31 | register unsigned long arg1 __asm__ ("r1") = (unsigned long)next; \ | 27 | register unsigned long arg1 __asm__ ("r1") = (unsigned long)next; \ |
diff --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h index e8ae61956a51..819cc28a94f7 100644 --- a/include/asm-m32r/uaccess.h +++ b/include/asm-m32r/uaccess.h | |||
@@ -5,17 +5,9 @@ | |||
5 | * linux/include/asm-m32r/uaccess.h | 5 | * linux/include/asm-m32r/uaccess.h |
6 | * | 6 | * |
7 | * M32R version. | 7 | * M32R version. |
8 | * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> | 8 | * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #undef UACCESS_DEBUG | ||
12 | |||
13 | #ifdef UACCESS_DEBUG | ||
14 | #define UAPRINTK(args...) printk(args) | ||
15 | #else | ||
16 | #define UAPRINTK(args...) | ||
17 | #endif /* UACCESS_DEBUG */ | ||
18 | |||
19 | /* | 11 | /* |
20 | * User space memory access functions | 12 | * User space memory access functions |
21 | */ | 13 | */ |
@@ -38,27 +30,29 @@ | |||
38 | #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) | 30 | #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) |
39 | 31 | ||
40 | #ifdef CONFIG_MMU | 32 | #ifdef CONFIG_MMU |
33 | |||
41 | #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) | 34 | #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) |
42 | #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) | 35 | #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) |
43 | #else | ||
44 | #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) | ||
45 | #define USER_DS MAKE_MM_SEG(0xFFFFFFFF) | ||
46 | #endif /* CONFIG_MMU */ | ||
47 | |||
48 | #define get_ds() (KERNEL_DS) | 36 | #define get_ds() (KERNEL_DS) |
49 | #ifdef CONFIG_MMU | ||
50 | #define get_fs() (current_thread_info()->addr_limit) | 37 | #define get_fs() (current_thread_info()->addr_limit) |
51 | #define set_fs(x) (current_thread_info()->addr_limit = (x)) | 38 | #define set_fs(x) (current_thread_info()->addr_limit = (x)) |
52 | #else | 39 | |
40 | #else /* not CONFIG_MMU */ | ||
41 | |||
42 | #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) | ||
43 | #define USER_DS MAKE_MM_SEG(0xFFFFFFFF) | ||
44 | #define get_ds() (KERNEL_DS) | ||
45 | |||
53 | static inline mm_segment_t get_fs(void) | 46 | static inline mm_segment_t get_fs(void) |
54 | { | 47 | { |
55 | return USER_DS; | 48 | return USER_DS; |
56 | } | 49 | } |
57 | 50 | ||
58 | static inline void set_fs(mm_segment_t s) | 51 | static inline void set_fs(mm_segment_t s) |
59 | { | 52 | { |
60 | } | 53 | } |
61 | #endif /* CONFIG_MMU */ | 54 | |
55 | #endif /* not CONFIG_MMU */ | ||
62 | 56 | ||
63 | #define segment_eq(a,b) ((a).seg == (b).seg) | 57 | #define segment_eq(a,b) ((a).seg == (b).seg) |
64 | 58 | ||
@@ -83,9 +77,9 @@ static inline void set_fs(mm_segment_t s) | |||
83 | " subx %0, %0\n" \ | 77 | " subx %0, %0\n" \ |
84 | " cmpu %4, %1\n" \ | 78 | " cmpu %4, %1\n" \ |
85 | " subx %0, %5\n" \ | 79 | " subx %0, %5\n" \ |
86 | : "=&r"(flag), "=r"(sum) \ | 80 | : "=&r" (flag), "=r" (sum) \ |
87 | : "1"(addr), "r"((int)(size)), \ | 81 | : "1" (addr), "r" ((int)(size)), \ |
88 | "r"(current_thread_info()->addr_limit.seg), "r"(0) \ | 82 | "r" (current_thread_info()->addr_limit.seg), "r" (0) \ |
89 | : "cbit" ); \ | 83 | : "cbit" ); \ |
90 | flag; }) | 84 | flag; }) |
91 | 85 | ||
@@ -113,10 +107,10 @@ static inline void set_fs(mm_segment_t s) | |||
113 | #else | 107 | #else |
114 | static inline int access_ok(int type, const void *addr, unsigned long size) | 108 | static inline int access_ok(int type, const void *addr, unsigned long size) |
115 | { | 109 | { |
116 | extern unsigned long memory_start, memory_end; | 110 | extern unsigned long memory_start, memory_end; |
117 | unsigned long val = (unsigned long)addr; | 111 | unsigned long val = (unsigned long)addr; |
118 | 112 | ||
119 | return ((val >= memory_start) && ((val + size) < memory_end)); | 113 | return ((val >= memory_start) && ((val + size) < memory_end)); |
120 | } | 114 | } |
121 | #endif /* CONFIG_MMU */ | 115 | #endif /* CONFIG_MMU */ |
122 | 116 | ||
@@ -155,39 +149,6 @@ extern int fixup_exception(struct pt_regs *regs); | |||
155 | * accesses to the same area of user memory). | 149 | * accesses to the same area of user memory). |
156 | */ | 150 | */ |
157 | 151 | ||
158 | extern void __get_user_1(void); | ||
159 | extern void __get_user_2(void); | ||
160 | extern void __get_user_4(void); | ||
161 | |||
162 | #ifndef MODULE | ||
163 | #define __get_user_x(size,ret,x,ptr) \ | ||
164 | __asm__ __volatile__( \ | ||
165 | " mv r0, %0\n" \ | ||
166 | " mv r1, %1\n" \ | ||
167 | " bl __get_user_" #size "\n" \ | ||
168 | " mv %0, r0\n" \ | ||
169 | " mv %1, r1\n" \ | ||
170 | : "=r"(ret), "=r"(x) \ | ||
171 | : "0"(ptr) \ | ||
172 | : "r0", "r1", "r14" ) | ||
173 | #else /* MODULE */ | ||
174 | /* | ||
175 | * Use "jl" instead of "bl" for MODULE | ||
176 | */ | ||
177 | #define __get_user_x(size,ret,x,ptr) \ | ||
178 | __asm__ __volatile__( \ | ||
179 | " mv r0, %0\n" \ | ||
180 | " mv r1, %1\n" \ | ||
181 | " seth lr, #high(__get_user_" #size ")\n" \ | ||
182 | " or3 lr, lr, #low(__get_user_" #size ")\n" \ | ||
183 | " jl lr\n" \ | ||
184 | " mv %0, r0\n" \ | ||
185 | " mv %1, r1\n" \ | ||
186 | : "=r"(ret), "=r"(x) \ | ||
187 | : "0"(ptr) \ | ||
188 | : "r0", "r1", "r14" ) | ||
189 | #endif | ||
190 | |||
191 | /* Careful: we have to cast the result to the type of the pointer for sign | 152 | /* Careful: we have to cast the result to the type of the pointer for sign |
192 | reasons */ | 153 | reasons */ |
193 | /** | 154 | /** |
@@ -208,20 +169,7 @@ extern void __get_user_4(void); | |||
208 | * On error, the variable @x is set to zero. | 169 | * On error, the variable @x is set to zero. |
209 | */ | 170 | */ |
210 | #define get_user(x,ptr) \ | 171 | #define get_user(x,ptr) \ |
211 | ({ int __ret_gu; \ | 172 | __get_user_check((x),(ptr),sizeof(*(ptr))) |
212 | unsigned long __val_gu; \ | ||
213 | __chk_user_ptr(ptr); \ | ||
214 | switch(sizeof (*(ptr))) { \ | ||
215 | case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ | ||
216 | case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ | ||
217 | case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \ | ||
218 | default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \ | ||
219 | } \ | ||
220 | (x) = (__typeof__(*(ptr)))__val_gu; \ | ||
221 | __ret_gu; \ | ||
222 | }) | ||
223 | |||
224 | extern void __put_user_bad(void); | ||
225 | 173 | ||
226 | /** | 174 | /** |
227 | * put_user: - Write a simple value into user space. | 175 | * put_user: - Write a simple value into user space. |
@@ -240,8 +188,7 @@ extern void __put_user_bad(void); | |||
240 | * Returns zero on success, or -EFAULT on error. | 188 | * Returns zero on success, or -EFAULT on error. |
241 | */ | 189 | */ |
242 | #define put_user(x,ptr) \ | 190 | #define put_user(x,ptr) \ |
243 | __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) | 191 | __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) |
244 | |||
245 | 192 | ||
246 | /** | 193 | /** |
247 | * __get_user: - Get a simple variable from user space, with less checking. | 194 | * __get_user: - Get a simple variable from user space, with less checking. |
@@ -264,8 +211,64 @@ extern void __put_user_bad(void); | |||
264 | * On error, the variable @x is set to zero. | 211 | * On error, the variable @x is set to zero. |
265 | */ | 212 | */ |
266 | #define __get_user(x,ptr) \ | 213 | #define __get_user(x,ptr) \ |
267 | __get_user_nocheck((x),(ptr),sizeof(*(ptr))) | 214 | __get_user_nocheck((x),(ptr),sizeof(*(ptr))) |
268 | 215 | ||
216 | #define __get_user_nocheck(x,ptr,size) \ | ||
217 | ({ \ | ||
218 | long __gu_err = 0; \ | ||
219 | unsigned long __gu_val; \ | ||
220 | might_sleep(); \ | ||
221 | __get_user_size(__gu_val,(ptr),(size),__gu_err); \ | ||
222 | (x) = (__typeof__(*(ptr)))__gu_val; \ | ||
223 | __gu_err; \ | ||
224 | }) | ||
225 | |||
226 | #define __get_user_check(x,ptr,size) \ | ||
227 | ({ \ | ||
228 | long __gu_err = -EFAULT; \ | ||
229 | unsigned long __gu_val = 0; \ | ||
230 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ | ||
231 | might_sleep(); \ | ||
232 | if (access_ok(VERIFY_READ,__gu_addr,size)) \ | ||
233 | __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ | ||
234 | (x) = (__typeof__(*(ptr)))__gu_val; \ | ||
235 | __gu_err; \ | ||
236 | }) | ||
237 | |||
238 | extern long __get_user_bad(void); | ||
239 | |||
240 | #define __get_user_size(x,ptr,size,retval) \ | ||
241 | do { \ | ||
242 | retval = 0; \ | ||
243 | __chk_user_ptr(ptr); \ | ||
244 | switch (size) { \ | ||
245 | case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ | ||
246 | case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ | ||
247 | case 4: __get_user_asm(x,ptr,retval,""); break; \ | ||
248 | default: (x) = __get_user_bad(); \ | ||
249 | } \ | ||
250 | } while (0) | ||
251 | |||
252 | #define __get_user_asm(x, addr, err, itype) \ | ||
253 | __asm__ __volatile__( \ | ||
254 | " .fillinsn\n" \ | ||
255 | "1: ld"itype" %1,@%2\n" \ | ||
256 | " .fillinsn\n" \ | ||
257 | "2:\n" \ | ||
258 | ".section .fixup,\"ax\"\n" \ | ||
259 | " .balign 4\n" \ | ||
260 | "3: ldi %0,%3\n" \ | ||
261 | " seth r14,#high(2b)\n" \ | ||
262 | " or3 r14,r14,#low(2b)\n" \ | ||
263 | " jmp r14\n" \ | ||
264 | ".previous\n" \ | ||
265 | ".section __ex_table,\"a\"\n" \ | ||
266 | " .balign 4\n" \ | ||
267 | " .long 1b,3b\n" \ | ||
268 | ".previous" \ | ||
269 | : "=&r" (err), "=&r" (x) \ | ||
270 | : "r" (addr), "i" (-EFAULT), "0" (err) \ | ||
271 | : "r14", "memory") | ||
269 | 272 | ||
270 | /** | 273 | /** |
271 | * __put_user: - Write a simple value into user space, with less checking. | 274 | * __put_user: - Write a simple value into user space, with less checking. |
@@ -287,11 +290,13 @@ extern void __put_user_bad(void); | |||
287 | * Returns zero on success, or -EFAULT on error. | 290 | * Returns zero on success, or -EFAULT on error. |
288 | */ | 291 | */ |
289 | #define __put_user(x,ptr) \ | 292 | #define __put_user(x,ptr) \ |
290 | __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) | 293 | __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) |
294 | |||
291 | 295 | ||
292 | #define __put_user_nocheck(x,ptr,size) \ | 296 | #define __put_user_nocheck(x,ptr,size) \ |
293 | ({ \ | 297 | ({ \ |
294 | long __pu_err; \ | 298 | long __pu_err; \ |
299 | might_sleep(); \ | ||
295 | __put_user_size((x),(ptr),(size),__pu_err); \ | 300 | __put_user_size((x),(ptr),(size),__pu_err); \ |
296 | __pu_err; \ | 301 | __pu_err; \ |
297 | }) | 302 | }) |
@@ -308,28 +313,28 @@ extern void __put_user_bad(void); | |||
308 | }) | 313 | }) |
309 | 314 | ||
310 | #if defined(__LITTLE_ENDIAN__) | 315 | #if defined(__LITTLE_ENDIAN__) |
311 | #define __put_user_u64(x, addr, err) \ | 316 | #define __put_user_u64(x, addr, err) \ |
312 | __asm__ __volatile__( \ | 317 | __asm__ __volatile__( \ |
313 | " .fillinsn\n" \ | 318 | " .fillinsn\n" \ |
314 | "1: st %L1,@%2\n" \ | 319 | "1: st %L1,@%2\n" \ |
315 | " .fillinsn\n" \ | 320 | " .fillinsn\n" \ |
316 | "2: st %H1,@(4,%2)\n" \ | 321 | "2: st %H1,@(4,%2)\n" \ |
317 | " .fillinsn\n" \ | 322 | " .fillinsn\n" \ |
318 | "3:\n" \ | 323 | "3:\n" \ |
319 | ".section .fixup,\"ax\"\n" \ | 324 | ".section .fixup,\"ax\"\n" \ |
320 | " .balign 4\n" \ | 325 | " .balign 4\n" \ |
321 | "4: ldi %0,%3\n" \ | 326 | "4: ldi %0,%3\n" \ |
322 | " seth r14,#high(3b)\n" \ | 327 | " seth r14,#high(3b)\n" \ |
323 | " or3 r14,r14,#low(3b)\n" \ | 328 | " or3 r14,r14,#low(3b)\n" \ |
324 | " jmp r14\n" \ | 329 | " jmp r14\n" \ |
325 | ".previous\n" \ | 330 | ".previous\n" \ |
326 | ".section __ex_table,\"a\"\n" \ | 331 | ".section __ex_table,\"a\"\n" \ |
327 | " .balign 4\n" \ | 332 | " .balign 4\n" \ |
328 | " .long 1b,4b\n" \ | 333 | " .long 1b,4b\n" \ |
329 | " .long 2b,4b\n" \ | 334 | " .long 2b,4b\n" \ |
330 | ".previous" \ | 335 | ".previous" \ |
331 | : "=&r"(err) \ | 336 | : "=&r" (err) \ |
332 | : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ | 337 | : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ |
333 | : "r14", "memory") | 338 | : "r14", "memory") |
334 | 339 | ||
335 | #elif defined(__BIG_ENDIAN__) | 340 | #elif defined(__BIG_ENDIAN__) |
@@ -353,13 +358,15 @@ extern void __put_user_bad(void); | |||
353 | " .long 1b,4b\n" \ | 358 | " .long 1b,4b\n" \ |
354 | " .long 2b,4b\n" \ | 359 | " .long 2b,4b\n" \ |
355 | ".previous" \ | 360 | ".previous" \ |
356 | : "=&r"(err) \ | 361 | : "=&r" (err) \ |
357 | : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ | 362 | : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ |
358 | : "r14", "memory") | 363 | : "r14", "memory") |
359 | #else | 364 | #else |
360 | #error no endian defined | 365 | #error no endian defined |
361 | #endif | 366 | #endif |
362 | 367 | ||
368 | extern void __put_user_bad(void); | ||
369 | |||
363 | #define __put_user_size(x,ptr,size,retval) \ | 370 | #define __put_user_size(x,ptr,size,retval) \ |
364 | do { \ | 371 | do { \ |
365 | retval = 0; \ | 372 | retval = 0; \ |
@@ -398,52 +405,8 @@ struct __large_struct { unsigned long buf[100]; }; | |||
398 | " .balign 4\n" \ | 405 | " .balign 4\n" \ |
399 | " .long 1b,3b\n" \ | 406 | " .long 1b,3b\n" \ |
400 | ".previous" \ | 407 | ".previous" \ |
401 | : "=&r"(err) \ | 408 | : "=&r" (err) \ |
402 | : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ | 409 | : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ |
403 | : "r14", "memory") | ||
404 | |||
405 | #define __get_user_nocheck(x,ptr,size) \ | ||
406 | ({ \ | ||
407 | long __gu_err; \ | ||
408 | unsigned long __gu_val; \ | ||
409 | __get_user_size(__gu_val,(ptr),(size),__gu_err); \ | ||
410 | (x) = (__typeof__(*(ptr)))__gu_val; \ | ||
411 | __gu_err; \ | ||
412 | }) | ||
413 | |||
414 | extern long __get_user_bad(void); | ||
415 | |||
416 | #define __get_user_size(x,ptr,size,retval) \ | ||
417 | do { \ | ||
418 | retval = 0; \ | ||
419 | __chk_user_ptr(ptr); \ | ||
420 | switch (size) { \ | ||
421 | case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ | ||
422 | case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ | ||
423 | case 4: __get_user_asm(x,ptr,retval,""); break; \ | ||
424 | default: (x) = __get_user_bad(); \ | ||
425 | } \ | ||
426 | } while (0) | ||
427 | |||
428 | #define __get_user_asm(x, addr, err, itype) \ | ||
429 | __asm__ __volatile__( \ | ||
430 | " .fillinsn\n" \ | ||
431 | "1: ld"itype" %1,@%2\n" \ | ||
432 | " .fillinsn\n" \ | ||
433 | "2:\n" \ | ||
434 | ".section .fixup,\"ax\"\n" \ | ||
435 | " .balign 4\n" \ | ||
436 | "3: ldi %0,%3\n" \ | ||
437 | " seth r14,#high(2b)\n" \ | ||
438 | " or3 r14,r14,#low(2b)\n" \ | ||
439 | " jmp r14\n" \ | ||
440 | ".previous\n" \ | ||
441 | ".section __ex_table,\"a\"\n" \ | ||
442 | " .balign 4\n" \ | ||
443 | " .long 1b,3b\n" \ | ||
444 | ".previous" \ | ||
445 | : "=&r"(err), "=&r"(x) \ | ||
446 | : "r"(addr), "i"(-EFAULT), "0"(err) \ | ||
447 | : "r14", "memory") | 410 | : "r14", "memory") |
448 | 411 | ||
449 | /* | 412 | /* |
@@ -453,7 +416,6 @@ do { \ | |||
453 | * anything, so this is accurate. | 416 | * anything, so this is accurate. |
454 | */ | 417 | */ |
455 | 418 | ||
456 | |||
457 | /* | 419 | /* |
458 | * Copy To/From Userspace | 420 | * Copy To/From Userspace |
459 | */ | 421 | */ |
@@ -511,8 +473,9 @@ do { \ | |||
511 | " .long 2b,9b\n" \ | 473 | " .long 2b,9b\n" \ |
512 | " .long 3b,9b\n" \ | 474 | " .long 3b,9b\n" \ |
513 | ".previous\n" \ | 475 | ".previous\n" \ |
514 | : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ | 476 | : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ |
515 | : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ | 477 | "=&r" (__c) \ |
478 | : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ | ||
516 | : "r14", "memory"); \ | 479 | : "r14", "memory"); \ |
517 | } while (0) | 480 | } while (0) |
518 | 481 | ||
@@ -573,8 +536,9 @@ do { \ | |||
573 | " .long 2b,7b\n" \ | 536 | " .long 2b,7b\n" \ |
574 | " .long 3b,7b\n" \ | 537 | " .long 3b,7b\n" \ |
575 | ".previous\n" \ | 538 | ".previous\n" \ |
576 | : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ | 539 | : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ |
577 | : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ | 540 | "=&r" (__c) \ |
541 | : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ | ||
578 | : "r14", "memory"); \ | 542 | : "r14", "memory"); \ |
579 | } while (0) | 543 | } while (0) |
580 | 544 | ||
@@ -676,7 +640,7 @@ unsigned long __generic_copy_from_user(void *, const void __user *, unsigned lon | |||
676 | #define copy_from_user(to,from,n) \ | 640 | #define copy_from_user(to,from,n) \ |
677 | ({ \ | 641 | ({ \ |
678 | might_sleep(); \ | 642 | might_sleep(); \ |
679 | __generic_copy_from_user((to),(from),(n)); \ | 643 | __generic_copy_from_user((to),(from),(n)); \ |
680 | }) | 644 | }) |
681 | 645 | ||
682 | long __must_check strncpy_from_user(char *dst, const char __user *src, | 646 | long __must_check strncpy_from_user(char *dst, const char __user *src, |
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h index 39be87ca2a5a..be0eb014c3b0 100644 --- a/include/asm-m32r/unistd.h +++ b/include/asm-m32r/unistd.h | |||
@@ -292,7 +292,7 @@ | |||
292 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 292 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
293 | #define __NR_mq_notify (__NR_mq_open+4) | 293 | #define __NR_mq_notify (__NR_mq_open+4) |
294 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 294 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
295 | #define __NR_sys_kexec_load 283 | 295 | #define __NR_kexec_load 283 |
296 | #define __NR_waitid 284 | 296 | #define __NR_waitid 284 |
297 | 297 | ||
298 | #define NR_syscalls 285 | 298 | #define NR_syscalls 285 |
diff --git a/include/asm-mips/numnodes.h b/include/asm-mips/numnodes.h deleted file mode 100644 index 4f00c16ceeb0..000000000000 --- a/include/asm-mips/numnodes.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _ASM_MAX_NUMNODES_H | ||
2 | #define _ASM_MAX_NUMNODES_H | ||
3 | |||
4 | /* Max 128 Nodes */ | ||
5 | #define NODES_SHIFT 6 | ||
6 | |||
7 | #endif /* _ASM_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-parisc/numnodes.h b/include/asm-parisc/numnodes.h deleted file mode 100644 index 6c67651efd1c..000000000000 --- a/include/asm-parisc/numnodes.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _ASM_MAX_NUMNODES_H | ||
2 | #define _ASM_MAX_NUMNODES_H | ||
3 | |||
4 | /* Max 8 Nodes */ | ||
5 | #define NODES_SHIFT 3 | ||
6 | |||
7 | #endif /* _ASM_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-powerpc/numnodes.h b/include/asm-powerpc/numnodes.h deleted file mode 100644 index e138edae09dd..000000000000 --- a/include/asm-powerpc/numnodes.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #ifndef _ASM_POWERPC_MAX_NUMNODES_H | ||
2 | #define _ASM_POWERPC_MAX_NUMNODES_H | ||
3 | #ifdef __KERNEL__ | ||
4 | |||
5 | /* Max 16 Nodes */ | ||
6 | #define NODES_SHIFT 4 | ||
7 | |||
8 | #endif /* __KERNEL__ */ | ||
9 | #endif /* _ASM_POWERPC_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index de1d9926aa60..399bf02894dd 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef __ARCH_S390_ATOMIC__ | 1 | #ifndef __ARCH_S390_ATOMIC__ |
2 | #define __ARCH_S390_ATOMIC__ | 2 | #define __ARCH_S390_ATOMIC__ |
3 | 3 | ||
4 | #include <linux/compiler.h> | ||
5 | |||
4 | /* | 6 | /* |
5 | * include/asm-s390/atomic.h | 7 | * include/asm-s390/atomic.h |
6 | * | 8 | * |
diff --git a/include/asm-s390/ebcdic.h b/include/asm-s390/ebcdic.h index 4cbc336e4d60..15fd2eda6c90 100644 --- a/include/asm-s390/ebcdic.h +++ b/include/asm-s390/ebcdic.h | |||
@@ -14,12 +14,12 @@ | |||
14 | #include <types.h> | 14 | #include <types.h> |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | extern __u8 _ascebc_500[]; /* ASCII -> EBCDIC 500 conversion table */ | 17 | extern __u8 _ascebc_500[256]; /* ASCII -> EBCDIC 500 conversion table */ |
18 | extern __u8 _ebcasc_500[]; /* EBCDIC 500 -> ASCII conversion table */ | 18 | extern __u8 _ebcasc_500[256]; /* EBCDIC 500 -> ASCII conversion table */ |
19 | extern __u8 _ascebc[]; /* ASCII -> EBCDIC conversion table */ | 19 | extern __u8 _ascebc[256]; /* ASCII -> EBCDIC conversion table */ |
20 | extern __u8 _ebcasc[]; /* EBCDIC -> ASCII conversion table */ | 20 | extern __u8 _ebcasc[256]; /* EBCDIC -> ASCII conversion table */ |
21 | extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */ | 21 | extern __u8 _ebc_tolower[256]; /* EBCDIC -> lowercase */ |
22 | extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */ | 22 | extern __u8 _ebc_toupper[256]; /* EBCDIC -> uppercase */ |
23 | 23 | ||
24 | static inline void | 24 | static inline void |
25 | codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr) | 25 | codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr) |
diff --git a/include/asm-sh/numnodes.h b/include/asm-sh/numnodes.h deleted file mode 100644 index f73e85b72ecb..000000000000 --- a/include/asm-sh/numnodes.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _ASM_MAX_NUMNODES_H | ||
2 | #define _ASM_MAX_NUMNODES_H | ||
3 | |||
4 | /* Max 2 Nodes */ | ||
5 | #define NODES_SHIFT 1 | ||
6 | |||
7 | #endif /* _ASM_MAX_NUMNODES_H */ | ||
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h index f2c8e14d1fd9..05520cebda12 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h | |||
@@ -290,7 +290,7 @@ | |||
290 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 290 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
291 | #define __NR_mq_notify (__NR_mq_open+4) | 291 | #define __NR_mq_notify (__NR_mq_open+4) |
292 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 292 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
293 | #define __NR_sys_kexec_load 283 | 293 | #define __NR_kexec_load 283 |
294 | #define __NR_waitid 284 | 294 | #define __NR_waitid 284 |
295 | #define __NR_add_key 285 | 295 | #define __NR_add_key 285 |
296 | #define __NR_request_key 286 | 296 | #define __NR_request_key 286 |
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h index 2a1cfa404ea4..1f8f394ae371 100644 --- a/include/asm-sh64/unistd.h +++ b/include/asm-sh64/unistd.h | |||
@@ -333,7 +333,7 @@ | |||
333 | #define __NR_mq_timedreceive (__NR_mq_open+3) | 333 | #define __NR_mq_timedreceive (__NR_mq_open+3) |
334 | #define __NR_mq_notify (__NR_mq_open+4) | 334 | #define __NR_mq_notify (__NR_mq_open+4) |
335 | #define __NR_mq_getsetattr (__NR_mq_open+5) | 335 | #define __NR_mq_getsetattr (__NR_mq_open+5) |
336 | #define __NR_sys_kexec_load 311 | 336 | #define __NR_kexec_load 311 |
337 | #define __NR_waitid 312 | 337 | #define __NR_waitid 312 |
338 | #define __NR_add_key 313 | 338 | #define __NR_add_key 313 |
339 | #define __NR_request_key 314 | 339 | #define __NR_request_key 314 |
diff --git a/include/asm-sparc/vga.h b/include/asm-sparc/vga.h new file mode 100644 index 000000000000..c69d5b2ba19a --- /dev/null +++ b/include/asm-sparc/vga.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Access to VGA videoram | ||
3 | * | ||
4 | * (c) 1998 Martin Mares <mj@ucw.cz> | ||
5 | */ | ||
6 | |||
7 | #ifndef _LINUX_ASM_VGA_H_ | ||
8 | #define _LINUX_ASM_VGA_H_ | ||
9 | |||
10 | #include <asm/types.h> | ||
11 | |||
12 | #define VT_BUF_HAVE_RW | ||
13 | |||
14 | #undef scr_writew | ||
15 | #undef scr_readw | ||
16 | |||
17 | static inline void scr_writew(u16 val, u16 *addr) | ||
18 | { | ||
19 | BUG_ON((long) addr >= 0); | ||
20 | |||
21 | *addr = val; | ||
22 | } | ||
23 | |||
24 | static inline u16 scr_readw(const u16 *addr) | ||
25 | { | ||
26 | BUG_ON((long) addr >= 0); | ||
27 | |||
28 | return *addr; | ||
29 | } | ||
30 | |||
31 | #define VGA_MAP_MEM(x,s) (x) | ||
32 | |||
33 | #endif | ||
diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h index 82032e159a76..baef13b58952 100644 --- a/include/asm-sparc64/percpu.h +++ b/include/asm-sparc64/percpu.h | |||
@@ -26,7 +26,7 @@ register unsigned long __local_per_cpu_offset asm("g5"); | |||
26 | #define percpu_modcopy(pcpudst, src, size) \ | 26 | #define percpu_modcopy(pcpudst, src, size) \ |
27 | do { \ | 27 | do { \ |
28 | unsigned int __i; \ | 28 | unsigned int __i; \ |
29 | for_each_cpu(__i) \ | 29 | for_each_possible_cpu(__i) \ |
30 | memcpy((pcpudst)+__per_cpu_offset(__i), \ | 30 | memcpy((pcpudst)+__per_cpu_offset(__i), \ |
31 | (src), (size)); \ | 31 | (src), (size)); \ |
32 | } while (0) | 32 | } while (0) |
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h index 30656c962d74..6e2528bb0083 100644 --- a/include/asm-um/ptrace-i386.h +++ b/include/asm-um/ptrace-i386.h | |||
@@ -56,6 +56,9 @@ extern int do_get_thread_area_tt(struct user_desc *info); | |||
56 | extern int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to); | 56 | extern int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to); |
57 | extern int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to); | 57 | extern int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to); |
58 | 58 | ||
59 | extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to); | ||
60 | extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to); | ||
61 | |||
59 | static inline int do_get_thread_area(struct user_desc *info) | 62 | static inline int do_get_thread_area(struct user_desc *info) |
60 | { | 63 | { |
61 | return CHOOSE_MODE_PROC(do_get_thread_area_tt, do_get_thread_area_skas, info); | 64 | return CHOOSE_MODE_PROC(do_get_thread_area_tt, do_get_thread_area_skas, info); |
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h index 107decbd6e6c..7091af4b7866 100644 --- a/include/asm-v850/system.h +++ b/include/asm-v850/system.h | |||
@@ -18,8 +18,6 @@ | |||
18 | #include <asm/ptrace.h> | 18 | #include <asm/ptrace.h> |
19 | 19 | ||
20 | 20 | ||
21 | #define prepare_to_switch() do { } while (0) | ||
22 | |||
23 | /* | 21 | /* |
24 | * switch_to(n) should switch tasks to task ptr, first checking that | 22 | * switch_to(n) should switch tasks to task ptr, first checking that |
25 | * ptr isn't the current task, in which case it does nothing. | 23 | * ptr isn't the current task, in which case it does nothing. |
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h index 8dcc32665240..93b51df51687 100644 --- a/include/asm-x86_64/e820.h +++ b/include/asm-x86_64/e820.h | |||
@@ -47,7 +47,8 @@ extern void contig_e820_setup(void); | |||
47 | extern unsigned long e820_end_of_ram(void); | 47 | extern unsigned long e820_end_of_ram(void); |
48 | extern void e820_reserve_resources(void); | 48 | extern void e820_reserve_resources(void); |
49 | extern void e820_print_map(char *who); | 49 | extern void e820_print_map(char *who); |
50 | extern int e820_mapped(unsigned long start, unsigned long end, unsigned type); | 50 | extern int e820_any_mapped(unsigned long start, unsigned long end, unsigned type); |
51 | extern int e820_all_mapped(unsigned long start, unsigned long end, unsigned type); | ||
51 | 52 | ||
52 | extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end); | 53 | extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end); |
53 | extern void e820_setup_gap(void); | 54 | extern void e820_setup_gap(void); |
diff --git a/include/asm-x86_64/hpet.h b/include/asm-x86_64/hpet.h index 08b75c15269a..18ff7ee9e774 100644 --- a/include/asm-x86_64/hpet.h +++ b/include/asm-x86_64/hpet.h | |||
@@ -51,6 +51,8 @@ | |||
51 | 51 | ||
52 | #define HPET_TN_ROUTE_SHIFT 9 | 52 | #define HPET_TN_ROUTE_SHIFT 9 |
53 | 53 | ||
54 | #define HPET_TICK_RATE (HZ * 100000UL) | ||
55 | |||
54 | extern int is_hpet_enabled(void); | 56 | extern int is_hpet_enabled(void); |
55 | extern int hpet_rtc_timer_init(void); | 57 | extern int hpet_rtc_timer_init(void); |
56 | extern int oem_force_hpet_timer(void); | 58 | extern int oem_force_hpet_timer(void); |
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h index eeb2bcd635de..b4f4b172b15a 100644 --- a/include/asm-x86_64/ia32_unistd.h +++ b/include/asm-x86_64/ia32_unistd.h | |||
@@ -317,6 +317,4 @@ | |||
317 | #define __NR_ia32_ppoll 309 | 317 | #define __NR_ia32_ppoll 309 |
318 | #define __NR_ia32_unshare 310 | 318 | #define __NR_ia32_unshare 310 |
319 | 319 | ||
320 | #define IA32_NR_syscalls 315 /* must be > than biggest syscall! */ | ||
321 | |||
322 | #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ | 320 | #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ |
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h index cafdfb37f0d8..a05da8a50bfd 100644 --- a/include/asm-x86_64/io.h +++ b/include/asm-x86_64/io.h | |||
@@ -177,7 +177,7 @@ static inline __u16 __readw(const volatile void __iomem *addr) | |||
177 | { | 177 | { |
178 | return *(__force volatile __u16 *)addr; | 178 | return *(__force volatile __u16 *)addr; |
179 | } | 179 | } |
180 | static inline __u32 __readl(const volatile void __iomem *addr) | 180 | static __always_inline __u32 __readl(const volatile void __iomem *addr) |
181 | { | 181 | { |
182 | return *(__force volatile __u32 *)addr; | 182 | return *(__force volatile __u32 *)addr; |
183 | } | 183 | } |
diff --git a/include/asm-x86_64/mce.h b/include/asm-x86_64/mce.h index 5d298b799a9f..7229785094e3 100644 --- a/include/asm-x86_64/mce.h +++ b/include/asm-x86_64/mce.h | |||
@@ -70,6 +70,9 @@ struct mce_log { | |||
70 | #define MCE_THRESHOLD_BASE MCE_EXTENDED_BANK + 1 /* MCE_AMD */ | 70 | #define MCE_THRESHOLD_BASE MCE_EXTENDED_BANK + 1 /* MCE_AMD */ |
71 | #define MCE_THRESHOLD_DRAM_ECC MCE_THRESHOLD_BASE + 4 | 71 | #define MCE_THRESHOLD_DRAM_ECC MCE_THRESHOLD_BASE + 4 |
72 | 72 | ||
73 | #ifdef __KERNEL__ | ||
74 | #include <asm/atomic.h> | ||
75 | |||
73 | void mce_log(struct mce *m); | 76 | void mce_log(struct mce *m); |
74 | #ifdef CONFIG_X86_MCE_INTEL | 77 | #ifdef CONFIG_X86_MCE_INTEL |
75 | void mce_intel_feature_init(struct cpuinfo_x86 *c); | 78 | void mce_intel_feature_init(struct cpuinfo_x86 *c); |
@@ -87,4 +90,8 @@ static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
87 | } | 90 | } |
88 | #endif | 91 | #endif |
89 | 92 | ||
93 | extern atomic_t mce_entry; | ||
94 | |||
95 | #endif | ||
96 | |||
90 | #endif | 97 | #endif |
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h index f6cbb4cbb5a3..1cc92fe02503 100644 --- a/include/asm-x86_64/numa.h +++ b/include/asm-x86_64/numa.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define _ASM_X8664_NUMA_H 1 | 2 | #define _ASM_X8664_NUMA_H 1 |
3 | 3 | ||
4 | #include <linux/nodemask.h> | 4 | #include <linux/nodemask.h> |
5 | #include <asm/numnodes.h> | ||
6 | 5 | ||
7 | struct bootnode { | 6 | struct bootnode { |
8 | u64 start,end; | 7 | u64 start,end; |
@@ -18,6 +17,8 @@ extern void numa_init_array(void); | |||
18 | extern int numa_off; | 17 | extern int numa_off; |
19 | 18 | ||
20 | extern void numa_set_node(int cpu, int node); | 19 | extern void numa_set_node(int cpu, int node); |
20 | extern void srat_reserve_add_area(int nodeid); | ||
21 | extern int hotadd_percent; | ||
21 | 22 | ||
22 | extern unsigned char apicid_to_node[256]; | 23 | extern unsigned char apicid_to_node[256]; |
23 | #ifdef CONFIG_NUMA | 24 | #ifdef CONFIG_NUMA |
diff --git a/include/asm-x86_64/numnodes.h b/include/asm-x86_64/numnodes.h deleted file mode 100644 index 32be16b8ae96..000000000000 --- a/include/asm-x86_64/numnodes.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #ifndef _ASM_X8664_NUMNODES_H | ||
2 | #define _ASM_X8664_NUMNODES_H 1 | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | |||
6 | #ifdef CONFIG_NUMA | ||
7 | #define NODES_SHIFT 6 | ||
8 | #else | ||
9 | #define NODES_SHIFT 0 | ||
10 | #endif | ||
11 | |||
12 | #endif | ||
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h index f18443fcdf04..b9e5320b7625 100644 --- a/include/asm-x86_64/timex.h +++ b/include/asm-x86_64/timex.h | |||
@@ -33,7 +33,7 @@ static __always_inline cycles_t get_cycles_sync(void) | |||
33 | unsigned eax; | 33 | unsigned eax; |
34 | /* Don't do an additional sync on CPUs where we know | 34 | /* Don't do an additional sync on CPUs where we know |
35 | RDTSC is already synchronous. */ | 35 | RDTSC is already synchronous. */ |
36 | alternative_io(ASM_NOP2, "cpuid", X86_FEATURE_SYNC_RDTSC, | 36 | alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, |
37 | "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); | 37 | "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); |
38 | rdtscll(ret); | 38 | rdtscll(ret); |
39 | return ret; | 39 | return ret; |
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h index 9284867f1cb9..b29f7ae6a08a 100644 --- a/include/asm-xtensa/system.h +++ b/include/asm-xtensa/system.h | |||
@@ -111,8 +111,6 @@ extern void *_switch_to(void *last, void *next); | |||
111 | 111 | ||
112 | #endif /* __ASSEMBLY__ */ | 112 | #endif /* __ASSEMBLY__ */ |
113 | 113 | ||
114 | #define prepare_to_switch() do { } while(0) | ||
115 | |||
116 | #define switch_to(prev,next,last) \ | 114 | #define switch_to(prev,next,last) \ |
117 | do { \ | 115 | do { \ |
118 | clear_cpenable(); \ | 116 | clear_cpenable(); \ |
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index de3eb8d8ae26..da2d107fe2cf 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
@@ -45,6 +45,7 @@ extern unsigned long __init bootmem_bootmap_pages (unsigned long); | |||
45 | extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend); | 45 | extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend); |
46 | extern void __init free_bootmem (unsigned long addr, unsigned long size); | 46 | extern void __init free_bootmem (unsigned long addr, unsigned long size); |
47 | extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal); | 47 | extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal); |
48 | extern void * __init __alloc_bootmem_nopanic (unsigned long size, unsigned long align, unsigned long goal); | ||
48 | extern void * __init __alloc_bootmem_low(unsigned long size, | 49 | extern void * __init __alloc_bootmem_low(unsigned long size, |
49 | unsigned long align, | 50 | unsigned long align, |
50 | unsigned long goal); | 51 | unsigned long goal); |
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 9b4751aecc23..ff61817082fa 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -21,7 +21,7 @@ enum dma_data_direction { | |||
21 | #define DMA_30BIT_MASK 0x000000003fffffffULL | 21 | #define DMA_30BIT_MASK 0x000000003fffffffULL |
22 | #define DMA_29BIT_MASK 0x000000001fffffffULL | 22 | #define DMA_29BIT_MASK 0x000000001fffffffULL |
23 | #define DMA_28BIT_MASK 0x000000000fffffffULL | 23 | #define DMA_28BIT_MASK 0x000000000fffffffULL |
24 | #define DMA_24BIT_MASK 0x0000000000ffffffULL | 24 | #define DMA_24BIT_MASK 0x0000000000ffffffULL |
25 | 25 | ||
26 | #include <asm/dma-mapping.h> | 26 | #include <asm/dma-mapping.h> |
27 | 27 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 1e9ebaba07b7..162c6e57307a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -762,7 +762,7 @@ extern int fcntl_getlease(struct file *filp); | |||
762 | #define SYNC_FILE_RANGE_WRITE 2 | 762 | #define SYNC_FILE_RANGE_WRITE 2 |
763 | #define SYNC_FILE_RANGE_WAIT_AFTER 4 | 763 | #define SYNC_FILE_RANGE_WAIT_AFTER 4 |
764 | extern int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte, | 764 | extern int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte, |
765 | int flags); | 765 | unsigned int flags); |
766 | 766 | ||
767 | /* fs/locks.c */ | 767 | /* fs/locks.c */ |
768 | extern void locks_init_lock(struct file_lock *); | 768 | extern void locks_init_lock(struct file_lock *); |
@@ -1039,8 +1039,8 @@ struct file_operations { | |||
1039 | int (*check_flags)(int); | 1039 | int (*check_flags)(int); |
1040 | int (*dir_notify)(struct file *filp, unsigned long arg); | 1040 | int (*dir_notify)(struct file *filp, unsigned long arg); |
1041 | int (*flock) (struct file *, int, struct file_lock *); | 1041 | int (*flock) (struct file *, int, struct file_lock *); |
1042 | ssize_t (*splice_write)(struct inode *, struct file *, size_t, unsigned int); | 1042 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); |
1043 | ssize_t (*splice_read)(struct file *, struct inode *, size_t, unsigned int); | 1043 | ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); |
1044 | }; | 1044 | }; |
1045 | 1045 | ||
1046 | struct inode_operations { | 1046 | struct inode_operations { |
@@ -1611,8 +1611,17 @@ extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor | |||
1611 | extern void do_generic_mapping_read(struct address_space *mapping, | 1611 | extern void do_generic_mapping_read(struct address_space *mapping, |
1612 | struct file_ra_state *, struct file *, | 1612 | struct file_ra_state *, struct file *, |
1613 | loff_t *, read_descriptor_t *, read_actor_t); | 1613 | loff_t *, read_descriptor_t *, read_actor_t); |
1614 | extern ssize_t generic_file_splice_read(struct file *, struct inode *, size_t, unsigned int); | 1614 | |
1615 | extern ssize_t generic_file_splice_write(struct inode *, struct file *, size_t, unsigned int); | 1615 | /* fs/splice.c */ |
1616 | extern ssize_t generic_file_splice_read(struct file *, | ||
1617 | struct pipe_inode_info *, size_t, unsigned int); | ||
1618 | extern ssize_t generic_file_splice_write(struct pipe_inode_info *, | ||
1619 | struct file *, size_t, unsigned int); | ||
1620 | extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, | ||
1621 | struct file *out, size_t len, unsigned int flags); | ||
1622 | extern long do_splice_direct(struct file *in, struct file *out, | ||
1623 | size_t len, unsigned int flags); | ||
1624 | |||
1616 | extern void | 1625 | extern void |
1617 | file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); | 1626 | file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); |
1618 | extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, | 1627 | extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 7851e6b520cf..3ac452945a7d 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -57,6 +57,8 @@ struct vm_area_struct; | |||
57 | __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \ | 57 | __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \ |
58 | __GFP_NOMEMALLOC|__GFP_HARDWALL) | 58 | __GFP_NOMEMALLOC|__GFP_HARDWALL) |
59 | 59 | ||
60 | /* This equals 0, but use constants in case they ever change */ | ||
61 | #define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH) | ||
60 | /* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */ | 62 | /* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */ |
61 | #define GFP_ATOMIC (__GFP_HIGH) | 63 | #define GFP_ATOMIC (__GFP_HIGH) |
62 | #define GFP_NOIO (__GFP_WAIT) | 64 | #define GFP_NOIO (__GFP_WAIT) |
diff --git a/include/linux/init.h b/include/linux/init.h index ed0ac7c39fdc..93dcbe1abb4c 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -245,7 +245,8 @@ void __init parse_early_param(void); | |||
245 | #define __cpuexitdata __exitdata | 245 | #define __cpuexitdata __exitdata |
246 | #endif | 246 | #endif |
247 | 247 | ||
248 | #ifdef CONFIG_MEMORY_HOTPLUG | 248 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ |
249 | || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
249 | #define __meminit | 250 | #define __meminit |
250 | #define __meminitdata | 251 | #define __meminitdata |
251 | #define __memexit | 252 | #define __memexit |
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 99905e180532..043376920f51 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h | |||
@@ -36,6 +36,8 @@ | |||
36 | /* LATCH is used in the interval timer and ftape setup. */ | 36 | /* LATCH is used in the interval timer and ftape setup. */ |
37 | #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ | 37 | #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ |
38 | 38 | ||
39 | #define LATCH_HPET ((HPET_TICK_RATE + HZ/2) / HZ) | ||
40 | |||
39 | /* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can | 41 | /* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can |
40 | * improve accuracy by shifting LSH bits, hence calculating: | 42 | * improve accuracy by shifting LSH bits, hence calculating: |
41 | * (NOM << LSH) / DEN | 43 | * (NOM << LSH) / DEN |
@@ -51,9 +53,13 @@ | |||
51 | /* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */ | 53 | /* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */ |
52 | #define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8)) | 54 | #define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8)) |
53 | 55 | ||
56 | #define ACTHZ_HPET (SH_DIV (HPET_TICK_RATE, LATCH_HPET, 8)) | ||
57 | |||
54 | /* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */ | 58 | /* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */ |
55 | #define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8)) | 59 | #define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8)) |
56 | 60 | ||
61 | #define TICK_NSEC_HPET (SH_DIV(1000000UL * 1000, ACTHZ_HPET, 8)) | ||
62 | |||
57 | /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ | 63 | /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ |
58 | #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ) | 64 | #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ) |
59 | 65 | ||
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index a3720f973ea5..e1bd0842f6a1 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -176,7 +176,7 @@ static inline void console_verbose(void) | |||
176 | 176 | ||
177 | extern void bust_spinlocks(int yes); | 177 | extern void bust_spinlocks(int yes); |
178 | extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ | 178 | extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ |
179 | extern __deprecated_for_modules int panic_timeout; | 179 | extern int panic_timeout; |
180 | extern int panic_on_oops; | 180 | extern int panic_on_oops; |
181 | extern int tainted; | 181 | extern int tainted; |
182 | extern const char *print_tainted(void); | 182 | extern const char *print_tainted(void); |
diff --git a/include/linux/leds.h b/include/linux/leds.h index 4617e75903b0..dc23c7c639f3 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -19,39 +19,38 @@ struct class_device; | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | enum led_brightness { | 21 | enum led_brightness { |
22 | LED_OFF = 0, | 22 | LED_OFF = 0, |
23 | LED_HALF = 127, | 23 | LED_HALF = 127, |
24 | LED_FULL = 255, | 24 | LED_FULL = 255, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | struct led_classdev { | 27 | struct led_classdev { |
28 | const char *name; | 28 | const char *name; |
29 | int brightness; | 29 | int brightness; |
30 | int flags; | 30 | int flags; |
31 | #define LED_SUSPENDED (1 << 0) | ||
32 | 31 | ||
33 | /* A function to set the brightness of the led */ | 32 | #define LED_SUSPENDED (1 << 0) |
34 | void (*brightness_set)(struct led_classdev *led_cdev, | ||
35 | enum led_brightness brightness); | ||
36 | 33 | ||
37 | struct class_device *class_dev; | 34 | /* Set LED brightness level */ |
38 | /* LED Device linked list */ | 35 | void (*brightness_set)(struct led_classdev *led_cdev, |
39 | struct list_head node; | 36 | enum led_brightness brightness); |
37 | |||
38 | struct class_device *class_dev; | ||
39 | struct list_head node; /* LED Device list */ | ||
40 | char *default_trigger; /* Trigger to use */ | ||
40 | 41 | ||
41 | /* Trigger data */ | ||
42 | char *default_trigger; | ||
43 | #ifdef CONFIG_LEDS_TRIGGERS | 42 | #ifdef CONFIG_LEDS_TRIGGERS |
44 | rwlock_t trigger_lock; | ||
45 | /* Protects the trigger data below */ | 43 | /* Protects the trigger data below */ |
44 | rwlock_t trigger_lock; | ||
46 | 45 | ||
47 | struct led_trigger *trigger; | 46 | struct led_trigger *trigger; |
48 | struct list_head trig_list; | 47 | struct list_head trig_list; |
49 | void *trigger_data; | 48 | void *trigger_data; |
50 | #endif | 49 | #endif |
51 | }; | 50 | }; |
52 | 51 | ||
53 | extern int led_classdev_register(struct device *parent, | 52 | extern int led_classdev_register(struct device *parent, |
54 | struct led_classdev *led_cdev); | 53 | struct led_classdev *led_cdev); |
55 | extern void led_classdev_unregister(struct led_classdev *led_cdev); | 54 | extern void led_classdev_unregister(struct led_classdev *led_cdev); |
56 | extern void led_classdev_suspend(struct led_classdev *led_cdev); | 55 | extern void led_classdev_suspend(struct led_classdev *led_cdev); |
57 | extern void led_classdev_resume(struct led_classdev *led_cdev); | 56 | extern void led_classdev_resume(struct led_classdev *led_cdev); |
@@ -65,16 +64,16 @@ extern void led_classdev_resume(struct led_classdev *led_cdev); | |||
65 | 64 | ||
66 | struct led_trigger { | 65 | struct led_trigger { |
67 | /* Trigger Properties */ | 66 | /* Trigger Properties */ |
68 | const char *name; | 67 | const char *name; |
69 | void (*activate)(struct led_classdev *led_cdev); | 68 | void (*activate)(struct led_classdev *led_cdev); |
70 | void (*deactivate)(struct led_classdev *led_cdev); | 69 | void (*deactivate)(struct led_classdev *led_cdev); |
71 | 70 | ||
72 | /* LEDs under control by this trigger (for simple triggers) */ | 71 | /* LEDs under control by this trigger (for simple triggers) */ |
73 | rwlock_t leddev_list_lock; | 72 | rwlock_t leddev_list_lock; |
74 | struct list_head led_cdevs; | 73 | struct list_head led_cdevs; |
75 | 74 | ||
76 | /* Link to next registered trigger */ | 75 | /* Link to next registered trigger */ |
77 | struct list_head next_trig; | 76 | struct list_head next_trig; |
78 | }; | 77 | }; |
79 | 78 | ||
80 | /* Registration functions for complex triggers */ | 79 | /* Registration functions for complex triggers */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 03231cb6b406..a7161d42d18f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -530,6 +530,8 @@ extern void ata_host_set_remove(struct ata_host_set *host_set); | |||
530 | extern int ata_scsi_detect(struct scsi_host_template *sht); | 530 | extern int ata_scsi_detect(struct scsi_host_template *sht); |
531 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); | 531 | extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); |
532 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); | 532 | extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); |
533 | extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); | ||
534 | extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); | ||
533 | extern int ata_scsi_release(struct Scsi_Host *host); | 535 | extern int ata_scsi_release(struct Scsi_Host *host); |
534 | extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); | 536 | extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); |
535 | extern int ata_scsi_device_resume(struct scsi_device *); | 537 | extern int ata_scsi_device_resume(struct scsi_device *); |
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 968b1aa3732c..4ca3e6ad03ec 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
@@ -58,8 +58,6 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro); | |||
58 | /* need some defines for these for archs that don't support it */ | 58 | /* need some defines for these for archs that don't support it */ |
59 | extern void online_page(struct page *page); | 59 | extern void online_page(struct page *page); |
60 | /* VM interface that may be used by firmware interface */ | 60 | /* VM interface that may be used by firmware interface */ |
61 | extern int add_memory(u64 start, u64 size); | ||
62 | extern int remove_memory(u64 start, u64 size); | ||
63 | extern int online_pages(unsigned long, unsigned long); | 61 | extern int online_pages(unsigned long, unsigned long); |
64 | 62 | ||
65 | /* reasonably generic interface to expand the physical pages in a zone */ | 63 | /* reasonably generic interface to expand the physical pages in a zone */ |
@@ -92,11 +90,6 @@ static inline int mhp_notimplemented(const char *func) | |||
92 | return -ENOSYS; | 90 | return -ENOSYS; |
93 | } | 91 | } |
94 | 92 | ||
95 | static inline int __add_pages(struct zone *zone, unsigned long start_pfn, | ||
96 | unsigned long nr_pages) | ||
97 | { | ||
98 | return mhp_notimplemented(__FUNCTION__); | ||
99 | } | ||
100 | #endif /* ! CONFIG_MEMORY_HOTPLUG */ | 93 | #endif /* ! CONFIG_MEMORY_HOTPLUG */ |
101 | static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, | 94 | static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, |
102 | unsigned long nr_pages) | 95 | unsigned long nr_pages) |
@@ -105,4 +98,11 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, | |||
105 | dump_stack(); | 98 | dump_stack(); |
106 | return -ENOSYS; | 99 | return -ENOSYS; |
107 | } | 100 | } |
101 | |||
102 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ | ||
103 | || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
104 | extern int add_memory(u64 start, u64 size); | ||
105 | extern int remove_memory(u64 start, u64 size); | ||
106 | #endif | ||
107 | |||
108 | #endif /* __LINUX_MEMORY_HOTPLUG_H */ | 108 | #endif /* __LINUX_MEMORY_HOTPLUG_H */ |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 6aa016f1d3ae..1154684209a4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -229,10 +229,9 @@ struct page { | |||
229 | unsigned long private; /* Mapping-private opaque data: | 229 | unsigned long private; /* Mapping-private opaque data: |
230 | * usually used for buffer_heads | 230 | * usually used for buffer_heads |
231 | * if PagePrivate set; used for | 231 | * if PagePrivate set; used for |
232 | * swp_entry_t if PageSwapCache. | 232 | * swp_entry_t if PageSwapCache; |
233 | * When page is free, this | ||
234 | * indicates order in the buddy | 233 | * indicates order in the buddy |
235 | * system. | 234 | * system if PG_buddy is set. |
236 | */ | 235 | */ |
237 | struct address_space *mapping; /* If low bit clear, points to | 236 | struct address_space *mapping; /* If low bit clear, points to |
238 | * inode address_space, or NULL. | 237 | * inode address_space, or NULL. |
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 412e52ca9720..b31a9bca9361 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h | |||
@@ -110,6 +110,8 @@ struct nf_info | |||
110 | /* Function to register/unregister hook points. */ | 110 | /* Function to register/unregister hook points. */ |
111 | int nf_register_hook(struct nf_hook_ops *reg); | 111 | int nf_register_hook(struct nf_hook_ops *reg); |
112 | void nf_unregister_hook(struct nf_hook_ops *reg); | 112 | void nf_unregister_hook(struct nf_hook_ops *reg); |
113 | int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n); | ||
114 | void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n); | ||
113 | 115 | ||
114 | /* Functions to register get/setsockopt ranges (non-inclusive). You | 116 | /* Functions to register get/setsockopt ranges (non-inclusive). You |
115 | need to check permissions yourself! */ | 117 | need to check permissions yourself! */ |
@@ -281,16 +283,42 @@ extern void nf_invalidate_cache(int pf); | |||
281 | Returns true or false. */ | 283 | Returns true or false. */ |
282 | extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len); | 284 | extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len); |
283 | 285 | ||
284 | struct nf_queue_rerouter { | 286 | struct nf_afinfo { |
285 | void (*save)(const struct sk_buff *skb, struct nf_info *info); | 287 | unsigned short family; |
286 | int (*reroute)(struct sk_buff **skb, const struct nf_info *info); | 288 | unsigned int (*checksum)(struct sk_buff *skb, unsigned int hook, |
287 | int rer_size; | 289 | unsigned int dataoff, u_int8_t protocol); |
290 | void (*saveroute)(const struct sk_buff *skb, | ||
291 | struct nf_info *info); | ||
292 | int (*reroute)(struct sk_buff **skb, | ||
293 | const struct nf_info *info); | ||
294 | int route_key_size; | ||
288 | }; | 295 | }; |
289 | 296 | ||
290 | #define nf_info_reroute(x) ((void *)x + sizeof(struct nf_info)) | 297 | extern struct nf_afinfo *nf_afinfo[]; |
298 | static inline struct nf_afinfo *nf_get_afinfo(unsigned short family) | ||
299 | { | ||
300 | return rcu_dereference(nf_afinfo[family]); | ||
301 | } | ||
302 | |||
303 | static inline unsigned int | ||
304 | nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff, | ||
305 | u_int8_t protocol, unsigned short family) | ||
306 | { | ||
307 | struct nf_afinfo *afinfo; | ||
308 | unsigned int csum = 0; | ||
309 | |||
310 | rcu_read_lock(); | ||
311 | afinfo = nf_get_afinfo(family); | ||
312 | if (afinfo) | ||
313 | csum = afinfo->checksum(skb, hook, dataoff, protocol); | ||
314 | rcu_read_unlock(); | ||
315 | return csum; | ||
316 | } | ||
291 | 317 | ||
292 | extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer); | 318 | extern int nf_register_afinfo(struct nf_afinfo *afinfo); |
293 | extern int nf_unregister_queue_rerouter(int pf); | 319 | extern void nf_unregister_afinfo(struct nf_afinfo *afinfo); |
320 | |||
321 | #define nf_info_reroute(x) ((void *)x + sizeof(struct nf_info)) | ||
294 | 322 | ||
295 | #include <net/flow.h> | 323 | #include <net/flow.h> |
296 | extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); | 324 | extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); |
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index 43c09d790b83..85301c5e8d24 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h | |||
@@ -80,6 +80,8 @@ enum nf_ip_hook_priorities { | |||
80 | #ifdef __KERNEL__ | 80 | #ifdef __KERNEL__ |
81 | extern int ip_route_me_harder(struct sk_buff **pskb); | 81 | extern int ip_route_me_harder(struct sk_buff **pskb); |
82 | extern int ip_xfrm_me_harder(struct sk_buff **pskb); | 82 | extern int ip_xfrm_me_harder(struct sk_buff **pskb); |
83 | extern unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook, | ||
84 | unsigned int dataoff, u_int8_t protocol); | ||
83 | #endif /*__KERNEL__*/ | 85 | #endif /*__KERNEL__*/ |
84 | 86 | ||
85 | #endif /*__LINUX_IP_NETFILTER_H*/ | 87 | #endif /*__LINUX_IP_NETFILTER_H*/ |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_h323.h b/include/linux/netfilter_ipv4/ip_conntrack_h323.h index 0987cea53840..eace86bd2adb 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_h323.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_h323.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | 5 | ||
6 | #include <linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h> | ||
7 | |||
6 | #define RAS_PORT 1719 | 8 | #define RAS_PORT 1719 |
7 | #define Q931_PORT 1720 | 9 | #define Q931_PORT 1720 |
8 | #define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */ | 10 | #define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */ |
@@ -25,6 +27,56 @@ struct ip_ct_h323_master { | |||
25 | }; | 27 | }; |
26 | }; | 28 | }; |
27 | 29 | ||
30 | struct ip_conntrack_expect; | ||
31 | |||
32 | extern int get_h225_addr(unsigned char *data, TransportAddress * addr, | ||
33 | u_int32_t * ip, u_int16_t * port); | ||
34 | extern void ip_conntrack_h245_expect(struct ip_conntrack *new, | ||
35 | struct ip_conntrack_expect *this); | ||
36 | extern void ip_conntrack_q931_expect(struct ip_conntrack *new, | ||
37 | struct ip_conntrack_expect *this); | ||
38 | extern int (*set_h245_addr_hook) (struct sk_buff ** pskb, | ||
39 | unsigned char **data, int dataoff, | ||
40 | H245_TransportAddress * addr, | ||
41 | u_int32_t ip, u_int16_t port); | ||
42 | extern int (*set_h225_addr_hook) (struct sk_buff ** pskb, | ||
43 | unsigned char **data, int dataoff, | ||
44 | TransportAddress * addr, | ||
45 | u_int32_t ip, u_int16_t port); | ||
46 | extern int (*set_sig_addr_hook) (struct sk_buff ** pskb, | ||
47 | struct ip_conntrack * ct, | ||
48 | enum ip_conntrack_info ctinfo, | ||
49 | unsigned char **data, | ||
50 | TransportAddress * addr, int count); | ||
51 | extern int (*set_ras_addr_hook) (struct sk_buff ** pskb, | ||
52 | struct ip_conntrack * ct, | ||
53 | enum ip_conntrack_info ctinfo, | ||
54 | unsigned char **data, | ||
55 | TransportAddress * addr, int count); | ||
56 | extern int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb, | ||
57 | struct ip_conntrack * ct, | ||
58 | enum ip_conntrack_info ctinfo, | ||
59 | unsigned char **data, int dataoff, | ||
60 | H245_TransportAddress * addr, | ||
61 | u_int16_t port, u_int16_t rtp_port, | ||
62 | struct ip_conntrack_expect * rtp_exp, | ||
63 | struct ip_conntrack_expect * rtcp_exp); | ||
64 | extern int (*nat_t120_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
65 | enum ip_conntrack_info ctinfo, | ||
66 | unsigned char **data, int dataoff, | ||
67 | H245_TransportAddress * addr, u_int16_t port, | ||
68 | struct ip_conntrack_expect * exp); | ||
69 | extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
70 | enum ip_conntrack_info ctinfo, | ||
71 | unsigned char **data, int dataoff, | ||
72 | TransportAddress * addr, u_int16_t port, | ||
73 | struct ip_conntrack_expect * exp); | ||
74 | extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
75 | enum ip_conntrack_info ctinfo, | ||
76 | unsigned char **data, TransportAddress * addr, | ||
77 | int idx, u_int16_t port, | ||
78 | struct ip_conntrack_expect * exp); | ||
79 | |||
28 | #endif | 80 | #endif |
29 | 81 | ||
30 | #endif | 82 | #endif |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h b/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h index 0bd828081c0c..0bd828081c0c 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h | |||
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h b/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h index cc98f7aa5abe..cc98f7aa5abe 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_types.h | |||
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 14f2bd010884..52a7b9e76428 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h | |||
@@ -73,6 +73,9 @@ enum nf_ip6_hook_priorities { | |||
73 | }; | 73 | }; |
74 | 74 | ||
75 | #ifdef CONFIG_NETFILTER | 75 | #ifdef CONFIG_NETFILTER |
76 | extern unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, | ||
77 | unsigned int dataoff, u_int8_t protocol); | ||
78 | |||
76 | extern int ipv6_netfilter_init(void); | 79 | extern int ipv6_netfilter_init(void); |
77 | extern void ipv6_netfilter_fini(void); | 80 | extern void ipv6_netfilter_fini(void); |
78 | #else /* CONFIG_NETFILTER */ | 81 | #else /* CONFIG_NETFILTER */ |
diff --git a/include/linux/numa.h b/include/linux/numa.h index f0c539bd3cfc..e481feb1bfd8 100644 --- a/include/linux/numa.h +++ b/include/linux/numa.h | |||
@@ -3,11 +3,9 @@ | |||
3 | 3 | ||
4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
5 | 5 | ||
6 | #ifndef CONFIG_FLATMEM | 6 | #ifdef CONFIG_NODES_SHIFT |
7 | #include <asm/numnodes.h> | 7 | #define NODES_SHIFT CONFIG_NODES_SHIFT |
8 | #endif | 8 | #else |
9 | |||
10 | #ifndef NODES_SHIFT | ||
11 | #define NODES_SHIFT 0 | 9 | #define NODES_SHIFT 0 |
12 | #endif | 10 | #endif |
13 | 11 | ||
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 9ea629c02a4b..d276a4e2f825 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -48,8 +48,20 @@ | |||
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Don't use the *_dontuse flags. Use the macros. Otherwise you'll break | 50 | * Don't use the *_dontuse flags. Use the macros. Otherwise you'll break |
51 | * locked- and dirty-page accounting. The top eight bits of page->flags are | 51 | * locked- and dirty-page accounting. |
52 | * used for page->zone, so putting flag bits there doesn't work. | 52 | * |
53 | * The page flags field is split into two parts, the main flags area | ||
54 | * which extends from the low bits upwards, and the fields area which | ||
55 | * extends from the high bits downwards. | ||
56 | * | ||
57 | * | FIELD | ... | FLAGS | | ||
58 | * N-1 ^ 0 | ||
59 | * (N-FLAGS_RESERVED) | ||
60 | * | ||
61 | * The fields area is reserved for fields mapping zone, node and SPARSEMEM | ||
62 | * section. The boundry between these two areas is defined by | ||
63 | * FLAGS_RESERVED which defines the width of the fields section | ||
64 | * (see linux/mmzone.h). New flags must _not_ overlap with this area. | ||
53 | */ | 65 | */ |
54 | #define PG_locked 0 /* Page is locked. Don't touch. */ | 66 | #define PG_locked 0 /* Page is locked. Don't touch. */ |
55 | #define PG_error 1 | 67 | #define PG_error 1 |
@@ -74,7 +86,9 @@ | |||
74 | #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ | 86 | #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ |
75 | #define PG_reclaim 17 /* To be reclaimed asap */ | 87 | #define PG_reclaim 17 /* To be reclaimed asap */ |
76 | #define PG_nosave_free 18 /* Free, should not be written */ | 88 | #define PG_nosave_free 18 /* Free, should not be written */ |
77 | #define PG_uncached 19 /* Page has been mapped as uncached */ | 89 | #define PG_buddy 19 /* Page is free, on buddy lists */ |
90 | |||
91 | #define PG_uncached 20 /* Page has been mapped as uncached */ | ||
78 | 92 | ||
79 | /* | 93 | /* |
80 | * Global page accounting. One instance per CPU. Only unsigned longs are | 94 | * Global page accounting. One instance per CPU. Only unsigned longs are |
@@ -317,6 +331,10 @@ extern void __mod_page_state_offset(unsigned long offset, unsigned long delta); | |||
317 | #define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags) | 331 | #define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags) |
318 | #define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags) | 332 | #define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags) |
319 | 333 | ||
334 | #define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) | ||
335 | #define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) | ||
336 | #define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags) | ||
337 | |||
320 | #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) | 338 | #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) |
321 | #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) | 339 | #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) |
322 | #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) | 340 | #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ec384958d509..123a7c24bc72 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -36,27 +36,19 @@ struct pipe_inode_info { | |||
36 | unsigned int w_counter; | 36 | unsigned int w_counter; |
37 | struct fasync_struct *fasync_readers; | 37 | struct fasync_struct *fasync_readers; |
38 | struct fasync_struct *fasync_writers; | 38 | struct fasync_struct *fasync_writers; |
39 | struct inode *inode; | ||
39 | }; | 40 | }; |
40 | 41 | ||
41 | /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual | 42 | /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual |
42 | memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ | 43 | memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ |
43 | #define PIPE_SIZE PAGE_SIZE | 44 | #define PIPE_SIZE PAGE_SIZE |
44 | 45 | ||
45 | #define PIPE_MUTEX(inode) (&(inode).i_mutex) | ||
46 | #define PIPE_WAIT(inode) (&(inode).i_pipe->wait) | ||
47 | #define PIPE_READERS(inode) ((inode).i_pipe->readers) | ||
48 | #define PIPE_WRITERS(inode) ((inode).i_pipe->writers) | ||
49 | #define PIPE_WAITING_WRITERS(inode) ((inode).i_pipe->waiting_writers) | ||
50 | #define PIPE_RCOUNTER(inode) ((inode).i_pipe->r_counter) | ||
51 | #define PIPE_WCOUNTER(inode) ((inode).i_pipe->w_counter) | ||
52 | #define PIPE_FASYNC_READERS(inode) (&((inode).i_pipe->fasync_readers)) | ||
53 | #define PIPE_FASYNC_WRITERS(inode) (&((inode).i_pipe->fasync_writers)) | ||
54 | |||
55 | /* Drop the inode semaphore and wait for a pipe event, atomically */ | 46 | /* Drop the inode semaphore and wait for a pipe event, atomically */ |
56 | void pipe_wait(struct inode * inode); | 47 | void pipe_wait(struct pipe_inode_info *pipe); |
57 | 48 | ||
58 | struct inode* pipe_new(struct inode* inode); | 49 | struct pipe_inode_info * alloc_pipe_info(struct inode * inode); |
59 | void free_pipe_info(struct inode* inode); | 50 | void free_pipe_info(struct inode * inode); |
51 | void __free_pipe_info(struct pipe_inode_info *); | ||
60 | 52 | ||
61 | /* | 53 | /* |
62 | * splice is tied to pipes as a transport (at least for now), so we'll just | 54 | * splice is tied to pipes as a transport (at least for now), so we'll just |
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 135871df9911..4b47a0253425 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h | |||
@@ -79,7 +79,7 @@ struct kcore_list { | |||
79 | struct vmcore { | 79 | struct vmcore { |
80 | struct list_head list; | 80 | struct list_head list; |
81 | unsigned long long paddr; | 81 | unsigned long long paddr; |
82 | unsigned long size; | 82 | unsigned long long size; |
83 | loff_t offset; | 83 | loff_t offset; |
84 | }; | 84 | }; |
85 | 85 | ||
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 774e1acfb8c4..f1fbae7e390e 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h | |||
@@ -227,8 +227,8 @@ struct mdp_superblock_1 { | |||
227 | */ | 227 | */ |
228 | 228 | ||
229 | /* These are only valid with feature bit '4' */ | 229 | /* These are only valid with feature bit '4' */ |
230 | __u64 reshape_position; /* next address in array-space for reshape */ | ||
231 | __u32 new_level; /* new level we are reshaping to */ | 230 | __u32 new_level; /* new level we are reshaping to */ |
231 | __u64 reshape_position; /* next address in array-space for reshape */ | ||
232 | __u32 delta_disks; /* change in number of raid_disks */ | 232 | __u32 delta_disks; /* change in number of raid_disks */ |
233 | __u32 new_layout; /* new layout */ | 233 | __u32 new_layout; /* new layout */ |
234 | __u32 new_chunk; /* new chunk size (bytes) */ | 234 | __u32 new_chunk; /* new chunk size (bytes) */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 541f4828f5e7..e3539c14e47e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -684,6 +684,7 @@ static inline void prefetch_stack(struct task_struct *t) { } | |||
684 | 684 | ||
685 | struct audit_context; /* See audit.c */ | 685 | struct audit_context; /* See audit.c */ |
686 | struct mempolicy; | 686 | struct mempolicy; |
687 | struct pipe_inode_info; | ||
687 | 688 | ||
688 | enum sleep_type { | 689 | enum sleep_type { |
689 | SLEEP_NORMAL, | 690 | SLEEP_NORMAL, |
@@ -882,6 +883,11 @@ struct task_struct { | |||
882 | 883 | ||
883 | atomic_t fs_excl; /* holding fs exclusive resources */ | 884 | atomic_t fs_excl; /* holding fs exclusive resources */ |
884 | struct rcu_head rcu; | 885 | struct rcu_head rcu; |
886 | |||
887 | /* | ||
888 | * cache last used pipe for splice | ||
889 | */ | ||
890 | struct pipe_inode_info *splice_pipe; | ||
885 | }; | 891 | }; |
886 | 892 | ||
887 | static inline pid_t process_group(struct task_struct *tsk) | 893 | static inline pid_t process_group(struct task_struct *tsk) |
@@ -1203,9 +1209,10 @@ extern void wait_task_inactive(task_t * p); | |||
1203 | #define while_each_thread(g, t) \ | 1209 | #define while_each_thread(g, t) \ |
1204 | while ((t = next_thread(t)) != g) | 1210 | while ((t = next_thread(t)) != g) |
1205 | 1211 | ||
1206 | #define thread_group_leader(p) (p->pid == p->tgid) | 1212 | /* de_thread depends on thread_group_leader not being a pid based check */ |
1213 | #define thread_group_leader(p) (p == p->group_leader) | ||
1207 | 1214 | ||
1208 | static inline task_t *next_thread(task_t *p) | 1215 | static inline task_t *next_thread(const task_t *p) |
1209 | { | 1216 | { |
1210 | return list_entry(rcu_dereference(p->thread_group.next), | 1217 | return list_entry(rcu_dereference(p->thread_group.next), |
1211 | task_t, thread_group); | 1218 | task_t, thread_group); |
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h index 6336987dae62..2925e66a6732 100644 --- a/include/linux/screen_info.h +++ b/include/linux/screen_info.h | |||
@@ -41,7 +41,8 @@ struct screen_info { | |||
41 | u16 vesapm_off; /* 0x30 */ | 41 | u16 vesapm_off; /* 0x30 */ |
42 | u16 pages; /* 0x32 */ | 42 | u16 pages; /* 0x32 */ |
43 | u16 vesa_attributes; /* 0x34 */ | 43 | u16 vesa_attributes; /* 0x34 */ |
44 | /* 0x36 -- 0x3f reserved for future expansion */ | 44 | u32 capabilities; /* 0x36 */ |
45 | /* 0x3a -- 0x3f reserved for future expansion */ | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | extern struct screen_info screen_info; | 48 | extern struct screen_info screen_info; |
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index fca9b0fb5b4e..5a095572881d 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h | |||
@@ -73,7 +73,7 @@ static inline int write_tryseqlock(seqlock_t *sl) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | /* Start of read calculation -- fetch last complete writer token */ | 75 | /* Start of read calculation -- fetch last complete writer token */ |
76 | static inline unsigned read_seqbegin(const seqlock_t *sl) | 76 | static __always_inline unsigned read_seqbegin(const seqlock_t *sl) |
77 | { | 77 | { |
78 | unsigned ret = sl->sequence; | 78 | unsigned ret = sl->sequence; |
79 | smp_rmb(); | 79 | smp_rmb(); |
@@ -88,7 +88,7 @@ static inline unsigned read_seqbegin(const seqlock_t *sl) | |||
88 | * | 88 | * |
89 | * Using xor saves one conditional branch. | 89 | * Using xor saves one conditional branch. |
90 | */ | 90 | */ |
91 | static inline int read_seqretry(const seqlock_t *sl, unsigned iv) | 91 | static __always_inline int read_seqretry(const seqlock_t *sl, unsigned iv) |
92 | { | 92 | { |
93 | smp_rmb(); | 93 | smp_rmb(); |
94 | return (iv & 1) | (sl->sequence ^ iv); | 94 | return (iv & 1) | (sl->sequence ^ iv); |
diff --git a/include/linux/string.h b/include/linux/string.h index dee221429ad0..c61306da8c52 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -13,11 +13,6 @@ | |||
13 | extern "C" { | 13 | extern "C" { |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | extern char * strpbrk(const char *,const char *); | ||
17 | extern char * strsep(char **,const char *); | ||
18 | extern __kernel_size_t strspn(const char *,const char *); | ||
19 | extern __kernel_size_t strcspn(const char *,const char *); | ||
20 | |||
21 | extern char *strndup_user(const char __user *, long); | 16 | extern char *strndup_user(const char __user *, long); |
22 | 17 | ||
23 | /* | 18 | /* |
@@ -70,6 +65,18 @@ extern __kernel_size_t strlen(const char *); | |||
70 | #ifndef __HAVE_ARCH_STRNLEN | 65 | #ifndef __HAVE_ARCH_STRNLEN |
71 | extern __kernel_size_t strnlen(const char *,__kernel_size_t); | 66 | extern __kernel_size_t strnlen(const char *,__kernel_size_t); |
72 | #endif | 67 | #endif |
68 | #ifndef __HAVE_ARCH_STRPBRK | ||
69 | extern char * strpbrk(const char *,const char *); | ||
70 | #endif | ||
71 | #ifndef __HAVE_ARCH_STRSEP | ||
72 | extern char * strsep(char **,const char *); | ||
73 | #endif | ||
74 | #ifndef __HAVE_ARCH_STRSPN | ||
75 | extern __kernel_size_t strspn(const char *,const char *); | ||
76 | #endif | ||
77 | #ifndef __HAVE_ARCH_STRCSPN | ||
78 | extern __kernel_size_t strcspn(const char *,const char *); | ||
79 | #endif | ||
73 | 80 | ||
74 | #ifndef __HAVE_ARCH_MEMSET | 81 | #ifndef __HAVE_ARCH_MEMSET |
75 | extern void * memset(void *,int,__kernel_size_t); | 82 | extern void * memset(void *,int,__kernel_size_t); |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 50cab2a09f28..503564384545 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -197,15 +197,16 @@ svc_take_res_page(struct svc_rqst *rqstp) | |||
197 | return rqstp->rq_respages[rqstp->rq_resused++]; | 197 | return rqstp->rq_respages[rqstp->rq_resused++]; |
198 | } | 198 | } |
199 | 199 | ||
200 | static inline int svc_take_page(struct svc_rqst *rqstp) | 200 | static inline void svc_take_page(struct svc_rqst *rqstp) |
201 | { | 201 | { |
202 | if (rqstp->rq_arghi <= rqstp->rq_argused) | 202 | if (rqstp->rq_arghi <= rqstp->rq_argused) { |
203 | return -ENOMEM; | 203 | WARN_ON(1); |
204 | return; | ||
205 | } | ||
204 | rqstp->rq_arghi--; | 206 | rqstp->rq_arghi--; |
205 | rqstp->rq_respages[rqstp->rq_resused] = | 207 | rqstp->rq_respages[rqstp->rq_resused] = |
206 | rqstp->rq_argpages[rqstp->rq_arghi]; | 208 | rqstp->rq_argpages[rqstp->rq_arghi]; |
207 | rqstp->rq_resused++; | 209 | rqstp->rq_resused++; |
208 | return 0; | ||
209 | } | 210 | } |
210 | 211 | ||
211 | static inline void svc_pushback_allpages(struct svc_rqst *rqstp) | 212 | static inline void svc_pushback_allpages(struct svc_rqst *rqstp) |
diff --git a/include/linux/swap.h b/include/linux/swap.h index 54eac8a39a4c..5b1fdf1cff4f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -155,6 +155,7 @@ extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct * | |||
155 | /* linux/mm/page_alloc.c */ | 155 | /* linux/mm/page_alloc.c */ |
156 | extern unsigned long totalram_pages; | 156 | extern unsigned long totalram_pages; |
157 | extern unsigned long totalhigh_pages; | 157 | extern unsigned long totalhigh_pages; |
158 | extern unsigned long totalreserve_pages; | ||
158 | extern long nr_swap_pages; | 159 | extern long nr_swap_pages; |
159 | extern unsigned int nr_free_pages(void); | 160 | extern unsigned int nr_free_pages(void); |
160 | extern unsigned int nr_free_pages_pgdat(pg_data_t *pgdat); | 161 | extern unsigned int nr_free_pages_pgdat(pg_data_t *pgdat); |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 5717147596b6..f001bad28d9a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -569,9 +569,12 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename, | |||
569 | asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, | 569 | asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, |
570 | int flags, int mode); | 570 | int flags, int mode); |
571 | asmlinkage long sys_unshare(unsigned long unshare_flags); | 571 | asmlinkage long sys_unshare(unsigned long unshare_flags); |
572 | asmlinkage long sys_splice(int fdin, int fdout, size_t len, | 572 | |
573 | unsigned int flags); | 573 | asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, |
574 | int fd_out, loff_t __user *off_out, | ||
575 | size_t len, unsigned int flags); | ||
576 | |||
574 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | 577 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, |
575 | int flags); | 578 | unsigned int flags); |
576 | 579 | ||
577 | #endif | 580 | #endif |
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 0976a163b459..31548303ee37 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h | |||
@@ -6,9 +6,10 @@ extern int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *c | |||
6 | extern int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size); | 6 | extern int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size); |
7 | extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); | 7 | extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size); |
8 | extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); | 8 | extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size); |
9 | void tty_schedule_flip(struct tty_struct *tty); | ||
9 | 10 | ||
10 | static inline int tty_insert_flip_char(struct tty_struct *tty, | 11 | static inline int tty_insert_flip_char(struct tty_struct *tty, |
11 | unsigned char ch, char flag) | 12 | unsigned char ch, char flag) |
12 | { | 13 | { |
13 | struct tty_buffer *tb = tty->buf.tail; | 14 | struct tty_buffer *tb = tty->buf.tail; |
14 | if (tb && tb->active && tb->used < tb->size) { | 15 | if (tb && tb->active && tb->used < tb->size) { |
@@ -19,26 +20,4 @@ static inline int tty_insert_flip_char(struct tty_struct *tty, | |||
19 | return tty_insert_flip_string_flags(tty, &ch, &flag, 1); | 20 | return tty_insert_flip_string_flags(tty, &ch, &flag, 1); |
20 | } | 21 | } |
21 | 22 | ||
22 | static inline void tty_schedule_flip(struct tty_struct *tty) | ||
23 | { | ||
24 | unsigned long flags; | ||
25 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
26 | if (tty->buf.tail != NULL) { | ||
27 | tty->buf.tail->active = 0; | ||
28 | tty->buf.tail->commit = tty->buf.tail->used; | ||
29 | } | ||
30 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
31 | schedule_delayed_work(&tty->buf.work, 1); | ||
32 | } | ||
33 | |||
34 | #undef _INLINE_ | ||
35 | |||
36 | |||
37 | #endif /* _LINUX_TTY_FLIP_H */ | 23 | #endif /* _LINUX_TTY_FLIP_H */ |
38 | |||
39 | |||
40 | |||
41 | |||
42 | |||
43 | |||
44 | |||
diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index fadc535e2925..dc7c621e4647 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h | |||
@@ -12,6 +12,11 @@ | |||
12 | #else | 12 | #else |
13 | #define MODULE_VERMAGIC_PREEMPT "" | 13 | #define MODULE_VERMAGIC_PREEMPT "" |
14 | #endif | 14 | #endif |
15 | #ifdef CONFIG_MODULE_UNLOAD | ||
16 | #define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload " | ||
17 | #else | ||
18 | #define MODULE_VERMAGIC_MODULE_UNLOAD "" | ||
19 | #endif | ||
15 | #ifndef MODULE_ARCH_VERMAGIC | 20 | #ifndef MODULE_ARCH_VERMAGIC |
16 | #define MODULE_ARCH_VERMAGIC "" | 21 | #define MODULE_ARCH_VERMAGIC "" |
17 | #endif | 22 | #endif |
@@ -19,5 +24,5 @@ | |||
19 | #define VERMAGIC_STRING \ | 24 | #define VERMAGIC_STRING \ |
20 | UTS_RELEASE " " \ | 25 | UTS_RELEASE " " \ |
21 | MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ | 26 | MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ |
22 | MODULE_ARCH_VERMAGIC \ | 27 | MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC \ |
23 | "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__) | 28 | "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__) |
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 25f708ff020e..59f0c83d55a2 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h | |||
@@ -48,31 +48,7 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) | |||
48 | return inet6_ehashfn(laddr, lport, faddr, fport); | 48 | return inet6_ehashfn(laddr, lport, faddr, fport); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline void __inet6_hash(struct inet_hashinfo *hashinfo, | 51 | extern void __inet6_hash(struct inet_hashinfo *hashinfo, struct sock *sk); |
52 | struct sock *sk) | ||
53 | { | ||
54 | struct hlist_head *list; | ||
55 | rwlock_t *lock; | ||
56 | |||
57 | BUG_TRAP(sk_unhashed(sk)); | ||
58 | |||
59 | if (sk->sk_state == TCP_LISTEN) { | ||
60 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | ||
61 | lock = &hashinfo->lhash_lock; | ||
62 | inet_listen_wlock(hashinfo); | ||
63 | } else { | ||
64 | unsigned int hash; | ||
65 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); | ||
66 | hash &= (hashinfo->ehash_size - 1); | ||
67 | list = &hashinfo->ehash[hash].chain; | ||
68 | lock = &hashinfo->ehash[hash].lock; | ||
69 | write_lock(lock); | ||
70 | } | ||
71 | |||
72 | __sk_add_node(sk, list); | ||
73 | sock_prot_inc_use(sk->sk_prot); | ||
74 | write_unlock(lock); | ||
75 | } | ||
76 | 52 | ||
77 | /* | 53 | /* |
78 | * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so | 54 | * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so |
@@ -80,52 +56,12 @@ static inline void __inet6_hash(struct inet_hashinfo *hashinfo, | |||
80 | * | 56 | * |
81 | * The sockhash lock must be held as a reader here. | 57 | * The sockhash lock must be held as a reader here. |
82 | */ | 58 | */ |
83 | static inline struct sock * | 59 | extern struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo, |
84 | __inet6_lookup_established(struct inet_hashinfo *hashinfo, | ||
85 | const struct in6_addr *saddr, | 60 | const struct in6_addr *saddr, |
86 | const u16 sport, | 61 | const u16 sport, |
87 | const struct in6_addr *daddr, | 62 | const struct in6_addr *daddr, |
88 | const u16 hnum, | 63 | const u16 hnum, |
89 | const int dif) | 64 | const int dif); |
90 | { | ||
91 | struct sock *sk; | ||
92 | const struct hlist_node *node; | ||
93 | const __u32 ports = INET_COMBINED_PORTS(sport, hnum); | ||
94 | /* Optimize here for direct hit, only listening connections can | ||
95 | * have wildcards anyways. | ||
96 | */ | ||
97 | unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport); | ||
98 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | ||
99 | |||
100 | prefetch(head->chain.first); | ||
101 | read_lock(&head->lock); | ||
102 | sk_for_each(sk, node, &head->chain) { | ||
103 | /* For IPV6 do the cheaper port and family tests first. */ | ||
104 | if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif)) | ||
105 | goto hit; /* You sunk my battleship! */ | ||
106 | } | ||
107 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
108 | sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { | ||
109 | const struct inet_timewait_sock *tw = inet_twsk(sk); | ||
110 | |||
111 | if(*((__u32 *)&(tw->tw_dport)) == ports && | ||
112 | sk->sk_family == PF_INET6) { | ||
113 | const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); | ||
114 | |||
115 | if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && | ||
116 | ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && | ||
117 | (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif)) | ||
118 | goto hit; | ||
119 | } | ||
120 | } | ||
121 | read_unlock(&head->lock); | ||
122 | return NULL; | ||
123 | |||
124 | hit: | ||
125 | sock_hold(sk); | ||
126 | read_unlock(&head->lock); | ||
127 | return sk; | ||
128 | } | ||
129 | 65 | ||
130 | extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, | 66 | extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, |
131 | const struct in6_addr *daddr, | 67 | const struct in6_addr *daddr, |
diff --git a/include/net/ip.h b/include/net/ip.h index 8fe6156ca9b0..3d2e5ca62a5a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -95,6 +95,7 @@ extern int ip_local_deliver(struct sk_buff *skb); | |||
95 | extern int ip_mr_input(struct sk_buff *skb); | 95 | extern int ip_mr_input(struct sk_buff *skb); |
96 | extern int ip_output(struct sk_buff *skb); | 96 | extern int ip_output(struct sk_buff *skb); |
97 | extern int ip_mc_output(struct sk_buff *skb); | 97 | extern int ip_mc_output(struct sk_buff *skb); |
98 | extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); | ||
98 | extern int ip_do_nat(struct sk_buff *skb); | 99 | extern int ip_do_nat(struct sk_buff *skb); |
99 | extern void ip_send_check(struct iphdr *ip); | 100 | extern void ip_send_check(struct iphdr *ip); |
100 | extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); | 101 | extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); |
diff --git a/include/net/x25device.h b/include/net/x25device.h index 1a318374faef..1d10c879f7e2 100644 --- a/include/net/x25device.h +++ b/include/net/x25device.h | |||
@@ -8,6 +8,7 @@ | |||
8 | static inline __be16 x25_type_trans(struct sk_buff *skb, struct net_device *dev) | 8 | static inline __be16 x25_type_trans(struct sk_buff *skb, struct net_device *dev) |
9 | { | 9 | { |
10 | skb->mac.raw = skb->data; | 10 | skb->mac.raw = skb->data; |
11 | skb->dev = dev; | ||
11 | skb->pkt_type = PACKET_HOST; | 12 | skb->pkt_type = PACKET_HOST; |
12 | 13 | ||
13 | return htons(ETH_P_X25); | 14 | return htons(ETH_P_X25); |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index dc6862d09e53..de6ce541a046 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -140,7 +140,6 @@ struct scsi_host_template { | |||
140 | * | 140 | * |
141 | * Status: REQUIRED (at least one of them) | 141 | * Status: REQUIRED (at least one of them) |
142 | */ | 142 | */ |
143 | int (* eh_strategy_handler)(struct Scsi_Host *); | ||
144 | int (* eh_abort_handler)(struct scsi_cmnd *); | 143 | int (* eh_abort_handler)(struct scsi_cmnd *); |
145 | int (* eh_device_reset_handler)(struct scsi_cmnd *); | 144 | int (* eh_device_reset_handler)(struct scsi_cmnd *); |
146 | int (* eh_bus_reset_handler)(struct scsi_cmnd *); | 145 | int (* eh_bus_reset_handler)(struct scsi_cmnd *); |
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h index b3657f111937..cca1d4926d2a 100644 --- a/include/scsi/scsi_transport.h +++ b/include/scsi/scsi_transport.h | |||
@@ -50,6 +50,11 @@ struct scsi_transport_template { | |||
50 | unsigned int create_work_queue : 1; | 50 | unsigned int create_work_queue : 1; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Allows a transport to override the default error handler. | ||
54 | */ | ||
55 | void (* eh_strategy_handler)(struct Scsi_Host *); | ||
56 | |||
57 | /* | ||
53 | * This is an optional routine that allows the transport to become | 58 | * This is an optional routine that allows the transport to become |
54 | * involved when a scsi io timer fires. The return value tells the | 59 | * involved when a scsi io timer fires. The return value tells the |
55 | * timer routine how to finish the io timeout handling: | 60 | * timer routine how to finish the io timeout handling: |
diff --git a/init/Kconfig b/init/Kconfig index 3b36a1d53656..f1bc2f0e94e5 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -374,6 +374,15 @@ config SLAB | |||
374 | SLOB is more space efficient but does not scale well and is | 374 | SLOB is more space efficient but does not scale well and is |
375 | more susceptible to fragmentation. | 375 | more susceptible to fragmentation. |
376 | 376 | ||
377 | config DOUBLEFAULT | ||
378 | default y | ||
379 | bool "Enable doublefault exception handler" if EMBEDDED && X86_32 | ||
380 | help | ||
381 | This option allows trapping of rare doublefault exceptions that | ||
382 | would otherwise cause a system to silently reboot. Disabling this | ||
383 | option saves about 4k and might cause you much additional grey | ||
384 | hair. | ||
385 | |||
377 | endmenu # General setup | 386 | endmenu # General setup |
378 | 387 | ||
379 | config TINY_SHMEM | 388 | config TINY_SHMEM |
diff --git a/kernel/exit.c b/kernel/exit.c index 6c2eeb8f6390..1a9787ac6173 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/futex.h> | 35 | #include <linux/futex.h> |
36 | #include <linux/compat.h> | 36 | #include <linux/compat.h> |
37 | #include <linux/pipe_fs_i.h> | ||
37 | 38 | ||
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | #include <asm/unistd.h> | 40 | #include <asm/unistd.h> |
@@ -941,6 +942,9 @@ fastcall NORET_TYPE void do_exit(long code) | |||
941 | if (tsk->io_context) | 942 | if (tsk->io_context) |
942 | exit_io_context(); | 943 | exit_io_context(); |
943 | 944 | ||
945 | if (tsk->splice_pipe) | ||
946 | __free_pipe_info(tsk->splice_pipe); | ||
947 | |||
944 | /* PF_DEAD causes final put_task_struct after we schedule. */ | 948 | /* PF_DEAD causes final put_task_struct after we schedule. */ |
945 | preempt_disable(); | 949 | preempt_disable(); |
946 | BUG_ON(tsk->flags & PF_DEAD); | 950 | BUG_ON(tsk->flags & PF_DEAD); |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index f181ff4dd32e..d2a7296c8251 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -501,6 +501,7 @@ int hrtimer_cancel(struct hrtimer *timer) | |||
501 | 501 | ||
502 | if (ret >= 0) | 502 | if (ret >= 0) |
503 | return ret; | 503 | return ret; |
504 | cpu_relax(); | ||
504 | } | 505 | } |
505 | } | 506 | } |
506 | 507 | ||
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile index 2b33f852be3e..9f77f50d8143 100644 --- a/kernel/irq/Makefile +++ b/kernel/irq/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | 1 | ||
2 | obj-y := handle.o manage.o spurious.o migration.o | 2 | obj-y := handle.o manage.o spurious.o |
3 | obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o | 3 | obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o |
4 | obj-$(CONFIG_PROC_FS) += proc.o | 4 | obj-$(CONFIG_PROC_FS) += proc.o |
5 | obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o | ||
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index 52a8655fa080..134f9f2e0e39 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include <linux/irq.h> | ||
2 | 1 | ||
3 | #if defined(CONFIG_GENERIC_PENDING_IRQ) | 2 | #include <linux/irq.h> |
4 | 3 | ||
5 | void set_pending_irq(unsigned int irq, cpumask_t mask) | 4 | void set_pending_irq(unsigned int irq, cpumask_t mask) |
6 | { | 5 | { |
@@ -61,5 +60,3 @@ void move_native_irq(int irq) | |||
61 | } | 60 | } |
62 | cpus_clear(pending_irq_cpumask[irq]); | 61 | cpus_clear(pending_irq_cpumask[irq]); |
63 | } | 62 | } |
64 | |||
65 | #endif | ||
diff --git a/kernel/panic.c b/kernel/panic.c index f895c7c01d5b..cc2a4c9c36ac 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -27,7 +27,6 @@ static int pause_on_oops_flag; | |||
27 | static DEFINE_SPINLOCK(pause_on_oops_lock); | 27 | static DEFINE_SPINLOCK(pause_on_oops_lock); |
28 | 28 | ||
29 | int panic_timeout; | 29 | int panic_timeout; |
30 | EXPORT_SYMBOL(panic_timeout); | ||
31 | 30 | ||
32 | ATOMIC_NOTIFIER_HEAD(panic_notifier_list); | 31 | ATOMIC_NOTIFIER_HEAD(panic_notifier_list); |
33 | 32 | ||
diff --git a/kernel/sched.c b/kernel/sched.c index dd153d6f8a04..365f0b90b4de 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -665,13 +665,55 @@ static int effective_prio(task_t *p) | |||
665 | } | 665 | } |
666 | 666 | ||
667 | /* | 667 | /* |
668 | * We place interactive tasks back into the active array, if possible. | ||
669 | * | ||
670 | * To guarantee that this does not starve expired tasks we ignore the | ||
671 | * interactivity of a task if the first expired task had to wait more | ||
672 | * than a 'reasonable' amount of time. This deadline timeout is | ||
673 | * load-dependent, as the frequency of array switched decreases with | ||
674 | * increasing number of running tasks. We also ignore the interactivity | ||
675 | * if a better static_prio task has expired, and switch periodically | ||
676 | * regardless, to ensure that highly interactive tasks do not starve | ||
677 | * the less fortunate for unreasonably long periods. | ||
678 | */ | ||
679 | static inline int expired_starving(runqueue_t *rq) | ||
680 | { | ||
681 | int limit; | ||
682 | |||
683 | /* | ||
684 | * Arrays were recently switched, all is well | ||
685 | */ | ||
686 | if (!rq->expired_timestamp) | ||
687 | return 0; | ||
688 | |||
689 | limit = STARVATION_LIMIT * rq->nr_running; | ||
690 | |||
691 | /* | ||
692 | * It's time to switch arrays | ||
693 | */ | ||
694 | if (jiffies - rq->expired_timestamp >= limit) | ||
695 | return 1; | ||
696 | |||
697 | /* | ||
698 | * There's a better selection in the expired array | ||
699 | */ | ||
700 | if (rq->curr->static_prio > rq->best_expired_prio) | ||
701 | return 1; | ||
702 | |||
703 | /* | ||
704 | * All is well | ||
705 | */ | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | /* | ||
668 | * __activate_task - move a task to the runqueue. | 710 | * __activate_task - move a task to the runqueue. |
669 | */ | 711 | */ |
670 | static void __activate_task(task_t *p, runqueue_t *rq) | 712 | static void __activate_task(task_t *p, runqueue_t *rq) |
671 | { | 713 | { |
672 | prio_array_t *target = rq->active; | 714 | prio_array_t *target = rq->active; |
673 | 715 | ||
674 | if (batch_task(p)) | 716 | if (unlikely(batch_task(p) || (expired_starving(rq) && !rt_task(p)))) |
675 | target = rq->expired; | 717 | target = rq->expired; |
676 | enqueue_task(p, target); | 718 | enqueue_task(p, target); |
677 | rq->nr_running++; | 719 | rq->nr_running++; |
@@ -2490,22 +2532,6 @@ unsigned long long current_sched_time(const task_t *tsk) | |||
2490 | } | 2532 | } |
2491 | 2533 | ||
2492 | /* | 2534 | /* |
2493 | * We place interactive tasks back into the active array, if possible. | ||
2494 | * | ||
2495 | * To guarantee that this does not starve expired tasks we ignore the | ||
2496 | * interactivity of a task if the first expired task had to wait more | ||
2497 | * than a 'reasonable' amount of time. This deadline timeout is | ||
2498 | * load-dependent, as the frequency of array switched decreases with | ||
2499 | * increasing number of running tasks. We also ignore the interactivity | ||
2500 | * if a better static_prio task has expired: | ||
2501 | */ | ||
2502 | #define EXPIRED_STARVING(rq) \ | ||
2503 | ((STARVATION_LIMIT && ((rq)->expired_timestamp && \ | ||
2504 | (jiffies - (rq)->expired_timestamp >= \ | ||
2505 | STARVATION_LIMIT * ((rq)->nr_running) + 1))) || \ | ||
2506 | ((rq)->curr->static_prio > (rq)->best_expired_prio)) | ||
2507 | |||
2508 | /* | ||
2509 | * Account user cpu time to a process. | 2535 | * Account user cpu time to a process. |
2510 | * @p: the process that the cpu time gets accounted to | 2536 | * @p: the process that the cpu time gets accounted to |
2511 | * @hardirq_offset: the offset to subtract from hardirq_count() | 2537 | * @hardirq_offset: the offset to subtract from hardirq_count() |
@@ -2640,7 +2666,7 @@ void scheduler_tick(void) | |||
2640 | 2666 | ||
2641 | if (!rq->expired_timestamp) | 2667 | if (!rq->expired_timestamp) |
2642 | rq->expired_timestamp = jiffies; | 2668 | rq->expired_timestamp = jiffies; |
2643 | if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) { | 2669 | if (!TASK_INTERACTIVE(p) || expired_starving(rq)) { |
2644 | enqueue_task(p, rq->expired); | 2670 | enqueue_task(p, rq->expired); |
2645 | if (p->static_prio < rq->best_expired_prio) | 2671 | if (p->static_prio < rq->best_expired_prio) |
2646 | rq->best_expired_prio = p->static_prio; | 2672 | rq->best_expired_prio = p->static_prio; |
diff --git a/kernel/signal.c b/kernel/signal.c index 5ccaac505e8d..b14f895027c3 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -868,7 +868,6 @@ __group_complete_signal(int sig, struct task_struct *p) | |||
868 | if (t == NULL) | 868 | if (t == NULL) |
869 | /* restart balancing at this thread */ | 869 | /* restart balancing at this thread */ |
870 | t = p->signal->curr_target = p; | 870 | t = p->signal->curr_target = p; |
871 | BUG_ON(t->tgid != p->tgid); | ||
872 | 871 | ||
873 | while (!wants_signal(sig, t)) { | 872 | while (!wants_signal(sig, t)) { |
874 | t = next_thread(t); | 873 | t = next_thread(t); |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index d82864c4a617..5433195040f1 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
@@ -120,3 +120,15 @@ cond_syscall(sys32_sysctl); | |||
120 | cond_syscall(ppc_rtas); | 120 | cond_syscall(ppc_rtas); |
121 | cond_syscall(sys_spu_run); | 121 | cond_syscall(sys_spu_run); |
122 | cond_syscall(sys_spu_create); | 122 | cond_syscall(sys_spu_create); |
123 | |||
124 | /* mmu depending weak syscall entries */ | ||
125 | cond_syscall(sys_mprotect); | ||
126 | cond_syscall(sys_msync); | ||
127 | cond_syscall(sys_mlock); | ||
128 | cond_syscall(sys_munlock); | ||
129 | cond_syscall(sys_mlockall); | ||
130 | cond_syscall(sys_munlockall); | ||
131 | cond_syscall(sys_mincore); | ||
132 | cond_syscall(sys_madvise); | ||
133 | cond_syscall(sys_mremap); | ||
134 | cond_syscall(sys_remap_file_pages); | ||
diff --git a/kernel/timer.c b/kernel/timer.c index c3a874f1393c..883773788836 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -81,9 +81,10 @@ struct tvec_t_base_s { | |||
81 | } ____cacheline_aligned_in_smp; | 81 | } ____cacheline_aligned_in_smp; |
82 | 82 | ||
83 | typedef struct tvec_t_base_s tvec_base_t; | 83 | typedef struct tvec_t_base_s tvec_base_t; |
84 | static DEFINE_PER_CPU(tvec_base_t *, tvec_bases); | 84 | |
85 | tvec_base_t boot_tvec_bases; | 85 | tvec_base_t boot_tvec_bases; |
86 | EXPORT_SYMBOL(boot_tvec_bases); | 86 | EXPORT_SYMBOL(boot_tvec_bases); |
87 | static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = { &boot_tvec_bases }; | ||
87 | 88 | ||
88 | static inline void set_running_timer(tvec_base_t *base, | 89 | static inline void set_running_timer(tvec_base_t *base, |
89 | struct timer_list *timer) | 90 | struct timer_list *timer) |
@@ -1224,28 +1225,36 @@ static int __devinit init_timers_cpu(int cpu) | |||
1224 | { | 1225 | { |
1225 | int j; | 1226 | int j; |
1226 | tvec_base_t *base; | 1227 | tvec_base_t *base; |
1228 | static char __devinitdata tvec_base_done[NR_CPUS]; | ||
1227 | 1229 | ||
1228 | base = per_cpu(tvec_bases, cpu); | 1230 | if (!tvec_base_done[cpu]) { |
1229 | if (!base) { | ||
1230 | static char boot_done; | 1231 | static char boot_done; |
1231 | 1232 | ||
1232 | /* | ||
1233 | * Cannot do allocation in init_timers as that runs before the | ||
1234 | * allocator initializes (and would waste memory if there are | ||
1235 | * more possible CPUs than will ever be installed/brought up). | ||
1236 | */ | ||
1237 | if (boot_done) { | 1233 | if (boot_done) { |
1234 | /* | ||
1235 | * The APs use this path later in boot | ||
1236 | */ | ||
1238 | base = kmalloc_node(sizeof(*base), GFP_KERNEL, | 1237 | base = kmalloc_node(sizeof(*base), GFP_KERNEL, |
1239 | cpu_to_node(cpu)); | 1238 | cpu_to_node(cpu)); |
1240 | if (!base) | 1239 | if (!base) |
1241 | return -ENOMEM; | 1240 | return -ENOMEM; |
1242 | memset(base, 0, sizeof(*base)); | 1241 | memset(base, 0, sizeof(*base)); |
1242 | per_cpu(tvec_bases, cpu) = base; | ||
1243 | } else { | 1243 | } else { |
1244 | base = &boot_tvec_bases; | 1244 | /* |
1245 | * This is for the boot CPU - we use compile-time | ||
1246 | * static initialisation because per-cpu memory isn't | ||
1247 | * ready yet and because the memory allocators are not | ||
1248 | * initialised either. | ||
1249 | */ | ||
1245 | boot_done = 1; | 1250 | boot_done = 1; |
1251 | base = &boot_tvec_bases; | ||
1246 | } | 1252 | } |
1247 | per_cpu(tvec_bases, cpu) = base; | 1253 | tvec_base_done[cpu] = 1; |
1254 | } else { | ||
1255 | base = per_cpu(tvec_bases, cpu); | ||
1248 | } | 1256 | } |
1257 | |||
1249 | spin_lock_init(&base->lock); | 1258 | spin_lock_init(&base->lock); |
1250 | for (j = 0; j < TVN_SIZE; j++) { | 1259 | for (j = 0; j < TVN_SIZE; j++) { |
1251 | INIT_LIST_HEAD(base->tv5.vec + j); | 1260 | INIT_LIST_HEAD(base->tv5.vec + j); |
@@ -1455,7 +1464,7 @@ static void time_interpolator_update(long delta_nsec) | |||
1455 | */ | 1464 | */ |
1456 | if (jiffies % INTERPOLATOR_ADJUST == 0) | 1465 | if (jiffies % INTERPOLATOR_ADJUST == 0) |
1457 | { | 1466 | { |
1458 | if (time_interpolator->skips == 0 && time_interpolator->offset > TICK_NSEC) | 1467 | if (time_interpolator->skips == 0 && time_interpolator->offset > tick_nsec) |
1459 | time_interpolator->nsec_per_cyc--; | 1468 | time_interpolator->nsec_per_cyc--; |
1460 | if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0) | 1469 | if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0) |
1461 | time_interpolator->nsec_per_cyc++; | 1470 | time_interpolator->nsec_per_cyc++; |
diff --git a/lib/string.c b/lib/string.c index b3c28a3f6332..064f6315b1c3 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -362,6 +362,7 @@ size_t strspn(const char *s, const char *accept) | |||
362 | EXPORT_SYMBOL(strspn); | 362 | EXPORT_SYMBOL(strspn); |
363 | #endif | 363 | #endif |
364 | 364 | ||
365 | #ifndef __HAVE_ARCH_STRCSPN | ||
365 | /** | 366 | /** |
366 | * strcspn - Calculate the length of the initial substring of @s which does | 367 | * strcspn - Calculate the length of the initial substring of @s which does |
367 | * not contain letters in @reject | 368 | * not contain letters in @reject |
@@ -384,6 +385,7 @@ size_t strcspn(const char *s, const char *reject) | |||
384 | return count; | 385 | return count; |
385 | } | 386 | } |
386 | EXPORT_SYMBOL(strcspn); | 387 | EXPORT_SYMBOL(strcspn); |
388 | #endif | ||
387 | 389 | ||
388 | #ifndef __HAVE_ARCH_STRPBRK | 390 | #ifndef __HAVE_ARCH_STRPBRK |
389 | /** | 391 | /** |
@@ -403,6 +405,7 @@ char *strpbrk(const char *cs, const char *ct) | |||
403 | } | 405 | } |
404 | return NULL; | 406 | return NULL; |
405 | } | 407 | } |
408 | EXPORT_SYMBOL(strpbrk); | ||
406 | #endif | 409 | #endif |
407 | 410 | ||
408 | #ifndef __HAVE_ARCH_STRSEP | 411 | #ifndef __HAVE_ARCH_STRSEP |
@@ -467,7 +470,7 @@ EXPORT_SYMBOL(memset); | |||
467 | void *memcpy(void *dest, const void *src, size_t count) | 470 | void *memcpy(void *dest, const void *src, size_t count) |
468 | { | 471 | { |
469 | char *tmp = dest; | 472 | char *tmp = dest; |
470 | char *s = src; | 473 | const char *s = src; |
471 | 474 | ||
472 | while (count--) | 475 | while (count--) |
473 | *tmp++ = *s++; | 476 | *tmp++ = *s++; |
diff --git a/mm/bootmem.c b/mm/bootmem.c index d3e3bd2ffcea..d213feded10d 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -401,7 +401,7 @@ unsigned long __init free_all_bootmem (void) | |||
401 | return(free_all_bootmem_core(NODE_DATA(0))); | 401 | return(free_all_bootmem_core(NODE_DATA(0))); |
402 | } | 402 | } |
403 | 403 | ||
404 | void * __init __alloc_bootmem(unsigned long size, unsigned long align, unsigned long goal) | 404 | void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align, unsigned long goal) |
405 | { | 405 | { |
406 | bootmem_data_t *bdata; | 406 | bootmem_data_t *bdata; |
407 | void *ptr; | 407 | void *ptr; |
@@ -409,7 +409,14 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align, unsigned | |||
409 | list_for_each_entry(bdata, &bdata_list, list) | 409 | list_for_each_entry(bdata, &bdata_list, list) |
410 | if ((ptr = __alloc_bootmem_core(bdata, size, align, goal, 0))) | 410 | if ((ptr = __alloc_bootmem_core(bdata, size, align, goal, 0))) |
411 | return(ptr); | 411 | return(ptr); |
412 | return NULL; | ||
413 | } | ||
412 | 414 | ||
415 | void * __init __alloc_bootmem(unsigned long size, unsigned long align, unsigned long goal) | ||
416 | { | ||
417 | void *mem = __alloc_bootmem_nopanic(size,align,goal); | ||
418 | if (mem) | ||
419 | return mem; | ||
413 | /* | 420 | /* |
414 | * Whoops, we cannot satisfy the allocation request. | 421 | * Whoops, we cannot satisfy the allocation request. |
415 | */ | 422 | */ |
diff --git a/mm/migrate.c b/mm/migrate.c index 09f6e4aa87fc..d444229f2599 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -16,8 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/buffer_head.h> /* for try_to_release_page(), | 19 | #include <linux/buffer_head.h> |
20 | buffer_heads_over_limit */ | ||
21 | #include <linux/mm_inline.h> | 20 | #include <linux/mm_inline.h> |
22 | #include <linux/pagevec.h> | 21 | #include <linux/pagevec.h> |
23 | #include <linux/rmap.h> | 22 | #include <linux/rmap.h> |
@@ -28,8 +27,6 @@ | |||
28 | 27 | ||
29 | #include "internal.h" | 28 | #include "internal.h" |
30 | 29 | ||
31 | #include "internal.h" | ||
32 | |||
33 | /* The maximum number of pages to take off the LRU for migration */ | 30 | /* The maximum number of pages to take off the LRU for migration */ |
34 | #define MIGRATE_CHUNK_SIZE 256 | 31 | #define MIGRATE_CHUNK_SIZE 256 |
35 | 32 | ||
@@ -176,7 +173,6 @@ unlock_retry: | |||
176 | retry: | 173 | retry: |
177 | return -EAGAIN; | 174 | return -EAGAIN; |
178 | } | 175 | } |
179 | EXPORT_SYMBOL(swap_page); | ||
180 | 176 | ||
181 | /* | 177 | /* |
182 | * Remove references for a page and establish the new page with the correct | 178 | * Remove references for a page and establish the new page with the correct |
@@ -234,7 +230,7 @@ int migrate_page_remove_references(struct page *newpage, | |||
234 | if (!page_mapping(page) || page_count(page) != nr_refs || | 230 | if (!page_mapping(page) || page_count(page) != nr_refs || |
235 | *radix_pointer != page) { | 231 | *radix_pointer != page) { |
236 | write_unlock_irq(&mapping->tree_lock); | 232 | write_unlock_irq(&mapping->tree_lock); |
237 | return 1; | 233 | return -EAGAIN; |
238 | } | 234 | } |
239 | 235 | ||
240 | /* | 236 | /* |
@@ -121,14 +121,26 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
121 | * only call if we're about to fail. | 121 | * only call if we're about to fail. |
122 | */ | 122 | */ |
123 | n = nr_free_pages(); | 123 | n = nr_free_pages(); |
124 | |||
125 | /* | ||
126 | * Leave reserved pages. The pages are not for anonymous pages. | ||
127 | */ | ||
128 | if (n <= totalreserve_pages) | ||
129 | goto error; | ||
130 | else | ||
131 | n -= totalreserve_pages; | ||
132 | |||
133 | /* | ||
134 | * Leave the last 3% for root | ||
135 | */ | ||
124 | if (!cap_sys_admin) | 136 | if (!cap_sys_admin) |
125 | n -= n / 32; | 137 | n -= n / 32; |
126 | free += n; | 138 | free += n; |
127 | 139 | ||
128 | if (free > pages) | 140 | if (free > pages) |
129 | return 0; | 141 | return 0; |
130 | vm_unacct_memory(pages); | 142 | |
131 | return -ENOMEM; | 143 | goto error; |
132 | } | 144 | } |
133 | 145 | ||
134 | allowed = (totalram_pages - hugetlb_total_pages()) | 146 | allowed = (totalram_pages - hugetlb_total_pages()) |
@@ -150,7 +162,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
150 | */ | 162 | */ |
151 | if (atomic_read(&vm_committed_space) < (long)allowed) | 163 | if (atomic_read(&vm_committed_space) < (long)allowed) |
152 | return 0; | 164 | return 0; |
153 | 165 | error: | |
154 | vm_unacct_memory(pages); | 166 | vm_unacct_memory(pages); |
155 | 167 | ||
156 | return -ENOMEM; | 168 | return -ENOMEM; |
@@ -220,6 +232,17 @@ asmlinkage unsigned long sys_brk(unsigned long brk) | |||
220 | 232 | ||
221 | if (brk < mm->end_code) | 233 | if (brk < mm->end_code) |
222 | goto out; | 234 | goto out; |
235 | |||
236 | /* | ||
237 | * Check against rlimit here. If this check is done later after the test | ||
238 | * of oldbrk with newbrk then it can escape the test and let the data | ||
239 | * segment grow beyond its set limit the in case where the limit is | ||
240 | * not page aligned -Ram Gupta | ||
241 | */ | ||
242 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
243 | if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) | ||
244 | goto out; | ||
245 | |||
223 | newbrk = PAGE_ALIGN(brk); | 246 | newbrk = PAGE_ALIGN(brk); |
224 | oldbrk = PAGE_ALIGN(mm->brk); | 247 | oldbrk = PAGE_ALIGN(mm->brk); |
225 | if (oldbrk == newbrk) | 248 | if (oldbrk == newbrk) |
@@ -232,11 +255,6 @@ asmlinkage unsigned long sys_brk(unsigned long brk) | |||
232 | goto out; | 255 | goto out; |
233 | } | 256 | } |
234 | 257 | ||
235 | /* Check against rlimit.. */ | ||
236 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
237 | if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) | ||
238 | goto out; | ||
239 | |||
240 | /* Check against existing mmap mappings. */ | 258 | /* Check against existing mmap mappings. */ |
241 | if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) | 259 | if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) |
242 | goto out; | 260 | goto out; |
diff --git a/mm/nommu.c b/mm/nommu.c index db45efac17cc..029fadac0fb5 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1147,14 +1147,26 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
1147 | * only call if we're about to fail. | 1147 | * only call if we're about to fail. |
1148 | */ | 1148 | */ |
1149 | n = nr_free_pages(); | 1149 | n = nr_free_pages(); |
1150 | |||
1151 | /* | ||
1152 | * Leave reserved pages. The pages are not for anonymous pages. | ||
1153 | */ | ||
1154 | if (n <= totalreserve_pages) | ||
1155 | goto error; | ||
1156 | else | ||
1157 | n -= totalreserve_pages; | ||
1158 | |||
1159 | /* | ||
1160 | * Leave the last 3% for root | ||
1161 | */ | ||
1150 | if (!cap_sys_admin) | 1162 | if (!cap_sys_admin) |
1151 | n -= n / 32; | 1163 | n -= n / 32; |
1152 | free += n; | 1164 | free += n; |
1153 | 1165 | ||
1154 | if (free > pages) | 1166 | if (free > pages) |
1155 | return 0; | 1167 | return 0; |
1156 | vm_unacct_memory(pages); | 1168 | |
1157 | return -ENOMEM; | 1169 | goto error; |
1158 | } | 1170 | } |
1159 | 1171 | ||
1160 | allowed = totalram_pages * sysctl_overcommit_ratio / 100; | 1172 | allowed = totalram_pages * sysctl_overcommit_ratio / 100; |
@@ -1175,7 +1187,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
1175 | */ | 1187 | */ |
1176 | if (atomic_read(&vm_committed_space) < (long)allowed) | 1188 | if (atomic_read(&vm_committed_space) < (long)allowed) |
1177 | return 0; | 1189 | return 0; |
1178 | 1190 | error: | |
1179 | vm_unacct_memory(pages); | 1191 | vm_unacct_memory(pages); |
1180 | 1192 | ||
1181 | return -ENOMEM; | 1193 | return -ENOMEM; |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 6dcce3a4bbdc..75d7f48b79bb 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -72,13 +72,12 @@ int dirty_background_ratio = 10; | |||
72 | int vm_dirty_ratio = 40; | 72 | int vm_dirty_ratio = 40; |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * The interval between `kupdate'-style writebacks, in centiseconds | 75 | * The interval between `kupdate'-style writebacks, in jiffies |
76 | * (hundredths of a second) | ||
77 | */ | 76 | */ |
78 | int dirty_writeback_interval = 5 * HZ; | 77 | int dirty_writeback_interval = 5 * HZ; |
79 | 78 | ||
80 | /* | 79 | /* |
81 | * The longest number of centiseconds for which data is allowed to remain dirty | 80 | * The longest number of jiffies for which data is allowed to remain dirty |
82 | */ | 81 | */ |
83 | int dirty_expire_interval = 30 * HZ; | 82 | int dirty_expire_interval = 30 * HZ; |
84 | 83 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index dc523a1f270d..97d6827c7d66 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -51,6 +51,7 @@ nodemask_t node_possible_map __read_mostly = NODE_MASK_ALL; | |||
51 | EXPORT_SYMBOL(node_possible_map); | 51 | EXPORT_SYMBOL(node_possible_map); |
52 | unsigned long totalram_pages __read_mostly; | 52 | unsigned long totalram_pages __read_mostly; |
53 | unsigned long totalhigh_pages __read_mostly; | 53 | unsigned long totalhigh_pages __read_mostly; |
54 | unsigned long totalreserve_pages __read_mostly; | ||
54 | long nr_swap_pages; | 55 | long nr_swap_pages; |
55 | int percpu_pagelist_fraction; | 56 | int percpu_pagelist_fraction; |
56 | 57 | ||
@@ -151,7 +152,8 @@ static void bad_page(struct page *page) | |||
151 | 1 << PG_reclaim | | 152 | 1 << PG_reclaim | |
152 | 1 << PG_slab | | 153 | 1 << PG_slab | |
153 | 1 << PG_swapcache | | 154 | 1 << PG_swapcache | |
154 | 1 << PG_writeback ); | 155 | 1 << PG_writeback | |
156 | 1 << PG_buddy ); | ||
155 | set_page_count(page, 0); | 157 | set_page_count(page, 0); |
156 | reset_page_mapcount(page); | 158 | reset_page_mapcount(page); |
157 | page->mapping = NULL; | 159 | page->mapping = NULL; |
@@ -236,12 +238,12 @@ static inline unsigned long page_order(struct page *page) { | |||
236 | 238 | ||
237 | static inline void set_page_order(struct page *page, int order) { | 239 | static inline void set_page_order(struct page *page, int order) { |
238 | set_page_private(page, order); | 240 | set_page_private(page, order); |
239 | __SetPagePrivate(page); | 241 | __SetPageBuddy(page); |
240 | } | 242 | } |
241 | 243 | ||
242 | static inline void rmv_page_order(struct page *page) | 244 | static inline void rmv_page_order(struct page *page) |
243 | { | 245 | { |
244 | __ClearPagePrivate(page); | 246 | __ClearPageBuddy(page); |
245 | set_page_private(page, 0); | 247 | set_page_private(page, 0); |
246 | } | 248 | } |
247 | 249 | ||
@@ -280,11 +282,13 @@ __find_combined_index(unsigned long page_idx, unsigned int order) | |||
280 | * This function checks whether a page is free && is the buddy | 282 | * This function checks whether a page is free && is the buddy |
281 | * we can do coalesce a page and its buddy if | 283 | * we can do coalesce a page and its buddy if |
282 | * (a) the buddy is not in a hole && | 284 | * (a) the buddy is not in a hole && |
283 | * (b) the buddy is free && | 285 | * (b) the buddy is in the buddy system && |
284 | * (c) the buddy is on the buddy system && | 286 | * (c) a page and its buddy have the same order. |
285 | * (d) a page and its buddy have the same order. | 287 | * |
286 | * for recording page's order, we use page_private(page) and PG_private. | 288 | * For recording whether a page is in the buddy system, we use PG_buddy. |
289 | * Setting, clearing, and testing PG_buddy is serialized by zone->lock. | ||
287 | * | 290 | * |
291 | * For recording page's order, we use page_private(page). | ||
288 | */ | 292 | */ |
289 | static inline int page_is_buddy(struct page *page, int order) | 293 | static inline int page_is_buddy(struct page *page, int order) |
290 | { | 294 | { |
@@ -293,10 +297,10 @@ static inline int page_is_buddy(struct page *page, int order) | |||
293 | return 0; | 297 | return 0; |
294 | #endif | 298 | #endif |
295 | 299 | ||
296 | if (PagePrivate(page) && | 300 | if (PageBuddy(page) && page_order(page) == order) { |
297 | (page_order(page) == order) && | 301 | BUG_ON(page_count(page) != 0); |
298 | page_count(page) == 0) | ||
299 | return 1; | 302 | return 1; |
303 | } | ||
300 | return 0; | 304 | return 0; |
301 | } | 305 | } |
302 | 306 | ||
@@ -313,7 +317,7 @@ static inline int page_is_buddy(struct page *page, int order) | |||
313 | * as necessary, plus some accounting needed to play nicely with other | 317 | * as necessary, plus some accounting needed to play nicely with other |
314 | * parts of the VM system. | 318 | * parts of the VM system. |
315 | * At each level, we keep a list of pages, which are heads of continuous | 319 | * At each level, we keep a list of pages, which are heads of continuous |
316 | * free pages of length of (1 << order) and marked with PG_Private.Page's | 320 | * free pages of length of (1 << order) and marked with PG_buddy. Page's |
317 | * order is recorded in page_private(page) field. | 321 | * order is recorded in page_private(page) field. |
318 | * So when we are allocating or freeing one, we can derive the state of the | 322 | * So when we are allocating or freeing one, we can derive the state of the |
319 | * other. That is, if we allocate a small block, and both were | 323 | * other. That is, if we allocate a small block, and both were |
@@ -376,7 +380,8 @@ static inline int free_pages_check(struct page *page) | |||
376 | 1 << PG_slab | | 380 | 1 << PG_slab | |
377 | 1 << PG_swapcache | | 381 | 1 << PG_swapcache | |
378 | 1 << PG_writeback | | 382 | 1 << PG_writeback | |
379 | 1 << PG_reserved )))) | 383 | 1 << PG_reserved | |
384 | 1 << PG_buddy )))) | ||
380 | bad_page(page); | 385 | bad_page(page); |
381 | if (PageDirty(page)) | 386 | if (PageDirty(page)) |
382 | __ClearPageDirty(page); | 387 | __ClearPageDirty(page); |
@@ -524,7 +529,8 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | |||
524 | 1 << PG_slab | | 529 | 1 << PG_slab | |
525 | 1 << PG_swapcache | | 530 | 1 << PG_swapcache | |
526 | 1 << PG_writeback | | 531 | 1 << PG_writeback | |
527 | 1 << PG_reserved )))) | 532 | 1 << PG_reserved | |
533 | 1 << PG_buddy )))) | ||
528 | bad_page(page); | 534 | bad_page(page); |
529 | 535 | ||
530 | /* | 536 | /* |
@@ -2472,6 +2478,38 @@ void __init page_alloc_init(void) | |||
2472 | } | 2478 | } |
2473 | 2479 | ||
2474 | /* | 2480 | /* |
2481 | * calculate_totalreserve_pages - called when sysctl_lower_zone_reserve_ratio | ||
2482 | * or min_free_kbytes changes. | ||
2483 | */ | ||
2484 | static void calculate_totalreserve_pages(void) | ||
2485 | { | ||
2486 | struct pglist_data *pgdat; | ||
2487 | unsigned long reserve_pages = 0; | ||
2488 | int i, j; | ||
2489 | |||
2490 | for_each_online_pgdat(pgdat) { | ||
2491 | for (i = 0; i < MAX_NR_ZONES; i++) { | ||
2492 | struct zone *zone = pgdat->node_zones + i; | ||
2493 | unsigned long max = 0; | ||
2494 | |||
2495 | /* Find valid and maximum lowmem_reserve in the zone */ | ||
2496 | for (j = i; j < MAX_NR_ZONES; j++) { | ||
2497 | if (zone->lowmem_reserve[j] > max) | ||
2498 | max = zone->lowmem_reserve[j]; | ||
2499 | } | ||
2500 | |||
2501 | /* we treat pages_high as reserved pages. */ | ||
2502 | max += zone->pages_high; | ||
2503 | |||
2504 | if (max > zone->present_pages) | ||
2505 | max = zone->present_pages; | ||
2506 | reserve_pages += max; | ||
2507 | } | ||
2508 | } | ||
2509 | totalreserve_pages = reserve_pages; | ||
2510 | } | ||
2511 | |||
2512 | /* | ||
2475 | * setup_per_zone_lowmem_reserve - called whenever | 2513 | * setup_per_zone_lowmem_reserve - called whenever |
2476 | * sysctl_lower_zone_reserve_ratio changes. Ensures that each zone | 2514 | * sysctl_lower_zone_reserve_ratio changes. Ensures that each zone |
2477 | * has a correct pages reserved value, so an adequate number of | 2515 | * has a correct pages reserved value, so an adequate number of |
@@ -2502,6 +2540,9 @@ static void setup_per_zone_lowmem_reserve(void) | |||
2502 | } | 2540 | } |
2503 | } | 2541 | } |
2504 | } | 2542 | } |
2543 | |||
2544 | /* update totalreserve_pages */ | ||
2545 | calculate_totalreserve_pages(); | ||
2505 | } | 2546 | } |
2506 | 2547 | ||
2507 | /* | 2548 | /* |
@@ -2556,6 +2597,9 @@ void setup_per_zone_pages_min(void) | |||
2556 | zone->pages_high = zone->pages_min + tmp / 2; | 2597 | zone->pages_high = zone->pages_min + tmp / 2; |
2557 | spin_unlock_irqrestore(&zone->lru_lock, flags); | 2598 | spin_unlock_irqrestore(&zone->lru_lock, flags); |
2558 | } | 2599 | } |
2600 | |||
2601 | /* update totalreserve_pages */ | ||
2602 | calculate_totalreserve_pages(); | ||
2559 | } | 2603 | } |
2560 | 2604 | ||
2561 | /* | 2605 | /* |
@@ -420,6 +420,7 @@ struct kmem_cache { | |||
420 | unsigned long max_freeable; | 420 | unsigned long max_freeable; |
421 | unsigned long node_allocs; | 421 | unsigned long node_allocs; |
422 | unsigned long node_frees; | 422 | unsigned long node_frees; |
423 | unsigned long node_overflow; | ||
423 | atomic_t allochit; | 424 | atomic_t allochit; |
424 | atomic_t allocmiss; | 425 | atomic_t allocmiss; |
425 | atomic_t freehit; | 426 | atomic_t freehit; |
@@ -465,6 +466,7 @@ struct kmem_cache { | |||
465 | #define STATS_INC_ERR(x) ((x)->errors++) | 466 | #define STATS_INC_ERR(x) ((x)->errors++) |
466 | #define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++) | 467 | #define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++) |
467 | #define STATS_INC_NODEFREES(x) ((x)->node_frees++) | 468 | #define STATS_INC_NODEFREES(x) ((x)->node_frees++) |
469 | #define STATS_INC_ACOVERFLOW(x) ((x)->node_overflow++) | ||
468 | #define STATS_SET_FREEABLE(x, i) \ | 470 | #define STATS_SET_FREEABLE(x, i) \ |
469 | do { \ | 471 | do { \ |
470 | if ((x)->max_freeable < i) \ | 472 | if ((x)->max_freeable < i) \ |
@@ -484,6 +486,7 @@ struct kmem_cache { | |||
484 | #define STATS_INC_ERR(x) do { } while (0) | 486 | #define STATS_INC_ERR(x) do { } while (0) |
485 | #define STATS_INC_NODEALLOCS(x) do { } while (0) | 487 | #define STATS_INC_NODEALLOCS(x) do { } while (0) |
486 | #define STATS_INC_NODEFREES(x) do { } while (0) | 488 | #define STATS_INC_NODEFREES(x) do { } while (0) |
489 | #define STATS_INC_ACOVERFLOW(x) do { } while (0) | ||
487 | #define STATS_SET_FREEABLE(x, i) do { } while (0) | 490 | #define STATS_SET_FREEABLE(x, i) do { } while (0) |
488 | #define STATS_INC_ALLOCHIT(x) do { } while (0) | 491 | #define STATS_INC_ALLOCHIT(x) do { } while (0) |
489 | #define STATS_INC_ALLOCMISS(x) do { } while (0) | 492 | #define STATS_INC_ALLOCMISS(x) do { } while (0) |
@@ -1453,7 +1456,14 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
1453 | int i; | 1456 | int i; |
1454 | 1457 | ||
1455 | flags |= cachep->gfpflags; | 1458 | flags |= cachep->gfpflags; |
1459 | #ifndef CONFIG_MMU | ||
1460 | /* nommu uses slab's for process anonymous memory allocations, so | ||
1461 | * requires __GFP_COMP to properly refcount higher order allocations" | ||
1462 | */ | ||
1463 | page = alloc_pages_node(nodeid, (flags | __GFP_COMP), cachep->gfporder); | ||
1464 | #else | ||
1456 | page = alloc_pages_node(nodeid, flags, cachep->gfporder); | 1465 | page = alloc_pages_node(nodeid, flags, cachep->gfporder); |
1466 | #endif | ||
1457 | if (!page) | 1467 | if (!page) |
1458 | return NULL; | 1468 | return NULL; |
1459 | addr = page_address(page); | 1469 | addr = page_address(page); |
@@ -2318,13 +2328,15 @@ EXPORT_SYMBOL(kmem_cache_destroy); | |||
2318 | 2328 | ||
2319 | /* Get the memory for a slab management obj. */ | 2329 | /* Get the memory for a slab management obj. */ |
2320 | static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, | 2330 | static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, |
2321 | int colour_off, gfp_t local_flags) | 2331 | int colour_off, gfp_t local_flags, |
2332 | int nodeid) | ||
2322 | { | 2333 | { |
2323 | struct slab *slabp; | 2334 | struct slab *slabp; |
2324 | 2335 | ||
2325 | if (OFF_SLAB(cachep)) { | 2336 | if (OFF_SLAB(cachep)) { |
2326 | /* Slab management obj is off-slab. */ | 2337 | /* Slab management obj is off-slab. */ |
2327 | slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags); | 2338 | slabp = kmem_cache_alloc_node(cachep->slabp_cache, |
2339 | local_flags, nodeid); | ||
2328 | if (!slabp) | 2340 | if (!slabp) |
2329 | return NULL; | 2341 | return NULL; |
2330 | } else { | 2342 | } else { |
@@ -2334,6 +2346,7 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, | |||
2334 | slabp->inuse = 0; | 2346 | slabp->inuse = 0; |
2335 | slabp->colouroff = colour_off; | 2347 | slabp->colouroff = colour_off; |
2336 | slabp->s_mem = objp + colour_off; | 2348 | slabp->s_mem = objp + colour_off; |
2349 | slabp->nodeid = nodeid; | ||
2337 | return slabp; | 2350 | return slabp; |
2338 | } | 2351 | } |
2339 | 2352 | ||
@@ -2519,7 +2532,7 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
2519 | goto failed; | 2532 | goto failed; |
2520 | 2533 | ||
2521 | /* Get slab management. */ | 2534 | /* Get slab management. */ |
2522 | slabp = alloc_slabmgmt(cachep, objp, offset, local_flags); | 2535 | slabp = alloc_slabmgmt(cachep, objp, offset, local_flags, nodeid); |
2523 | if (!slabp) | 2536 | if (!slabp) |
2524 | goto opps1; | 2537 | goto opps1; |
2525 | 2538 | ||
@@ -3080,9 +3093,11 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) | |||
3080 | if (l3->alien && l3->alien[nodeid]) { | 3093 | if (l3->alien && l3->alien[nodeid]) { |
3081 | alien = l3->alien[nodeid]; | 3094 | alien = l3->alien[nodeid]; |
3082 | spin_lock(&alien->lock); | 3095 | spin_lock(&alien->lock); |
3083 | if (unlikely(alien->avail == alien->limit)) | 3096 | if (unlikely(alien->avail == alien->limit)) { |
3097 | STATS_INC_ACOVERFLOW(cachep); | ||
3084 | __drain_alien_cache(cachep, | 3098 | __drain_alien_cache(cachep, |
3085 | alien, nodeid); | 3099 | alien, nodeid); |
3100 | } | ||
3086 | alien->entry[alien->avail++] = objp; | 3101 | alien->entry[alien->avail++] = objp; |
3087 | spin_unlock(&alien->lock); | 3102 | spin_unlock(&alien->lock); |
3088 | } else { | 3103 | } else { |
@@ -3760,7 +3775,7 @@ static void print_slabinfo_header(struct seq_file *m) | |||
3760 | seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); | 3775 | seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); |
3761 | #if STATS | 3776 | #if STATS |
3762 | seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> " | 3777 | seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> " |
3763 | "<error> <maxfreeable> <nodeallocs> <remotefrees>"); | 3778 | "<error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow>"); |
3764 | seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>"); | 3779 | seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>"); |
3765 | #endif | 3780 | #endif |
3766 | seq_putc(m, '\n'); | 3781 | seq_putc(m, '\n'); |
@@ -3874,11 +3889,12 @@ static int s_show(struct seq_file *m, void *p) | |||
3874 | unsigned long max_freeable = cachep->max_freeable; | 3889 | unsigned long max_freeable = cachep->max_freeable; |
3875 | unsigned long node_allocs = cachep->node_allocs; | 3890 | unsigned long node_allocs = cachep->node_allocs; |
3876 | unsigned long node_frees = cachep->node_frees; | 3891 | unsigned long node_frees = cachep->node_frees; |
3892 | unsigned long overflows = cachep->node_overflow; | ||
3877 | 3893 | ||
3878 | seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \ | 3894 | seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \ |
3879 | %4lu %4lu %4lu %4lu", allocs, high, grown, | 3895 | %4lu %4lu %4lu %4lu %4lu", allocs, high, grown, |
3880 | reaped, errors, max_freeable, node_allocs, | 3896 | reaped, errors, max_freeable, node_allocs, |
3881 | node_frees); | 3897 | node_frees, overflows); |
3882 | } | 3898 | } |
3883 | /* cpu stats */ | 3899 | /* cpu stats */ |
3884 | { | 3900 | { |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 6b61323ce23c..0c2d13ad69bb 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -255,7 +255,7 @@ static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | if ((err = hci_send_sco(conn->hcon, skb)) < 0) | 257 | if ((err = hci_send_sco(conn->hcon, skb)) < 0) |
258 | goto fail; | 258 | return err; |
259 | 259 | ||
260 | return count; | 260 | return count; |
261 | 261 | ||
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index f29450b788be..3da9264449f7 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -765,6 +765,15 @@ out: | |||
765 | return NF_STOLEN; | 765 | return NF_STOLEN; |
766 | } | 766 | } |
767 | 767 | ||
768 | static int br_nf_dev_queue_xmit(struct sk_buff *skb) | ||
769 | { | ||
770 | if (skb->protocol == htons(ETH_P_IP) && | ||
771 | skb->len > skb->dev->mtu && | ||
772 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | ||
773 | return ip_fragment(skb, br_dev_queue_push_xmit); | ||
774 | else | ||
775 | return br_dev_queue_push_xmit(skb); | ||
776 | } | ||
768 | 777 | ||
769 | /* PF_BRIDGE/POST_ROUTING ********************************************/ | 778 | /* PF_BRIDGE/POST_ROUTING ********************************************/ |
770 | static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, | 779 | static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, |
@@ -824,7 +833,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, | |||
824 | realoutdev = nf_bridge->netoutdev; | 833 | realoutdev = nf_bridge->netoutdev; |
825 | #endif | 834 | #endif |
826 | NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, | 835 | NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, |
827 | br_dev_queue_push_xmit); | 836 | br_nf_dev_queue_xmit); |
828 | 837 | ||
829 | return NF_STOLEN; | 838 | return NF_STOLEN; |
830 | 839 | ||
@@ -869,7 +878,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, | |||
869 | 878 | ||
870 | if ((out->hard_start_xmit == br_dev_xmit && | 879 | if ((out->hard_start_xmit == br_dev_xmit && |
871 | okfn != br_nf_forward_finish && | 880 | okfn != br_nf_forward_finish && |
872 | okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit) | 881 | okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit) |
873 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 882 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
874 | || ((out->priv_flags & IFF_802_1Q_VLAN) && | 883 | || ((out->priv_flags & IFF_802_1Q_VLAN) && |
875 | VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) | 884 | VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 01eae97c53d9..66bd93252c4e 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -829,7 +829,7 @@ static int translate_table(struct ebt_replace *repl, | |||
829 | * sizeof(struct ebt_chainstack)); | 829 | * sizeof(struct ebt_chainstack)); |
830 | if (!newinfo->chainstack) | 830 | if (!newinfo->chainstack) |
831 | return -ENOMEM; | 831 | return -ENOMEM; |
832 | for_each_cpu(i) { | 832 | for_each_possible_cpu(i) { |
833 | newinfo->chainstack[i] = | 833 | newinfo->chainstack[i] = |
834 | vmalloc(udc_cnt * sizeof(struct ebt_chainstack)); | 834 | vmalloc(udc_cnt * sizeof(struct ebt_chainstack)); |
835 | if (!newinfo->chainstack[i]) { | 835 | if (!newinfo->chainstack[i]) { |
@@ -901,7 +901,7 @@ static void get_counters(struct ebt_counter *oldcounters, | |||
901 | sizeof(struct ebt_counter) * nentries); | 901 | sizeof(struct ebt_counter) * nentries); |
902 | 902 | ||
903 | /* add other counters to those of cpu 0 */ | 903 | /* add other counters to those of cpu 0 */ |
904 | for_each_cpu(cpu) { | 904 | for_each_possible_cpu(cpu) { |
905 | if (cpu == 0) | 905 | if (cpu == 0) |
906 | continue; | 906 | continue; |
907 | counter_base = COUNTER_BASE(oldcounters, nentries, cpu); | 907 | counter_base = COUNTER_BASE(oldcounters, nentries, cpu); |
@@ -1036,7 +1036,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
1036 | 1036 | ||
1037 | vfree(table->entries); | 1037 | vfree(table->entries); |
1038 | if (table->chainstack) { | 1038 | if (table->chainstack) { |
1039 | for_each_cpu(i) | 1039 | for_each_possible_cpu(i) |
1040 | vfree(table->chainstack[i]); | 1040 | vfree(table->chainstack[i]); |
1041 | vfree(table->chainstack); | 1041 | vfree(table->chainstack); |
1042 | } | 1042 | } |
@@ -1054,7 +1054,7 @@ free_counterstmp: | |||
1054 | vfree(counterstmp); | 1054 | vfree(counterstmp); |
1055 | /* can be initialized in translate_table() */ | 1055 | /* can be initialized in translate_table() */ |
1056 | if (newinfo->chainstack) { | 1056 | if (newinfo->chainstack) { |
1057 | for_each_cpu(i) | 1057 | for_each_possible_cpu(i) |
1058 | vfree(newinfo->chainstack[i]); | 1058 | vfree(newinfo->chainstack[i]); |
1059 | vfree(newinfo->chainstack); | 1059 | vfree(newinfo->chainstack); |
1060 | } | 1060 | } |
@@ -1201,7 +1201,7 @@ free_unlock: | |||
1201 | mutex_unlock(&ebt_mutex); | 1201 | mutex_unlock(&ebt_mutex); |
1202 | free_chainstack: | 1202 | free_chainstack: |
1203 | if (newinfo->chainstack) { | 1203 | if (newinfo->chainstack) { |
1204 | for_each_cpu(i) | 1204 | for_each_possible_cpu(i) |
1205 | vfree(newinfo->chainstack[i]); | 1205 | vfree(newinfo->chainstack[i]); |
1206 | vfree(newinfo->chainstack); | 1206 | vfree(newinfo->chainstack); |
1207 | } | 1207 | } |
@@ -1224,7 +1224,7 @@ void ebt_unregister_table(struct ebt_table *table) | |||
1224 | mutex_unlock(&ebt_mutex); | 1224 | mutex_unlock(&ebt_mutex); |
1225 | vfree(table->private->entries); | 1225 | vfree(table->private->entries); |
1226 | if (table->private->chainstack) { | 1226 | if (table->private->chainstack) { |
1227 | for_each_cpu(i) | 1227 | for_each_possible_cpu(i) |
1228 | vfree(table->private->chainstack[i]); | 1228 | vfree(table->private->chainstack[i]); |
1229 | vfree(table->private->chainstack); | 1229 | vfree(table->private->chainstack); |
1230 | } | 1230 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 434220d093aa..83231a27ae02 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3042,11 +3042,11 @@ void netdev_run_todo(void) | |||
3042 | 3042 | ||
3043 | switch(dev->reg_state) { | 3043 | switch(dev->reg_state) { |
3044 | case NETREG_REGISTERING: | 3044 | case NETREG_REGISTERING: |
3045 | dev->reg_state = NETREG_REGISTERED; | ||
3045 | err = netdev_register_sysfs(dev); | 3046 | err = netdev_register_sysfs(dev); |
3046 | if (err) | 3047 | if (err) |
3047 | printk(KERN_ERR "%s: failed sysfs registration (%d)\n", | 3048 | printk(KERN_ERR "%s: failed sysfs registration (%d)\n", |
3048 | dev->name, err); | 3049 | dev->name, err); |
3049 | dev->reg_state = NETREG_REGISTERED; | ||
3050 | break; | 3050 | break; |
3051 | 3051 | ||
3052 | case NETREG_UNREGISTERING: | 3052 | case NETREG_UNREGISTERING: |
@@ -3100,12 +3100,11 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name, | |||
3100 | alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; | 3100 | alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; |
3101 | alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; | 3101 | alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; |
3102 | 3102 | ||
3103 | p = kmalloc(alloc_size, GFP_KERNEL); | 3103 | p = kzalloc(alloc_size, GFP_KERNEL); |
3104 | if (!p) { | 3104 | if (!p) { |
3105 | printk(KERN_ERR "alloc_dev: Unable to allocate device.\n"); | 3105 | printk(KERN_ERR "alloc_dev: Unable to allocate device.\n"); |
3106 | return NULL; | 3106 | return NULL; |
3107 | } | 3107 | } |
3108 | memset(p, 0, alloc_size); | ||
3109 | 3108 | ||
3110 | dev = (struct net_device *) | 3109 | dev = (struct net_device *) |
3111 | (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); | 3110 | (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); |
@@ -3347,7 +3346,7 @@ static int __init net_dev_init(void) | |||
3347 | * Initialise the packet receive queues. | 3346 | * Initialise the packet receive queues. |
3348 | */ | 3347 | */ |
3349 | 3348 | ||
3350 | for_each_cpu(i) { | 3349 | for_each_possible_cpu(i) { |
3351 | struct softnet_data *queue; | 3350 | struct softnet_data *queue; |
3352 | 3351 | ||
3353 | queue = &per_cpu(softnet_data, i); | 3352 | queue = &per_cpu(softnet_data, i); |
diff --git a/net/core/dv.c b/net/core/dv.c index cf581407538c..29ee77f15932 100644 --- a/net/core/dv.c +++ b/net/core/dv.c | |||
@@ -55,15 +55,12 @@ int alloc_divert_blk(struct net_device *dev) | |||
55 | 55 | ||
56 | dev->divert = NULL; | 56 | dev->divert = NULL; |
57 | if (dev->type == ARPHRD_ETHER) { | 57 | if (dev->type == ARPHRD_ETHER) { |
58 | dev->divert = (struct divert_blk *) | 58 | dev->divert = kzalloc(alloc_size, GFP_KERNEL); |
59 | kmalloc(alloc_size, GFP_KERNEL); | ||
60 | if (dev->divert == NULL) { | 59 | if (dev->divert == NULL) { |
61 | printk(KERN_INFO "divert: unable to allocate divert_blk for %s\n", | 60 | printk(KERN_INFO "divert: unable to allocate divert_blk for %s\n", |
62 | dev->name); | 61 | dev->name); |
63 | return -ENOMEM; | 62 | return -ENOMEM; |
64 | } | 63 | } |
65 | |||
66 | memset(dev->divert, 0, sizeof(struct divert_blk)); | ||
67 | dev_hold(dev); | 64 | dev_hold(dev); |
68 | } | 65 | } |
69 | 66 | ||
diff --git a/net/core/flow.c b/net/core/flow.c index 55789f832eda..2191af5f26ac 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -79,7 +79,7 @@ static void flow_cache_new_hashrnd(unsigned long arg) | |||
79 | { | 79 | { |
80 | int i; | 80 | int i; |
81 | 81 | ||
82 | for_each_cpu(i) | 82 | for_each_possible_cpu(i) |
83 | flow_hash_rnd_recalc(i) = 1; | 83 | flow_hash_rnd_recalc(i) = 1; |
84 | 84 | ||
85 | flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; | 85 | flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; |
@@ -318,12 +318,10 @@ static void __devinit flow_cache_cpu_prepare(int cpu) | |||
318 | /* NOTHING */; | 318 | /* NOTHING */; |
319 | 319 | ||
320 | flow_table(cpu) = (struct flow_cache_entry **) | 320 | flow_table(cpu) = (struct flow_cache_entry **) |
321 | __get_free_pages(GFP_KERNEL, order); | 321 | __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); |
322 | if (!flow_table(cpu)) | 322 | if (!flow_table(cpu)) |
323 | panic("NET: failed to allocate flow cache order %lu\n", order); | 323 | panic("NET: failed to allocate flow cache order %lu\n", order); |
324 | 324 | ||
325 | memset(flow_table(cpu), 0, PAGE_SIZE << order); | ||
326 | |||
327 | flow_hash_rnd_recalc(cpu) = 1; | 325 | flow_hash_rnd_recalc(cpu) = 1; |
328 | flow_count(cpu) = 0; | 326 | flow_count(cpu) = 0; |
329 | 327 | ||
@@ -363,7 +361,7 @@ static int __init flow_cache_init(void) | |||
363 | flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; | 361 | flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; |
364 | add_timer(&flow_hash_rnd_timer); | 362 | add_timer(&flow_hash_rnd_timer); |
365 | 363 | ||
366 | for_each_cpu(i) | 364 | for_each_possible_cpu(i) |
367 | flow_cache_cpu_prepare(i); | 365 | flow_cache_cpu_prepare(i); |
368 | 366 | ||
369 | hotcpu_notifier(flow_cache_cpu, 0); | 367 | hotcpu_notifier(flow_cache_cpu, 0); |
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index b07c029e8219..3cad026764f0 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -159,11 +159,10 @@ int gen_new_estimator(struct gnet_stats_basic *bstats, | |||
159 | if (parm->interval < -2 || parm->interval > 3) | 159 | if (parm->interval < -2 || parm->interval > 3) |
160 | return -EINVAL; | 160 | return -EINVAL; |
161 | 161 | ||
162 | est = kmalloc(sizeof(*est), GFP_KERNEL); | 162 | est = kzalloc(sizeof(*est), GFP_KERNEL); |
163 | if (est == NULL) | 163 | if (est == NULL) |
164 | return -ENOBUFS; | 164 | return -ENOBUFS; |
165 | 165 | ||
166 | memset(est, 0, sizeof(*est)); | ||
167 | est->interval = parm->interval + 2; | 166 | est->interval = parm->interval + 2; |
168 | est->bstats = bstats; | 167 | est->bstats = bstats; |
169 | est->rate_est = rate_est; | 168 | est->rate_est = rate_est; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 0c8666872d10..4cf878efdb49 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -284,14 +284,11 @@ static struct neighbour **neigh_hash_alloc(unsigned int entries) | |||
284 | struct neighbour **ret; | 284 | struct neighbour **ret; |
285 | 285 | ||
286 | if (size <= PAGE_SIZE) { | 286 | if (size <= PAGE_SIZE) { |
287 | ret = kmalloc(size, GFP_ATOMIC); | 287 | ret = kzalloc(size, GFP_ATOMIC); |
288 | } else { | 288 | } else { |
289 | ret = (struct neighbour **) | 289 | ret = (struct neighbour **) |
290 | __get_free_pages(GFP_ATOMIC, get_order(size)); | 290 | __get_free_pages(GFP_ATOMIC|__GFP_ZERO, get_order(size)); |
291 | } | 291 | } |
292 | if (ret) | ||
293 | memset(ret, 0, size); | ||
294 | |||
295 | return ret; | 292 | return ret; |
296 | } | 293 | } |
297 | 294 | ||
@@ -1089,8 +1086,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | |||
1089 | if (hh->hh_type == protocol) | 1086 | if (hh->hh_type == protocol) |
1090 | break; | 1087 | break; |
1091 | 1088 | ||
1092 | if (!hh && (hh = kmalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) { | 1089 | if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) { |
1093 | memset(hh, 0, sizeof(struct hh_cache)); | ||
1094 | rwlock_init(&hh->hh_lock); | 1090 | rwlock_init(&hh->hh_lock); |
1095 | hh->hh_type = protocol; | 1091 | hh->hh_type = protocol; |
1096 | atomic_set(&hh->hh_refcnt, 0); | 1092 | atomic_set(&hh->hh_refcnt, 0); |
@@ -1366,13 +1362,11 @@ void neigh_table_init(struct neigh_table *tbl) | |||
1366 | tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1); | 1362 | tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1); |
1367 | 1363 | ||
1368 | phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); | 1364 | phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); |
1369 | tbl->phash_buckets = kmalloc(phsize, GFP_KERNEL); | 1365 | tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); |
1370 | 1366 | ||
1371 | if (!tbl->hash_buckets || !tbl->phash_buckets) | 1367 | if (!tbl->hash_buckets || !tbl->phash_buckets) |
1372 | panic("cannot allocate neighbour cache hashes"); | 1368 | panic("cannot allocate neighbour cache hashes"); |
1373 | 1369 | ||
1374 | memset(tbl->phash_buckets, 0, phsize); | ||
1375 | |||
1376 | get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); | 1370 | get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); |
1377 | 1371 | ||
1378 | rwlock_init(&tbl->lock); | 1372 | rwlock_init(&tbl->lock); |
@@ -1633,7 +1627,7 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | |||
1633 | 1627 | ||
1634 | memset(&ndst, 0, sizeof(ndst)); | 1628 | memset(&ndst, 0, sizeof(ndst)); |
1635 | 1629 | ||
1636 | for_each_cpu(cpu) { | 1630 | for_each_possible_cpu(cpu) { |
1637 | struct neigh_statistics *st; | 1631 | struct neigh_statistics *st; |
1638 | 1632 | ||
1639 | st = per_cpu_ptr(tbl->stats, cpu); | 1633 | st = per_cpu_ptr(tbl->stats, cpu); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 21b68464cabb..c12990c9c603 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -165,7 +165,7 @@ static ssize_t show_operstate(struct class_device *dev, char *buf) | |||
165 | operstate = IF_OPER_DOWN; | 165 | operstate = IF_OPER_DOWN; |
166 | read_unlock(&dev_base_lock); | 166 | read_unlock(&dev_base_lock); |
167 | 167 | ||
168 | if (operstate >= sizeof(operstates)) | 168 | if (operstate >= ARRAY_SIZE(operstates)) |
169 | return -EINVAL; /* should not happen */ | 169 | return -EINVAL; /* should not happen */ |
170 | 170 | ||
171 | return sprintf(buf, "%s\n", operstates[operstate]); | 171 | return sprintf(buf, "%s\n", operstates[operstate]); |
diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 1e44eda1fda9..79ebd75fbe4d 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c | |||
@@ -38,13 +38,11 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, | |||
38 | { | 38 | { |
39 | const int lopt_size = sizeof(struct listen_sock) + | 39 | const int lopt_size = sizeof(struct listen_sock) + |
40 | nr_table_entries * sizeof(struct request_sock *); | 40 | nr_table_entries * sizeof(struct request_sock *); |
41 | struct listen_sock *lopt = kmalloc(lopt_size, GFP_KERNEL); | 41 | struct listen_sock *lopt = kzalloc(lopt_size, GFP_KERNEL); |
42 | 42 | ||
43 | if (lopt == NULL) | 43 | if (lopt == NULL) |
44 | return -ENOMEM; | 44 | return -ENOMEM; |
45 | 45 | ||
46 | memset(lopt, 0, lopt_size); | ||
47 | |||
48 | for (lopt->max_qlen_log = 6; | 46 | for (lopt->max_qlen_log = 6; |
49 | (1 << lopt->max_qlen_log) < sysctl_max_syn_backlog; | 47 | (1 << lopt->max_qlen_log) < sysctl_max_syn_backlog; |
50 | lopt->max_qlen_log++); | 48 | lopt->max_qlen_log++); |
diff --git a/net/core/utils.c b/net/core/utils.c index fdc4f38bc46c..4f96f389243d 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -121,7 +121,7 @@ void __init net_random_init(void) | |||
121 | { | 121 | { |
122 | int i; | 122 | int i; |
123 | 123 | ||
124 | for_each_cpu(i) { | 124 | for_each_possible_cpu(i) { |
125 | struct nrnd_state *state = &per_cpu(net_rand_state,i); | 125 | struct nrnd_state *state = &per_cpu(net_rand_state,i); |
126 | __net_srandom(state, i+jiffies); | 126 | __net_srandom(state, i+jiffies); |
127 | } | 127 | } |
@@ -133,7 +133,7 @@ static int net_random_reseed(void) | |||
133 | unsigned long seed[NR_CPUS]; | 133 | unsigned long seed[NR_CPUS]; |
134 | 134 | ||
135 | get_random_bytes(seed, sizeof(seed)); | 135 | get_random_bytes(seed, sizeof(seed)); |
136 | for_each_cpu(i) { | 136 | for_each_possible_cpu(i) { |
137 | struct nrnd_state *state = &per_cpu(net_rand_state,i); | 137 | struct nrnd_state *state = &per_cpu(net_rand_state,i); |
138 | __net_srandom(state, seed[i]); | 138 | __net_srandom(state, seed[i]); |
139 | } | 139 | } |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index ccd3efc6a173..95a639f2e3db 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -50,7 +50,7 @@ | |||
50 | * Patrick McHardy <kaber@trash.net> | 50 | * Patrick McHardy <kaber@trash.net> |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #define VERSION "0.406" | 53 | #define VERSION "0.407" |
54 | 54 | ||
55 | #include <linux/config.h> | 55 | #include <linux/config.h> |
56 | #include <asm/uaccess.h> | 56 | #include <asm/uaccess.h> |
@@ -314,11 +314,6 @@ static void __leaf_free_rcu(struct rcu_head *head) | |||
314 | kfree(container_of(head, struct leaf, rcu)); | 314 | kfree(container_of(head, struct leaf, rcu)); |
315 | } | 315 | } |
316 | 316 | ||
317 | static inline void free_leaf(struct leaf *leaf) | ||
318 | { | ||
319 | call_rcu(&leaf->rcu, __leaf_free_rcu); | ||
320 | } | ||
321 | |||
322 | static void __leaf_info_free_rcu(struct rcu_head *head) | 317 | static void __leaf_info_free_rcu(struct rcu_head *head) |
323 | { | 318 | { |
324 | kfree(container_of(head, struct leaf_info, rcu)); | 319 | kfree(container_of(head, struct leaf_info, rcu)); |
@@ -357,7 +352,12 @@ static void __tnode_free_rcu(struct rcu_head *head) | |||
357 | 352 | ||
358 | static inline void tnode_free(struct tnode *tn) | 353 | static inline void tnode_free(struct tnode *tn) |
359 | { | 354 | { |
360 | call_rcu(&tn->rcu, __tnode_free_rcu); | 355 | if(IS_LEAF(tn)) { |
356 | struct leaf *l = (struct leaf *) tn; | ||
357 | call_rcu_bh(&l->rcu, __leaf_free_rcu); | ||
358 | } | ||
359 | else | ||
360 | call_rcu(&tn->rcu, __tnode_free_rcu); | ||
361 | } | 361 | } |
362 | 362 | ||
363 | static struct leaf *leaf_new(void) | 363 | static struct leaf *leaf_new(void) |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 9831fd2c73a0..2a0455911ee0 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -1107,7 +1107,7 @@ void __init icmp_init(struct net_proto_family *ops) | |||
1107 | struct inet_sock *inet; | 1107 | struct inet_sock *inet; |
1108 | int i; | 1108 | int i; |
1109 | 1109 | ||
1110 | for_each_cpu(i) { | 1110 | for_each_possible_cpu(i) { |
1111 | int err; | 1111 | int err; |
1112 | 1112 | ||
1113 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | 1113 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2a8adda15e11..da734c439179 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -304,13 +304,17 @@ out: | |||
304 | 304 | ||
305 | /* Creation primitives. */ | 305 | /* Creation primitives. */ |
306 | 306 | ||
307 | static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) | 307 | static struct ipq *ip_frag_intern(struct ipq *qp_in) |
308 | { | 308 | { |
309 | struct ipq *qp; | 309 | struct ipq *qp; |
310 | #ifdef CONFIG_SMP | 310 | #ifdef CONFIG_SMP |
311 | struct hlist_node *n; | 311 | struct hlist_node *n; |
312 | #endif | 312 | #endif |
313 | unsigned int hash; | ||
314 | |||
313 | write_lock(&ipfrag_lock); | 315 | write_lock(&ipfrag_lock); |
316 | hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr, | ||
317 | qp_in->protocol); | ||
314 | #ifdef CONFIG_SMP | 318 | #ifdef CONFIG_SMP |
315 | /* With SMP race we have to recheck hash table, because | 319 | /* With SMP race we have to recheck hash table, because |
316 | * such entry could be created on other cpu, while we | 320 | * such entry could be created on other cpu, while we |
@@ -345,7 +349,7 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) | |||
345 | } | 349 | } |
346 | 350 | ||
347 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ | 351 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ |
348 | static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | 352 | static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) |
349 | { | 353 | { |
350 | struct ipq *qp; | 354 | struct ipq *qp; |
351 | 355 | ||
@@ -371,7 +375,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | |||
371 | spin_lock_init(&qp->lock); | 375 | spin_lock_init(&qp->lock); |
372 | atomic_set(&qp->refcnt, 1); | 376 | atomic_set(&qp->refcnt, 1); |
373 | 377 | ||
374 | return ip_frag_intern(hash, qp); | 378 | return ip_frag_intern(qp); |
375 | 379 | ||
376 | out_nomem: | 380 | out_nomem: |
377 | LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); | 381 | LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); |
@@ -387,11 +391,12 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
387 | __u32 saddr = iph->saddr; | 391 | __u32 saddr = iph->saddr; |
388 | __u32 daddr = iph->daddr; | 392 | __u32 daddr = iph->daddr; |
389 | __u8 protocol = iph->protocol; | 393 | __u8 protocol = iph->protocol; |
390 | unsigned int hash = ipqhashfn(id, saddr, daddr, protocol); | 394 | unsigned int hash; |
391 | struct ipq *qp; | 395 | struct ipq *qp; |
392 | struct hlist_node *n; | 396 | struct hlist_node *n; |
393 | 397 | ||
394 | read_lock(&ipfrag_lock); | 398 | read_lock(&ipfrag_lock); |
399 | hash = ipqhashfn(id, saddr, daddr, protocol); | ||
395 | hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { | 400 | hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { |
396 | if(qp->id == id && | 401 | if(qp->id == id && |
397 | qp->saddr == saddr && | 402 | qp->saddr == saddr && |
@@ -405,7 +410,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
405 | } | 410 | } |
406 | read_unlock(&ipfrag_lock); | 411 | read_unlock(&ipfrag_lock); |
407 | 412 | ||
408 | return ip_frag_create(hash, iph, user); | 413 | return ip_frag_create(iph, user); |
409 | } | 414 | } |
410 | 415 | ||
411 | /* Is the fragment too far ahead to be part of ipq? */ | 416 | /* Is the fragment too far ahead to be part of ipq? */ |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 9981dcd68f11..ab99bebdcdc8 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -656,7 +656,7 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
656 | read_unlock(&ipgre_lock); | 656 | read_unlock(&ipgre_lock); |
657 | return(0); | 657 | return(0); |
658 | } | 658 | } |
659 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); | 659 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); |
660 | 660 | ||
661 | drop: | 661 | drop: |
662 | read_unlock(&ipgre_lock); | 662 | read_unlock(&ipgre_lock); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f75ff1d96551..8dcba3887f04 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -86,8 +86,6 @@ | |||
86 | 86 | ||
87 | int sysctl_ip_default_ttl = IPDEFTTL; | 87 | int sysctl_ip_default_ttl = IPDEFTTL; |
88 | 88 | ||
89 | static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); | ||
90 | |||
91 | /* Generate a checksum for an outgoing IP datagram. */ | 89 | /* Generate a checksum for an outgoing IP datagram. */ |
92 | __inline__ void ip_send_check(struct iphdr *iph) | 90 | __inline__ void ip_send_check(struct iphdr *iph) |
93 | { | 91 | { |
@@ -421,7 +419,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
421 | * single device frame, and queue such a frame for sending. | 419 | * single device frame, and queue such a frame for sending. |
422 | */ | 420 | */ |
423 | 421 | ||
424 | static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | 422 | int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
425 | { | 423 | { |
426 | struct iphdr *iph; | 424 | struct iphdr *iph; |
427 | int raw = 0; | 425 | int raw = 0; |
@@ -673,6 +671,8 @@ fail: | |||
673 | return err; | 671 | return err; |
674 | } | 672 | } |
675 | 673 | ||
674 | EXPORT_SYMBOL(ip_fragment); | ||
675 | |||
676 | int | 676 | int |
677 | ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) | 677 | ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) |
678 | { | 678 | { |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 0a1d86a0f632..04a429465665 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -290,7 +290,7 @@ static void ipcomp_free_scratches(void) | |||
290 | if (!scratches) | 290 | if (!scratches) |
291 | return; | 291 | return; |
292 | 292 | ||
293 | for_each_cpu(i) { | 293 | for_each_possible_cpu(i) { |
294 | void *scratch = *per_cpu_ptr(scratches, i); | 294 | void *scratch = *per_cpu_ptr(scratches, i); |
295 | if (scratch) | 295 | if (scratch) |
296 | vfree(scratch); | 296 | vfree(scratch); |
@@ -313,7 +313,7 @@ static void **ipcomp_alloc_scratches(void) | |||
313 | 313 | ||
314 | ipcomp_scratches = scratches; | 314 | ipcomp_scratches = scratches; |
315 | 315 | ||
316 | for_each_cpu(i) { | 316 | for_each_possible_cpu(i) { |
317 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); | 317 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); |
318 | if (!scratch) | 318 | if (!scratch) |
319 | return NULL; | 319 | return NULL; |
@@ -344,7 +344,7 @@ static void ipcomp_free_tfms(struct crypto_tfm **tfms) | |||
344 | if (!tfms) | 344 | if (!tfms) |
345 | return; | 345 | return; |
346 | 346 | ||
347 | for_each_cpu(cpu) { | 347 | for_each_possible_cpu(cpu) { |
348 | struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); | 348 | struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); |
349 | crypto_free_tfm(tfm); | 349 | crypto_free_tfm(tfm); |
350 | } | 350 | } |
@@ -384,7 +384,7 @@ static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name) | |||
384 | if (!tfms) | 384 | if (!tfms) |
385 | goto error; | 385 | goto error; |
386 | 386 | ||
387 | for_each_cpu(cpu) { | 387 | for_each_possible_cpu(cpu) { |
388 | struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); | 388 | struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); |
389 | if (!tfm) | 389 | if (!tfm) |
390 | goto error; | 390 | goto error; |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index eef07b0916a3..ea398ee43f28 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -474,9 +474,6 @@ static int ipip_rcv(struct sk_buff *skb) | |||
474 | struct iphdr *iph; | 474 | struct iphdr *iph; |
475 | struct ip_tunnel *tunnel; | 475 | struct ip_tunnel *tunnel; |
476 | 476 | ||
477 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
478 | goto out; | ||
479 | |||
480 | iph = skb->nh.iph; | 477 | iph = skb->nh.iph; |
481 | 478 | ||
482 | read_lock(&ipip_lock); | 479 | read_lock(&ipip_lock); |
@@ -508,7 +505,6 @@ static int ipip_rcv(struct sk_buff *skb) | |||
508 | } | 505 | } |
509 | read_unlock(&ipip_lock); | 506 | read_unlock(&ipip_lock); |
510 | 507 | ||
511 | out: | ||
512 | return -1; | 508 | return -1; |
513 | } | 509 | } |
514 | 510 | ||
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index b5ad9ac2fbcc..6a9e34b794bc 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -133,7 +133,7 @@ struct ip_rt_info { | |||
133 | u_int8_t tos; | 133 | u_int8_t tos; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static void queue_save(const struct sk_buff *skb, struct nf_info *info) | 136 | static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info) |
137 | { | 137 | { |
138 | struct ip_rt_info *rt_info = nf_info_reroute(info); | 138 | struct ip_rt_info *rt_info = nf_info_reroute(info); |
139 | 139 | ||
@@ -146,7 +146,7 @@ static void queue_save(const struct sk_buff *skb, struct nf_info *info) | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | static int queue_reroute(struct sk_buff **pskb, const struct nf_info *info) | 149 | static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info) |
150 | { | 150 | { |
151 | const struct ip_rt_info *rt_info = nf_info_reroute(info); | 151 | const struct ip_rt_info *rt_info = nf_info_reroute(info); |
152 | 152 | ||
@@ -161,20 +161,54 @@ static int queue_reroute(struct sk_buff **pskb, const struct nf_info *info) | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | static struct nf_queue_rerouter ip_reroute = { | 164 | unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook, |
165 | .rer_size = sizeof(struct ip_rt_info), | 165 | unsigned int dataoff, u_int8_t protocol) |
166 | .save = queue_save, | 166 | { |
167 | .reroute = queue_reroute, | 167 | struct iphdr *iph = skb->nh.iph; |
168 | unsigned int csum = 0; | ||
169 | |||
170 | switch (skb->ip_summed) { | ||
171 | case CHECKSUM_HW: | ||
172 | if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN) | ||
173 | break; | ||
174 | if ((protocol == 0 && !(u16)csum_fold(skb->csum)) || | ||
175 | !csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
176 | skb->len - dataoff, protocol, | ||
177 | skb->csum)) { | ||
178 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
179 | break; | ||
180 | } | ||
181 | /* fall through */ | ||
182 | case CHECKSUM_NONE: | ||
183 | if (protocol == 0) | ||
184 | skb->csum = 0; | ||
185 | else | ||
186 | skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, | ||
187 | skb->len - dataoff, | ||
188 | protocol, 0); | ||
189 | csum = __skb_checksum_complete(skb); | ||
190 | } | ||
191 | return csum; | ||
192 | } | ||
193 | |||
194 | EXPORT_SYMBOL(nf_ip_checksum); | ||
195 | |||
196 | static struct nf_afinfo nf_ip_afinfo = { | ||
197 | .family = AF_INET, | ||
198 | .checksum = nf_ip_checksum, | ||
199 | .saveroute = nf_ip_saveroute, | ||
200 | .reroute = nf_ip_reroute, | ||
201 | .route_key_size = sizeof(struct ip_rt_info), | ||
168 | }; | 202 | }; |
169 | 203 | ||
170 | static int ipv4_netfilter_init(void) | 204 | static int ipv4_netfilter_init(void) |
171 | { | 205 | { |
172 | return nf_register_queue_rerouter(PF_INET, &ip_reroute); | 206 | return nf_register_afinfo(&nf_ip_afinfo); |
173 | } | 207 | } |
174 | 208 | ||
175 | static void ipv4_netfilter_fini(void) | 209 | static void ipv4_netfilter_fini(void) |
176 | { | 210 | { |
177 | nf_unregister_queue_rerouter(PF_INET); | 211 | nf_unregister_afinfo(&nf_ip_afinfo); |
178 | } | 212 | } |
179 | 213 | ||
180 | module_init(ipv4_netfilter_init); | 214 | module_init(ipv4_netfilter_init); |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 77855ccd6b43..c60fd5c4ea1e 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -69,6 +69,7 @@ config IP_NF_CONNTRACK_NETLINK | |||
69 | tristate 'Connection tracking netlink interface (EXPERIMENTAL)' | 69 | tristate 'Connection tracking netlink interface (EXPERIMENTAL)' |
70 | depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK | 70 | depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK |
71 | depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m | 71 | depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m |
72 | depends on IP_NF_NAT=n || IP_NF_NAT | ||
72 | help | 73 | help |
73 | This option enables support for a netlink-based userspace interface | 74 | This option enables support for a netlink-based userspace interface |
74 | 75 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a44a5d73457d..c2d92f99a2b8 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -646,7 +646,7 @@ static int translate_table(const char *name, | |||
646 | } | 646 | } |
647 | 647 | ||
648 | /* And one copy for every other CPU */ | 648 | /* And one copy for every other CPU */ |
649 | for_each_cpu(i) { | 649 | for_each_possible_cpu(i) { |
650 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) | 650 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
651 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 651 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
652 | } | 652 | } |
@@ -696,7 +696,7 @@ static void get_counters(const struct xt_table_info *t, | |||
696 | counters, | 696 | counters, |
697 | &i); | 697 | &i); |
698 | 698 | ||
699 | for_each_cpu(cpu) { | 699 | for_each_possible_cpu(cpu) { |
700 | if (cpu == curcpu) | 700 | if (cpu == curcpu) |
701 | continue; | 701 | continue; |
702 | i = 0; | 702 | i = 0; |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index d0d379c7df9a..d7c472faa53b 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -181,33 +181,26 @@ static struct nf_hook_ops arpt_ops[] = { | |||
181 | 181 | ||
182 | static int __init arptable_filter_init(void) | 182 | static int __init arptable_filter_init(void) |
183 | { | 183 | { |
184 | int ret, i; | 184 | int ret; |
185 | 185 | ||
186 | /* Register table */ | 186 | /* Register table */ |
187 | ret = arpt_register_table(&packet_filter, &initial_table.repl); | 187 | ret = arpt_register_table(&packet_filter, &initial_table.repl); |
188 | if (ret < 0) | 188 | if (ret < 0) |
189 | return ret; | 189 | return ret; |
190 | 190 | ||
191 | for (i = 0; i < ARRAY_SIZE(arpt_ops); i++) | 191 | ret = nf_register_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); |
192 | if ((ret = nf_register_hook(&arpt_ops[i])) < 0) | 192 | if (ret < 0) |
193 | goto cleanup_hooks; | 193 | goto cleanup_table; |
194 | return ret; | 194 | return ret; |
195 | 195 | ||
196 | cleanup_hooks: | 196 | cleanup_table: |
197 | while (--i >= 0) | ||
198 | nf_unregister_hook(&arpt_ops[i]); | ||
199 | |||
200 | arpt_unregister_table(&packet_filter); | 197 | arpt_unregister_table(&packet_filter); |
201 | return ret; | 198 | return ret; |
202 | } | 199 | } |
203 | 200 | ||
204 | static void __exit arptable_filter_fini(void) | 201 | static void __exit arptable_filter_fini(void) |
205 | { | 202 | { |
206 | unsigned int i; | 203 | nf_unregister_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); |
207 | |||
208 | for (i = 0; i < ARRAY_SIZE(arpt_ops); i++) | ||
209 | nf_unregister_hook(&arpt_ops[i]); | ||
210 | |||
211 | arpt_unregister_table(&packet_filter); | 204 | arpt_unregister_table(&packet_filter); |
212 | } | 205 | } |
213 | 206 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index ceaabc18202b..979a2eac6f00 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -133,7 +133,7 @@ static void ip_ct_event_cache_flush(void) | |||
133 | struct ip_conntrack_ecache *ecache; | 133 | struct ip_conntrack_ecache *ecache; |
134 | int cpu; | 134 | int cpu; |
135 | 135 | ||
136 | for_each_cpu(cpu) { | 136 | for_each_possible_cpu(cpu) { |
137 | ecache = &per_cpu(ip_conntrack_ecache, cpu); | 137 | ecache = &per_cpu(ip_conntrack_ecache, cpu); |
138 | if (ecache->ct) | 138 | if (ecache->ct) |
139 | ip_conntrack_put(ecache->ct); | 139 | ip_conntrack_put(ecache->ct); |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index daeb1395faa4..2c2fb700d835 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | |||
@@ -9,37 +9,6 @@ | |||
9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> |
10 | * | 10 | * |
11 | * For more information, please see http://nath323.sourceforge.net/ | 11 | * For more information, please see http://nath323.sourceforge.net/ |
12 | * | ||
13 | * Changes: | ||
14 | * 2006-02-01 - initial version 0.1 | ||
15 | * | ||
16 | * 2006-02-20 - version 0.2 | ||
17 | * 1. Changed source format to follow kernel conventions | ||
18 | * 2. Deleted some unnecessary structures | ||
19 | * 3. Minor fixes | ||
20 | * | ||
21 | * 2006-03-10 - version 0.3 | ||
22 | * 1. Added support for multiple TPKTs in one packet (suggested by | ||
23 | * Patrick McHardy) | ||
24 | * 2. Avoid excessive stack usage (based on Patrick McHardy's patch) | ||
25 | * 3. Added support for non-linear skb (based on Patrick McHardy's patch) | ||
26 | * 4. Fixed missing H.245 module owner (Patrick McHardy) | ||
27 | * 5. Avoid long RAS expectation chains (Patrick McHardy) | ||
28 | * 6. Fixed incorrect __exit attribute (Patrick McHardy) | ||
29 | * 7. Eliminated unnecessary return code | ||
30 | * 8. Fixed incorrect use of NAT data from conntrack code (suggested by | ||
31 | * Patrick McHardy) | ||
32 | * 9. Fixed TTL calculation error in RCF | ||
33 | * 10. Added TTL support in RRQ | ||
34 | * 11. Better support for separate TPKT header and data | ||
35 | * | ||
36 | * 2006-03-15 - version 0.4 | ||
37 | * 1. Added support for T.120 channels | ||
38 | * 2. Added parameter gkrouted_only (suggested by Patrick McHardy) | ||
39 | * 3. Splitted ASN.1 code and data (suggested by Patrick McHardy) | ||
40 | * 4. Sort ASN.1 data to avoid forwarding declarations (suggested by | ||
41 | * Patrick McHardy) | ||
42 | * 5. Reset next TPKT data length in get_tpkt_data() | ||
43 | */ | 12 | */ |
44 | 13 | ||
45 | #include <linux/config.h> | 14 | #include <linux/config.h> |
@@ -54,8 +23,6 @@ | |||
54 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> | 23 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> |
55 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
56 | 25 | ||
57 | #include "ip_conntrack_helper_h323_asn1.h" | ||
58 | |||
59 | #if 0 | 26 | #if 0 |
60 | #define DEBUGP printk | 27 | #define DEBUGP printk |
61 | #else | 28 | #else |
@@ -63,6 +30,10 @@ | |||
63 | #endif | 30 | #endif |
64 | 31 | ||
65 | /* Parameters */ | 32 | /* Parameters */ |
33 | static unsigned int default_rrq_ttl = 300; | ||
34 | module_param(default_rrq_ttl, uint, 0600); | ||
35 | MODULE_PARM_DESC(default_rrq_ttl, "use this TTL if it's missing in RRQ"); | ||
36 | |||
66 | static int gkrouted_only = 1; | 37 | static int gkrouted_only = 1; |
67 | module_param(gkrouted_only, int, 0600); | 38 | module_param(gkrouted_only, int, 0600); |
68 | MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); | 39 | MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); |
@@ -222,8 +193,8 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
222 | } | 193 | } |
223 | 194 | ||
224 | /****************************************************************************/ | 195 | /****************************************************************************/ |
225 | int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, | 196 | static int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, |
226 | u_int32_t * ip, u_int16_t * port) | 197 | u_int32_t * ip, u_int16_t * port) |
227 | { | 198 | { |
228 | unsigned char *p; | 199 | unsigned char *p; |
229 | 200 | ||
@@ -1302,7 +1273,7 @@ static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
1302 | DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive); | 1273 | DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive); |
1303 | info->timeout = rrq->timeToLive; | 1274 | info->timeout = rrq->timeToLive; |
1304 | } else | 1275 | } else |
1305 | info->timeout = 0; | 1276 | info->timeout = default_rrq_ttl; |
1306 | 1277 | ||
1307 | return 0; | 1278 | return 0; |
1308 | } | 1279 | } |
@@ -1713,18 +1684,17 @@ static int __init init(void) | |||
1713 | module_init(init); | 1684 | module_init(init); |
1714 | module_exit(fini); | 1685 | module_exit(fini); |
1715 | 1686 | ||
1716 | EXPORT_SYMBOL(get_h245_addr); | 1687 | EXPORT_SYMBOL_GPL(get_h225_addr); |
1717 | EXPORT_SYMBOL(get_h225_addr); | 1688 | EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect); |
1718 | EXPORT_SYMBOL(ip_conntrack_h245_expect); | 1689 | EXPORT_SYMBOL_GPL(ip_conntrack_q931_expect); |
1719 | EXPORT_SYMBOL(ip_conntrack_q931_expect); | 1690 | EXPORT_SYMBOL_GPL(set_h245_addr_hook); |
1720 | EXPORT_SYMBOL(set_h245_addr_hook); | 1691 | EXPORT_SYMBOL_GPL(set_h225_addr_hook); |
1721 | EXPORT_SYMBOL(set_h225_addr_hook); | 1692 | EXPORT_SYMBOL_GPL(set_sig_addr_hook); |
1722 | EXPORT_SYMBOL(set_sig_addr_hook); | 1693 | EXPORT_SYMBOL_GPL(set_ras_addr_hook); |
1723 | EXPORT_SYMBOL(set_ras_addr_hook); | 1694 | EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook); |
1724 | EXPORT_SYMBOL(nat_rtp_rtcp_hook); | 1695 | EXPORT_SYMBOL_GPL(nat_t120_hook); |
1725 | EXPORT_SYMBOL(nat_t120_hook); | 1696 | EXPORT_SYMBOL_GPL(nat_h245_hook); |
1726 | EXPORT_SYMBOL(nat_h245_hook); | 1697 | EXPORT_SYMBOL_GPL(nat_q931_hook); |
1727 | EXPORT_SYMBOL(nat_q931_hook); | ||
1728 | 1698 | ||
1729 | MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); | 1699 | MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); |
1730 | MODULE_DESCRIPTION("H.323 connection tracking helper"); | 1700 | MODULE_DESCRIPTION("H.323 connection tracking helper"); |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c index afa525129b51..48078002e450 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #else | 15 | #else |
16 | #include <stdio.h> | 16 | #include <stdio.h> |
17 | #endif | 17 | #endif |
18 | #include "ip_conntrack_helper_h323_asn1.h" | 18 | #include <linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h> |
19 | 19 | ||
20 | /* Trace Flag */ | 20 | /* Trace Flag */ |
21 | #ifndef H323_TRACE | 21 | #ifndef H323_TRACE |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 3021af0910f1..d8b14a9010a6 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c | |||
@@ -224,25 +224,14 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
224 | } | 224 | } |
225 | 225 | ||
226 | /* See ip_conntrack_proto_tcp.c */ | 226 | /* See ip_conntrack_proto_tcp.c */ |
227 | if (hooknum != NF_IP_PRE_ROUTING) | 227 | if (hooknum == NF_IP_PRE_ROUTING && |
228 | goto checksum_skipped; | 228 | nf_ip_checksum(skb, hooknum, skb->nh.iph->ihl * 4, 0)) { |
229 | 229 | if (LOG_INVALID(IPPROTO_ICMP)) | |
230 | switch (skb->ip_summed) { | 230 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
231 | case CHECKSUM_HW: | 231 | "ip_ct_icmp: bad ICMP checksum "); |
232 | if (!(u16)csum_fold(skb->csum)) | 232 | return -NF_ACCEPT; |
233 | break; | ||
234 | /* fall through */ | ||
235 | case CHECKSUM_NONE: | ||
236 | skb->csum = 0; | ||
237 | if (__skb_checksum_complete(skb)) { | ||
238 | if (LOG_INVALID(IPPROTO_ICMP)) | ||
239 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | ||
240 | "ip_ct_icmp: bad ICMP checksum "); | ||
241 | return -NF_ACCEPT; | ||
242 | } | ||
243 | } | 233 | } |
244 | 234 | ||
245 | checksum_skipped: | ||
246 | /* | 235 | /* |
247 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 236 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
248 | * | 237 | * |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index e0dc37063545..062b252b58ad 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -870,11 +870,8 @@ static int tcp_error(struct sk_buff *skb, | |||
870 | * and moreover root might send raw packets. | 870 | * and moreover root might send raw packets. |
871 | */ | 871 | */ |
872 | /* FIXME: Source route IP option packets --RR */ | 872 | /* FIXME: Source route IP option packets --RR */ |
873 | if (hooknum == NF_IP_PRE_ROUTING | 873 | if (hooknum == NF_IP_PRE_ROUTING && |
874 | && skb->ip_summed != CHECKSUM_UNNECESSARY | 874 | nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_TCP)) { |
875 | && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, | ||
876 | skb->ip_summed == CHECKSUM_HW ? skb->csum | ||
877 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { | ||
878 | if (LOG_INVALID(IPPROTO_TCP)) | 875 | if (LOG_INVALID(IPPROTO_TCP)) |
879 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 876 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
880 | "ip_ct_tcp: bad TCP checksum "); | 877 | "ip_ct_tcp: bad TCP checksum "); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c index 55b7d3210adf..70899868783b 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c | |||
@@ -120,11 +120,8 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
120 | * because the semantic of CHECKSUM_HW is different there | 120 | * because the semantic of CHECKSUM_HW is different there |
121 | * and moreover root might send raw packets. | 121 | * and moreover root might send raw packets. |
122 | * FIXME: Source route IP option packets --RR */ | 122 | * FIXME: Source route IP option packets --RR */ |
123 | if (hooknum == NF_IP_PRE_ROUTING | 123 | if (hooknum == NF_IP_PRE_ROUTING && |
124 | && skb->ip_summed != CHECKSUM_UNNECESSARY | 124 | nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_UDP)) { |
125 | && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, | ||
126 | skb->ip_summed == CHECKSUM_HW ? skb->csum | ||
127 | : skb_checksum(skb, iph->ihl*4, udplen, 0))) { | ||
128 | if (LOG_INVALID(IPPROTO_UDP)) | 125 | if (LOG_INVALID(IPPROTO_UDP)) |
129 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 126 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
130 | "ip_ct_udp: bad UDP checksum "); | 127 | "ip_ct_udp: bad UDP checksum "); |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 52076026db36..929d61f7be91 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -469,70 +469,63 @@ static unsigned int ip_conntrack_local(unsigned int hooknum, | |||
469 | 469 | ||
470 | /* Connection tracking may drop packets, but never alters them, so | 470 | /* Connection tracking may drop packets, but never alters them, so |
471 | make it the first hook. */ | 471 | make it the first hook. */ |
472 | static struct nf_hook_ops ip_conntrack_defrag_ops = { | 472 | static struct nf_hook_ops ip_conntrack_ops[] = { |
473 | .hook = ip_conntrack_defrag, | 473 | { |
474 | .owner = THIS_MODULE, | 474 | .hook = ip_conntrack_defrag, |
475 | .pf = PF_INET, | 475 | .owner = THIS_MODULE, |
476 | .hooknum = NF_IP_PRE_ROUTING, | 476 | .pf = PF_INET, |
477 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 477 | .hooknum = NF_IP_PRE_ROUTING, |
478 | }; | 478 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
479 | 479 | }, | |
480 | static struct nf_hook_ops ip_conntrack_in_ops = { | 480 | { |
481 | .hook = ip_conntrack_in, | 481 | .hook = ip_conntrack_in, |
482 | .owner = THIS_MODULE, | 482 | .owner = THIS_MODULE, |
483 | .pf = PF_INET, | 483 | .pf = PF_INET, |
484 | .hooknum = NF_IP_PRE_ROUTING, | 484 | .hooknum = NF_IP_PRE_ROUTING, |
485 | .priority = NF_IP_PRI_CONNTRACK, | 485 | .priority = NF_IP_PRI_CONNTRACK, |
486 | }; | 486 | }, |
487 | 487 | { | |
488 | static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = { | 488 | .hook = ip_conntrack_defrag, |
489 | .hook = ip_conntrack_defrag, | 489 | .owner = THIS_MODULE, |
490 | .owner = THIS_MODULE, | 490 | .pf = PF_INET, |
491 | .pf = PF_INET, | 491 | .hooknum = NF_IP_LOCAL_OUT, |
492 | .hooknum = NF_IP_LOCAL_OUT, | 492 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
493 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 493 | }, |
494 | }; | 494 | { |
495 | 495 | .hook = ip_conntrack_local, | |
496 | static struct nf_hook_ops ip_conntrack_local_out_ops = { | 496 | .owner = THIS_MODULE, |
497 | .hook = ip_conntrack_local, | 497 | .pf = PF_INET, |
498 | .owner = THIS_MODULE, | 498 | .hooknum = NF_IP_LOCAL_OUT, |
499 | .pf = PF_INET, | 499 | .priority = NF_IP_PRI_CONNTRACK, |
500 | .hooknum = NF_IP_LOCAL_OUT, | 500 | }, |
501 | .priority = NF_IP_PRI_CONNTRACK, | 501 | { |
502 | }; | 502 | .hook = ip_conntrack_help, |
503 | 503 | .owner = THIS_MODULE, | |
504 | /* helpers */ | 504 | .pf = PF_INET, |
505 | static struct nf_hook_ops ip_conntrack_helper_out_ops = { | 505 | .hooknum = NF_IP_POST_ROUTING, |
506 | .hook = ip_conntrack_help, | 506 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
507 | .owner = THIS_MODULE, | 507 | }, |
508 | .pf = PF_INET, | 508 | { |
509 | .hooknum = NF_IP_POST_ROUTING, | 509 | .hook = ip_conntrack_help, |
510 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 510 | .owner = THIS_MODULE, |
511 | }; | 511 | .pf = PF_INET, |
512 | 512 | .hooknum = NF_IP_LOCAL_IN, | |
513 | static struct nf_hook_ops ip_conntrack_helper_in_ops = { | 513 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
514 | .hook = ip_conntrack_help, | 514 | }, |
515 | .owner = THIS_MODULE, | 515 | { |
516 | .pf = PF_INET, | 516 | .hook = ip_confirm, |
517 | .hooknum = NF_IP_LOCAL_IN, | 517 | .owner = THIS_MODULE, |
518 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 518 | .pf = PF_INET, |
519 | }; | 519 | .hooknum = NF_IP_POST_ROUTING, |
520 | 520 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | |
521 | /* Refragmenter; last chance. */ | 521 | }, |
522 | static struct nf_hook_ops ip_conntrack_out_ops = { | 522 | { |
523 | .hook = ip_confirm, | 523 | .hook = ip_confirm, |
524 | .owner = THIS_MODULE, | 524 | .owner = THIS_MODULE, |
525 | .pf = PF_INET, | 525 | .pf = PF_INET, |
526 | .hooknum = NF_IP_POST_ROUTING, | 526 | .hooknum = NF_IP_LOCAL_IN, |
527 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | 527 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, |
528 | }; | 528 | }, |
529 | |||
530 | static struct nf_hook_ops ip_conntrack_local_in_ops = { | ||
531 | .hook = ip_confirm, | ||
532 | .owner = THIS_MODULE, | ||
533 | .pf = PF_INET, | ||
534 | .hooknum = NF_IP_LOCAL_IN, | ||
535 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | ||
536 | }; | 529 | }; |
537 | 530 | ||
538 | /* Sysctl support */ | 531 | /* Sysctl support */ |
@@ -783,18 +776,46 @@ static ctl_table ip_ct_net_table[] = { | |||
783 | EXPORT_SYMBOL(ip_ct_log_invalid); | 776 | EXPORT_SYMBOL(ip_ct_log_invalid); |
784 | #endif /* CONFIG_SYSCTL */ | 777 | #endif /* CONFIG_SYSCTL */ |
785 | 778 | ||
786 | static int init_or_cleanup(int init) | 779 | /* FIXME: Allow NULL functions and sub in pointers to generic for |
780 | them. --RR */ | ||
781 | int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) | ||
782 | { | ||
783 | int ret = 0; | ||
784 | |||
785 | write_lock_bh(&ip_conntrack_lock); | ||
786 | if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { | ||
787 | ret = -EBUSY; | ||
788 | goto out; | ||
789 | } | ||
790 | ip_ct_protos[proto->proto] = proto; | ||
791 | out: | ||
792 | write_unlock_bh(&ip_conntrack_lock); | ||
793 | return ret; | ||
794 | } | ||
795 | |||
796 | void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) | ||
797 | { | ||
798 | write_lock_bh(&ip_conntrack_lock); | ||
799 | ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; | ||
800 | write_unlock_bh(&ip_conntrack_lock); | ||
801 | |||
802 | /* Somebody could be still looking at the proto in bh. */ | ||
803 | synchronize_net(); | ||
804 | |||
805 | /* Remove all contrack entries for this protocol */ | ||
806 | ip_ct_iterate_cleanup(kill_proto, &proto->proto); | ||
807 | } | ||
808 | |||
809 | static int __init ip_conntrack_standalone_init(void) | ||
787 | { | 810 | { |
788 | #ifdef CONFIG_PROC_FS | 811 | #ifdef CONFIG_PROC_FS |
789 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; | 812 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; |
790 | #endif | 813 | #endif |
791 | int ret = 0; | 814 | int ret = 0; |
792 | 815 | ||
793 | if (!init) goto cleanup; | ||
794 | |||
795 | ret = ip_conntrack_init(); | 816 | ret = ip_conntrack_init(); |
796 | if (ret < 0) | 817 | if (ret < 0) |
797 | goto cleanup_nothing; | 818 | return ret; |
798 | 819 | ||
799 | #ifdef CONFIG_PROC_FS | 820 | #ifdef CONFIG_PROC_FS |
800 | ret = -ENOMEM; | 821 | ret = -ENOMEM; |
@@ -813,78 +834,25 @@ static int init_or_cleanup(int init) | |||
813 | proc_stat->owner = THIS_MODULE; | 834 | proc_stat->owner = THIS_MODULE; |
814 | #endif | 835 | #endif |
815 | 836 | ||
816 | ret = nf_register_hook(&ip_conntrack_defrag_ops); | 837 | ret = nf_register_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); |
817 | if (ret < 0) { | 838 | if (ret < 0) { |
818 | printk("ip_conntrack: can't register pre-routing defrag hook.\n"); | 839 | printk("ip_conntrack: can't register hooks.\n"); |
819 | goto cleanup_proc_stat; | 840 | goto cleanup_proc_stat; |
820 | } | 841 | } |
821 | ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops); | ||
822 | if (ret < 0) { | ||
823 | printk("ip_conntrack: can't register local_out defrag hook.\n"); | ||
824 | goto cleanup_defragops; | ||
825 | } | ||
826 | ret = nf_register_hook(&ip_conntrack_in_ops); | ||
827 | if (ret < 0) { | ||
828 | printk("ip_conntrack: can't register pre-routing hook.\n"); | ||
829 | goto cleanup_defraglocalops; | ||
830 | } | ||
831 | ret = nf_register_hook(&ip_conntrack_local_out_ops); | ||
832 | if (ret < 0) { | ||
833 | printk("ip_conntrack: can't register local out hook.\n"); | ||
834 | goto cleanup_inops; | ||
835 | } | ||
836 | ret = nf_register_hook(&ip_conntrack_helper_in_ops); | ||
837 | if (ret < 0) { | ||
838 | printk("ip_conntrack: can't register local in helper hook.\n"); | ||
839 | goto cleanup_inandlocalops; | ||
840 | } | ||
841 | ret = nf_register_hook(&ip_conntrack_helper_out_ops); | ||
842 | if (ret < 0) { | ||
843 | printk("ip_conntrack: can't register postrouting helper hook.\n"); | ||
844 | goto cleanup_helperinops; | ||
845 | } | ||
846 | ret = nf_register_hook(&ip_conntrack_out_ops); | ||
847 | if (ret < 0) { | ||
848 | printk("ip_conntrack: can't register post-routing hook.\n"); | ||
849 | goto cleanup_helperoutops; | ||
850 | } | ||
851 | ret = nf_register_hook(&ip_conntrack_local_in_ops); | ||
852 | if (ret < 0) { | ||
853 | printk("ip_conntrack: can't register local in hook.\n"); | ||
854 | goto cleanup_inoutandlocalops; | ||
855 | } | ||
856 | #ifdef CONFIG_SYSCTL | 842 | #ifdef CONFIG_SYSCTL |
857 | ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0); | 843 | ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0); |
858 | if (ip_ct_sysctl_header == NULL) { | 844 | if (ip_ct_sysctl_header == NULL) { |
859 | printk("ip_conntrack: can't register to sysctl.\n"); | 845 | printk("ip_conntrack: can't register to sysctl.\n"); |
860 | ret = -ENOMEM; | 846 | ret = -ENOMEM; |
861 | goto cleanup_localinops; | 847 | goto cleanup_hooks; |
862 | } | 848 | } |
863 | #endif | 849 | #endif |
864 | |||
865 | return ret; | 850 | return ret; |
866 | 851 | ||
867 | cleanup: | ||
868 | synchronize_net(); | ||
869 | #ifdef CONFIG_SYSCTL | 852 | #ifdef CONFIG_SYSCTL |
870 | unregister_sysctl_table(ip_ct_sysctl_header); | 853 | cleanup_hooks: |
871 | cleanup_localinops: | 854 | nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); |
872 | #endif | 855 | #endif |
873 | nf_unregister_hook(&ip_conntrack_local_in_ops); | ||
874 | cleanup_inoutandlocalops: | ||
875 | nf_unregister_hook(&ip_conntrack_out_ops); | ||
876 | cleanup_helperoutops: | ||
877 | nf_unregister_hook(&ip_conntrack_helper_out_ops); | ||
878 | cleanup_helperinops: | ||
879 | nf_unregister_hook(&ip_conntrack_helper_in_ops); | ||
880 | cleanup_inandlocalops: | ||
881 | nf_unregister_hook(&ip_conntrack_local_out_ops); | ||
882 | cleanup_inops: | ||
883 | nf_unregister_hook(&ip_conntrack_in_ops); | ||
884 | cleanup_defraglocalops: | ||
885 | nf_unregister_hook(&ip_conntrack_defrag_local_out_ops); | ||
886 | cleanup_defragops: | ||
887 | nf_unregister_hook(&ip_conntrack_defrag_ops); | ||
888 | cleanup_proc_stat: | 856 | cleanup_proc_stat: |
889 | #ifdef CONFIG_PROC_FS | 857 | #ifdef CONFIG_PROC_FS |
890 | remove_proc_entry("ip_conntrack", proc_net_stat); | 858 | remove_proc_entry("ip_conntrack", proc_net_stat); |
@@ -895,48 +863,22 @@ static int init_or_cleanup(int init) | |||
895 | cleanup_init: | 863 | cleanup_init: |
896 | #endif /* CONFIG_PROC_FS */ | 864 | #endif /* CONFIG_PROC_FS */ |
897 | ip_conntrack_cleanup(); | 865 | ip_conntrack_cleanup(); |
898 | cleanup_nothing: | ||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | /* FIXME: Allow NULL functions and sub in pointers to generic for | ||
903 | them. --RR */ | ||
904 | int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) | ||
905 | { | ||
906 | int ret = 0; | ||
907 | |||
908 | write_lock_bh(&ip_conntrack_lock); | ||
909 | if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { | ||
910 | ret = -EBUSY; | ||
911 | goto out; | ||
912 | } | ||
913 | ip_ct_protos[proto->proto] = proto; | ||
914 | out: | ||
915 | write_unlock_bh(&ip_conntrack_lock); | ||
916 | return ret; | 866 | return ret; |
917 | } | 867 | } |
918 | 868 | ||
919 | void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) | ||
920 | { | ||
921 | write_lock_bh(&ip_conntrack_lock); | ||
922 | ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; | ||
923 | write_unlock_bh(&ip_conntrack_lock); | ||
924 | |||
925 | /* Somebody could be still looking at the proto in bh. */ | ||
926 | synchronize_net(); | ||
927 | |||
928 | /* Remove all contrack entries for this protocol */ | ||
929 | ip_ct_iterate_cleanup(kill_proto, &proto->proto); | ||
930 | } | ||
931 | |||
932 | static int __init ip_conntrack_standalone_init(void) | ||
933 | { | ||
934 | return init_or_cleanup(1); | ||
935 | } | ||
936 | |||
937 | static void __exit ip_conntrack_standalone_fini(void) | 869 | static void __exit ip_conntrack_standalone_fini(void) |
938 | { | 870 | { |
939 | init_or_cleanup(0); | 871 | synchronize_net(); |
872 | #ifdef CONFIG_SYSCTL | ||
873 | unregister_sysctl_table(ip_ct_sysctl_header); | ||
874 | #endif | ||
875 | nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); | ||
876 | #ifdef CONFIG_PROC_FS | ||
877 | remove_proc_entry("ip_conntrack", proc_net_stat); | ||
878 | proc_net_remove("ip_conntrack_expect"); | ||
879 | proc_net_remove("ip_conntrack"); | ||
880 | #endif /* CONFIG_PROC_FS */ | ||
881 | ip_conntrack_cleanup(); | ||
940 | } | 882 | } |
941 | 883 | ||
942 | module_init(ip_conntrack_standalone_init); | 884 | module_init(ip_conntrack_standalone_init); |
diff --git a/net/ipv4/netfilter/ip_nat_helper_h323.c b/net/ipv4/netfilter/ip_nat_helper_h323.c index a0bc883928c0..d45663d137a7 100644 --- a/net/ipv4/netfilter/ip_nat_helper_h323.c +++ b/net/ipv4/netfilter/ip_nat_helper_h323.c | |||
@@ -7,24 +7,6 @@ | |||
7 | * | 7 | * |
8 | * Based on the 'brute force' H.323 NAT module by | 8 | * Based on the 'brute force' H.323 NAT module by |
9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> |
10 | * | ||
11 | * Changes: | ||
12 | * 2006-02-01 - initial version 0.1 | ||
13 | * | ||
14 | * 2006-02-20 - version 0.2 | ||
15 | * 1. Changed source format to follow kernel conventions | ||
16 | * 2. Deleted some unnecessary structures | ||
17 | * 3. Minor fixes | ||
18 | * | ||
19 | * 2006-03-10 - version 0.3 | ||
20 | * 1. Added support for multiple TPKTs in one packet (suggested by | ||
21 | * Patrick McHardy) | ||
22 | * 2. Added support for non-linear skb (based on Patrick McHardy's patch) | ||
23 | * 3. Eliminated unnecessary return code | ||
24 | * | ||
25 | * 2006-03-15 - version 0.4 | ||
26 | * 1. Added support for T.120 channels | ||
27 | * 2. Added parameter gkrouted_only (suggested by Patrick McHardy) | ||
28 | */ | 10 | */ |
29 | 11 | ||
30 | #include <linux/module.h> | 12 | #include <linux/module.h> |
@@ -41,65 +23,12 @@ | |||
41 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> | 23 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> |
42 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 24 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
43 | 25 | ||
44 | #include "ip_conntrack_helper_h323_asn1.h" | ||
45 | |||
46 | #if 0 | 26 | #if 0 |
47 | #define DEBUGP printk | 27 | #define DEBUGP printk |
48 | #else | 28 | #else |
49 | #define DEBUGP(format, args...) | 29 | #define DEBUGP(format, args...) |
50 | #endif | 30 | #endif |
51 | 31 | ||
52 | extern int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, | ||
53 | u_int32_t * ip, u_int16_t * port); | ||
54 | extern int get_h225_addr(unsigned char *data, TransportAddress * addr, | ||
55 | u_int32_t * ip, u_int16_t * port); | ||
56 | extern void ip_conntrack_h245_expect(struct ip_conntrack *new, | ||
57 | struct ip_conntrack_expect *this); | ||
58 | extern void ip_conntrack_q931_expect(struct ip_conntrack *new, | ||
59 | struct ip_conntrack_expect *this); | ||
60 | extern int (*set_h245_addr_hook) (struct sk_buff ** pskb, | ||
61 | unsigned char **data, int dataoff, | ||
62 | H245_TransportAddress * addr, | ||
63 | u_int32_t ip, u_int16_t port); | ||
64 | extern int (*set_h225_addr_hook) (struct sk_buff ** pskb, | ||
65 | unsigned char **data, int dataoff, | ||
66 | TransportAddress * addr, | ||
67 | u_int32_t ip, u_int16_t port); | ||
68 | extern int (*set_sig_addr_hook) (struct sk_buff ** pskb, | ||
69 | struct ip_conntrack * ct, | ||
70 | enum ip_conntrack_info ctinfo, | ||
71 | unsigned char **data, | ||
72 | TransportAddress * addr, int count); | ||
73 | extern int (*set_ras_addr_hook) (struct sk_buff ** pskb, | ||
74 | struct ip_conntrack * ct, | ||
75 | enum ip_conntrack_info ctinfo, | ||
76 | unsigned char **data, | ||
77 | TransportAddress * addr, int count); | ||
78 | extern int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb, | ||
79 | struct ip_conntrack * ct, | ||
80 | enum ip_conntrack_info ctinfo, | ||
81 | unsigned char **data, int dataoff, | ||
82 | H245_TransportAddress * addr, | ||
83 | u_int16_t port, u_int16_t rtp_port, | ||
84 | struct ip_conntrack_expect * rtp_exp, | ||
85 | struct ip_conntrack_expect * rtcp_exp); | ||
86 | extern int (*nat_t120_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
87 | enum ip_conntrack_info ctinfo, | ||
88 | unsigned char **data, int dataoff, | ||
89 | H245_TransportAddress * addr, u_int16_t port, | ||
90 | struct ip_conntrack_expect * exp); | ||
91 | extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
92 | enum ip_conntrack_info ctinfo, | ||
93 | unsigned char **data, int dataoff, | ||
94 | TransportAddress * addr, u_int16_t port, | ||
95 | struct ip_conntrack_expect * exp); | ||
96 | extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
97 | enum ip_conntrack_info ctinfo, | ||
98 | unsigned char **data, TransportAddress * addr, | ||
99 | int idx, u_int16_t port, | ||
100 | struct ip_conntrack_expect * exp); | ||
101 | |||
102 | |||
103 | /****************************************************************************/ | 32 | /****************************************************************************/ |
104 | static int set_addr(struct sk_buff **pskb, | 33 | static int set_addr(struct sk_buff **pskb, |
105 | unsigned char **data, int dataoff, | 34 | unsigned char **data, int dataoff, |
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index efba8c4e42e0..1aba926c1cb0 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
@@ -279,7 +279,7 @@ static struct ipt_target ipt_dnat_reg = { | |||
279 | .target = ipt_dnat_target, | 279 | .target = ipt_dnat_target, |
280 | .targetsize = sizeof(struct ip_nat_multi_range_compat), | 280 | .targetsize = sizeof(struct ip_nat_multi_range_compat), |
281 | .table = "nat", | 281 | .table = "nat", |
282 | .hooks = 1 << NF_IP_PRE_ROUTING, | 282 | .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT), |
283 | .checkentry = ipt_dnat_checkentry, | 283 | .checkentry = ipt_dnat_checkentry, |
284 | }; | 284 | }; |
285 | 285 | ||
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 3505b0de2e04..8f760b28617e 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -299,69 +299,63 @@ ip_nat_adjust(unsigned int hooknum, | |||
299 | 299 | ||
300 | /* We must be after connection tracking and before packet filtering. */ | 300 | /* We must be after connection tracking and before packet filtering. */ |
301 | 301 | ||
302 | /* Before packet filtering, change destination */ | 302 | static struct nf_hook_ops ip_nat_ops[] = { |
303 | static struct nf_hook_ops ip_nat_in_ops = { | 303 | /* Before packet filtering, change destination */ |
304 | .hook = ip_nat_in, | 304 | { |
305 | .owner = THIS_MODULE, | 305 | .hook = ip_nat_in, |
306 | .pf = PF_INET, | 306 | .owner = THIS_MODULE, |
307 | .hooknum = NF_IP_PRE_ROUTING, | 307 | .pf = PF_INET, |
308 | .priority = NF_IP_PRI_NAT_DST, | 308 | .hooknum = NF_IP_PRE_ROUTING, |
309 | .priority = NF_IP_PRI_NAT_DST, | ||
310 | }, | ||
311 | /* After packet filtering, change source */ | ||
312 | { | ||
313 | .hook = ip_nat_out, | ||
314 | .owner = THIS_MODULE, | ||
315 | .pf = PF_INET, | ||
316 | .hooknum = NF_IP_POST_ROUTING, | ||
317 | .priority = NF_IP_PRI_NAT_SRC, | ||
318 | }, | ||
319 | /* After conntrack, adjust sequence number */ | ||
320 | { | ||
321 | .hook = ip_nat_adjust, | ||
322 | .owner = THIS_MODULE, | ||
323 | .pf = PF_INET, | ||
324 | .hooknum = NF_IP_POST_ROUTING, | ||
325 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
326 | }, | ||
327 | /* Before packet filtering, change destination */ | ||
328 | { | ||
329 | .hook = ip_nat_local_fn, | ||
330 | .owner = THIS_MODULE, | ||
331 | .pf = PF_INET, | ||
332 | .hooknum = NF_IP_LOCAL_OUT, | ||
333 | .priority = NF_IP_PRI_NAT_DST, | ||
334 | }, | ||
335 | /* After packet filtering, change source */ | ||
336 | { | ||
337 | .hook = ip_nat_fn, | ||
338 | .owner = THIS_MODULE, | ||
339 | .pf = PF_INET, | ||
340 | .hooknum = NF_IP_LOCAL_IN, | ||
341 | .priority = NF_IP_PRI_NAT_SRC, | ||
342 | }, | ||
343 | /* After conntrack, adjust sequence number */ | ||
344 | { | ||
345 | .hook = ip_nat_adjust, | ||
346 | .owner = THIS_MODULE, | ||
347 | .pf = PF_INET, | ||
348 | .hooknum = NF_IP_LOCAL_IN, | ||
349 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
350 | }, | ||
309 | }; | 351 | }; |
310 | 352 | ||
311 | /* After packet filtering, change source */ | 353 | static int __init ip_nat_standalone_init(void) |
312 | static struct nf_hook_ops ip_nat_out_ops = { | ||
313 | .hook = ip_nat_out, | ||
314 | .owner = THIS_MODULE, | ||
315 | .pf = PF_INET, | ||
316 | .hooknum = NF_IP_POST_ROUTING, | ||
317 | .priority = NF_IP_PRI_NAT_SRC, | ||
318 | }; | ||
319 | |||
320 | /* After conntrack, adjust sequence number */ | ||
321 | static struct nf_hook_ops ip_nat_adjust_out_ops = { | ||
322 | .hook = ip_nat_adjust, | ||
323 | .owner = THIS_MODULE, | ||
324 | .pf = PF_INET, | ||
325 | .hooknum = NF_IP_POST_ROUTING, | ||
326 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
327 | }; | ||
328 | |||
329 | /* Before packet filtering, change destination */ | ||
330 | static struct nf_hook_ops ip_nat_local_out_ops = { | ||
331 | .hook = ip_nat_local_fn, | ||
332 | .owner = THIS_MODULE, | ||
333 | .pf = PF_INET, | ||
334 | .hooknum = NF_IP_LOCAL_OUT, | ||
335 | .priority = NF_IP_PRI_NAT_DST, | ||
336 | }; | ||
337 | |||
338 | /* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */ | ||
339 | static struct nf_hook_ops ip_nat_local_in_ops = { | ||
340 | .hook = ip_nat_fn, | ||
341 | .owner = THIS_MODULE, | ||
342 | .pf = PF_INET, | ||
343 | .hooknum = NF_IP_LOCAL_IN, | ||
344 | .priority = NF_IP_PRI_NAT_SRC, | ||
345 | }; | ||
346 | |||
347 | /* After conntrack, adjust sequence number */ | ||
348 | static struct nf_hook_ops ip_nat_adjust_in_ops = { | ||
349 | .hook = ip_nat_adjust, | ||
350 | .owner = THIS_MODULE, | ||
351 | .pf = PF_INET, | ||
352 | .hooknum = NF_IP_LOCAL_IN, | ||
353 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
354 | }; | ||
355 | |||
356 | |||
357 | static int init_or_cleanup(int init) | ||
358 | { | 354 | { |
359 | int ret = 0; | 355 | int ret = 0; |
360 | 356 | ||
361 | need_conntrack(); | 357 | need_conntrack(); |
362 | 358 | ||
363 | if (!init) goto cleanup; | ||
364 | |||
365 | #ifdef CONFIG_XFRM | 359 | #ifdef CONFIG_XFRM |
366 | BUG_ON(ip_nat_decode_session != NULL); | 360 | BUG_ON(ip_nat_decode_session != NULL); |
367 | ip_nat_decode_session = nat_decode_session; | 361 | ip_nat_decode_session = nat_decode_session; |
@@ -371,50 +365,13 @@ static int init_or_cleanup(int init) | |||
371 | printk("ip_nat_init: can't setup rules.\n"); | 365 | printk("ip_nat_init: can't setup rules.\n"); |
372 | goto cleanup_decode_session; | 366 | goto cleanup_decode_session; |
373 | } | 367 | } |
374 | ret = nf_register_hook(&ip_nat_in_ops); | 368 | ret = nf_register_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops)); |
375 | if (ret < 0) { | 369 | if (ret < 0) { |
376 | printk("ip_nat_init: can't register in hook.\n"); | 370 | printk("ip_nat_init: can't register hooks.\n"); |
377 | goto cleanup_rule_init; | 371 | goto cleanup_rule_init; |
378 | } | 372 | } |
379 | ret = nf_register_hook(&ip_nat_out_ops); | ||
380 | if (ret < 0) { | ||
381 | printk("ip_nat_init: can't register out hook.\n"); | ||
382 | goto cleanup_inops; | ||
383 | } | ||
384 | ret = nf_register_hook(&ip_nat_adjust_in_ops); | ||
385 | if (ret < 0) { | ||
386 | printk("ip_nat_init: can't register adjust in hook.\n"); | ||
387 | goto cleanup_outops; | ||
388 | } | ||
389 | ret = nf_register_hook(&ip_nat_adjust_out_ops); | ||
390 | if (ret < 0) { | ||
391 | printk("ip_nat_init: can't register adjust out hook.\n"); | ||
392 | goto cleanup_adjustin_ops; | ||
393 | } | ||
394 | ret = nf_register_hook(&ip_nat_local_out_ops); | ||
395 | if (ret < 0) { | ||
396 | printk("ip_nat_init: can't register local out hook.\n"); | ||
397 | goto cleanup_adjustout_ops; | ||
398 | } | ||
399 | ret = nf_register_hook(&ip_nat_local_in_ops); | ||
400 | if (ret < 0) { | ||
401 | printk("ip_nat_init: can't register local in hook.\n"); | ||
402 | goto cleanup_localoutops; | ||
403 | } | ||
404 | return ret; | 373 | return ret; |
405 | 374 | ||
406 | cleanup: | ||
407 | nf_unregister_hook(&ip_nat_local_in_ops); | ||
408 | cleanup_localoutops: | ||
409 | nf_unregister_hook(&ip_nat_local_out_ops); | ||
410 | cleanup_adjustout_ops: | ||
411 | nf_unregister_hook(&ip_nat_adjust_out_ops); | ||
412 | cleanup_adjustin_ops: | ||
413 | nf_unregister_hook(&ip_nat_adjust_in_ops); | ||
414 | cleanup_outops: | ||
415 | nf_unregister_hook(&ip_nat_out_ops); | ||
416 | cleanup_inops: | ||
417 | nf_unregister_hook(&ip_nat_in_ops); | ||
418 | cleanup_rule_init: | 375 | cleanup_rule_init: |
419 | ip_nat_rule_cleanup(); | 376 | ip_nat_rule_cleanup(); |
420 | cleanup_decode_session: | 377 | cleanup_decode_session: |
@@ -425,14 +382,14 @@ static int init_or_cleanup(int init) | |||
425 | return ret; | 382 | return ret; |
426 | } | 383 | } |
427 | 384 | ||
428 | static int __init ip_nat_standalone_init(void) | ||
429 | { | ||
430 | return init_or_cleanup(1); | ||
431 | } | ||
432 | |||
433 | static void __exit ip_nat_standalone_fini(void) | 385 | static void __exit ip_nat_standalone_fini(void) |
434 | { | 386 | { |
435 | init_or_cleanup(0); | 387 | nf_unregister_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops)); |
388 | ip_nat_rule_cleanup(); | ||
389 | #ifdef CONFIG_XFRM | ||
390 | ip_nat_decode_session = NULL; | ||
391 | synchronize_net(); | ||
392 | #endif | ||
436 | } | 393 | } |
437 | 394 | ||
438 | module_init(ip_nat_standalone_init); | 395 | module_init(ip_nat_standalone_init); |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 896a244f8f91..b93f0494362f 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -662,15 +662,11 @@ static struct nf_queue_handler nfqh = { | |||
662 | .outfn = &ipq_enqueue_packet, | 662 | .outfn = &ipq_enqueue_packet, |
663 | }; | 663 | }; |
664 | 664 | ||
665 | static int | 665 | static int __init ip_queue_init(void) |
666 | init_or_cleanup(int init) | ||
667 | { | 666 | { |
668 | int status = -ENOMEM; | 667 | int status = -ENOMEM; |
669 | struct proc_dir_entry *proc; | 668 | struct proc_dir_entry *proc; |
670 | 669 | ||
671 | if (!init) | ||
672 | goto cleanup; | ||
673 | |||
674 | netlink_register_notifier(&ipq_nl_notifier); | 670 | netlink_register_notifier(&ipq_nl_notifier); |
675 | ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk, | 671 | ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk, |
676 | THIS_MODULE); | 672 | THIS_MODULE); |
@@ -697,11 +693,6 @@ init_or_cleanup(int init) | |||
697 | } | 693 | } |
698 | return status; | 694 | return status; |
699 | 695 | ||
700 | cleanup: | ||
701 | nf_unregister_queue_handlers(&nfqh); | ||
702 | synchronize_net(); | ||
703 | ipq_flush(NF_DROP); | ||
704 | |||
705 | cleanup_sysctl: | 696 | cleanup_sysctl: |
706 | unregister_sysctl_table(ipq_sysctl_header); | 697 | unregister_sysctl_table(ipq_sysctl_header); |
707 | unregister_netdevice_notifier(&ipq_dev_notifier); | 698 | unregister_netdevice_notifier(&ipq_dev_notifier); |
@@ -717,15 +708,21 @@ cleanup_netlink_notifier: | |||
717 | return status; | 708 | return status; |
718 | } | 709 | } |
719 | 710 | ||
720 | static int __init ip_queue_init(void) | ||
721 | { | ||
722 | |||
723 | return init_or_cleanup(1); | ||
724 | } | ||
725 | |||
726 | static void __exit ip_queue_fini(void) | 711 | static void __exit ip_queue_fini(void) |
727 | { | 712 | { |
728 | init_or_cleanup(0); | 713 | nf_unregister_queue_handlers(&nfqh); |
714 | synchronize_net(); | ||
715 | ipq_flush(NF_DROP); | ||
716 | |||
717 | unregister_sysctl_table(ipq_sysctl_header); | ||
718 | unregister_netdevice_notifier(&ipq_dev_notifier); | ||
719 | proc_net_remove(IPQ_PROC_FS_NAME); | ||
720 | |||
721 | sock_release(ipqnl->sk_socket); | ||
722 | mutex_lock(&ipqnl_mutex); | ||
723 | mutex_unlock(&ipqnl_mutex); | ||
724 | |||
725 | netlink_unregister_notifier(&ipq_nl_notifier); | ||
729 | } | 726 | } |
730 | 727 | ||
731 | MODULE_DESCRIPTION("IPv4 packet queue handler"); | 728 | MODULE_DESCRIPTION("IPv4 packet queue handler"); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d5b8cdd361ce..d25ac8ba6eba 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -735,7 +735,7 @@ translate_table(const char *name, | |||
735 | } | 735 | } |
736 | 736 | ||
737 | /* And one copy for every other CPU */ | 737 | /* And one copy for every other CPU */ |
738 | for_each_cpu(i) { | 738 | for_each_possible_cpu(i) { |
739 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) | 739 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
740 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 740 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
741 | } | 741 | } |
@@ -788,7 +788,7 @@ get_counters(const struct xt_table_info *t, | |||
788 | counters, | 788 | counters, |
789 | &i); | 789 | &i); |
790 | 790 | ||
791 | for_each_cpu(cpu) { | 791 | for_each_possible_cpu(cpu) { |
792 | if (cpu == curcpu) | 792 | if (cpu == curcpu) |
793 | continue; | 793 | continue; |
794 | i = 0; | 794 | i = 0; |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index e4768a31718b..aad9d28c8d71 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -725,22 +725,17 @@ static struct file_operations clusterip_proc_fops = { | |||
725 | 725 | ||
726 | #endif /* CONFIG_PROC_FS */ | 726 | #endif /* CONFIG_PROC_FS */ |
727 | 727 | ||
728 | static int init_or_cleanup(int fini) | 728 | static int __init ipt_clusterip_init(void) |
729 | { | 729 | { |
730 | int ret; | 730 | int ret; |
731 | 731 | ||
732 | if (fini) | 732 | ret = ipt_register_target(&clusterip_tgt); |
733 | goto cleanup; | 733 | if (ret < 0) |
734 | 734 | return ret; | |
735 | if (ipt_register_target(&clusterip_tgt)) { | ||
736 | ret = -EINVAL; | ||
737 | goto cleanup_none; | ||
738 | } | ||
739 | 735 | ||
740 | if (nf_register_hook(&cip_arp_ops) < 0) { | 736 | ret = nf_register_hook(&cip_arp_ops); |
741 | ret = -EINVAL; | 737 | if (ret < 0) |
742 | goto cleanup_target; | 738 | goto cleanup_target; |
743 | } | ||
744 | 739 | ||
745 | #ifdef CONFIG_PROC_FS | 740 | #ifdef CONFIG_PROC_FS |
746 | clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net); | 741 | clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net); |
@@ -753,31 +748,24 @@ static int init_or_cleanup(int fini) | |||
753 | 748 | ||
754 | printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", | 749 | printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", |
755 | CLUSTERIP_VERSION); | 750 | CLUSTERIP_VERSION); |
756 | |||
757 | return 0; | 751 | return 0; |
758 | 752 | ||
759 | cleanup: | ||
760 | printk(KERN_NOTICE "ClusterIP Version %s unloading\n", | ||
761 | CLUSTERIP_VERSION); | ||
762 | #ifdef CONFIG_PROC_FS | ||
763 | remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); | ||
764 | #endif | ||
765 | cleanup_hook: | 753 | cleanup_hook: |
766 | nf_unregister_hook(&cip_arp_ops); | 754 | nf_unregister_hook(&cip_arp_ops); |
767 | cleanup_target: | 755 | cleanup_target: |
768 | ipt_unregister_target(&clusterip_tgt); | 756 | ipt_unregister_target(&clusterip_tgt); |
769 | cleanup_none: | 757 | return ret; |
770 | return -EINVAL; | ||
771 | } | ||
772 | |||
773 | static int __init ipt_clusterip_init(void) | ||
774 | { | ||
775 | return init_or_cleanup(0); | ||
776 | } | 758 | } |
777 | 759 | ||
778 | static void __exit ipt_clusterip_fini(void) | 760 | static void __exit ipt_clusterip_fini(void) |
779 | { | 761 | { |
780 | init_or_cleanup(1); | 762 | printk(KERN_NOTICE "ClusterIP Version %s unloading\n", |
763 | CLUSTERIP_VERSION); | ||
764 | #ifdef CONFIG_PROC_FS | ||
765 | remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); | ||
766 | #endif | ||
767 | nf_unregister_hook(&cip_arp_ops); | ||
768 | ipt_unregister_target(&clusterip_tgt); | ||
781 | } | 769 | } |
782 | 770 | ||
783 | module_init(ipt_clusterip_init); | 771 | module_init(ipt_clusterip_init); |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 4269a5440d43..0bba3c2bb786 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -106,7 +106,6 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
106 | struct rtable *rt; | 106 | struct rtable *rt; |
107 | u_int16_t tmp_port; | 107 | u_int16_t tmp_port; |
108 | u_int32_t tmp_addr; | 108 | u_int32_t tmp_addr; |
109 | unsigned int tcplen; | ||
110 | int needs_ack; | 109 | int needs_ack; |
111 | int hh_len; | 110 | int hh_len; |
112 | 111 | ||
@@ -124,13 +123,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
124 | return; | 123 | return; |
125 | 124 | ||
126 | /* Check checksum */ | 125 | /* Check checksum */ |
127 | tcplen = oldskb->len - iph->ihl * 4; | 126 | if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP)) |
128 | if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) || | ||
129 | (hook == NF_IP_LOCAL_IN && | ||
130 | oldskb->ip_summed != CHECKSUM_UNNECESSARY)) && | ||
131 | csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, | ||
132 | oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum : | ||
133 | skb_checksum(oldskb, iph->ihl * 4, tcplen, 0))) | ||
134 | return; | 127 | return; |
135 | 128 | ||
136 | if ((rt = route_reverse(oldskb, oth, hook)) == NULL) | 129 | if ((rt = route_reverse(oldskb, oth, hook)) == NULL) |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 3d80aefe9cfa..7f417484bfbf 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -157,37 +157,20 @@ static int __init iptable_filter_init(void) | |||
157 | return ret; | 157 | return ret; |
158 | 158 | ||
159 | /* Register hooks */ | 159 | /* Register hooks */ |
160 | ret = nf_register_hook(&ipt_ops[0]); | 160 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
161 | if (ret < 0) | 161 | if (ret < 0) |
162 | goto cleanup_table; | 162 | goto cleanup_table; |
163 | 163 | ||
164 | ret = nf_register_hook(&ipt_ops[1]); | ||
165 | if (ret < 0) | ||
166 | goto cleanup_hook0; | ||
167 | |||
168 | ret = nf_register_hook(&ipt_ops[2]); | ||
169 | if (ret < 0) | ||
170 | goto cleanup_hook1; | ||
171 | |||
172 | return ret; | 164 | return ret; |
173 | 165 | ||
174 | cleanup_hook1: | ||
175 | nf_unregister_hook(&ipt_ops[1]); | ||
176 | cleanup_hook0: | ||
177 | nf_unregister_hook(&ipt_ops[0]); | ||
178 | cleanup_table: | 166 | cleanup_table: |
179 | ipt_unregister_table(&packet_filter); | 167 | ipt_unregister_table(&packet_filter); |
180 | |||
181 | return ret; | 168 | return ret; |
182 | } | 169 | } |
183 | 170 | ||
184 | static void __exit iptable_filter_fini(void) | 171 | static void __exit iptable_filter_fini(void) |
185 | { | 172 | { |
186 | unsigned int i; | 173 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
187 | |||
188 | for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) | ||
189 | nf_unregister_hook(&ipt_ops[i]); | ||
190 | |||
191 | ipt_unregister_table(&packet_filter); | 174 | ipt_unregister_table(&packet_filter); |
192 | } | 175 | } |
193 | 176 | ||
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 412fc96cc896..397b95cc026b 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -211,49 +211,20 @@ static int __init iptable_mangle_init(void) | |||
211 | return ret; | 211 | return ret; |
212 | 212 | ||
213 | /* Register hooks */ | 213 | /* Register hooks */ |
214 | ret = nf_register_hook(&ipt_ops[0]); | 214 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
215 | if (ret < 0) | 215 | if (ret < 0) |
216 | goto cleanup_table; | 216 | goto cleanup_table; |
217 | 217 | ||
218 | ret = nf_register_hook(&ipt_ops[1]); | ||
219 | if (ret < 0) | ||
220 | goto cleanup_hook0; | ||
221 | |||
222 | ret = nf_register_hook(&ipt_ops[2]); | ||
223 | if (ret < 0) | ||
224 | goto cleanup_hook1; | ||
225 | |||
226 | ret = nf_register_hook(&ipt_ops[3]); | ||
227 | if (ret < 0) | ||
228 | goto cleanup_hook2; | ||
229 | |||
230 | ret = nf_register_hook(&ipt_ops[4]); | ||
231 | if (ret < 0) | ||
232 | goto cleanup_hook3; | ||
233 | |||
234 | return ret; | 218 | return ret; |
235 | 219 | ||
236 | cleanup_hook3: | ||
237 | nf_unregister_hook(&ipt_ops[3]); | ||
238 | cleanup_hook2: | ||
239 | nf_unregister_hook(&ipt_ops[2]); | ||
240 | cleanup_hook1: | ||
241 | nf_unregister_hook(&ipt_ops[1]); | ||
242 | cleanup_hook0: | ||
243 | nf_unregister_hook(&ipt_ops[0]); | ||
244 | cleanup_table: | 220 | cleanup_table: |
245 | ipt_unregister_table(&packet_mangler); | 221 | ipt_unregister_table(&packet_mangler); |
246 | |||
247 | return ret; | 222 | return ret; |
248 | } | 223 | } |
249 | 224 | ||
250 | static void __exit iptable_mangle_fini(void) | 225 | static void __exit iptable_mangle_fini(void) |
251 | { | 226 | { |
252 | unsigned int i; | 227 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
253 | |||
254 | for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) | ||
255 | nf_unregister_hook(&ipt_ops[i]); | ||
256 | |||
257 | ipt_unregister_table(&packet_mangler); | 228 | ipt_unregister_table(&packet_mangler); |
258 | } | 229 | } |
259 | 230 | ||
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 03cc79a6160a..7912cce1e1b8 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -101,18 +101,18 @@ ipt_hook(unsigned int hook, | |||
101 | /* 'raw' is the very first table. */ | 101 | /* 'raw' is the very first table. */ |
102 | static struct nf_hook_ops ipt_ops[] = { | 102 | static struct nf_hook_ops ipt_ops[] = { |
103 | { | 103 | { |
104 | .hook = ipt_hook, | 104 | .hook = ipt_hook, |
105 | .pf = PF_INET, | 105 | .pf = PF_INET, |
106 | .hooknum = NF_IP_PRE_ROUTING, | 106 | .hooknum = NF_IP_PRE_ROUTING, |
107 | .priority = NF_IP_PRI_RAW, | 107 | .priority = NF_IP_PRI_RAW, |
108 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
109 | }, | 109 | }, |
110 | { | 110 | { |
111 | .hook = ipt_hook, | 111 | .hook = ipt_hook, |
112 | .pf = PF_INET, | 112 | .pf = PF_INET, |
113 | .hooknum = NF_IP_LOCAL_OUT, | 113 | .hooknum = NF_IP_LOCAL_OUT, |
114 | .priority = NF_IP_PRI_RAW, | 114 | .priority = NF_IP_PRI_RAW, |
115 | .owner = THIS_MODULE, | 115 | .owner = THIS_MODULE, |
116 | }, | 116 | }, |
117 | }; | 117 | }; |
118 | 118 | ||
@@ -126,31 +126,20 @@ static int __init iptable_raw_init(void) | |||
126 | return ret; | 126 | return ret; |
127 | 127 | ||
128 | /* Register hooks */ | 128 | /* Register hooks */ |
129 | ret = nf_register_hook(&ipt_ops[0]); | 129 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
130 | if (ret < 0) | 130 | if (ret < 0) |
131 | goto cleanup_table; | 131 | goto cleanup_table; |
132 | 132 | ||
133 | ret = nf_register_hook(&ipt_ops[1]); | ||
134 | if (ret < 0) | ||
135 | goto cleanup_hook0; | ||
136 | |||
137 | return ret; | 133 | return ret; |
138 | 134 | ||
139 | cleanup_hook0: | ||
140 | nf_unregister_hook(&ipt_ops[0]); | ||
141 | cleanup_table: | 135 | cleanup_table: |
142 | ipt_unregister_table(&packet_raw); | 136 | ipt_unregister_table(&packet_raw); |
143 | |||
144 | return ret; | 137 | return ret; |
145 | } | 138 | } |
146 | 139 | ||
147 | static void __exit iptable_raw_fini(void) | 140 | static void __exit iptable_raw_fini(void) |
148 | { | 141 | { |
149 | unsigned int i; | 142 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
150 | |||
151 | for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) | ||
152 | nf_unregister_hook(&ipt_ops[i]); | ||
153 | |||
154 | ipt_unregister_table(&packet_raw); | 143 | ipt_unregister_table(&packet_raw); |
155 | } | 144 | } |
156 | 145 | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 4afbc699d3ba..5bc9f64d7b5b 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -210,71 +210,63 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum, | |||
210 | 210 | ||
211 | /* Connection tracking may drop packets, but never alters them, so | 211 | /* Connection tracking may drop packets, but never alters them, so |
212 | make it the first hook. */ | 212 | make it the first hook. */ |
213 | static struct nf_hook_ops ipv4_conntrack_defrag_ops = { | 213 | static struct nf_hook_ops ipv4_conntrack_ops[] = { |
214 | .hook = ipv4_conntrack_defrag, | 214 | { |
215 | .owner = THIS_MODULE, | 215 | .hook = ipv4_conntrack_defrag, |
216 | .pf = PF_INET, | 216 | .owner = THIS_MODULE, |
217 | .hooknum = NF_IP_PRE_ROUTING, | 217 | .pf = PF_INET, |
218 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 218 | .hooknum = NF_IP_PRE_ROUTING, |
219 | }; | 219 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
220 | 220 | }, | |
221 | static struct nf_hook_ops ipv4_conntrack_in_ops = { | 221 | { |
222 | .hook = ipv4_conntrack_in, | 222 | .hook = ipv4_conntrack_in, |
223 | .owner = THIS_MODULE, | 223 | .owner = THIS_MODULE, |
224 | .pf = PF_INET, | 224 | .pf = PF_INET, |
225 | .hooknum = NF_IP_PRE_ROUTING, | 225 | .hooknum = NF_IP_PRE_ROUTING, |
226 | .priority = NF_IP_PRI_CONNTRACK, | 226 | .priority = NF_IP_PRI_CONNTRACK, |
227 | }; | 227 | }, |
228 | 228 | { | |
229 | static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = { | 229 | .hook = ipv4_conntrack_defrag, |
230 | .hook = ipv4_conntrack_defrag, | 230 | .owner = THIS_MODULE, |
231 | .owner = THIS_MODULE, | 231 | .pf = PF_INET, |
232 | .pf = PF_INET, | 232 | .hooknum = NF_IP_LOCAL_OUT, |
233 | .hooknum = NF_IP_LOCAL_OUT, | 233 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
234 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 234 | }, |
235 | }; | 235 | { |
236 | 236 | .hook = ipv4_conntrack_local, | |
237 | static struct nf_hook_ops ipv4_conntrack_local_out_ops = { | 237 | .owner = THIS_MODULE, |
238 | .hook = ipv4_conntrack_local, | 238 | .pf = PF_INET, |
239 | .owner = THIS_MODULE, | 239 | .hooknum = NF_IP_LOCAL_OUT, |
240 | .pf = PF_INET, | 240 | .priority = NF_IP_PRI_CONNTRACK, |
241 | .hooknum = NF_IP_LOCAL_OUT, | 241 | }, |
242 | .priority = NF_IP_PRI_CONNTRACK, | 242 | { |
243 | }; | 243 | .hook = ipv4_conntrack_help, |
244 | 244 | .owner = THIS_MODULE, | |
245 | /* helpers */ | 245 | .pf = PF_INET, |
246 | static struct nf_hook_ops ipv4_conntrack_helper_out_ops = { | 246 | .hooknum = NF_IP_POST_ROUTING, |
247 | .hook = ipv4_conntrack_help, | 247 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
248 | .owner = THIS_MODULE, | 248 | }, |
249 | .pf = PF_INET, | 249 | { |
250 | .hooknum = NF_IP_POST_ROUTING, | 250 | .hook = ipv4_conntrack_help, |
251 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 251 | .owner = THIS_MODULE, |
252 | }; | 252 | .pf = PF_INET, |
253 | 253 | .hooknum = NF_IP_LOCAL_IN, | |
254 | static struct nf_hook_ops ipv4_conntrack_helper_in_ops = { | 254 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
255 | .hook = ipv4_conntrack_help, | 255 | }, |
256 | .owner = THIS_MODULE, | 256 | { |
257 | .pf = PF_INET, | 257 | .hook = ipv4_confirm, |
258 | .hooknum = NF_IP_LOCAL_IN, | 258 | .owner = THIS_MODULE, |
259 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 259 | .pf = PF_INET, |
260 | }; | 260 | .hooknum = NF_IP_POST_ROUTING, |
261 | 261 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | |
262 | 262 | }, | |
263 | /* Refragmenter; last chance. */ | 263 | { |
264 | static struct nf_hook_ops ipv4_conntrack_out_ops = { | 264 | .hook = ipv4_confirm, |
265 | .hook = ipv4_confirm, | 265 | .owner = THIS_MODULE, |
266 | .owner = THIS_MODULE, | 266 | .pf = PF_INET, |
267 | .pf = PF_INET, | 267 | .hooknum = NF_IP_LOCAL_IN, |
268 | .hooknum = NF_IP_POST_ROUTING, | 268 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, |
269 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | 269 | }, |
270 | }; | ||
271 | |||
272 | static struct nf_hook_ops ipv4_conntrack_local_in_ops = { | ||
273 | .hook = ipv4_confirm, | ||
274 | .owner = THIS_MODULE, | ||
275 | .pf = PF_INET, | ||
276 | .hooknum = NF_IP_LOCAL_IN, | ||
277 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | ||
278 | }; | 270 | }; |
279 | 271 | ||
280 | #ifdef CONFIG_SYSCTL | 272 | #ifdef CONFIG_SYSCTL |
@@ -440,16 +432,20 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { | |||
440 | extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4; | 432 | extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4; |
441 | extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; | 433 | extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; |
442 | extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp; | 434 | extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp; |
443 | static int init_or_cleanup(int init) | 435 | |
436 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); | ||
437 | MODULE_LICENSE("GPL"); | ||
438 | |||
439 | static int __init nf_conntrack_l3proto_ipv4_init(void) | ||
444 | { | 440 | { |
445 | int ret = 0; | 441 | int ret = 0; |
446 | 442 | ||
447 | if (!init) goto cleanup; | 443 | need_conntrack(); |
448 | 444 | ||
449 | ret = nf_register_sockopt(&so_getorigdst); | 445 | ret = nf_register_sockopt(&so_getorigdst); |
450 | if (ret < 0) { | 446 | if (ret < 0) { |
451 | printk(KERN_ERR "Unable to register netfilter socket option\n"); | 447 | printk(KERN_ERR "Unable to register netfilter socket option\n"); |
452 | goto cleanup_nothing; | 448 | return ret; |
453 | } | 449 | } |
454 | 450 | ||
455 | ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4); | 451 | ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4); |
@@ -476,84 +472,26 @@ static int init_or_cleanup(int init) | |||
476 | goto cleanup_icmp; | 472 | goto cleanup_icmp; |
477 | } | 473 | } |
478 | 474 | ||
479 | ret = nf_register_hook(&ipv4_conntrack_defrag_ops); | 475 | ret = nf_register_hooks(ipv4_conntrack_ops, |
476 | ARRAY_SIZE(ipv4_conntrack_ops)); | ||
480 | if (ret < 0) { | 477 | if (ret < 0) { |
481 | printk("nf_conntrack_ipv4: can't register pre-routing defrag hook.\n"); | 478 | printk("nf_conntrack_ipv4: can't register hooks.\n"); |
482 | goto cleanup_ipv4; | 479 | goto cleanup_ipv4; |
483 | } | 480 | } |
484 | ret = nf_register_hook(&ipv4_conntrack_defrag_local_out_ops); | ||
485 | if (ret < 0) { | ||
486 | printk("nf_conntrack_ipv4: can't register local_out defrag hook.\n"); | ||
487 | goto cleanup_defragops; | ||
488 | } | ||
489 | |||
490 | ret = nf_register_hook(&ipv4_conntrack_in_ops); | ||
491 | if (ret < 0) { | ||
492 | printk("nf_conntrack_ipv4: can't register pre-routing hook.\n"); | ||
493 | goto cleanup_defraglocalops; | ||
494 | } | ||
495 | |||
496 | ret = nf_register_hook(&ipv4_conntrack_local_out_ops); | ||
497 | if (ret < 0) { | ||
498 | printk("nf_conntrack_ipv4: can't register local out hook.\n"); | ||
499 | goto cleanup_inops; | ||
500 | } | ||
501 | |||
502 | ret = nf_register_hook(&ipv4_conntrack_helper_in_ops); | ||
503 | if (ret < 0) { | ||
504 | printk("nf_conntrack_ipv4: can't register local helper hook.\n"); | ||
505 | goto cleanup_inandlocalops; | ||
506 | } | ||
507 | |||
508 | ret = nf_register_hook(&ipv4_conntrack_helper_out_ops); | ||
509 | if (ret < 0) { | ||
510 | printk("nf_conntrack_ipv4: can't register postrouting helper hook.\n"); | ||
511 | goto cleanup_helperinops; | ||
512 | } | ||
513 | |||
514 | ret = nf_register_hook(&ipv4_conntrack_out_ops); | ||
515 | if (ret < 0) { | ||
516 | printk("nf_conntrack_ipv4: can't register post-routing hook.\n"); | ||
517 | goto cleanup_helperoutops; | ||
518 | } | ||
519 | |||
520 | ret = nf_register_hook(&ipv4_conntrack_local_in_ops); | ||
521 | if (ret < 0) { | ||
522 | printk("nf_conntrack_ipv4: can't register local in hook.\n"); | ||
523 | goto cleanup_inoutandlocalops; | ||
524 | } | ||
525 | |||
526 | #ifdef CONFIG_SYSCTL | 481 | #ifdef CONFIG_SYSCTL |
527 | nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); | 482 | nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); |
528 | if (nf_ct_ipv4_sysctl_header == NULL) { | 483 | if (nf_ct_ipv4_sysctl_header == NULL) { |
529 | printk("nf_conntrack: can't register to sysctl.\n"); | 484 | printk("nf_conntrack: can't register to sysctl.\n"); |
530 | ret = -ENOMEM; | 485 | ret = -ENOMEM; |
531 | goto cleanup_localinops; | 486 | goto cleanup_hooks; |
532 | } | 487 | } |
533 | #endif | 488 | #endif |
534 | return ret; | 489 | return ret; |
535 | 490 | ||
536 | cleanup: | ||
537 | synchronize_net(); | ||
538 | #ifdef CONFIG_SYSCTL | 491 | #ifdef CONFIG_SYSCTL |
539 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); | 492 | cleanup_hooks: |
540 | cleanup_localinops: | 493 | nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); |
541 | #endif | 494 | #endif |
542 | nf_unregister_hook(&ipv4_conntrack_local_in_ops); | ||
543 | cleanup_inoutandlocalops: | ||
544 | nf_unregister_hook(&ipv4_conntrack_out_ops); | ||
545 | cleanup_helperoutops: | ||
546 | nf_unregister_hook(&ipv4_conntrack_helper_out_ops); | ||
547 | cleanup_helperinops: | ||
548 | nf_unregister_hook(&ipv4_conntrack_helper_in_ops); | ||
549 | cleanup_inandlocalops: | ||
550 | nf_unregister_hook(&ipv4_conntrack_local_out_ops); | ||
551 | cleanup_inops: | ||
552 | nf_unregister_hook(&ipv4_conntrack_in_ops); | ||
553 | cleanup_defraglocalops: | ||
554 | nf_unregister_hook(&ipv4_conntrack_defrag_local_out_ops); | ||
555 | cleanup_defragops: | ||
556 | nf_unregister_hook(&ipv4_conntrack_defrag_ops); | ||
557 | cleanup_ipv4: | 495 | cleanup_ipv4: |
558 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); | 496 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); |
559 | cleanup_icmp: | 497 | cleanup_icmp: |
@@ -564,22 +502,21 @@ static int init_or_cleanup(int init) | |||
564 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); | 502 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); |
565 | cleanup_sockopt: | 503 | cleanup_sockopt: |
566 | nf_unregister_sockopt(&so_getorigdst); | 504 | nf_unregister_sockopt(&so_getorigdst); |
567 | cleanup_nothing: | ||
568 | return ret; | 505 | return ret; |
569 | } | 506 | } |
570 | 507 | ||
571 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); | ||
572 | MODULE_LICENSE("GPL"); | ||
573 | |||
574 | static int __init nf_conntrack_l3proto_ipv4_init(void) | ||
575 | { | ||
576 | need_conntrack(); | ||
577 | return init_or_cleanup(1); | ||
578 | } | ||
579 | |||
580 | static void __exit nf_conntrack_l3proto_ipv4_fini(void) | 508 | static void __exit nf_conntrack_l3proto_ipv4_fini(void) |
581 | { | 509 | { |
582 | init_or_cleanup(0); | 510 | synchronize_net(); |
511 | #ifdef CONFIG_SYSCTL | ||
512 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); | ||
513 | #endif | ||
514 | nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); | ||
515 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); | ||
516 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp); | ||
517 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4); | ||
518 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); | ||
519 | nf_unregister_sockopt(&so_getorigdst); | ||
583 | } | 520 | } |
584 | 521 | ||
585 | module_init(nf_conntrack_l3proto_ipv4_init); | 522 | module_init(nf_conntrack_l3proto_ipv4_init); |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 52dc175be39a..4b0d361cc6e6 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -235,30 +235,14 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
235 | } | 235 | } |
236 | 236 | ||
237 | /* See ip_conntrack_proto_tcp.c */ | 237 | /* See ip_conntrack_proto_tcp.c */ |
238 | if (hooknum != NF_IP_PRE_ROUTING) | 238 | if (hooknum == NF_IP_PRE_ROUTING && |
239 | goto checksum_skipped; | 239 | nf_ip_checksum(skb, hooknum, dataoff, 0)) { |
240 | |||
241 | switch (skb->ip_summed) { | ||
242 | case CHECKSUM_HW: | ||
243 | if (!(u16)csum_fold(skb->csum)) | ||
244 | break; | ||
245 | if (LOG_INVALID(IPPROTO_ICMP)) | 240 | if (LOG_INVALID(IPPROTO_ICMP)) |
246 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 241 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
247 | "nf_ct_icmp: bad HW ICMP checksum "); | 242 | "nf_ct_icmp: bad HW ICMP checksum "); |
248 | return -NF_ACCEPT; | 243 | return -NF_ACCEPT; |
249 | case CHECKSUM_NONE: | ||
250 | if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { | ||
251 | if (LOG_INVALID(IPPROTO_ICMP)) | ||
252 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | ||
253 | NULL, | ||
254 | "nf_ct_icmp: bad ICMP checksum "); | ||
255 | return -NF_ACCEPT; | ||
256 | } | ||
257 | default: | ||
258 | break; | ||
259 | } | 244 | } |
260 | 245 | ||
261 | checksum_skipped: | ||
262 | /* | 246 | /* |
263 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 247 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
264 | * | 248 | * |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b167c4bb3be..d61e2a9d394d 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto) | |||
49 | int res = 0; | 49 | int res = 0; |
50 | int cpu; | 50 | int cpu; |
51 | 51 | ||
52 | for_each_cpu(cpu) | 52 | for_each_possible_cpu(cpu) |
53 | res += proto->stats[cpu].inuse; | 53 | res += proto->stats[cpu].inuse; |
54 | 54 | ||
55 | return res; | 55 | return res; |
@@ -91,7 +91,7 @@ fold_field(void *mib[], int offt) | |||
91 | unsigned long res = 0; | 91 | unsigned long res = 0; |
92 | int i; | 92 | int i; |
93 | 93 | ||
94 | for_each_cpu(i) { | 94 | for_each_possible_cpu(i) { |
95 | res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); | 95 | res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); |
96 | res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); | 96 | res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); |
97 | } | 97 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 94fcbc5e5a1b..ff434821909f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -3083,7 +3083,7 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset, | |||
3083 | memcpy(dst, src, length); | 3083 | memcpy(dst, src, length); |
3084 | 3084 | ||
3085 | /* Add the other cpus in, one int at a time */ | 3085 | /* Add the other cpus in, one int at a time */ |
3086 | for_each_cpu(i) { | 3086 | for_each_possible_cpu(i) { |
3087 | unsigned int j; | 3087 | unsigned int j; |
3088 | 3088 | ||
3089 | src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; | 3089 | src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; |
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 0d7d386dac22..8d30c48f090e 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <linux/mutex.h> | 8 | #include <linux/mutex.h> |
9 | #include <linux/netdevice.h> | 9 | #include <linux/netdevice.h> |
10 | #include <linux/skbuff.h> | 10 | #include <linux/skbuff.h> |
11 | #include <net/icmp.h> | ||
12 | #include <net/ip.h> | ||
11 | #include <net/protocol.h> | 13 | #include <net/protocol.h> |
12 | #include <net/xfrm.h> | 14 | #include <net/xfrm.h> |
13 | 15 | ||
@@ -70,10 +72,16 @@ static int tunnel4_rcv(struct sk_buff *skb) | |||
70 | { | 72 | { |
71 | struct xfrm_tunnel *handler; | 73 | struct xfrm_tunnel *handler; |
72 | 74 | ||
75 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
76 | goto drop; | ||
77 | |||
73 | for (handler = tunnel4_handlers; handler; handler = handler->next) | 78 | for (handler = tunnel4_handlers; handler; handler = handler->next) |
74 | if (!handler->handler(skb)) | 79 | if (!handler->handler(skb)) |
75 | return 0; | 80 | return 0; |
76 | 81 | ||
82 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | ||
83 | |||
84 | drop: | ||
77 | kfree_skb(skb); | 85 | kfree_skb(skb); |
78 | return 0; | 86 | return 0; |
79 | } | 87 | } |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index e1b8f4b90d80..3e174c83bfe7 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -37,8 +37,6 @@ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) | |||
37 | { | 37 | { |
38 | switch (nexthdr) { | 38 | switch (nexthdr) { |
39 | case IPPROTO_IPIP: | 39 | case IPPROTO_IPIP: |
40 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
41 | return -EINVAL; | ||
42 | *spi = skb->nh.iph->saddr; | 40 | *spi = skb->nh.iph->saddr; |
43 | *seq = 0; | 41 | *seq = 0; |
44 | return 0; | 42 | return 0; |
@@ -90,7 +88,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
90 | if (unlikely(x->km.state != XFRM_STATE_VALID)) | 88 | if (unlikely(x->km.state != XFRM_STATE_VALID)) |
91 | goto drop_unlock; | 89 | goto drop_unlock; |
92 | 90 | ||
93 | if (x->encap->encap_type != encap_type) | 91 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) |
94 | goto drop_unlock; | 92 | goto drop_unlock; |
95 | 93 | ||
96 | if (x->props.replay_window && xfrm_replay_check(x, seq)) | 94 | if (x->props.replay_window && xfrm_replay_check(x, seq)) |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 21eb725e885f..1044b6fce0d5 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -717,7 +717,7 @@ int __init icmpv6_init(struct net_proto_family *ops) | |||
717 | struct sock *sk; | 717 | struct sock *sk; |
718 | int err, i, j; | 718 | int err, i, j; |
719 | 719 | ||
720 | for_each_cpu(i) { | 720 | for_each_possible_cpu(i) { |
721 | err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, | 721 | err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, |
722 | &per_cpu(__icmpv6_socket, i)); | 722 | &per_cpu(__icmpv6_socket, i)); |
723 | if (err < 0) { | 723 | if (err < 0) { |
@@ -763,7 +763,7 @@ void icmpv6_cleanup(void) | |||
763 | { | 763 | { |
764 | int i; | 764 | int i; |
765 | 765 | ||
766 | for_each_cpu(i) { | 766 | for_each_possible_cpu(i) { |
767 | sock_release(per_cpu(__icmpv6_socket, i)); | 767 | sock_release(per_cpu(__icmpv6_socket, i)); |
768 | } | 768 | } |
769 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); | 769 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index bb8ffb8a14c5..2ae84c961678 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -23,6 +23,86 @@ | |||
23 | #include <net/inet6_hashtables.h> | 23 | #include <net/inet6_hashtables.h> |
24 | #include <net/ip.h> | 24 | #include <net/ip.h> |
25 | 25 | ||
26 | void __inet6_hash(struct inet_hashinfo *hashinfo, | ||
27 | struct sock *sk) | ||
28 | { | ||
29 | struct hlist_head *list; | ||
30 | rwlock_t *lock; | ||
31 | |||
32 | BUG_TRAP(sk_unhashed(sk)); | ||
33 | |||
34 | if (sk->sk_state == TCP_LISTEN) { | ||
35 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | ||
36 | lock = &hashinfo->lhash_lock; | ||
37 | inet_listen_wlock(hashinfo); | ||
38 | } else { | ||
39 | unsigned int hash; | ||
40 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); | ||
41 | hash &= (hashinfo->ehash_size - 1); | ||
42 | list = &hashinfo->ehash[hash].chain; | ||
43 | lock = &hashinfo->ehash[hash].lock; | ||
44 | write_lock(lock); | ||
45 | } | ||
46 | |||
47 | __sk_add_node(sk, list); | ||
48 | sock_prot_inc_use(sk->sk_prot); | ||
49 | write_unlock(lock); | ||
50 | } | ||
51 | EXPORT_SYMBOL(__inet6_hash); | ||
52 | |||
53 | /* | ||
54 | * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so | ||
55 | * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM | ||
56 | * | ||
57 | * The sockhash lock must be held as a reader here. | ||
58 | */ | ||
59 | struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo, | ||
60 | const struct in6_addr *saddr, | ||
61 | const u16 sport, | ||
62 | const struct in6_addr *daddr, | ||
63 | const u16 hnum, | ||
64 | const int dif) | ||
65 | { | ||
66 | struct sock *sk; | ||
67 | const struct hlist_node *node; | ||
68 | const __u32 ports = INET_COMBINED_PORTS(sport, hnum); | ||
69 | /* Optimize here for direct hit, only listening connections can | ||
70 | * have wildcards anyways. | ||
71 | */ | ||
72 | unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport); | ||
73 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | ||
74 | |||
75 | prefetch(head->chain.first); | ||
76 | read_lock(&head->lock); | ||
77 | sk_for_each(sk, node, &head->chain) { | ||
78 | /* For IPV6 do the cheaper port and family tests first. */ | ||
79 | if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif)) | ||
80 | goto hit; /* You sunk my battleship! */ | ||
81 | } | ||
82 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
83 | sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { | ||
84 | const struct inet_timewait_sock *tw = inet_twsk(sk); | ||
85 | |||
86 | if(*((__u32 *)&(tw->tw_dport)) == ports && | ||
87 | sk->sk_family == PF_INET6) { | ||
88 | const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); | ||
89 | |||
90 | if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && | ||
91 | ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && | ||
92 | (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif)) | ||
93 | goto hit; | ||
94 | } | ||
95 | } | ||
96 | read_unlock(&head->lock); | ||
97 | return NULL; | ||
98 | |||
99 | hit: | ||
100 | sock_hold(sk); | ||
101 | read_unlock(&head->lock); | ||
102 | return sk; | ||
103 | } | ||
104 | EXPORT_SYMBOL(__inet6_lookup_established); | ||
105 | |||
26 | struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, | 106 | struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, |
27 | const struct in6_addr *daddr, | 107 | const struct in6_addr *daddr, |
28 | const unsigned short hnum, const int dif) | 108 | const unsigned short hnum, const int dif) |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index ff9040c92556..a995796b5a57 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -519,9 +519,6 @@ ip6ip6_rcv(struct sk_buff *skb) | |||
519 | struct ipv6hdr *ipv6h; | 519 | struct ipv6hdr *ipv6h; |
520 | struct ip6_tnl *t; | 520 | struct ip6_tnl *t; |
521 | 521 | ||
522 | if (!pskb_may_pull(skb, sizeof (*ipv6h))) | ||
523 | goto discard; | ||
524 | |||
525 | ipv6h = skb->nh.ipv6h; | 522 | ipv6h = skb->nh.ipv6h; |
526 | 523 | ||
527 | read_lock(&ip6ip6_lock); | 524 | read_lock(&ip6ip6_lock); |
@@ -529,8 +526,7 @@ ip6ip6_rcv(struct sk_buff *skb) | |||
529 | if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) { | 526 | if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) { |
530 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 527 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
531 | read_unlock(&ip6ip6_lock); | 528 | read_unlock(&ip6ip6_lock); |
532 | kfree_skb(skb); | 529 | goto discard; |
533 | return 0; | ||
534 | } | 530 | } |
535 | 531 | ||
536 | if (!(t->parms.flags & IP6_TNL_F_CAP_RCV)) { | 532 | if (!(t->parms.flags & IP6_TNL_F_CAP_RCV)) { |
@@ -557,9 +553,11 @@ ip6ip6_rcv(struct sk_buff *skb) | |||
557 | return 0; | 553 | return 0; |
558 | } | 554 | } |
559 | read_unlock(&ip6ip6_lock); | 555 | read_unlock(&ip6ip6_lock); |
560 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); | ||
561 | discard: | ||
562 | return 1; | 556 | return 1; |
557 | |||
558 | discard: | ||
559 | kfree_skb(skb); | ||
560 | return 0; | ||
563 | } | 561 | } |
564 | 562 | ||
565 | static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) | 563 | static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) |
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 00f3fadfcca7..05eb67def39f 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -290,7 +290,7 @@ static void ipcomp6_free_scratches(void) | |||
290 | if (!scratches) | 290 | if (!scratches) |
291 | return; | 291 | return; |
292 | 292 | ||
293 | for_each_cpu(i) { | 293 | for_each_possible_cpu(i) { |
294 | void *scratch = *per_cpu_ptr(scratches, i); | 294 | void *scratch = *per_cpu_ptr(scratches, i); |
295 | 295 | ||
296 | vfree(scratch); | 296 | vfree(scratch); |
@@ -313,7 +313,7 @@ static void **ipcomp6_alloc_scratches(void) | |||
313 | 313 | ||
314 | ipcomp6_scratches = scratches; | 314 | ipcomp6_scratches = scratches; |
315 | 315 | ||
316 | for_each_cpu(i) { | 316 | for_each_possible_cpu(i) { |
317 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); | 317 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); |
318 | if (!scratch) | 318 | if (!scratch) |
319 | return NULL; | 319 | return NULL; |
@@ -344,7 +344,7 @@ static void ipcomp6_free_tfms(struct crypto_tfm **tfms) | |||
344 | if (!tfms) | 344 | if (!tfms) |
345 | return; | 345 | return; |
346 | 346 | ||
347 | for_each_cpu(cpu) { | 347 | for_each_possible_cpu(cpu) { |
348 | struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); | 348 | struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); |
349 | crypto_free_tfm(tfm); | 349 | crypto_free_tfm(tfm); |
350 | } | 350 | } |
@@ -384,7 +384,7 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name) | |||
384 | if (!tfms) | 384 | if (!tfms) |
385 | goto error; | 385 | goto error; |
386 | 386 | ||
387 | for_each_cpu(cpu) { | 387 | for_each_possible_cpu(cpu) { |
388 | struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); | 388 | struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); |
389 | if (!tfm) | 389 | if (!tfm) |
390 | goto error; | 390 | goto error; |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index d750cfc019dc..395a417ba955 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <net/ipv6.h> | 7 | #include <net/ipv6.h> |
8 | #include <net/ip6_route.h> | 8 | #include <net/ip6_route.h> |
9 | #include <net/xfrm.h> | 9 | #include <net/xfrm.h> |
10 | #include <net/ip6_checksum.h> | ||
10 | 11 | ||
11 | int ip6_route_me_harder(struct sk_buff *skb) | 12 | int ip6_route_me_harder(struct sk_buff *skb) |
12 | { | 13 | { |
@@ -54,7 +55,7 @@ struct ip6_rt_info { | |||
54 | struct in6_addr saddr; | 55 | struct in6_addr saddr; |
55 | }; | 56 | }; |
56 | 57 | ||
57 | static void save(const struct sk_buff *skb, struct nf_info *info) | 58 | static void nf_ip6_saveroute(const struct sk_buff *skb, struct nf_info *info) |
58 | { | 59 | { |
59 | struct ip6_rt_info *rt_info = nf_info_reroute(info); | 60 | struct ip6_rt_info *rt_info = nf_info_reroute(info); |
60 | 61 | ||
@@ -66,7 +67,7 @@ static void save(const struct sk_buff *skb, struct nf_info *info) | |||
66 | } | 67 | } |
67 | } | 68 | } |
68 | 69 | ||
69 | static int reroute(struct sk_buff **pskb, const struct nf_info *info) | 70 | static int nf_ip6_reroute(struct sk_buff **pskb, const struct nf_info *info) |
70 | { | 71 | { |
71 | struct ip6_rt_info *rt_info = nf_info_reroute(info); | 72 | struct ip6_rt_info *rt_info = nf_info_reroute(info); |
72 | 73 | ||
@@ -79,15 +80,50 @@ static int reroute(struct sk_buff **pskb, const struct nf_info *info) | |||
79 | return 0; | 80 | return 0; |
80 | } | 81 | } |
81 | 82 | ||
82 | static struct nf_queue_rerouter ip6_reroute = { | 83 | unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, |
83 | .rer_size = sizeof(struct ip6_rt_info), | 84 | unsigned int dataoff, u_int8_t protocol) |
84 | .save = &save, | 85 | { |
85 | .reroute = &reroute, | 86 | struct ipv6hdr *ip6h = skb->nh.ipv6h; |
87 | unsigned int csum = 0; | ||
88 | |||
89 | switch (skb->ip_summed) { | ||
90 | case CHECKSUM_HW: | ||
91 | if (hook != NF_IP6_PRE_ROUTING && hook != NF_IP6_LOCAL_IN) | ||
92 | break; | ||
93 | if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, | ||
94 | skb->len - dataoff, protocol, | ||
95 | csum_sub(skb->csum, | ||
96 | skb_checksum(skb, 0, | ||
97 | dataoff, 0)))) { | ||
98 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
99 | break; | ||
100 | } | ||
101 | /* fall through */ | ||
102 | case CHECKSUM_NONE: | ||
103 | skb->csum = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, | ||
104 | skb->len - dataoff, | ||
105 | protocol, | ||
106 | csum_sub(0, | ||
107 | skb_checksum(skb, 0, | ||
108 | dataoff, 0))); | ||
109 | csum = __skb_checksum_complete(skb); | ||
110 | } | ||
111 | return csum; | ||
112 | } | ||
113 | |||
114 | EXPORT_SYMBOL(nf_ip6_checksum); | ||
115 | |||
116 | static struct nf_afinfo nf_ip6_afinfo = { | ||
117 | .family = AF_INET6, | ||
118 | .checksum = nf_ip6_checksum, | ||
119 | .saveroute = nf_ip6_saveroute, | ||
120 | .reroute = nf_ip6_reroute, | ||
121 | .route_key_size = sizeof(struct ip6_rt_info), | ||
86 | }; | 122 | }; |
87 | 123 | ||
88 | int __init ipv6_netfilter_init(void) | 124 | int __init ipv6_netfilter_init(void) |
89 | { | 125 | { |
90 | return nf_register_queue_rerouter(PF_INET6, &ip6_reroute); | 126 | return nf_register_afinfo(&nf_ip6_afinfo); |
91 | } | 127 | } |
92 | 128 | ||
93 | /* This can be called from inet6_init() on errors, so it cannot | 129 | /* This can be called from inet6_init() on errors, so it cannot |
@@ -95,5 +131,5 @@ int __init ipv6_netfilter_init(void) | |||
95 | */ | 131 | */ |
96 | void ipv6_netfilter_fini(void) | 132 | void ipv6_netfilter_fini(void) |
97 | { | 133 | { |
98 | nf_unregister_queue_rerouter(PF_INET6); | 134 | nf_unregister_afinfo(&nf_ip6_afinfo); |
99 | } | 135 | } |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index e81c6a9dab81..b4b7d441af25 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -658,15 +658,11 @@ static struct nf_queue_handler nfqh = { | |||
658 | .outfn = &ipq_enqueue_packet, | 658 | .outfn = &ipq_enqueue_packet, |
659 | }; | 659 | }; |
660 | 660 | ||
661 | static int | 661 | static int __init ip6_queue_init(void) |
662 | init_or_cleanup(int init) | ||
663 | { | 662 | { |
664 | int status = -ENOMEM; | 663 | int status = -ENOMEM; |
665 | struct proc_dir_entry *proc; | 664 | struct proc_dir_entry *proc; |
666 | 665 | ||
667 | if (!init) | ||
668 | goto cleanup; | ||
669 | |||
670 | netlink_register_notifier(&ipq_nl_notifier); | 666 | netlink_register_notifier(&ipq_nl_notifier); |
671 | ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, | 667 | ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, |
672 | THIS_MODULE); | 668 | THIS_MODULE); |
@@ -693,11 +689,6 @@ init_or_cleanup(int init) | |||
693 | } | 689 | } |
694 | return status; | 690 | return status; |
695 | 691 | ||
696 | cleanup: | ||
697 | nf_unregister_queue_handlers(&nfqh); | ||
698 | synchronize_net(); | ||
699 | ipq_flush(NF_DROP); | ||
700 | |||
701 | cleanup_sysctl: | 692 | cleanup_sysctl: |
702 | unregister_sysctl_table(ipq_sysctl_header); | 693 | unregister_sysctl_table(ipq_sysctl_header); |
703 | unregister_netdevice_notifier(&ipq_dev_notifier); | 694 | unregister_netdevice_notifier(&ipq_dev_notifier); |
@@ -713,15 +704,21 @@ cleanup_netlink_notifier: | |||
713 | return status; | 704 | return status; |
714 | } | 705 | } |
715 | 706 | ||
716 | static int __init ip6_queue_init(void) | ||
717 | { | ||
718 | |||
719 | return init_or_cleanup(1); | ||
720 | } | ||
721 | |||
722 | static void __exit ip6_queue_fini(void) | 707 | static void __exit ip6_queue_fini(void) |
723 | { | 708 | { |
724 | init_or_cleanup(0); | 709 | nf_unregister_queue_handlers(&nfqh); |
710 | synchronize_net(); | ||
711 | ipq_flush(NF_DROP); | ||
712 | |||
713 | unregister_sysctl_table(ipq_sysctl_header); | ||
714 | unregister_netdevice_notifier(&ipq_dev_notifier); | ||
715 | proc_net_remove(IPQ_PROC_FS_NAME); | ||
716 | |||
717 | sock_release(ipqnl->sk_socket); | ||
718 | mutex_lock(&ipqnl_mutex); | ||
719 | mutex_unlock(&ipqnl_mutex); | ||
720 | |||
721 | netlink_unregister_notifier(&ipq_nl_notifier); | ||
725 | } | 722 | } |
726 | 723 | ||
727 | MODULE_DESCRIPTION("IPv6 packet queue handler"); | 724 | MODULE_DESCRIPTION("IPv6 packet queue handler"); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 3ecf2db841f8..642b4b11464f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -788,7 +788,7 @@ translate_table(const char *name, | |||
788 | } | 788 | } |
789 | 789 | ||
790 | /* And one copy for every other CPU */ | 790 | /* And one copy for every other CPU */ |
791 | for_each_cpu(i) { | 791 | for_each_possible_cpu(i) { |
792 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) | 792 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
793 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 793 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
794 | } | 794 | } |
@@ -841,7 +841,7 @@ get_counters(const struct xt_table_info *t, | |||
841 | counters, | 841 | counters, |
842 | &i); | 842 | &i); |
843 | 843 | ||
844 | for_each_cpu(cpu) { | 844 | for_each_possible_cpu(cpu) { |
845 | if (cpu == curcpu) | 845 | if (cpu == curcpu) |
846 | continue; | 846 | continue; |
847 | i = 0; | 847 | i = 0; |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index e5e724d9ee60..60976c0c58e8 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -177,37 +177,20 @@ static int __init ip6table_filter_init(void) | |||
177 | return ret; | 177 | return ret; |
178 | 178 | ||
179 | /* Register hooks */ | 179 | /* Register hooks */ |
180 | ret = nf_register_hook(&ip6t_ops[0]); | 180 | ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); |
181 | if (ret < 0) | 181 | if (ret < 0) |
182 | goto cleanup_table; | 182 | goto cleanup_table; |
183 | 183 | ||
184 | ret = nf_register_hook(&ip6t_ops[1]); | ||
185 | if (ret < 0) | ||
186 | goto cleanup_hook0; | ||
187 | |||
188 | ret = nf_register_hook(&ip6t_ops[2]); | ||
189 | if (ret < 0) | ||
190 | goto cleanup_hook1; | ||
191 | |||
192 | return ret; | 184 | return ret; |
193 | 185 | ||
194 | cleanup_hook1: | ||
195 | nf_unregister_hook(&ip6t_ops[1]); | ||
196 | cleanup_hook0: | ||
197 | nf_unregister_hook(&ip6t_ops[0]); | ||
198 | cleanup_table: | 186 | cleanup_table: |
199 | ip6t_unregister_table(&packet_filter); | 187 | ip6t_unregister_table(&packet_filter); |
200 | |||
201 | return ret; | 188 | return ret; |
202 | } | 189 | } |
203 | 190 | ||
204 | static void __exit ip6table_filter_fini(void) | 191 | static void __exit ip6table_filter_fini(void) |
205 | { | 192 | { |
206 | unsigned int i; | 193 | nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); |
207 | |||
208 | for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++) | ||
209 | nf_unregister_hook(&ip6t_ops[i]); | ||
210 | |||
211 | ip6t_unregister_table(&packet_filter); | 194 | ip6t_unregister_table(&packet_filter); |
212 | } | 195 | } |
213 | 196 | ||
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index e1f0f6ae9841..03a13eab1dae 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -238,49 +238,20 @@ static int __init ip6table_mangle_init(void) | |||
238 | return ret; | 238 | return ret; |
239 | 239 | ||
240 | /* Register hooks */ | 240 | /* Register hooks */ |
241 | ret = nf_register_hook(&ip6t_ops[0]); | 241 | ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); |
242 | if (ret < 0) | 242 | if (ret < 0) |
243 | goto cleanup_table; | 243 | goto cleanup_table; |
244 | 244 | ||
245 | ret = nf_register_hook(&ip6t_ops[1]); | ||
246 | if (ret < 0) | ||
247 | goto cleanup_hook0; | ||
248 | |||
249 | ret = nf_register_hook(&ip6t_ops[2]); | ||
250 | if (ret < 0) | ||
251 | goto cleanup_hook1; | ||
252 | |||
253 | ret = nf_register_hook(&ip6t_ops[3]); | ||
254 | if (ret < 0) | ||
255 | goto cleanup_hook2; | ||
256 | |||
257 | ret = nf_register_hook(&ip6t_ops[4]); | ||
258 | if (ret < 0) | ||
259 | goto cleanup_hook3; | ||
260 | |||
261 | return ret; | 245 | return ret; |
262 | 246 | ||
263 | cleanup_hook3: | ||
264 | nf_unregister_hook(&ip6t_ops[3]); | ||
265 | cleanup_hook2: | ||
266 | nf_unregister_hook(&ip6t_ops[2]); | ||
267 | cleanup_hook1: | ||
268 | nf_unregister_hook(&ip6t_ops[1]); | ||
269 | cleanup_hook0: | ||
270 | nf_unregister_hook(&ip6t_ops[0]); | ||
271 | cleanup_table: | 247 | cleanup_table: |
272 | ip6t_unregister_table(&packet_mangler); | 248 | ip6t_unregister_table(&packet_mangler); |
273 | |||
274 | return ret; | 249 | return ret; |
275 | } | 250 | } |
276 | 251 | ||
277 | static void __exit ip6table_mangle_fini(void) | 252 | static void __exit ip6table_mangle_fini(void) |
278 | { | 253 | { |
279 | unsigned int i; | 254 | nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); |
280 | |||
281 | for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++) | ||
282 | nf_unregister_hook(&ip6t_ops[i]); | ||
283 | |||
284 | ip6t_unregister_table(&packet_mangler); | 255 | ip6t_unregister_table(&packet_mangler); |
285 | } | 256 | } |
286 | 257 | ||
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index 54d1fffd62ba..61a7c58e99f8 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -152,31 +152,20 @@ static int __init ip6table_raw_init(void) | |||
152 | return ret; | 152 | return ret; |
153 | 153 | ||
154 | /* Register hooks */ | 154 | /* Register hooks */ |
155 | ret = nf_register_hook(&ip6t_ops[0]); | 155 | ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); |
156 | if (ret < 0) | 156 | if (ret < 0) |
157 | goto cleanup_table; | 157 | goto cleanup_table; |
158 | 158 | ||
159 | ret = nf_register_hook(&ip6t_ops[1]); | ||
160 | if (ret < 0) | ||
161 | goto cleanup_hook0; | ||
162 | |||
163 | return ret; | 159 | return ret; |
164 | 160 | ||
165 | cleanup_hook0: | ||
166 | nf_unregister_hook(&ip6t_ops[0]); | ||
167 | cleanup_table: | 161 | cleanup_table: |
168 | ip6t_unregister_table(&packet_raw); | 162 | ip6t_unregister_table(&packet_raw); |
169 | |||
170 | return ret; | 163 | return ret; |
171 | } | 164 | } |
172 | 165 | ||
173 | static void __exit ip6table_raw_fini(void) | 166 | static void __exit ip6table_raw_fini(void) |
174 | { | 167 | { |
175 | unsigned int i; | 168 | nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); |
176 | |||
177 | for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++) | ||
178 | nf_unregister_hook(&ip6t_ops[i]); | ||
179 | |||
180 | ip6t_unregister_table(&packet_raw); | 169 | ip6t_unregister_table(&packet_raw); |
181 | } | 170 | } |
182 | 171 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index c8b5a96cbb0f..93bae36f2663 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -286,55 +286,49 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum, | |||
286 | return ipv6_conntrack_in(hooknum, pskb, in, out, okfn); | 286 | return ipv6_conntrack_in(hooknum, pskb, in, out, okfn); |
287 | } | 287 | } |
288 | 288 | ||
289 | /* Connection tracking may drop packets, but never alters them, so | 289 | static struct nf_hook_ops ipv6_conntrack_ops[] = { |
290 | make it the first hook. */ | 290 | { |
291 | static struct nf_hook_ops ipv6_conntrack_defrag_ops = { | 291 | .hook = ipv6_defrag, |
292 | .hook = ipv6_defrag, | 292 | .owner = THIS_MODULE, |
293 | .owner = THIS_MODULE, | 293 | .pf = PF_INET6, |
294 | .pf = PF_INET6, | 294 | .hooknum = NF_IP6_PRE_ROUTING, |
295 | .hooknum = NF_IP6_PRE_ROUTING, | 295 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, |
296 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, | 296 | }, |
297 | }; | 297 | { |
298 | 298 | .hook = ipv6_conntrack_in, | |
299 | static struct nf_hook_ops ipv6_conntrack_in_ops = { | 299 | .owner = THIS_MODULE, |
300 | .hook = ipv6_conntrack_in, | 300 | .pf = PF_INET6, |
301 | .owner = THIS_MODULE, | 301 | .hooknum = NF_IP6_PRE_ROUTING, |
302 | .pf = PF_INET6, | 302 | .priority = NF_IP6_PRI_CONNTRACK, |
303 | .hooknum = NF_IP6_PRE_ROUTING, | 303 | }, |
304 | .priority = NF_IP6_PRI_CONNTRACK, | 304 | { |
305 | }; | 305 | .hook = ipv6_conntrack_local, |
306 | 306 | .owner = THIS_MODULE, | |
307 | static struct nf_hook_ops ipv6_conntrack_local_out_ops = { | 307 | .pf = PF_INET6, |
308 | .hook = ipv6_conntrack_local, | 308 | .hooknum = NF_IP6_LOCAL_OUT, |
309 | .owner = THIS_MODULE, | 309 | .priority = NF_IP6_PRI_CONNTRACK, |
310 | .pf = PF_INET6, | 310 | }, |
311 | .hooknum = NF_IP6_LOCAL_OUT, | 311 | { |
312 | .priority = NF_IP6_PRI_CONNTRACK, | 312 | .hook = ipv6_defrag, |
313 | }; | 313 | .owner = THIS_MODULE, |
314 | 314 | .pf = PF_INET6, | |
315 | static struct nf_hook_ops ipv6_conntrack_defrag_local_out_ops = { | 315 | .hooknum = NF_IP6_LOCAL_OUT, |
316 | .hook = ipv6_defrag, | 316 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, |
317 | .owner = THIS_MODULE, | 317 | }, |
318 | .pf = PF_INET6, | 318 | { |
319 | .hooknum = NF_IP6_LOCAL_OUT, | 319 | .hook = ipv6_confirm, |
320 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, | 320 | .owner = THIS_MODULE, |
321 | }; | 321 | .pf = PF_INET6, |
322 | 322 | .hooknum = NF_IP6_POST_ROUTING, | |
323 | /* Refragmenter; last chance. */ | 323 | .priority = NF_IP6_PRI_LAST, |
324 | static struct nf_hook_ops ipv6_conntrack_out_ops = { | 324 | }, |
325 | .hook = ipv6_confirm, | 325 | { |
326 | .owner = THIS_MODULE, | 326 | .hook = ipv6_confirm, |
327 | .pf = PF_INET6, | 327 | .owner = THIS_MODULE, |
328 | .hooknum = NF_IP6_POST_ROUTING, | 328 | .pf = PF_INET6, |
329 | .priority = NF_IP6_PRI_LAST, | 329 | .hooknum = NF_IP6_LOCAL_IN, |
330 | }; | 330 | .priority = NF_IP6_PRI_LAST-1, |
331 | 331 | }, | |
332 | static struct nf_hook_ops ipv6_conntrack_local_in_ops = { | ||
333 | .hook = ipv6_confirm, | ||
334 | .owner = THIS_MODULE, | ||
335 | .pf = PF_INET6, | ||
336 | .hooknum = NF_IP6_LOCAL_IN, | ||
337 | .priority = NF_IP6_PRI_LAST-1, | ||
338 | }; | 332 | }; |
339 | 333 | ||
340 | #ifdef CONFIG_SYSCTL | 334 | #ifdef CONFIG_SYSCTL |
@@ -470,16 +464,21 @@ extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6; | |||
470 | extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6; | 464 | extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6; |
471 | extern int nf_ct_frag6_init(void); | 465 | extern int nf_ct_frag6_init(void); |
472 | extern void nf_ct_frag6_cleanup(void); | 466 | extern void nf_ct_frag6_cleanup(void); |
473 | static int init_or_cleanup(int init) | 467 | |
468 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); | ||
469 | MODULE_LICENSE("GPL"); | ||
470 | MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); | ||
471 | |||
472 | static int __init nf_conntrack_l3proto_ipv6_init(void) | ||
474 | { | 473 | { |
475 | int ret = 0; | 474 | int ret = 0; |
476 | 475 | ||
477 | if (!init) goto cleanup; | 476 | need_conntrack(); |
478 | 477 | ||
479 | ret = nf_ct_frag6_init(); | 478 | ret = nf_ct_frag6_init(); |
480 | if (ret < 0) { | 479 | if (ret < 0) { |
481 | printk("nf_conntrack_ipv6: can't initialize frag6.\n"); | 480 | printk("nf_conntrack_ipv6: can't initialize frag6.\n"); |
482 | goto cleanup_nothing; | 481 | return ret; |
483 | } | 482 | } |
484 | ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6); | 483 | ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6); |
485 | if (ret < 0) { | 484 | if (ret < 0) { |
@@ -505,71 +504,27 @@ static int init_or_cleanup(int init) | |||
505 | goto cleanup_icmpv6; | 504 | goto cleanup_icmpv6; |
506 | } | 505 | } |
507 | 506 | ||
508 | ret = nf_register_hook(&ipv6_conntrack_defrag_ops); | 507 | ret = nf_register_hooks(ipv6_conntrack_ops, |
508 | ARRAY_SIZE(ipv6_conntrack_ops)); | ||
509 | if (ret < 0) { | 509 | if (ret < 0) { |
510 | printk("nf_conntrack_ipv6: can't register pre-routing defrag " | 510 | printk("nf_conntrack_ipv6: can't register pre-routing defrag " |
511 | "hook.\n"); | 511 | "hook.\n"); |
512 | goto cleanup_ipv6; | 512 | goto cleanup_ipv6; |
513 | } | 513 | } |
514 | |||
515 | ret = nf_register_hook(&ipv6_conntrack_defrag_local_out_ops); | ||
516 | if (ret < 0) { | ||
517 | printk("nf_conntrack_ipv6: can't register local_out defrag " | ||
518 | "hook.\n"); | ||
519 | goto cleanup_defragops; | ||
520 | } | ||
521 | |||
522 | ret = nf_register_hook(&ipv6_conntrack_in_ops); | ||
523 | if (ret < 0) { | ||
524 | printk("nf_conntrack_ipv6: can't register pre-routing hook.\n"); | ||
525 | goto cleanup_defraglocalops; | ||
526 | } | ||
527 | |||
528 | ret = nf_register_hook(&ipv6_conntrack_local_out_ops); | ||
529 | if (ret < 0) { | ||
530 | printk("nf_conntrack_ipv6: can't register local out hook.\n"); | ||
531 | goto cleanup_inops; | ||
532 | } | ||
533 | |||
534 | ret = nf_register_hook(&ipv6_conntrack_out_ops); | ||
535 | if (ret < 0) { | ||
536 | printk("nf_conntrack_ipv6: can't register post-routing hook.\n"); | ||
537 | goto cleanup_inandlocalops; | ||
538 | } | ||
539 | |||
540 | ret = nf_register_hook(&ipv6_conntrack_local_in_ops); | ||
541 | if (ret < 0) { | ||
542 | printk("nf_conntrack_ipv6: can't register local in hook.\n"); | ||
543 | goto cleanup_inoutandlocalops; | ||
544 | } | ||
545 | |||
546 | #ifdef CONFIG_SYSCTL | 514 | #ifdef CONFIG_SYSCTL |
547 | nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); | 515 | nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); |
548 | if (nf_ct_ipv6_sysctl_header == NULL) { | 516 | if (nf_ct_ipv6_sysctl_header == NULL) { |
549 | printk("nf_conntrack: can't register to sysctl.\n"); | 517 | printk("nf_conntrack: can't register to sysctl.\n"); |
550 | ret = -ENOMEM; | 518 | ret = -ENOMEM; |
551 | goto cleanup_localinops; | 519 | goto cleanup_hooks; |
552 | } | 520 | } |
553 | #endif | 521 | #endif |
554 | return ret; | 522 | return ret; |
555 | 523 | ||
556 | cleanup: | ||
557 | synchronize_net(); | ||
558 | #ifdef CONFIG_SYSCTL | 524 | #ifdef CONFIG_SYSCTL |
559 | unregister_sysctl_table(nf_ct_ipv6_sysctl_header); | 525 | cleanup_hooks: |
560 | cleanup_localinops: | 526 | nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); |
561 | #endif | 527 | #endif |
562 | nf_unregister_hook(&ipv6_conntrack_local_in_ops); | ||
563 | cleanup_inoutandlocalops: | ||
564 | nf_unregister_hook(&ipv6_conntrack_out_ops); | ||
565 | cleanup_inandlocalops: | ||
566 | nf_unregister_hook(&ipv6_conntrack_local_out_ops); | ||
567 | cleanup_inops: | ||
568 | nf_unregister_hook(&ipv6_conntrack_in_ops); | ||
569 | cleanup_defraglocalops: | ||
570 | nf_unregister_hook(&ipv6_conntrack_defrag_local_out_ops); | ||
571 | cleanup_defragops: | ||
572 | nf_unregister_hook(&ipv6_conntrack_defrag_ops); | ||
573 | cleanup_ipv6: | 528 | cleanup_ipv6: |
574 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); | 529 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); |
575 | cleanup_icmpv6: | 530 | cleanup_icmpv6: |
@@ -580,23 +535,21 @@ static int init_or_cleanup(int init) | |||
580 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); | 535 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); |
581 | cleanup_frag6: | 536 | cleanup_frag6: |
582 | nf_ct_frag6_cleanup(); | 537 | nf_ct_frag6_cleanup(); |
583 | cleanup_nothing: | ||
584 | return ret; | 538 | return ret; |
585 | } | 539 | } |
586 | 540 | ||
587 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); | ||
588 | MODULE_LICENSE("GPL"); | ||
589 | MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); | ||
590 | |||
591 | static int __init nf_conntrack_l3proto_ipv6_init(void) | ||
592 | { | ||
593 | need_conntrack(); | ||
594 | return init_or_cleanup(1); | ||
595 | } | ||
596 | |||
597 | static void __exit nf_conntrack_l3proto_ipv6_fini(void) | 541 | static void __exit nf_conntrack_l3proto_ipv6_fini(void) |
598 | { | 542 | { |
599 | init_or_cleanup(0); | 543 | synchronize_net(); |
544 | #ifdef CONFIG_SYSCTL | ||
545 | unregister_sysctl_table(nf_ct_ipv6_sysctl_header); | ||
546 | #endif | ||
547 | nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); | ||
548 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); | ||
549 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6); | ||
550 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6); | ||
551 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); | ||
552 | nf_ct_frag6_cleanup(); | ||
600 | } | 553 | } |
601 | 554 | ||
602 | module_init(nf_conntrack_l3proto_ipv6_init); | 555 | module_init(nf_conntrack_l3proto_ipv6_init); |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 09945c333055..86c6703265d0 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -233,21 +233,13 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff, | |||
233 | return -NF_ACCEPT; | 233 | return -NF_ACCEPT; |
234 | } | 234 | } |
235 | 235 | ||
236 | if (hooknum != NF_IP6_PRE_ROUTING) | 236 | if (hooknum == NF_IP6_PRE_ROUTING && |
237 | goto skipped; | 237 | nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { |
238 | |||
239 | /* Ignore it if the checksum's bogus. */ | ||
240 | if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, | ||
241 | skb->len - dataoff, IPPROTO_ICMPV6, | ||
242 | skb_checksum(skb, dataoff, | ||
243 | skb->len - dataoff, 0))) { | ||
244 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, | 238 | nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, |
245 | "nf_ct_icmpv6: ICMPv6 checksum failed\n"); | 239 | "nf_ct_icmpv6: ICMPv6 checksum failed\n"); |
246 | return -NF_ACCEPT; | 240 | return -NF_ACCEPT; |
247 | } | 241 | } |
248 | 242 | ||
249 | skipped: | ||
250 | |||
251 | /* is not error message ? */ | 243 | /* is not error message ? */ |
252 | if (icmp6h->icmp6_type >= 128) | 244 | if (icmp6h->icmp6_type >= 128) |
253 | return NF_ACCEPT; | 245 | return NF_ACCEPT; |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 4238b1ed8860..779ddf77f4d4 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -38,7 +38,7 @@ static int fold_prot_inuse(struct proto *proto) | |||
38 | int res = 0; | 38 | int res = 0; |
39 | int cpu; | 39 | int cpu; |
40 | 40 | ||
41 | for_each_cpu(cpu) | 41 | for_each_possible_cpu(cpu) |
42 | res += proto->stats[cpu].inuse; | 42 | res += proto->stats[cpu].inuse; |
43 | 43 | ||
44 | return res; | 44 | return res; |
@@ -140,7 +140,7 @@ fold_field(void *mib[], int offt) | |||
140 | unsigned long res = 0; | 140 | unsigned long res = 0; |
141 | int i; | 141 | int i; |
142 | 142 | ||
143 | for_each_cpu(i) { | 143 | for_each_possible_cpu(i) { |
144 | res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt); | 144 | res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt); |
145 | res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt); | 145 | res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt); |
146 | } | 146 | } |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index c2d3e17beae6..6578c3080f47 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -397,7 +397,7 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); | 400 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); |
401 | kfree_skb(skb); | 401 | kfree_skb(skb); |
402 | read_unlock(&ipip6_lock); | 402 | read_unlock(&ipip6_lock); |
403 | out: | 403 | out: |
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index 5659b52284bd..0ef9a35798d1 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c | |||
@@ -19,11 +19,13 @@ | |||
19 | * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 19 | * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/icmpv6.h> | ||
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
25 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
26 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
28 | #include <net/ipv6.h> | ||
27 | #include <net/protocol.h> | 29 | #include <net/protocol.h> |
28 | #include <net/xfrm.h> | 30 | #include <net/xfrm.h> |
29 | 31 | ||
@@ -87,10 +89,16 @@ static int tunnel6_rcv(struct sk_buff **pskb) | |||
87 | struct sk_buff *skb = *pskb; | 89 | struct sk_buff *skb = *pskb; |
88 | struct xfrm6_tunnel *handler; | 90 | struct xfrm6_tunnel *handler; |
89 | 91 | ||
92 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) | ||
93 | goto drop; | ||
94 | |||
90 | for (handler = tunnel6_handlers; handler; handler = handler->next) | 95 | for (handler = tunnel6_handlers; handler; handler = handler->next) |
91 | if (!handler->handler(skb)) | 96 | if (!handler->handler(skb)) |
92 | return 0; | 97 | return 0; |
93 | 98 | ||
99 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev); | ||
100 | |||
101 | drop: | ||
94 | kfree_skb(skb); | 102 | kfree_skb(skb); |
95 | return 0; | 103 | return 0; |
96 | } | 104 | } |
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 1ceb1a6c254b..8455a32ea5c4 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -27,6 +27,29 @@ | |||
27 | 27 | ||
28 | #include "nf_internals.h" | 28 | #include "nf_internals.h" |
29 | 29 | ||
30 | static DEFINE_SPINLOCK(afinfo_lock); | ||
31 | |||
32 | struct nf_afinfo *nf_afinfo[NPROTO]; | ||
33 | EXPORT_SYMBOL(nf_afinfo); | ||
34 | |||
35 | int nf_register_afinfo(struct nf_afinfo *afinfo) | ||
36 | { | ||
37 | spin_lock(&afinfo_lock); | ||
38 | rcu_assign_pointer(nf_afinfo[afinfo->family], afinfo); | ||
39 | spin_unlock(&afinfo_lock); | ||
40 | return 0; | ||
41 | } | ||
42 | EXPORT_SYMBOL_GPL(nf_register_afinfo); | ||
43 | |||
44 | void nf_unregister_afinfo(struct nf_afinfo *afinfo) | ||
45 | { | ||
46 | spin_lock(&afinfo_lock); | ||
47 | rcu_assign_pointer(nf_afinfo[afinfo->family], NULL); | ||
48 | spin_unlock(&afinfo_lock); | ||
49 | synchronize_rcu(); | ||
50 | } | ||
51 | EXPORT_SYMBOL_GPL(nf_unregister_afinfo); | ||
52 | |||
30 | /* In this code, we can be waiting indefinitely for userspace to | 53 | /* In this code, we can be waiting indefinitely for userspace to |
31 | * service a packet if a hook returns NF_QUEUE. We could keep a count | 54 | * service a packet if a hook returns NF_QUEUE. We could keep a count |
32 | * of skbuffs queued for userspace, and not deregister a hook unless | 55 | * of skbuffs queued for userspace, and not deregister a hook unless |
@@ -63,6 +86,34 @@ void nf_unregister_hook(struct nf_hook_ops *reg) | |||
63 | } | 86 | } |
64 | EXPORT_SYMBOL(nf_unregister_hook); | 87 | EXPORT_SYMBOL(nf_unregister_hook); |
65 | 88 | ||
89 | int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n) | ||
90 | { | ||
91 | unsigned int i; | ||
92 | int err = 0; | ||
93 | |||
94 | for (i = 0; i < n; i++) { | ||
95 | err = nf_register_hook(®[i]); | ||
96 | if (err) | ||
97 | goto err; | ||
98 | } | ||
99 | return err; | ||
100 | |||
101 | err: | ||
102 | if (i > 0) | ||
103 | nf_unregister_hooks(reg, i); | ||
104 | return err; | ||
105 | } | ||
106 | EXPORT_SYMBOL(nf_register_hooks); | ||
107 | |||
108 | void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) | ||
109 | { | ||
110 | unsigned int i; | ||
111 | |||
112 | for (i = 0; i < n; i++) | ||
113 | nf_unregister_hook(®[i]); | ||
114 | } | ||
115 | EXPORT_SYMBOL(nf_unregister_hooks); | ||
116 | |||
66 | unsigned int nf_iterate(struct list_head *head, | 117 | unsigned int nf_iterate(struct list_head *head, |
67 | struct sk_buff **skb, | 118 | struct sk_buff **skb, |
68 | int hook, | 119 | int hook, |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 56389c83557c..e581190fb6c3 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -146,7 +146,7 @@ static void nf_ct_event_cache_flush(void) | |||
146 | struct nf_conntrack_ecache *ecache; | 146 | struct nf_conntrack_ecache *ecache; |
147 | int cpu; | 147 | int cpu; |
148 | 148 | ||
149 | for_each_cpu(cpu) { | 149 | for_each_possible_cpu(cpu) { |
150 | ecache = &per_cpu(nf_conntrack_ecache, cpu); | 150 | ecache = &per_cpu(nf_conntrack_ecache, cpu); |
151 | if (ecache->ct) | 151 | if (ecache->ct) |
152 | nf_ct_put(ecache->ct); | 152 | nf_ct_put(ecache->ct); |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 6492ed66fb3c..69899f27d26a 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -799,8 +799,7 @@ static int tcp_error(struct sk_buff *skb, | |||
799 | unsigned int dataoff, | 799 | unsigned int dataoff, |
800 | enum ip_conntrack_info *ctinfo, | 800 | enum ip_conntrack_info *ctinfo, |
801 | int pf, | 801 | int pf, |
802 | unsigned int hooknum, | 802 | unsigned int hooknum) |
803 | int(*csum)(const struct sk_buff *,unsigned int)) | ||
804 | { | 803 | { |
805 | struct tcphdr _tcph, *th; | 804 | struct tcphdr _tcph, *th; |
806 | unsigned int tcplen = skb->len - dataoff; | 805 | unsigned int tcplen = skb->len - dataoff; |
@@ -830,9 +829,8 @@ static int tcp_error(struct sk_buff *skb, | |||
830 | */ | 829 | */ |
831 | /* FIXME: Source route IP option packets --RR */ | 830 | /* FIXME: Source route IP option packets --RR */ |
832 | if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) || | 831 | if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) || |
833 | (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) | 832 | (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) && |
834 | && skb->ip_summed != CHECKSUM_UNNECESSARY | 833 | nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) { |
835 | && csum(skb, dataoff)) { | ||
836 | if (LOG_INVALID(IPPROTO_TCP)) | 834 | if (LOG_INVALID(IPPROTO_TCP)) |
837 | nf_log_packet(pf, 0, skb, NULL, NULL, NULL, | 835 | nf_log_packet(pf, 0, skb, NULL, NULL, NULL, |
838 | "nf_ct_tcp: bad TCP checksum "); | 836 | "nf_ct_tcp: bad TCP checksum "); |
@@ -851,44 +849,6 @@ static int tcp_error(struct sk_buff *skb, | |||
851 | return NF_ACCEPT; | 849 | return NF_ACCEPT; |
852 | } | 850 | } |
853 | 851 | ||
854 | static int csum4(const struct sk_buff *skb, unsigned int dataoff) | ||
855 | { | ||
856 | return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr, | ||
857 | skb->len - dataoff, IPPROTO_TCP, | ||
858 | skb->ip_summed == CHECKSUM_HW ? skb->csum | ||
859 | : skb_checksum(skb, dataoff, | ||
860 | skb->len - dataoff, 0)); | ||
861 | } | ||
862 | |||
863 | static int csum6(const struct sk_buff *skb, unsigned int dataoff) | ||
864 | { | ||
865 | return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, | ||
866 | skb->len - dataoff, IPPROTO_TCP, | ||
867 | skb->ip_summed == CHECKSUM_HW | ||
868 | ? csum_sub(skb->csum, | ||
869 | skb_checksum(skb, 0, dataoff, 0)) | ||
870 | : skb_checksum(skb, dataoff, skb->len - dataoff, | ||
871 | 0)); | ||
872 | } | ||
873 | |||
874 | static int tcp_error4(struct sk_buff *skb, | ||
875 | unsigned int dataoff, | ||
876 | enum ip_conntrack_info *ctinfo, | ||
877 | int pf, | ||
878 | unsigned int hooknum) | ||
879 | { | ||
880 | return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum4); | ||
881 | } | ||
882 | |||
883 | static int tcp_error6(struct sk_buff *skb, | ||
884 | unsigned int dataoff, | ||
885 | enum ip_conntrack_info *ctinfo, | ||
886 | int pf, | ||
887 | unsigned int hooknum) | ||
888 | { | ||
889 | return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum6); | ||
890 | } | ||
891 | |||
892 | /* Returns verdict for packet, or -1 for invalid. */ | 852 | /* Returns verdict for packet, or -1 for invalid. */ |
893 | static int tcp_packet(struct nf_conn *conntrack, | 853 | static int tcp_packet(struct nf_conn *conntrack, |
894 | const struct sk_buff *skb, | 854 | const struct sk_buff *skb, |
@@ -1218,7 +1178,7 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 = | |||
1218 | .print_conntrack = tcp_print_conntrack, | 1178 | .print_conntrack = tcp_print_conntrack, |
1219 | .packet = tcp_packet, | 1179 | .packet = tcp_packet, |
1220 | .new = tcp_new, | 1180 | .new = tcp_new, |
1221 | .error = tcp_error4, | 1181 | .error = tcp_error, |
1222 | #if defined(CONFIG_NF_CT_NETLINK) || \ | 1182 | #if defined(CONFIG_NF_CT_NETLINK) || \ |
1223 | defined(CONFIG_NF_CT_NETLINK_MODULE) | 1183 | defined(CONFIG_NF_CT_NETLINK_MODULE) |
1224 | .to_nfattr = tcp_to_nfattr, | 1184 | .to_nfattr = tcp_to_nfattr, |
@@ -1239,7 +1199,7 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 = | |||
1239 | .print_conntrack = tcp_print_conntrack, | 1199 | .print_conntrack = tcp_print_conntrack, |
1240 | .packet = tcp_packet, | 1200 | .packet = tcp_packet, |
1241 | .new = tcp_new, | 1201 | .new = tcp_new, |
1242 | .error = tcp_error6, | 1202 | .error = tcp_error, |
1243 | #if defined(CONFIG_NF_CT_NETLINK) || \ | 1203 | #if defined(CONFIG_NF_CT_NETLINK) || \ |
1244 | defined(CONFIG_NF_CT_NETLINK_MODULE) | 1204 | defined(CONFIG_NF_CT_NETLINK_MODULE) |
1245 | .to_nfattr = tcp_to_nfattr, | 1205 | .to_nfattr = tcp_to_nfattr, |
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 831d206344e0..d93edbfde9e3 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c | |||
@@ -103,8 +103,7 @@ static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb, | |||
103 | static int udp_error(struct sk_buff *skb, unsigned int dataoff, | 103 | static int udp_error(struct sk_buff *skb, unsigned int dataoff, |
104 | enum ip_conntrack_info *ctinfo, | 104 | enum ip_conntrack_info *ctinfo, |
105 | int pf, | 105 | int pf, |
106 | unsigned int hooknum, | 106 | unsigned int hooknum) |
107 | int (*csum)(const struct sk_buff *, unsigned int)) | ||
108 | { | 107 | { |
109 | unsigned int udplen = skb->len - dataoff; | 108 | unsigned int udplen = skb->len - dataoff; |
110 | struct udphdr _hdr, *hdr; | 109 | struct udphdr _hdr, *hdr; |
@@ -136,9 +135,8 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff, | |||
136 | * and moreover root might send raw packets. | 135 | * and moreover root might send raw packets. |
137 | * FIXME: Source route IP option packets --RR */ | 136 | * FIXME: Source route IP option packets --RR */ |
138 | if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) || | 137 | if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) || |
139 | (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) | 138 | (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) && |
140 | && skb->ip_summed != CHECKSUM_UNNECESSARY | 139 | nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) { |
141 | && csum(skb, dataoff)) { | ||
142 | if (LOG_INVALID(IPPROTO_UDP)) | 140 | if (LOG_INVALID(IPPROTO_UDP)) |
143 | nf_log_packet(pf, 0, skb, NULL, NULL, NULL, | 141 | nf_log_packet(pf, 0, skb, NULL, NULL, NULL, |
144 | "nf_ct_udp: bad UDP checksum "); | 142 | "nf_ct_udp: bad UDP checksum "); |
@@ -148,44 +146,6 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff, | |||
148 | return NF_ACCEPT; | 146 | return NF_ACCEPT; |
149 | } | 147 | } |
150 | 148 | ||
151 | static int csum4(const struct sk_buff *skb, unsigned int dataoff) | ||
152 | { | ||
153 | return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr, | ||
154 | skb->len - dataoff, IPPROTO_UDP, | ||
155 | skb->ip_summed == CHECKSUM_HW ? skb->csum | ||
156 | : skb_checksum(skb, dataoff, | ||
157 | skb->len - dataoff, 0)); | ||
158 | } | ||
159 | |||
160 | static int csum6(const struct sk_buff *skb, unsigned int dataoff) | ||
161 | { | ||
162 | return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, | ||
163 | skb->len - dataoff, IPPROTO_UDP, | ||
164 | skb->ip_summed == CHECKSUM_HW | ||
165 | ? csum_sub(skb->csum, | ||
166 | skb_checksum(skb, 0, dataoff, 0)) | ||
167 | : skb_checksum(skb, dataoff, skb->len - dataoff, | ||
168 | 0)); | ||
169 | } | ||
170 | |||
171 | static int udp_error4(struct sk_buff *skb, | ||
172 | unsigned int dataoff, | ||
173 | enum ip_conntrack_info *ctinfo, | ||
174 | int pf, | ||
175 | unsigned int hooknum) | ||
176 | { | ||
177 | return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum4); | ||
178 | } | ||
179 | |||
180 | static int udp_error6(struct sk_buff *skb, | ||
181 | unsigned int dataoff, | ||
182 | enum ip_conntrack_info *ctinfo, | ||
183 | int pf, | ||
184 | unsigned int hooknum) | ||
185 | { | ||
186 | return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum6); | ||
187 | } | ||
188 | |||
189 | struct nf_conntrack_protocol nf_conntrack_protocol_udp4 = | 149 | struct nf_conntrack_protocol nf_conntrack_protocol_udp4 = |
190 | { | 150 | { |
191 | .l3proto = PF_INET, | 151 | .l3proto = PF_INET, |
@@ -197,7 +157,7 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp4 = | |||
197 | .print_conntrack = udp_print_conntrack, | 157 | .print_conntrack = udp_print_conntrack, |
198 | .packet = udp_packet, | 158 | .packet = udp_packet, |
199 | .new = udp_new, | 159 | .new = udp_new, |
200 | .error = udp_error4, | 160 | .error = udp_error, |
201 | #if defined(CONFIG_NF_CT_NETLINK) || \ | 161 | #if defined(CONFIG_NF_CT_NETLINK) || \ |
202 | defined(CONFIG_NF_CT_NETLINK_MODULE) | 162 | defined(CONFIG_NF_CT_NETLINK_MODULE) |
203 | .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, | 163 | .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, |
@@ -216,7 +176,7 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp6 = | |||
216 | .print_conntrack = udp_print_conntrack, | 176 | .print_conntrack = udp_print_conntrack, |
217 | .packet = udp_packet, | 177 | .packet = udp_packet, |
218 | .new = udp_new, | 178 | .new = udp_new, |
219 | .error = udp_error6, | 179 | .error = udp_error, |
220 | #if defined(CONFIG_NF_CT_NETLINK) || \ | 180 | #if defined(CONFIG_NF_CT_NETLINK) || \ |
221 | defined(CONFIG_NF_CT_NETLINK_MODULE) | 181 | defined(CONFIG_NF_CT_NETLINK_MODULE) |
222 | .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, | 182 | .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index c72aa3cd22e4..408960c6a544 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -649,63 +649,6 @@ static ctl_table nf_ct_net_table[] = { | |||
649 | EXPORT_SYMBOL(nf_ct_log_invalid); | 649 | EXPORT_SYMBOL(nf_ct_log_invalid); |
650 | #endif /* CONFIG_SYSCTL */ | 650 | #endif /* CONFIG_SYSCTL */ |
651 | 651 | ||
652 | static int init_or_cleanup(int init) | ||
653 | { | ||
654 | #ifdef CONFIG_PROC_FS | ||
655 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; | ||
656 | #endif | ||
657 | int ret = 0; | ||
658 | |||
659 | if (!init) goto cleanup; | ||
660 | |||
661 | ret = nf_conntrack_init(); | ||
662 | if (ret < 0) | ||
663 | goto cleanup_nothing; | ||
664 | |||
665 | #ifdef CONFIG_PROC_FS | ||
666 | proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops); | ||
667 | if (!proc) goto cleanup_init; | ||
668 | |||
669 | proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440, | ||
670 | &exp_file_ops); | ||
671 | if (!proc_exp) goto cleanup_proc; | ||
672 | |||
673 | proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat); | ||
674 | if (!proc_stat) | ||
675 | goto cleanup_proc_exp; | ||
676 | |||
677 | proc_stat->proc_fops = &ct_cpu_seq_fops; | ||
678 | proc_stat->owner = THIS_MODULE; | ||
679 | #endif | ||
680 | #ifdef CONFIG_SYSCTL | ||
681 | nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); | ||
682 | if (nf_ct_sysctl_header == NULL) { | ||
683 | printk("nf_conntrack: can't register to sysctl.\n"); | ||
684 | ret = -ENOMEM; | ||
685 | goto cleanup_proc_stat; | ||
686 | } | ||
687 | #endif | ||
688 | |||
689 | return ret; | ||
690 | |||
691 | cleanup: | ||
692 | #ifdef CONFIG_SYSCTL | ||
693 | unregister_sysctl_table(nf_ct_sysctl_header); | ||
694 | cleanup_proc_stat: | ||
695 | #endif | ||
696 | #ifdef CONFIG_PROC_FS | ||
697 | remove_proc_entry("nf_conntrack", proc_net_stat); | ||
698 | cleanup_proc_exp: | ||
699 | proc_net_remove("nf_conntrack_expect"); | ||
700 | cleanup_proc: | ||
701 | proc_net_remove("nf_conntrack"); | ||
702 | cleanup_init: | ||
703 | #endif /* CNFIG_PROC_FS */ | ||
704 | nf_conntrack_cleanup(); | ||
705 | cleanup_nothing: | ||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) | 652 | int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) |
710 | { | 653 | { |
711 | int ret = 0; | 654 | int ret = 0; |
@@ -808,12 +751,66 @@ void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto) | |||
808 | 751 | ||
809 | static int __init nf_conntrack_standalone_init(void) | 752 | static int __init nf_conntrack_standalone_init(void) |
810 | { | 753 | { |
811 | return init_or_cleanup(1); | 754 | #ifdef CONFIG_PROC_FS |
755 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; | ||
756 | #endif | ||
757 | int ret = 0; | ||
758 | |||
759 | ret = nf_conntrack_init(); | ||
760 | if (ret < 0) | ||
761 | return ret; | ||
762 | |||
763 | #ifdef CONFIG_PROC_FS | ||
764 | proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops); | ||
765 | if (!proc) goto cleanup_init; | ||
766 | |||
767 | proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440, | ||
768 | &exp_file_ops); | ||
769 | if (!proc_exp) goto cleanup_proc; | ||
770 | |||
771 | proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat); | ||
772 | if (!proc_stat) | ||
773 | goto cleanup_proc_exp; | ||
774 | |||
775 | proc_stat->proc_fops = &ct_cpu_seq_fops; | ||
776 | proc_stat->owner = THIS_MODULE; | ||
777 | #endif | ||
778 | #ifdef CONFIG_SYSCTL | ||
779 | nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); | ||
780 | if (nf_ct_sysctl_header == NULL) { | ||
781 | printk("nf_conntrack: can't register to sysctl.\n"); | ||
782 | ret = -ENOMEM; | ||
783 | goto cleanup_proc_stat; | ||
784 | } | ||
785 | #endif | ||
786 | return ret; | ||
787 | |||
788 | #ifdef CONFIG_SYSCTL | ||
789 | cleanup_proc_stat: | ||
790 | #endif | ||
791 | #ifdef CONFIG_PROC_FS | ||
792 | remove_proc_entry("nf_conntrack", proc_net_stat); | ||
793 | cleanup_proc_exp: | ||
794 | proc_net_remove("nf_conntrack_expect"); | ||
795 | cleanup_proc: | ||
796 | proc_net_remove("nf_conntrack"); | ||
797 | cleanup_init: | ||
798 | #endif /* CNFIG_PROC_FS */ | ||
799 | nf_conntrack_cleanup(); | ||
800 | return ret; | ||
812 | } | 801 | } |
813 | 802 | ||
814 | static void __exit nf_conntrack_standalone_fini(void) | 803 | static void __exit nf_conntrack_standalone_fini(void) |
815 | { | 804 | { |
816 | init_or_cleanup(0); | 805 | #ifdef CONFIG_SYSCTL |
806 | unregister_sysctl_table(nf_ct_sysctl_header); | ||
807 | #endif | ||
808 | #ifdef CONFIG_PROC_FS | ||
809 | remove_proc_entry("nf_conntrack", proc_net_stat); | ||
810 | proc_net_remove("nf_conntrack_expect"); | ||
811 | proc_net_remove("nf_conntrack"); | ||
812 | #endif /* CNFIG_PROC_FS */ | ||
813 | nf_conntrack_cleanup(); | ||
817 | } | 814 | } |
818 | 815 | ||
819 | module_init(nf_conntrack_standalone_init); | 816 | module_init(nf_conntrack_standalone_init); |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index d9f0d7ef103b..ee8f70889f47 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -17,7 +17,6 @@ | |||
17 | * for queueing and must reinject all packets it receives, no matter what. | 17 | * for queueing and must reinject all packets it receives, no matter what. |
18 | */ | 18 | */ |
19 | static struct nf_queue_handler *queue_handler[NPROTO]; | 19 | static struct nf_queue_handler *queue_handler[NPROTO]; |
20 | static struct nf_queue_rerouter *queue_rerouter[NPROTO]; | ||
21 | 20 | ||
22 | static DEFINE_RWLOCK(queue_handler_lock); | 21 | static DEFINE_RWLOCK(queue_handler_lock); |
23 | 22 | ||
@@ -59,32 +58,6 @@ int nf_unregister_queue_handler(int pf) | |||
59 | } | 58 | } |
60 | EXPORT_SYMBOL(nf_unregister_queue_handler); | 59 | EXPORT_SYMBOL(nf_unregister_queue_handler); |
61 | 60 | ||
62 | int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer) | ||
63 | { | ||
64 | if (pf >= NPROTO) | ||
65 | return -EINVAL; | ||
66 | |||
67 | write_lock_bh(&queue_handler_lock); | ||
68 | rcu_assign_pointer(queue_rerouter[pf], rer); | ||
69 | write_unlock_bh(&queue_handler_lock); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | EXPORT_SYMBOL_GPL(nf_register_queue_rerouter); | ||
74 | |||
75 | int nf_unregister_queue_rerouter(int pf) | ||
76 | { | ||
77 | if (pf >= NPROTO) | ||
78 | return -EINVAL; | ||
79 | |||
80 | write_lock_bh(&queue_handler_lock); | ||
81 | rcu_assign_pointer(queue_rerouter[pf], NULL); | ||
82 | write_unlock_bh(&queue_handler_lock); | ||
83 | synchronize_rcu(); | ||
84 | return 0; | ||
85 | } | ||
86 | EXPORT_SYMBOL_GPL(nf_unregister_queue_rerouter); | ||
87 | |||
88 | void nf_unregister_queue_handlers(struct nf_queue_handler *qh) | 61 | void nf_unregister_queue_handlers(struct nf_queue_handler *qh) |
89 | { | 62 | { |
90 | int pf; | 63 | int pf; |
@@ -116,7 +89,7 @@ int nf_queue(struct sk_buff **skb, | |||
116 | struct net_device *physindev = NULL; | 89 | struct net_device *physindev = NULL; |
117 | struct net_device *physoutdev = NULL; | 90 | struct net_device *physoutdev = NULL; |
118 | #endif | 91 | #endif |
119 | struct nf_queue_rerouter *rerouter; | 92 | struct nf_afinfo *afinfo; |
120 | 93 | ||
121 | /* QUEUE == DROP if noone is waiting, to be safe. */ | 94 | /* QUEUE == DROP if noone is waiting, to be safe. */ |
122 | read_lock(&queue_handler_lock); | 95 | read_lock(&queue_handler_lock); |
@@ -126,7 +99,14 @@ int nf_queue(struct sk_buff **skb, | |||
126 | return 1; | 99 | return 1; |
127 | } | 100 | } |
128 | 101 | ||
129 | info = kmalloc(sizeof(*info)+queue_rerouter[pf]->rer_size, GFP_ATOMIC); | 102 | afinfo = nf_get_afinfo(pf); |
103 | if (!afinfo) { | ||
104 | read_unlock(&queue_handler_lock); | ||
105 | kfree_skb(*skb); | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | info = kmalloc(sizeof(*info) + afinfo->route_key_size, GFP_ATOMIC); | ||
130 | if (!info) { | 110 | if (!info) { |
131 | if (net_ratelimit()) | 111 | if (net_ratelimit()) |
132 | printk(KERN_ERR "OOM queueing packet %p\n", | 112 | printk(KERN_ERR "OOM queueing packet %p\n", |
@@ -158,10 +138,7 @@ int nf_queue(struct sk_buff **skb, | |||
158 | if (physoutdev) dev_hold(physoutdev); | 138 | if (physoutdev) dev_hold(physoutdev); |
159 | } | 139 | } |
160 | #endif | 140 | #endif |
161 | rerouter = rcu_dereference(queue_rerouter[pf]); | 141 | afinfo->saveroute(*skb, info); |
162 | if (rerouter) | ||
163 | rerouter->save(*skb, info); | ||
164 | |||
165 | status = queue_handler[pf]->outfn(*skb, info, queuenum, | 142 | status = queue_handler[pf]->outfn(*skb, info, queuenum, |
166 | queue_handler[pf]->data); | 143 | queue_handler[pf]->data); |
167 | 144 | ||
@@ -190,7 +167,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, | |||
190 | { | 167 | { |
191 | struct list_head *elem = &info->elem->list; | 168 | struct list_head *elem = &info->elem->list; |
192 | struct list_head *i; | 169 | struct list_head *i; |
193 | struct nf_queue_rerouter *rerouter; | 170 | struct nf_afinfo *afinfo; |
194 | 171 | ||
195 | rcu_read_lock(); | 172 | rcu_read_lock(); |
196 | 173 | ||
@@ -228,8 +205,8 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, | |||
228 | } | 205 | } |
229 | 206 | ||
230 | if (verdict == NF_ACCEPT) { | 207 | if (verdict == NF_ACCEPT) { |
231 | rerouter = rcu_dereference(queue_rerouter[info->pf]); | 208 | afinfo = nf_get_afinfo(info->pf); |
232 | if (rerouter && rerouter->reroute(&skb, info) < 0) | 209 | if (!afinfo || afinfo->reroute(&skb, info) < 0) |
233 | verdict = NF_DROP; | 210 | verdict = NF_DROP; |
234 | } | 211 | } |
235 | 212 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 3e3f5448bacb..c60273cad778 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -1033,17 +1033,13 @@ static struct file_operations nful_file_ops = { | |||
1033 | 1033 | ||
1034 | #endif /* PROC_FS */ | 1034 | #endif /* PROC_FS */ |
1035 | 1035 | ||
1036 | static int | 1036 | static int __init nfnetlink_log_init(void) |
1037 | init_or_cleanup(int init) | ||
1038 | { | 1037 | { |
1039 | int i, status = -ENOMEM; | 1038 | int i, status = -ENOMEM; |
1040 | #ifdef CONFIG_PROC_FS | 1039 | #ifdef CONFIG_PROC_FS |
1041 | struct proc_dir_entry *proc_nful; | 1040 | struct proc_dir_entry *proc_nful; |
1042 | #endif | 1041 | #endif |
1043 | 1042 | ||
1044 | if (!init) | ||
1045 | goto cleanup; | ||
1046 | |||
1047 | for (i = 0; i < INSTANCE_BUCKETS; i++) | 1043 | for (i = 0; i < INSTANCE_BUCKETS; i++) |
1048 | INIT_HLIST_HEAD(&instance_table[i]); | 1044 | INIT_HLIST_HEAD(&instance_table[i]); |
1049 | 1045 | ||
@@ -1066,30 +1062,25 @@ init_or_cleanup(int init) | |||
1066 | goto cleanup_subsys; | 1062 | goto cleanup_subsys; |
1067 | proc_nful->proc_fops = &nful_file_ops; | 1063 | proc_nful->proc_fops = &nful_file_ops; |
1068 | #endif | 1064 | #endif |
1069 | |||
1070 | return status; | 1065 | return status; |
1071 | 1066 | ||
1072 | cleanup: | ||
1073 | nf_log_unregister_logger(&nfulnl_logger); | ||
1074 | #ifdef CONFIG_PROC_FS | 1067 | #ifdef CONFIG_PROC_FS |
1075 | remove_proc_entry("nfnetlink_log", proc_net_netfilter); | ||
1076 | cleanup_subsys: | 1068 | cleanup_subsys: |
1077 | #endif | ||
1078 | nfnetlink_subsys_unregister(&nfulnl_subsys); | 1069 | nfnetlink_subsys_unregister(&nfulnl_subsys); |
1070 | #endif | ||
1079 | cleanup_netlink_notifier: | 1071 | cleanup_netlink_notifier: |
1080 | netlink_unregister_notifier(&nfulnl_rtnl_notifier); | 1072 | netlink_unregister_notifier(&nfulnl_rtnl_notifier); |
1081 | return status; | 1073 | return status; |
1082 | } | 1074 | } |
1083 | 1075 | ||
1084 | static int __init nfnetlink_log_init(void) | ||
1085 | { | ||
1086 | |||
1087 | return init_or_cleanup(1); | ||
1088 | } | ||
1089 | |||
1090 | static void __exit nfnetlink_log_fini(void) | 1076 | static void __exit nfnetlink_log_fini(void) |
1091 | { | 1077 | { |
1092 | init_or_cleanup(0); | 1078 | nf_log_unregister_logger(&nfulnl_logger); |
1079 | #ifdef CONFIG_PROC_FS | ||
1080 | remove_proc_entry("nfnetlink_log", proc_net_netfilter); | ||
1081 | #endif | ||
1082 | nfnetlink_subsys_unregister(&nfulnl_subsys); | ||
1083 | netlink_unregister_notifier(&nfulnl_rtnl_notifier); | ||
1093 | } | 1084 | } |
1094 | 1085 | ||
1095 | MODULE_DESCRIPTION("netfilter userspace logging"); | 1086 | MODULE_DESCRIPTION("netfilter userspace logging"); |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index d0e62f68139f..86a4ac33de34 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -1071,17 +1071,13 @@ static struct file_operations nfqnl_file_ops = { | |||
1071 | 1071 | ||
1072 | #endif /* PROC_FS */ | 1072 | #endif /* PROC_FS */ |
1073 | 1073 | ||
1074 | static int | 1074 | static int __init nfnetlink_queue_init(void) |
1075 | init_or_cleanup(int init) | ||
1076 | { | 1075 | { |
1077 | int i, status = -ENOMEM; | 1076 | int i, status = -ENOMEM; |
1078 | #ifdef CONFIG_PROC_FS | 1077 | #ifdef CONFIG_PROC_FS |
1079 | struct proc_dir_entry *proc_nfqueue; | 1078 | struct proc_dir_entry *proc_nfqueue; |
1080 | #endif | 1079 | #endif |
1081 | 1080 | ||
1082 | if (!init) | ||
1083 | goto cleanup; | ||
1084 | |||
1085 | for (i = 0; i < INSTANCE_BUCKETS; i++) | 1081 | for (i = 0; i < INSTANCE_BUCKETS; i++) |
1086 | INIT_HLIST_HEAD(&instance_table[i]); | 1082 | INIT_HLIST_HEAD(&instance_table[i]); |
1087 | 1083 | ||
@@ -1101,31 +1097,26 @@ init_or_cleanup(int init) | |||
1101 | #endif | 1097 | #endif |
1102 | 1098 | ||
1103 | register_netdevice_notifier(&nfqnl_dev_notifier); | 1099 | register_netdevice_notifier(&nfqnl_dev_notifier); |
1104 | |||
1105 | return status; | 1100 | return status; |
1106 | 1101 | ||
1107 | cleanup: | ||
1108 | nf_unregister_queue_handlers(&nfqh); | ||
1109 | unregister_netdevice_notifier(&nfqnl_dev_notifier); | ||
1110 | #ifdef CONFIG_PROC_FS | 1102 | #ifdef CONFIG_PROC_FS |
1111 | remove_proc_entry("nfnetlink_queue", proc_net_netfilter); | ||
1112 | cleanup_subsys: | 1103 | cleanup_subsys: |
1113 | #endif | ||
1114 | nfnetlink_subsys_unregister(&nfqnl_subsys); | 1104 | nfnetlink_subsys_unregister(&nfqnl_subsys); |
1105 | #endif | ||
1115 | cleanup_netlink_notifier: | 1106 | cleanup_netlink_notifier: |
1116 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); | 1107 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); |
1117 | return status; | 1108 | return status; |
1118 | } | 1109 | } |
1119 | 1110 | ||
1120 | static int __init nfnetlink_queue_init(void) | ||
1121 | { | ||
1122 | |||
1123 | return init_or_cleanup(1); | ||
1124 | } | ||
1125 | |||
1126 | static void __exit nfnetlink_queue_fini(void) | 1111 | static void __exit nfnetlink_queue_fini(void) |
1127 | { | 1112 | { |
1128 | init_or_cleanup(0); | 1113 | nf_unregister_queue_handlers(&nfqh); |
1114 | unregister_netdevice_notifier(&nfqnl_dev_notifier); | ||
1115 | #ifdef CONFIG_PROC_FS | ||
1116 | remove_proc_entry("nfnetlink_queue", proc_net_netfilter); | ||
1117 | #endif | ||
1118 | nfnetlink_subsys_unregister(&nfqnl_subsys); | ||
1119 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); | ||
1129 | } | 1120 | } |
1130 | 1121 | ||
1131 | MODULE_DESCRIPTION("netfilter packet queue handler"); | 1122 | MODULE_DESCRIPTION("netfilter packet queue handler"); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index feb8a9e066b0..00cf0a4f4d92 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -413,7 +413,7 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size) | |||
413 | 413 | ||
414 | newinfo->size = size; | 414 | newinfo->size = size; |
415 | 415 | ||
416 | for_each_cpu(cpu) { | 416 | for_each_possible_cpu(cpu) { |
417 | if (size <= PAGE_SIZE) | 417 | if (size <= PAGE_SIZE) |
418 | newinfo->entries[cpu] = kmalloc_node(size, | 418 | newinfo->entries[cpu] = kmalloc_node(size, |
419 | GFP_KERNEL, | 419 | GFP_KERNEL, |
@@ -436,7 +436,7 @@ void xt_free_table_info(struct xt_table_info *info) | |||
436 | { | 436 | { |
437 | int cpu; | 437 | int cpu; |
438 | 438 | ||
439 | for_each_cpu(cpu) { | 439 | for_each_possible_cpu(cpu) { |
440 | if (info->size <= PAGE_SIZE) | 440 | if (info->size <= PAGE_SIZE) |
441 | kfree(info->entries[cpu]); | 441 | kfree(info->entries[cpu]); |
442 | else | 442 | else |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index fa877f8f652c..24c348fa8922 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -66,7 +66,7 @@ static __inline__ struct tcf_police * tcf_police_lookup(u32 index) | |||
66 | } | 66 | } |
67 | 67 | ||
68 | #ifdef CONFIG_NET_CLS_ACT | 68 | #ifdef CONFIG_NET_CLS_ACT |
69 | static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, | 69 | static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *cb, |
70 | int type, struct tc_action *a) | 70 | int type, struct tc_action *a) |
71 | { | 71 | { |
72 | struct tcf_police *p; | 72 | struct tcf_police *p; |
@@ -113,7 +113,7 @@ rtattr_failure: | |||
113 | } | 113 | } |
114 | 114 | ||
115 | static inline int | 115 | static inline int |
116 | tcf_hash_search(struct tc_action *a, u32 index) | 116 | tcf_act_police_hash_search(struct tc_action *a, u32 index) |
117 | { | 117 | { |
118 | struct tcf_police *p = tcf_police_lookup(index); | 118 | struct tcf_police *p = tcf_police_lookup(index); |
119 | 119 | ||
@@ -387,9 +387,9 @@ static struct tc_action_ops act_police_ops = { | |||
387 | .act = tcf_act_police, | 387 | .act = tcf_act_police, |
388 | .dump = tcf_act_police_dump, | 388 | .dump = tcf_act_police_dump, |
389 | .cleanup = tcf_act_police_cleanup, | 389 | .cleanup = tcf_act_police_cleanup, |
390 | .lookup = tcf_hash_search, | 390 | .lookup = tcf_act_police_hash_search, |
391 | .init = tcf_act_police_locate, | 391 | .init = tcf_act_police_locate, |
392 | .walk = tcf_generic_walker | 392 | .walk = tcf_act_police_walker |
393 | }; | 393 | }; |
394 | 394 | ||
395 | static int __init | 395 | static int __init |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index d47a52c303a8..5b3b0e0ae7e5 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -69,7 +69,7 @@ fold_field(void *mib[], int nr) | |||
69 | unsigned long res = 0; | 69 | unsigned long res = 0; |
70 | int i; | 70 | int i; |
71 | 71 | ||
72 | for_each_cpu(i) { | 72 | for_each_possible_cpu(i) { |
73 | res += | 73 | res += |
74 | *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + | 74 | *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + |
75 | sizeof (unsigned long) * nr)); | 75 | sizeof (unsigned long) * nr)); |
diff --git a/net/socket.c b/net/socket.c index b807f360e02c..23898f45f713 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -119,10 +119,6 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector, | |||
119 | static ssize_t sock_sendpage(struct file *file, struct page *page, | 119 | static ssize_t sock_sendpage(struct file *file, struct page *page, |
120 | int offset, size_t size, loff_t *ppos, int more); | 120 | int offset, size_t size, loff_t *ppos, int more); |
121 | 121 | ||
122 | extern ssize_t generic_splice_sendpage(struct inode *inode, struct file *out, | ||
123 | size_t len, unsigned int flags); | ||
124 | |||
125 | |||
126 | /* | 122 | /* |
127 | * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear | 123 | * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear |
128 | * in the operation structures but are done directly via the socketcall() multiplexor. | 124 | * in the operation structures but are done directly via the socketcall() multiplexor. |
@@ -2136,7 +2132,7 @@ void socket_seq_show(struct seq_file *seq) | |||
2136 | int cpu; | 2132 | int cpu; |
2137 | int counter = 0; | 2133 | int counter = 0; |
2138 | 2134 | ||
2139 | for_each_cpu(cpu) | 2135 | for_each_possible_cpu(cpu) |
2140 | counter += per_cpu(sockets_in_use, cpu); | 2136 | counter += per_cpu(sockets_in_use, cpu); |
2141 | 2137 | ||
2142 | /* It can be negative, by the way. 8) */ | 2138 | /* It can be negative, by the way. 8) */ |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 4d7eb9e704da..d51e316c5821 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -1122,18 +1122,20 @@ svcauth_gss_release(struct svc_rqst *rqstp) | |||
1122 | integ_len)) | 1122 | integ_len)) |
1123 | BUG(); | 1123 | BUG(); |
1124 | if (resbuf->page_len == 0 | 1124 | if (resbuf->page_len == 0 |
1125 | && resbuf->tail[0].iov_len + RPC_MAX_AUTH_SIZE | 1125 | && resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE |
1126 | < PAGE_SIZE) { | 1126 | < PAGE_SIZE) { |
1127 | BUG_ON(resbuf->tail[0].iov_len); | 1127 | BUG_ON(resbuf->tail[0].iov_len); |
1128 | /* Use head for everything */ | 1128 | /* Use head for everything */ |
1129 | resv = &resbuf->head[0]; | 1129 | resv = &resbuf->head[0]; |
1130 | } else if (resbuf->tail[0].iov_base == NULL) { | 1130 | } else if (resbuf->tail[0].iov_base == NULL) { |
1131 | /* copied from nfsd4_encode_read */ | 1131 | if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE |
1132 | svc_take_page(rqstp); | 1132 | > PAGE_SIZE) |
1133 | resbuf->tail[0].iov_base = page_address(rqstp | 1133 | goto out_err; |
1134 | ->rq_respages[rqstp->rq_resused-1]); | 1134 | resbuf->tail[0].iov_base = |
1135 | rqstp->rq_restailpage = rqstp->rq_resused-1; | 1135 | resbuf->head[0].iov_base |
1136 | + resbuf->head[0].iov_len; | ||
1136 | resbuf->tail[0].iov_len = 0; | 1137 | resbuf->tail[0].iov_len = 0; |
1138 | rqstp->rq_restailpage = 0; | ||
1137 | resv = &resbuf->tail[0]; | 1139 | resv = &resbuf->tail[0]; |
1138 | } else { | 1140 | } else { |
1139 | resv = &resbuf->tail[0]; | 1141 | resv = &resbuf->tail[0]; |
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 59620b1554e0..b0d067be7390 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include | |||
@@ -87,6 +87,11 @@ cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \ | |||
87 | # $(Q)$(MAKE) $(build)=dir | 87 | # $(Q)$(MAKE) $(build)=dir |
88 | build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj | 88 | build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj |
89 | 89 | ||
90 | # Prefix -I with $(srctree) if it is not an absolute path | ||
91 | addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) | ||
92 | # Find all -I options and call addtree | ||
93 | flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) | ||
94 | |||
90 | # If quiet is set, only print short version of command | 95 | # If quiet is set, only print short version of command |
91 | cmd = @$(echo-cmd) $(cmd_$(1)) | 96 | cmd = @$(echo-cmd) $(cmd_$(1)) |
92 | 97 | ||
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 550798f57da5..2cb4935e85d1 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -99,11 +99,6 @@ __a_flags = $(_a_flags) | |||
99 | __cpp_flags = $(_cpp_flags) | 99 | __cpp_flags = $(_cpp_flags) |
100 | else | 100 | else |
101 | 101 | ||
102 | # Prefix -I with $(srctree) if it is not an absolute path | ||
103 | addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) | ||
104 | # Find all -I options and call addtree | ||
105 | flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) | ||
106 | |||
107 | # -I$(obj) locates generated .h files | 102 | # -I$(obj) locates generated .h files |
108 | # $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files | 103 | # $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files |
109 | # and locates generated .h files | 104 | # and locates generated .h files |
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 75f21d843c1d..75f21d843c1d 100644..100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter | |||
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index dadfa20ffec0..dadfa20ffec0 100644..100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl | |||
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 6d411169bfa6..56b3bed1108f 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh | |||
@@ -1,22 +1,55 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org> | 2 | # Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org> |
3 | # Released under the terms of the GNU GPL | 3 | # Copyright (c) 2006 Sam Ravnborg <sam@ravnborg.org> |
4 | # | ||
5 | # Generate a newline separated list of entries from the file/directory | ||
6 | # supplied as an argument. | ||
7 | # | ||
8 | # If a file/directory is not supplied then generate a small dummy file. | ||
9 | # | 4 | # |
10 | # The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c. | 5 | # Released under the terms of the GNU GPL |
11 | # | 6 | # |
7 | # Generate a cpio packed initramfs. It uses gen_init_cpio to generate | ||
8 | # the cpio archive, and gzip to pack it. | ||
9 | # The script may also be used to generate the inputfile used for gen_init_cpio | ||
10 | # This script assumes that gen_init_cpio is located in usr/ directory | ||
11 | |||
12 | # error out on errors | ||
13 | set -e | ||
14 | |||
15 | usage() { | ||
16 | cat << EOF | ||
17 | Usage: | ||
18 | $0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ... | ||
19 | -o <file> Create gzipped initramfs file named <file> using | ||
20 | gen_init_cpio and gzip | ||
21 | -u <uid> User ID to map to user ID 0 (root). | ||
22 | <uid> is only meaningful if <cpio_source> | ||
23 | is a directory. | ||
24 | -g <gid> Group ID to map to group ID 0 (root). | ||
25 | <gid> is only meaningful if <cpio_source> | ||
26 | is a directory. | ||
27 | <cpio_source> File list or directory for cpio archive. | ||
28 | If <cpio_source> is a .cpio file it will be used | ||
29 | as direct input to initramfs. | ||
30 | -d Output the default cpio list. | ||
31 | |||
32 | All options except -o and -l may be repeated and are interpreted | ||
33 | sequentially and immediately. -u and -g states are preserved across | ||
34 | <cpio_source> options so an explicit "-u 0 -g 0" is required | ||
35 | to reset the root/group mapping. | ||
36 | EOF | ||
37 | } | ||
38 | |||
39 | list_default_initramfs() { | ||
40 | # echo usr/kinit/kinit | ||
41 | : | ||
42 | } | ||
12 | 43 | ||
13 | default_initramfs() { | 44 | default_initramfs() { |
14 | cat <<-EOF | 45 | cat <<-EOF >> ${output} |
15 | # This is a very simple, default initramfs | 46 | # This is a very simple, default initramfs |
16 | 47 | ||
17 | dir /dev 0755 0 0 | 48 | dir /dev 0755 0 0 |
18 | nod /dev/console 0600 0 0 c 5 1 | 49 | nod /dev/console 0600 0 0 c 5 1 |
19 | dir /root 0700 0 0 | 50 | dir /root 0700 0 0 |
51 | # file /kinit usr/kinit/kinit 0755 0 0 | ||
52 | # slink /init kinit 0755 0 0 | ||
20 | EOF | 53 | EOF |
21 | } | 54 | } |
22 | 55 | ||
@@ -42,18 +75,28 @@ filetype() { | |||
42 | return 0 | 75 | return 0 |
43 | } | 76 | } |
44 | 77 | ||
78 | list_print_mtime() { | ||
79 | : | ||
80 | } | ||
81 | |||
45 | print_mtime() { | 82 | print_mtime() { |
46 | local argv1="$1" | ||
47 | local my_mtime="0" | 83 | local my_mtime="0" |
48 | 84 | ||
49 | if [ -e "${argv1}" ]; then | 85 | if [ -e "$1" ]; then |
50 | my_mtime=$(find "${argv1}" -printf "%T@\n" | sort -r | head -n 1) | 86 | my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1) |
51 | fi | 87 | fi |
52 | 88 | ||
53 | echo "# Last modified: ${my_mtime}" | 89 | echo "# Last modified: ${my_mtime}" >> ${output} |
54 | echo | 90 | echo "" >> ${output} |
91 | } | ||
92 | |||
93 | list_parse() { | ||
94 | echo "$1 \\" | ||
55 | } | 95 | } |
56 | 96 | ||
97 | # for each file print a line in following format | ||
98 | # <filetype> <name> <path to file> <octal mode> <uid> <gid> | ||
99 | # for links, devices etc the format differs. See gen_init_cpio for details | ||
57 | parse() { | 100 | parse() { |
58 | local location="$1" | 101 | local location="$1" |
59 | local name="${location/${srcdir}//}" | 102 | local name="${location/${srcdir}//}" |
@@ -99,80 +142,112 @@ parse() { | |||
99 | ;; | 142 | ;; |
100 | esac | 143 | esac |
101 | 144 | ||
102 | echo "${str}" | 145 | echo "${str}" >> ${output} |
103 | 146 | ||
104 | return 0 | 147 | return 0 |
105 | } | 148 | } |
106 | 149 | ||
107 | usage() { | 150 | unknown_option() { |
108 | printf "Usage:\n" | 151 | printf "ERROR: unknown option \"$arg\"\n" >&2 |
109 | printf "$0 [ [-u <root_uid>] [-g <root_gid>] [-d | <cpio_source>] ] . . .\n" | 152 | printf "If the filename validly begins with '-', " >&2 |
110 | printf "\n" | 153 | printf "then it must be prefixed\n" >&2 |
111 | printf -- "-u <root_uid> User ID to map to user ID 0 (root).\n" | 154 | printf "by './' so that it won't be interpreted as an option." >&2 |
112 | printf " <root_uid> is only meaningful if <cpio_source>\n" | 155 | printf "\n" >&2 |
113 | printf " is a directory.\n" | 156 | usage >&2 |
114 | printf -- "-g <root_gid> Group ID to map to group ID 0 (root).\n" | 157 | exit 1 |
115 | printf " <root_gid> is only meaningful if <cpio_source>\n" | 158 | } |
116 | printf " is a directory.\n" | 159 | |
117 | printf "<cpio_source> File list or directory for cpio archive.\n" | 160 | list_header() { |
118 | printf " If <cpio_source> is not provided then a\n" | 161 | echo "deps_initramfs := \\" |
119 | printf " a default list will be output.\n" | 162 | } |
120 | printf -- "-d Output the default cpio list. If no <cpio_source>\n" | 163 | |
121 | printf " is given then the default cpio list will be output.\n" | 164 | header() { |
122 | printf "\n" | 165 | printf "\n#####################\n# $1\n" >> ${output} |
123 | printf "All options may be repeated and are interpreted sequentially\n" | 166 | } |
124 | printf "and immediately. -u and -g states are preserved across\n" | 167 | |
125 | printf "<cpio_source> options so an explicit \"-u 0 -g 0\" is required\n" | 168 | # process one directory (incl sub-directories) |
126 | printf "to reset the root/group mapping.\n" | 169 | dir_filelist() { |
170 | ${dep_list}header "$1" | ||
171 | |||
172 | srcdir=$(echo "$1" | sed -e 's://*:/:g') | ||
173 | dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null) | ||
174 | |||
175 | # If $dirlist is only one line, then the directory is empty | ||
176 | if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then | ||
177 | ${dep_list}print_mtime "$1" | ||
178 | |||
179 | echo "${dirlist}" | \ | ||
180 | while read x; do | ||
181 | ${dep_list}parse ${x} | ||
182 | done | ||
183 | fi | ||
127 | } | 184 | } |
128 | 185 | ||
129 | build_list() { | 186 | # if only one file is specified and it is .cpio file then use it direct as fs |
130 | printf "\n#####################\n# $cpio_source\n" | 187 | # if a directory is specified then add all files in given direcotry to fs |
131 | 188 | # if a regular file is specified assume it is in gen_initramfs format | |
132 | if [ -f "$cpio_source" ]; then | 189 | input_file() { |
133 | print_mtime "$cpio_source" | 190 | source="$1" |
134 | cat "$cpio_source" | 191 | if [ -f "$1" ]; then |
135 | elif [ -d "$cpio_source" ]; then | 192 | ${dep_list}header "$1" |
136 | srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g') | 193 | is_cpio="$(echo "$1" | sed 's/^.*\.cpio/cpio/')" |
137 | dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null) | 194 | if [ $2 -eq 0 -a ${is_cpio} == "cpio" ]; then |
138 | 195 | cpio_file=$1 | |
139 | # If $dirlist is only one line, then the directory is empty | 196 | [ ! -z ${dep_list} ] && echo "$1" |
140 | if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then | 197 | return 0 |
141 | print_mtime "$cpio_source" | 198 | fi |
142 | 199 | if [ -z ${dep_list} ]; then | |
143 | echo "${dirlist}" | \ | 200 | print_mtime "$1" >> ${output} |
144 | while read x; do | 201 | cat "$1" >> ${output} |
145 | parse ${x} | ||
146 | done | ||
147 | else | 202 | else |
148 | # Failsafe in case directory is empty | 203 | grep ^file "$1" | cut -d ' ' -f 3 |
149 | default_initramfs | ||
150 | fi | 204 | fi |
205 | elif [ -d "$1" ]; then | ||
206 | dir_filelist "$1" | ||
151 | else | 207 | else |
152 | echo " $0: Cannot open '$cpio_source'" >&2 | 208 | echo " ${prog}: Cannot open '$1'" >&2 |
153 | exit 1 | 209 | exit 1 |
154 | fi | 210 | fi |
155 | } | 211 | } |
156 | 212 | ||
157 | 213 | prog=$0 | |
158 | root_uid=0 | 214 | root_uid=0 |
159 | root_gid=0 | 215 | root_gid=0 |
216 | dep_list= | ||
217 | cpio_file= | ||
218 | cpio_list= | ||
219 | output="/dev/stdout" | ||
220 | output_file="" | ||
160 | 221 | ||
222 | arg="$1" | ||
223 | case "$arg" in | ||
224 | "-l") # files included in initramfs - used by kbuild | ||
225 | dep_list="list_" | ||
226 | shift | ||
227 | ;; | ||
228 | "-o") # generate gzipped cpio image named $1 | ||
229 | shift | ||
230 | output_file="$1" | ||
231 | cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)" | ||
232 | output=${cpio_list} | ||
233 | shift | ||
234 | ;; | ||
235 | esac | ||
161 | while [ $# -gt 0 ]; do | 236 | while [ $# -gt 0 ]; do |
162 | arg="$1" | 237 | arg="$1" |
163 | shift | 238 | shift |
164 | case "$arg" in | 239 | case "$arg" in |
165 | "-u") | 240 | "-u") # map $1 to uid=0 (root) |
166 | root_uid="$1" | 241 | root_uid="$1" |
167 | shift | 242 | shift |
168 | ;; | 243 | ;; |
169 | "-g") | 244 | "-g") # map $1 to gid=0 (root) |
170 | root_gid="$1" | 245 | root_gid="$1" |
171 | shift | 246 | shift |
172 | ;; | 247 | ;; |
173 | "-d") | 248 | "-d") # display default initramfs list |
174 | default_list="$arg" | 249 | default_list="$arg" |
175 | default_initramfs | 250 | ${dep_list}default_initramfs |
176 | ;; | 251 | ;; |
177 | "-h") | 252 | "-h") |
178 | usage | 253 | usage |
@@ -181,23 +256,27 @@ while [ $# -gt 0 ]; do | |||
181 | *) | 256 | *) |
182 | case "$arg" in | 257 | case "$arg" in |
183 | "-"*) | 258 | "-"*) |
184 | printf "ERROR: unknown option \"$arg\"\n" >&2 | 259 | unknown_option |
185 | printf "If the filename validly begins with '-', then it must be prefixed\n" >&2 | ||
186 | printf "by './' so that it won't be interpreted as an option." >&2 | ||
187 | printf "\n" >&2 | ||
188 | usage >&2 | ||
189 | exit 1 | ||
190 | ;; | 260 | ;; |
191 | *) | 261 | *) # input file/dir - process it |
192 | cpio_source="$arg" | 262 | input_file "$arg" "$#" |
193 | build_list | ||
194 | ;; | 263 | ;; |
195 | esac | 264 | esac |
196 | ;; | 265 | ;; |
197 | esac | 266 | esac |
198 | done | 267 | done |
199 | 268 | ||
200 | # spit out the default cpio list if a source hasn't been specified | 269 | # If output_file is set we will generate cpio archive and gzip it |
201 | [ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs | 270 | # we are carefull to delete tmp files |
202 | 271 | if [ ! -z ${output_file} ]; then | |
272 | if [ -z ${cpio_file} ]; then | ||
273 | cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)" | ||
274 | usr/gen_init_cpio ${cpio_list} > ${cpio_tfile} | ||
275 | else | ||
276 | cpio_tfile=${cpio_file} | ||
277 | fi | ||
278 | rm ${cpio_list} | ||
279 | cat ${cpio_tfile} | gzip -f -9 - > ${output_file} | ||
280 | [ -z ${cpio_file} ] && rm ${cpio_tfile} | ||
281 | fi | ||
203 | exit 0 | 282 | exit 0 |
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 10eeae53d827..ae5ab981bb1d 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -63,20 +63,6 @@ static void check_stdin(void) | |||
63 | } | 63 | } |
64 | } | 64 | } |
65 | 65 | ||
66 | static char *fgets_check_stream(char *s, int size, FILE *stream) | ||
67 | { | ||
68 | char *ret = fgets(s, size, stream); | ||
69 | |||
70 | if (ret == NULL && feof(stream)) { | ||
71 | printf(_("aborted!\n\n")); | ||
72 | printf(_("Console input is closed. ")); | ||
73 | printf(_("Run 'make oldconfig' to update configuration.\n\n")); | ||
74 | exit(1); | ||
75 | } | ||
76 | |||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static void conf_askvalue(struct symbol *sym, const char *def) | 66 | static void conf_askvalue(struct symbol *sym, const char *def) |
81 | { | 67 | { |
82 | enum symbol_type type = sym_get_type(sym); | 68 | enum symbol_type type = sym_get_type(sym); |
@@ -114,7 +100,7 @@ static void conf_askvalue(struct symbol *sym, const char *def) | |||
114 | check_stdin(); | 100 | check_stdin(); |
115 | case ask_all: | 101 | case ask_all: |
116 | fflush(stdout); | 102 | fflush(stdout); |
117 | fgets_check_stream(line, 128, stdin); | 103 | fgets(line, 128, stdin); |
118 | return; | 104 | return; |
119 | case set_default: | 105 | case set_default: |
120 | printf("%s\n", def); | 106 | printf("%s\n", def); |
@@ -328,8 +314,7 @@ static int conf_choice(struct menu *menu) | |||
328 | printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); | 314 | printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); |
329 | def_sym = sym_get_choice_value(sym); | 315 | def_sym = sym_get_choice_value(sym); |
330 | cnt = def = 0; | 316 | cnt = def = 0; |
331 | line[0] = '0'; | 317 | line[0] = 0; |
332 | line[1] = 0; | ||
333 | for (child = menu->list; child; child = child->next) { | 318 | for (child = menu->list; child; child = child->next) { |
334 | if (!menu_is_visible(child)) | 319 | if (!menu_is_visible(child)) |
335 | continue; | 320 | continue; |
@@ -370,7 +355,7 @@ static int conf_choice(struct menu *menu) | |||
370 | check_stdin(); | 355 | check_stdin(); |
371 | case ask_all: | 356 | case ask_all: |
372 | fflush(stdout); | 357 | fflush(stdout); |
373 | fgets_check_stream(line, 128, stdin); | 358 | fgets(line, 128, stdin); |
374 | strip(line); | 359 | strip(line); |
375 | if (line[0] == '?') { | 360 | if (line[0] == '?') { |
376 | printf("\n%s\n", menu->sym->help ? | 361 | printf("\n%s\n", menu->sym->help ? |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 1b8882ddbc74..1b5df589f3ae 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -325,7 +325,7 @@ int conf_read(const char *name) | |||
325 | sym->flags |= e->right.sym->flags & SYMBOL_NEW; | 325 | sym->flags |= e->right.sym->flags & SYMBOL_NEW; |
326 | } | 326 | } |
327 | 327 | ||
328 | sym_change_count = conf_warnings && conf_unsaved; | 328 | sym_change_count = conf_warnings || conf_unsaved; |
329 | 329 | ||
330 | return 0; | 330 | return 0; |
331 | } | 331 | } |
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 09512b544375..bf8052f4fd4a 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c | |||
@@ -58,8 +58,7 @@ | |||
58 | 58 | ||
59 | #include "dialog.h" | 59 | #include "dialog.h" |
60 | 60 | ||
61 | #define ITEM_IDENT 1 /* Indent of menu entries. Fixed for all menus */ | 61 | static int menu_width, item_x; |
62 | static int menu_width; | ||
63 | 62 | ||
64 | /* | 63 | /* |
65 | * Print menu item | 64 | * Print menu item |
@@ -70,7 +69,7 @@ static void do_print_item(WINDOW * win, const char *item, int choice, | |||
70 | int j; | 69 | int j; |
71 | char *menu_item = malloc(menu_width + 1); | 70 | char *menu_item = malloc(menu_width + 1); |
72 | 71 | ||
73 | strncpy(menu_item, item, menu_width - ITEM_IDENT); | 72 | strncpy(menu_item, item, menu_width - item_x); |
74 | menu_item[menu_width] = 0; | 73 | menu_item[menu_width] = 0; |
75 | j = first_alpha(menu_item, "YyNnMmHh"); | 74 | j = first_alpha(menu_item, "YyNnMmHh"); |
76 | 75 | ||
@@ -87,13 +86,13 @@ static void do_print_item(WINDOW * win, const char *item, int choice, | |||
87 | wclrtoeol(win); | 86 | wclrtoeol(win); |
88 | #endif | 87 | #endif |
89 | wattrset(win, selected ? item_selected_attr : item_attr); | 88 | wattrset(win, selected ? item_selected_attr : item_attr); |
90 | mvwaddstr(win, choice, ITEM_IDENT, menu_item); | 89 | mvwaddstr(win, choice, item_x, menu_item); |
91 | if (hotkey) { | 90 | if (hotkey) { |
92 | wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); | 91 | wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); |
93 | mvwaddch(win, choice, ITEM_IDENT + j, menu_item[j]); | 92 | mvwaddch(win, choice, item_x + j, menu_item[j]); |
94 | } | 93 | } |
95 | if (selected) { | 94 | if (selected) { |
96 | wmove(win, choice, ITEM_IDENT + 1); | 95 | wmove(win, choice, item_x + 1); |
97 | } | 96 | } |
98 | free(menu_item); | 97 | free(menu_item); |
99 | wrefresh(win); | 98 | wrefresh(win); |
@@ -227,6 +226,8 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
227 | draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, | 226 | draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, |
228 | menubox_border_attr, menubox_attr); | 227 | menubox_border_attr, menubox_attr); |
229 | 228 | ||
229 | item_x = (menu_width - 70) / 2; | ||
230 | |||
230 | /* Set choice to default item */ | 231 | /* Set choice to default item */ |
231 | for (i = 0; i < item_no; i++) | 232 | for (i = 0; i < item_no; i++) |
232 | if (strcmp(current, items[i * 2]) == 0) | 233 | if (strcmp(current, items[i * 2]) == 0) |
@@ -263,10 +264,10 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
263 | wnoutrefresh(menu); | 264 | wnoutrefresh(menu); |
264 | 265 | ||
265 | print_arrows(dialog, item_no, scroll, | 266 | print_arrows(dialog, item_no, scroll, |
266 | box_y, box_x + ITEM_IDENT + 1, menu_height); | 267 | box_y, box_x + item_x + 1, menu_height); |
267 | 268 | ||
268 | print_buttons(dialog, height, width, 0); | 269 | print_buttons(dialog, height, width, 0); |
269 | wmove(menu, choice, ITEM_IDENT + 1); | 270 | wmove(menu, choice, item_x + 1); |
270 | wrefresh(menu); | 271 | wrefresh(menu); |
271 | 272 | ||
272 | while (key != ESC) { | 273 | while (key != ESC) { |
@@ -349,7 +350,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
349 | print_item(scroll + choice, choice, TRUE); | 350 | print_item(scroll + choice, choice, TRUE); |
350 | 351 | ||
351 | print_arrows(dialog, item_no, scroll, | 352 | print_arrows(dialog, item_no, scroll, |
352 | box_y, box_x + ITEM_IDENT + 1, menu_height); | 353 | box_y, box_x + item_x + 1, menu_height); |
353 | 354 | ||
354 | wnoutrefresh(dialog); | 355 | wnoutrefresh(dialog); |
355 | wrefresh(menu); | 356 | wrefresh(menu); |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0b92ddff26fd..7e8079a34adf 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -658,7 +658,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
658 | warn("%s - Section mismatch: reference to %s:%s from %s " | 658 | warn("%s - Section mismatch: reference to %s:%s from %s " |
659 | "before '%s' (at offset -0x%llx)\n", | 659 | "before '%s' (at offset -0x%llx)\n", |
660 | modname, secname, refsymname, fromsec, | 660 | modname, secname, refsymname, fromsec, |
661 | elf->strtab + before->st_name, | 661 | elf->strtab + after->st_name, |
662 | (long long)r.r_offset); | 662 | (long long)r.r_offset); |
663 | } else { | 663 | } else { |
664 | warn("%s - Section mismatch: reference to %s:%s from %s " | 664 | warn("%s - Section mismatch: reference to %s:%s from %s " |
diff --git a/scripts/namespace.pl b/scripts/namespace.pl index f34373853ef8..f34373853ef8 100644..100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl | |||
diff --git a/scripts/show_delta b/scripts/show_delta index 48a706ab3d0c..48a706ab3d0c 100644..100755 --- a/scripts/show_delta +++ b/scripts/show_delta | |||
diff --git a/scripts/ver_linux b/scripts/ver_linux index beb43ef7f761..84999f69773d 100755 --- a/scripts/ver_linux +++ b/scripts/ver_linux | |||
@@ -39,10 +39,10 @@ tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \ | |||
39 | fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \ | 39 | fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \ |
40 | 'NR==1 {print "jfsutils ", $3}' | 40 | 'NR==1 {print "jfsutils ", $3}' |
41 | 41 | ||
42 | reiserfsck -V 2>&1 | grep reiserfsck | awk \ | 42 | reiserfsck -V 2>&1 | grep ^reiserfsck | awk \ |
43 | 'NR==1{print "reiserfsprogs ", $2}' | 43 | 'NR==1{print "reiserfsprogs ", $2}' |
44 | 44 | ||
45 | fsck.reiser4 -V 2>&1 | grep fsck.reiser4 | awk \ | 45 | fsck.reiser4 -V 2>&1 | grep ^fsck.reiser4 | awk \ |
46 | 'NR==1{print "reiser4progs ", $2}' | 46 | 'NR==1{print "reiser4progs ", $2}' |
47 | 47 | ||
48 | xfs_db -V 2>&1 | grep version | awk \ | 48 | xfs_db -V 2>&1 | grep version | awk \ |
diff --git a/security/keys/key.c b/security/keys/key.c index a057e3311aad..b6061fa29da7 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -785,6 +785,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
785 | 785 | ||
786 | key_check(keyring); | 786 | key_check(keyring); |
787 | 787 | ||
788 | key_ref = ERR_PTR(-ENOTDIR); | ||
789 | if (keyring->type != &key_type_keyring) | ||
790 | goto error_2; | ||
791 | |||
788 | down_write(&keyring->sem); | 792 | down_write(&keyring->sem); |
789 | 793 | ||
790 | /* if we're going to allocate a new key, we're going to have | 794 | /* if we're going to allocate a new key, we're going to have |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index d65a180f888d..bffa924c1f88 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -437,6 +437,7 @@ EXPORT_SYMBOL(keyring_search); | |||
437 | /* | 437 | /* |
438 | * search the given keyring only (no recursion) | 438 | * search the given keyring only (no recursion) |
439 | * - keyring must be locked by caller | 439 | * - keyring must be locked by caller |
440 | * - caller must guarantee that the keyring is a keyring | ||
440 | */ | 441 | */ |
441 | key_ref_t __keyring_search_one(key_ref_t keyring_ref, | 442 | key_ref_t __keyring_search_one(key_ref_t keyring_ref, |
442 | const struct key_type *ktype, | 443 | const struct key_type *ktype, |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index f6940618e345..217a0bef3c82 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -168,11 +168,12 @@ error: | |||
168 | */ | 168 | */ |
169 | int install_process_keyring(struct task_struct *tsk) | 169 | int install_process_keyring(struct task_struct *tsk) |
170 | { | 170 | { |
171 | unsigned long flags; | ||
172 | struct key *keyring; | 171 | struct key *keyring; |
173 | char buf[20]; | 172 | char buf[20]; |
174 | int ret; | 173 | int ret; |
175 | 174 | ||
175 | might_sleep(); | ||
176 | |||
176 | if (!tsk->signal->process_keyring) { | 177 | if (!tsk->signal->process_keyring) { |
177 | sprintf(buf, "_pid.%u", tsk->tgid); | 178 | sprintf(buf, "_pid.%u", tsk->tgid); |
178 | 179 | ||
@@ -183,12 +184,12 @@ int install_process_keyring(struct task_struct *tsk) | |||
183 | } | 184 | } |
184 | 185 | ||
185 | /* attach keyring */ | 186 | /* attach keyring */ |
186 | spin_lock_irqsave(&tsk->sighand->siglock, flags); | 187 | spin_lock_irq(&tsk->sighand->siglock); |
187 | if (!tsk->signal->process_keyring) { | 188 | if (!tsk->signal->process_keyring) { |
188 | tsk->signal->process_keyring = keyring; | 189 | tsk->signal->process_keyring = keyring; |
189 | keyring = NULL; | 190 | keyring = NULL; |
190 | } | 191 | } |
191 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); | 192 | spin_unlock_irq(&tsk->sighand->siglock); |
192 | 193 | ||
193 | key_put(keyring); | 194 | key_put(keyring); |
194 | } | 195 | } |
@@ -207,38 +208,37 @@ error: | |||
207 | static int install_session_keyring(struct task_struct *tsk, | 208 | static int install_session_keyring(struct task_struct *tsk, |
208 | struct key *keyring) | 209 | struct key *keyring) |
209 | { | 210 | { |
210 | unsigned long flags; | ||
211 | struct key *old; | 211 | struct key *old; |
212 | char buf[20]; | 212 | char buf[20]; |
213 | int ret; | 213 | |
214 | might_sleep(); | ||
214 | 215 | ||
215 | /* create an empty session keyring */ | 216 | /* create an empty session keyring */ |
216 | if (!keyring) { | 217 | if (!keyring) { |
217 | sprintf(buf, "_ses.%u", tsk->tgid); | 218 | sprintf(buf, "_ses.%u", tsk->tgid); |
218 | 219 | ||
219 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | 220 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); |
220 | if (IS_ERR(keyring)) { | 221 | if (IS_ERR(keyring)) |
221 | ret = PTR_ERR(keyring); | 222 | return PTR_ERR(keyring); |
222 | goto error; | ||
223 | } | ||
224 | } | 223 | } |
225 | else { | 224 | else { |
226 | atomic_inc(&keyring->usage); | 225 | atomic_inc(&keyring->usage); |
227 | } | 226 | } |
228 | 227 | ||
229 | /* install the keyring */ | 228 | /* install the keyring */ |
230 | spin_lock_irqsave(&tsk->sighand->siglock, flags); | 229 | spin_lock_irq(&tsk->sighand->siglock); |
231 | old = rcu_dereference(tsk->signal->session_keyring); | 230 | old = tsk->signal->session_keyring; |
232 | rcu_assign_pointer(tsk->signal->session_keyring, keyring); | 231 | rcu_assign_pointer(tsk->signal->session_keyring, keyring); |
233 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); | 232 | spin_unlock_irq(&tsk->sighand->siglock); |
234 | 233 | ||
235 | ret = 0; | 234 | /* we're using RCU on the pointer, but there's no point synchronising |
235 | * on it if it didn't previously point to anything */ | ||
236 | if (old) { | ||
237 | synchronize_rcu(); | ||
238 | key_put(old); | ||
239 | } | ||
236 | 240 | ||
237 | /* we're using RCU on the pointer */ | 241 | return 0; |
238 | synchronize_rcu(); | ||
239 | key_put(old); | ||
240 | error: | ||
241 | return ret; | ||
242 | 242 | ||
243 | } /* end install_session_keyring() */ | 243 | } /* end install_session_keyring() */ |
244 | 244 | ||
@@ -311,7 +311,6 @@ void exit_keys(struct task_struct *tsk) | |||
311 | */ | 311 | */ |
312 | int exec_keys(struct task_struct *tsk) | 312 | int exec_keys(struct task_struct *tsk) |
313 | { | 313 | { |
314 | unsigned long flags; | ||
315 | struct key *old; | 314 | struct key *old; |
316 | 315 | ||
317 | /* newly exec'd tasks don't get a thread keyring */ | 316 | /* newly exec'd tasks don't get a thread keyring */ |
@@ -323,10 +322,10 @@ int exec_keys(struct task_struct *tsk) | |||
323 | key_put(old); | 322 | key_put(old); |
324 | 323 | ||
325 | /* discard the process keyring from a newly exec'd task */ | 324 | /* discard the process keyring from a newly exec'd task */ |
326 | spin_lock_irqsave(&tsk->sighand->siglock, flags); | 325 | spin_lock_irq(&tsk->sighand->siglock); |
327 | old = tsk->signal->process_keyring; | 326 | old = tsk->signal->process_keyring; |
328 | tsk->signal->process_keyring = NULL; | 327 | tsk->signal->process_keyring = NULL; |
329 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); | 328 | spin_unlock_irq(&tsk->sighand->siglock); |
330 | 329 | ||
331 | key_put(old); | 330 | key_put(old); |
332 | 331 | ||
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index dfab6c886698..abe99d881376 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -281,7 +281,7 @@ u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) | |||
281 | int i; | 281 | int i; |
282 | 282 | ||
283 | for (i = sp->len-1; i >= 0; i--) { | 283 | for (i = sp->len-1; i >= 0; i--) { |
284 | struct xfrm_state *x = sp->x[i].xvec; | 284 | struct xfrm_state *x = sp->xvec[i]; |
285 | if (selinux_authorizable_xfrm(x)) { | 285 | if (selinux_authorizable_xfrm(x)) { |
286 | struct xfrm_sec_ctx *ctx = x->security; | 286 | struct xfrm_sec_ctx *ctx = x->security; |
287 | return ctx->ctx_sid; | 287 | return ctx->ctx_sid; |
@@ -314,7 +314,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) | |||
314 | * Only need to verify the existence of an authorizable sp. | 314 | * Only need to verify the existence of an authorizable sp. |
315 | */ | 315 | */ |
316 | for (i = 0; i < sp->len; i++) { | 316 | for (i = 0; i < sp->len; i++) { |
317 | struct xfrm_state *x = sp->x[i].xvec; | 317 | struct xfrm_state *x = sp->xvec[i]; |
318 | 318 | ||
319 | if (x && selinux_authorizable_xfrm(x)) | 319 | if (x && selinux_authorizable_xfrm(x)) |
320 | goto accept; | 320 | goto accept; |
diff --git a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c index 0cd44a6f7ac0..3721c5857b90 100644 --- a/sound/oss/emu10k1/main.c +++ b/sound/oss/emu10k1/main.c | |||
@@ -94,6 +94,7 @@ | |||
94 | #include <linux/init.h> | 94 | #include <linux/init.h> |
95 | #include <linux/delay.h> | 95 | #include <linux/delay.h> |
96 | #include <linux/proc_fs.h> | 96 | #include <linux/proc_fs.h> |
97 | #include <linux/dma-mapping.h> | ||
97 | 98 | ||
98 | #include "hwaccess.h" | 99 | #include "hwaccess.h" |
99 | #include "8010.h" | 100 | #include "8010.h" |
@@ -119,7 +120,7 @@ | |||
119 | 120 | ||
120 | 121 | ||
121 | /* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */ | 122 | /* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */ |
122 | #define EMU10K1_DMA_MASK 0x1fffffff /* DMA buffer mask for pci_alloc_consist */ | 123 | #define EMU10K1_DMA_MASK DMA_29BIT_MASK /* DMA buffer mask for pci_alloc_consist */ |
123 | 124 | ||
124 | #ifndef PCI_VENDOR_ID_CREATIVE | 125 | #ifndef PCI_VENDOR_ID_CREATIVE |
125 | #define PCI_VENDOR_ID_CREATIVE 0x1102 | 126 | #define PCI_VENDOR_ID_CREATIVE 0x1102 |
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 37b80570a5c6..91899f87f037 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/dma-mapping.h> | ||
38 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
39 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
40 | 41 | ||
@@ -691,8 +692,8 @@ static int __devinit snd_als300_create(snd_card_t *card, | |||
691 | if ((err = pci_enable_device(pci)) < 0) | 692 | if ((err = pci_enable_device(pci)) < 0) |
692 | return err; | 693 | return err; |
693 | 694 | ||
694 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 695 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
695 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 696 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
696 | printk(KERN_ERR "error setting 28bit DMA mask\n"); | 697 | printk(KERN_ERR "error setting 28bit DMA mask\n"); |
697 | pci_disable_device(pci); | 698 | pci_disable_device(pci); |
698 | return -ENXIO; | 699 | return -ENXIO; |
diff --git a/usr/Makefile b/usr/Makefile index e2129cb570bb..19d74e6f2685 100644 --- a/usr/Makefile +++ b/usr/Makefile | |||
@@ -1,65 +1,48 @@ | |||
1 | # | ||
2 | # kbuild file for usr/ - including initramfs image | ||
3 | # | ||
1 | 4 | ||
2 | obj-y := initramfs_data.o | 5 | klibcdirs:; |
3 | |||
4 | hostprogs-y := gen_init_cpio | ||
5 | 6 | ||
6 | clean-files := initramfs_data.cpio.gz initramfs_list | 7 | # Generate builtin.o based on initramfs_data.o |
8 | obj-y := initramfs_data.o | ||
7 | 9 | ||
8 | # initramfs_data.o contains the initramfs_data.cpio.gz image. | 10 | # initramfs_data.o contains the initramfs_data.cpio.gz image. |
9 | # The image is included using .incbin, a dependency which is not | 11 | # The image is included using .incbin, a dependency which is not |
10 | # tracked automatically. | 12 | # tracked automatically. |
11 | $(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE | 13 | $(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE |
12 | 14 | ||
13 | ifdef CONFIG_INITRAMFS_ROOT_UID | 15 | ##### |
14 | gen_initramfs_args += -u $(CONFIG_INITRAMFS_ROOT_UID) | 16 | # Generate the initramfs cpio archive |
15 | endif | 17 | |
16 | 18 | hostprogs-y := gen_init_cpio | |
17 | ifdef CONFIG_INITRAMFS_ROOT_GID | 19 | initramfs := $(CONFIG_SHELL) $(srctree)/scripts/gen_initramfs_list.sh |
18 | gen_initramfs_args += -g $(CONFIG_INITRAMFS_ROOT_GID) | 20 | ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \ |
19 | endif | 21 | $(CONFIG_INITRAMFS_SOURCE),-d) |
20 | 22 | ramfs-args := \ | |
21 | # The $(shell echo $(CONFIG_INITRAMFS_SOURCE)) is to remove the | 23 | $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \ |
22 | # gratuitous begin and end quotes from the Kconfig string type. | 24 | $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) \ |
23 | # Internal, escaped quotes in the Kconfig string will loose the | 25 | $(ramfs-input) |
24 | # escape and become active quotes. | 26 | |
25 | quotefixed_initramfs_source := $(shell echo $(CONFIG_INITRAMFS_SOURCE)) | 27 | # .initramfs_data.cpio.gz.d is used to identify all files included |
26 | 28 | # in initramfs and to detect if any files are added/removed. | |
27 | filechk_initramfs_list = $(CONFIG_SHELL) \ | 29 | # Removed files are identified by directory timestamp being updated |
28 | $(srctree)/scripts/gen_initramfs_list.sh $(gen_initramfs_args) $(quotefixed_initramfs_source) | 30 | # The dependency list is generated by gen_initramfs.sh -l |
29 | 31 | ifneq ($(wildcard $(obj)/.initramfs_data.cpio.gz.d),) | |
30 | $(obj)/initramfs_list: $(obj)/Makefile FORCE | 32 | include $(obj)/.initramfs_data.cpio.gz.d |
31 | $(call filechk,initramfs_list) | ||
32 | |||
33 | quiet_cmd_cpio = CPIO $@ | ||
34 | cmd_cpio = ./$< $(obj)/initramfs_list > $@ | ||
35 | |||
36 | |||
37 | # Check if the INITRAMFS_SOURCE is a cpio archive | ||
38 | ifneq (,$(findstring .cpio,$(quotefixed_initramfs_source))) | ||
39 | |||
40 | # INITRAMFS_SOURCE has a cpio archive - verify that it's a single file | ||
41 | ifneq (1,$(words $(quotefixed_initramfs_source))) | ||
42 | $(error Only a single file may be specified in CONFIG_INITRAMFS_SOURCE (="$(quotefixed_initramfs_source)") when a cpio archive is directly specified.) | ||
43 | endif | ||
44 | # Now use the cpio archive directly | ||
45 | initramfs_data_cpio = $(quotefixed_initramfs_source) | ||
46 | targets += $(quotefixed_initramfs_source) | ||
47 | |||
48 | else | ||
49 | |||
50 | # INITRAMFS_SOURCE is not a cpio archive - create one | ||
51 | $(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio \ | ||
52 | $(initramfs-y) $(obj)/initramfs_list FORCE | ||
53 | $(call if_changed,cpio) | ||
54 | |||
55 | targets += initramfs_data.cpio | ||
56 | initramfs_data_cpio = $(obj)/initramfs_data.cpio | ||
57 | |||
58 | endif | 33 | endif |
59 | 34 | ||
60 | 35 | quiet_cmd_initfs = GEN $@ | |
61 | $(obj)/initramfs_data.cpio.gz: $(initramfs_data_cpio) FORCE | 36 | cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) |
62 | $(call if_changed,gzip) | 37 | |
63 | 38 | targets := initramfs_data.cpio.gz | |
64 | targets += initramfs_data.cpio.gz | 39 | $(deps_initramfs): klibcdirs |
40 | # We rebuild initramfs_data.cpio.gz if: | ||
41 | # 1) Any included file is newer then initramfs_data.cpio.gz | ||
42 | # 2) There are changes in which files are included (added or deleted) | ||
43 | # 3) If gen_init_cpio are newer than initramfs_data.cpio.gz | ||
44 | # 4) arguments to gen_initramfs.sh changes | ||
45 | $(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs | ||
46 | $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.gz.d | ||
47 | $(call if_changed,initfs) | ||
65 | 48 | ||